| Target | ConversationId |
|---|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- We need a doctype to allow us to use special characters like
We use a "strict" DTD to make IE follow the alignment rules. -->
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
<head>
<link rel="stylesheet" type="text/css" href="${context:css/examples/conversationslist.css}"/>
</head>
<body>
<h1>Conversations List</h1>
This page shows which "conversations" are in your session. The Wizard examples use conversations.<br/>
<div class="eg">
<table class="grid">
<tr>
<th>Target</th>
<th>ConversationId</th>
</tr>
<tr t:type="Loop" t:source="allConversations" t:value="conversation">
<td>${object.class}</td>
<td><a t:type="eventlink" t:event="GoTo" t:context="conversation.id" href="#">${conversation.id}</a></td>
</tr>
</table>
<div t:type="if" t:test="allConversations" t:negate="true">
<div class="nodata">(No Conversations to display)</div>
</div>
</div>
References:
<a href="http://tapestry.apache.org/session-storage.html">Session Storage</a>.<br/><br/>
<a t:type="pagelink" t:page="Index" href="#">Home</a><br/><br/>
<t:sourcecodedisplay src="/web/src/main/java/jumpstart/web/pages/examples/wizard/ConversationsList.tml"/>
<t:sourcecodedisplay src="/web/src/main/java/jumpstart/web/pages/examples/wizard/ConversationsList.java"/>
<t:sourcecodedisplay src="/web/src/main/java/jumpstart/web/css/examples/conversationslist.css"/>
<t:sourcecodedisplay src="/web/src/main/java/jumpstart/web/model/Conversation.java"/>
<t:sourcecodedisplay src="/web/src/main/java/jumpstart/web/model/Conversations.java"/>
</body>
</html>
package jumpstart.web.pages.examples.wizard;
import java.util.Collection;
import jumpstart.web.base.examples.wizard.WizardConversationalPage;
import jumpstart.web.model.Conversation;
import jumpstart.web.model.Conversations;
import org.apache.tapestry5.annotations.InjectPage;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.annotations.SessionState;
public class ConversationsList {
// Screen fields
@Property
private Collection<Conversation> allConversations;
@Property
private Conversation conversation;
// Other pages
@InjectPage
private WizardUsingPages1 creditRequestsWizard;
// Generally useful bits and pieces
@SessionState
private Conversations conversations;
// The code
void setupRender() {
allConversations = conversations.getAll();
}
Object onGoTo(String conversationId) throws Exception {
Conversation conversation = conversations.get(conversationId);
if (conversation != null) {
// We know of 1 type of conversation only - it belongs to the credit requests wizard
if (conversation.getObject(WizardConversationalPage.CREDIT_REQUEST_KEY) != null) {
creditRequestsWizard.set(conversationId);
return creditRequestsWizard;
}
}
return null;
}
public Object getObject() throws Exception {
if (conversation != null) {
// We know of 1 type of conversation only - it belongs to the credit requests wizard
Object object = conversation.getObject(WizardConversationalPage.CREDIT_REQUEST_KEY);
return object;
}
return null;
}
}
body { font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px; font-weight: normal; color: #333;
line-height: 17px; }
h1 { font-size: 26px; line-height: 20px; } /* For IE 7 */
.eg { margin: 20px 0; padding: 20px;
border: 1px solid #ddd; border-radius: 4px; -webkit-border-radius: 4px; -mox-border-radius: 4px; }
a { text-decoration: none; color: #3D69B6; }
a:hover { text-decoration: underline; }
.grid { border-collapse: collapse; border-spacing: 0; border: 1px solid #ddd; font-size: 13px; }
.grid tr { border-top: 1px solid #f8f8f8; }
.grid th { padding: 3px 5px; text-align: left; width: 400px; border: 1px solid #ddd;
font-weight: normal; background-color: #eee;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbfbfb', endColorstr='#e4e4e4'); /* for IE */
background: -webkit-gradient(linear, left top, left bottom, from(#fbfbfb), to(#e4e4e4)); /* for webkit browsers */
background: -moz-linear-gradient(top, #fbfbfb, #e4e4e4); /* for firefox 3.6+ */ }
.grid td { padding: 3px 5px; text-align:left; }
.nodata { margin-top: 5px; margin-left:40px; }
package jumpstart.web.model;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class Conversation {
private String id;
private Map<Object, Object> objectsByKey = null;
public Conversation(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setObject(Object key, Object obj) {
if (objectsByKey == null) {
objectsByKey = new HashMap<Object, Object>(1);
}
objectsByKey.put(key, obj);
}
public Object getObject(Object key) {
if (objectsByKey == null) {
return null;
}
else {
return objectsByKey.get(key);
}
}
public String toString() {
final String DIVIDER = ", ";
StringBuilder buf = new StringBuilder();
buf.append(this.getClass().getSimpleName() + ": ");
buf.append("[");
buf.append("id=" + id + DIVIDER);
buf.append("objectsByKey=");
if (objectsByKey == null) {
buf.append("null");
}
else {
buf.append("{");
for (Iterator<Object> iterator = objectsByKey.keySet().iterator(); iterator.hasNext();) {
Object key = (Object) iterator.next();
buf.append("(" + key + "," + "<" + objectsByKey.get(key) == null ? "null" : objectsByKey.get(key).getClass()
.getSimpleName()
+ ">" + ")");
}
buf.append("}");
}
buf.append("]");
return buf.toString();
}
}
package jumpstart.web.model;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class Conversations {
private Map<String, Integer> counters = new HashMap<String, Integer>();
private Map<String, Conversation> conversations = new HashMap<String, Conversation>();
public String startConversation() {
return startConversation("dEfAuLt");
}
public synchronized String startConversation(String conversationIdPrefix) {
int conversationNumber = incrementCounter(conversationIdPrefix);
String conversationId = conversationIdPrefix + Integer.toString(conversationNumber);
startConversationForId(conversationId);
return conversationId;
}
public synchronized void startConversationForId(String conversationId) {
Conversation conversation = new Conversation(conversationId);
add(conversation);
}
public void saveToConversation(String conversationId, Object key, Object value) {
Conversation conversation = get(conversationId);
// Save a new reference to the object, just in case Tapestry cleans up the other one as we leave the page.
Object valueNewRef = value;
conversation.setObject(key, valueNewRef);
}
public Object restoreFromConversation(String conversationId, Object key) {
Conversation conversation = get(conversationId);
return conversation == null ? null : conversation.getObject(key);
}
public void endConversation(String conversationId) {
remove(conversationId);
}
public Collection<Conversation> getAll() {
return conversations.values();
}
public boolean isEmpty() {
return conversations.isEmpty();
}
private synchronized void add(Conversation conversation) {
if (conversations.containsKey(conversation.getId())) {
throw new IllegalArgumentException("Conversation already exists. conversationId = " + conversation.getId());
}
conversations.put(conversation.getId(), conversation);
}
public Conversation get(String conversationId) {
return conversations.get(conversationId);
}
private void remove(String conversationId) {
Object obj = conversations.remove(conversationId);
if (obj == null) {
throw new IllegalArgumentException("Conversation did not exist. conversationId = " + conversationId);
}
}
public synchronized int incrementCounter(String counterKey) {
if (counters == null) {
counters = new HashMap<String, Integer>(2);
}
Integer counterValue = counters.get(counterKey);
if (counterValue == null) {
counterValue = 1;
}
else {
counterValue++;
}
counters.put(counterKey, counterValue);
return counterValue;
}
public String toString() {
final String DIVIDER = ", ";
StringBuilder buf = new StringBuilder();
buf.append(this.getClass().getSimpleName() + ": ");
buf.append("[ ");
buf.append("counters=");
if (counters == null) {
buf.append("null");
}
else {
buf.append("{");
for (Iterator<String> iterator = counters.keySet().iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
buf.append("(" + key + ", " + counters.get(key) + ")");
}
buf.append("}");
}
buf.append(DIVIDER);
buf.append("conversations=");
if (conversations == null) {
buf.append("null");
}
else {
buf.append("{");
for (Iterator<String> iterator = conversations.keySet().iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
buf.append("(" + key + ", " + conversations.get(key) + ")");
}
buf.append("}");
}
buf.append("]");
return buf.toString();
}
}