001: /*
002: * Copyright 2004-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.springframework.webflow.conversation.impl;
017:
018: import java.io.Serializable;
019: import java.util.ArrayList;
020: import java.util.Iterator;
021: import java.util.List;
022:
023: import org.springframework.webflow.conversation.Conversation;
024: import org.springframework.webflow.conversation.ConversationId;
025: import org.springframework.webflow.conversation.ConversationParameters;
026: import org.springframework.webflow.conversation.NoSuchConversationException;
027:
028: /**
029: * Container for conversations that is stored in the session. When the
030: * session expires this container will go with it, implicitly expiring all
031: * contained conversations.
032: * <p>
033: * This is an internal helper class of the {@link SessionBindingConversationManager}.
034: *
035: * @author Erwin Vervaet
036: */
037: class ConversationContainer implements Serializable {
038:
039: /**
040: * Maximum number of conversations in this container. -1 for
041: * unlimited.
042: */
043: private int maxConversations;
044:
045: /**
046: * The key of this conversation container in the session.
047: */
048: private String sessionKey;
049:
050: /**
051: * The contained conversations. A list of {@link ContainedConversation} objects.
052: */
053: private List conversations;
054:
055: /**
056: * Create a new conversation container.
057: * @param maxConversations the maximum number of allowed concurrent
058: * conversations, -1 for unlimited
059: * @param sessionKey the key of this conversation container in the session
060: */
061: public ConversationContainer(int maxConversations, String sessionKey) {
062: this .maxConversations = maxConversations;
063: this .sessionKey = sessionKey;
064: this .conversations = new ArrayList();
065: }
066:
067: /**
068: * Returns the key of this conversation container in the session.
069: * For package level use only.
070: */
071: String getSessionKey() {
072: return sessionKey;
073: }
074:
075: /**
076: * Returns the current size of the conversation container: the number
077: * of conversations contained within it.
078: */
079: public int size() {
080: return conversations.size();
081: }
082:
083: /**
084: * Create a new conversation based on given parameters and add it to the
085: * container.
086: * @param id the unique id of the conversation
087: * @param parameters descriptive parameters
088: * @return the created conversation
089: */
090: public synchronized Conversation createAndAddConversation(
091: ConversationId id, ConversationParameters parameters) {
092: ContainedConversation conversation = new ContainedConversation(
093: this , id);
094: conversations.add(conversation);
095: if (maxExceeded()) {
096: // end oldest conversation
097: ((Conversation) conversations.get(0)).end();
098: }
099: return conversation;
100: }
101:
102: /**
103: * Return the identified conversation.
104: * @param id the id to lookup
105: * @return the conversation
106: * @throws NoSuchConversationException if the conversation cannot be
107: * found
108: */
109: public synchronized Conversation getConversation(ConversationId id)
110: throws NoSuchConversationException {
111: for (Iterator it = conversations.iterator(); it.hasNext();) {
112: ContainedConversation conversation = (ContainedConversation) it
113: .next();
114: if (conversation.getId().equals(id)) {
115: return conversation;
116: }
117: }
118: throw new NoSuchConversationException(id);
119: }
120:
121: /**
122: * Remove identified conversation from this container.
123: */
124: public synchronized void removeConversation(ConversationId id) {
125: for (Iterator it = conversations.iterator(); it.hasNext();) {
126: ContainedConversation conversation = (ContainedConversation) it
127: .next();
128: if (conversation.getId().equals(id)) {
129: it.remove();
130: break;
131: }
132: }
133: }
134:
135: /**
136: * Has the maximum number of allowed concurrent conversations in the
137: * session been exceeded?
138: */
139: private boolean maxExceeded() {
140: return maxConversations > 0
141: && conversations.size() > maxConversations;
142: }
143: }
|