KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > webflow > execution > factory > ConditionalFlowExecutionListenerLoader


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.springframework.webflow.execution.factory;
17
18 import java.util.Iterator JavaDoc;
19 import java.util.LinkedList JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Map JavaDoc;
22 import java.util.Map.Entry;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.springframework.core.style.StylerUtils;
27 import org.springframework.util.Assert;
28 import org.springframework.util.StringUtils;
29 import org.springframework.webflow.definition.FlowDefinition;
30 import org.springframework.webflow.execution.FlowExecutionListener;
31
32 /**
33  * A flow execution listener loader that stores listeners in a list-backed data
34  * structure and allows for configuration of which listeners should apply to
35  * which flow definitions. For trivial listener loading, see
36  * {@link StaticFlowExecutionListenerLoader}.
37  *
38  * @see StaticFlowExecutionListenerLoader
39  *
40  * @author Keith Donald
41  */

42 public class ConditionalFlowExecutionListenerLoader implements FlowExecutionListenerLoader {
43
44     /**
45      * Logger, usable by subclasses.
46      */

47     protected final Log logger = LogFactory.getLog(getClass());
48
49     /**
50      * The list of flow execution listeners containing
51      * {@link ConditionalFlowExecutionListenerHolder} objects. The list
52      * determines the conditions in which a single flow execution listener
53      * applies.
54      */

55     private List JavaDoc listeners = new LinkedList JavaDoc();
56
57     /**
58      * Add a listener that will listen to executions for all flows.
59      * @param listener the listener to add
60      */

61     public void addListener(FlowExecutionListener listener) {
62         addListener(listener, null);
63     }
64
65     /**
66      * Adds a collection of listeners that share a matching criteria.
67      * @param listeners the listeners
68      * @param criteria the criteria where these listeners apply
69      */

70     public void addListeners(FlowExecutionListener[] listeners, FlowExecutionListenerCriteria criteria) {
71         for (int i = 0; i < listeners.length; i++) {
72             addListener(listeners[i], criteria);
73         }
74     }
75
76     /**
77      * Add a listener that will listen to executions to flows matching the
78      * specified criteria.
79      * @param listener the listener
80      * @param criteria the listener criteria
81      */

82     public void addListener(FlowExecutionListener listener, FlowExecutionListenerCriteria criteria) {
83         if (listener == null) {
84             return;
85         }
86         if (logger.isDebugEnabled()) {
87             logger.debug("Adding flow execution listener " + listener + " with criteria " + criteria);
88         }
89         ConditionalFlowExecutionListenerHolder conditional = getHolder(listener);
90         if (conditional == null) {
91             conditional = new ConditionalFlowExecutionListenerHolder(listener);
92             listeners.add(conditional);
93         }
94         if (criteria == null) {
95             criteria = new FlowExecutionListenerCriteriaFactory().allFlows();
96         }
97         conditional.add(criteria);
98     }
99
100     /**
101      * Set the list of flow execution listeners with corresponding criteria.
102      * Allows for bean style configuration. The given map should have
103      * {@link FlowExecutionListener} objects as keys and Strings ("*", "flowId",
104      * "flowId1,flowId2") or {@link FlowExecutionListenerCriteria}
105      * objects as values. This will clear any listeners registered with
106      * this object using the <tt>addListener</tt> methods.
107      * @param listenersWithCriteria the map of listeners and their corresponding criteria
108      */

109     public void setListeners(Map JavaDoc listenersWithCriteria) {
110         removeAllListeners();
111         for (Iterator JavaDoc it = listenersWithCriteria.entrySet().iterator(); it.hasNext(); ) {
112             Entry entry = (Entry)it.next();
113             Assert.isInstanceOf(FlowExecutionListener.class, entry.getKey(),
114                     "The key in the listenersWithCriteria map needs to be a FlowExecutionListener object");
115             FlowExecutionListener listener = (FlowExecutionListener)entry.getKey();
116             FlowExecutionListenerCriteria criteria = null;
117             if (entry.getValue() instanceof String JavaDoc) {
118                 criteria = getCriteria((String JavaDoc)entry.getValue());
119             }
120             else if (entry.getValue() instanceof FlowExecutionListenerCriteria) {
121                 criteria = (FlowExecutionListenerCriteria)entry.getValue();
122             }
123             else if (entry.getValue() != null) {
124                 throw new IllegalArgumentException JavaDoc(
125                         "The value in the listenersWithCriteria map needs to be a " +
126                         "String or a FlowExecutionListenerCriteria object");
127             }
128             addListener(listener, criteria);
129         }
130     }
131
132     /**
133      * Is the given listener contained by this Flow execution manager?
134      * @param listener the listener
135      * @return true if yes, false otherwise
136      */

137     public boolean containsListener(FlowExecutionListener listener) {
138         Iterator JavaDoc it = listeners.iterator();
139         while (it.hasNext()) {
140             ConditionalFlowExecutionListenerHolder h = (ConditionalFlowExecutionListenerHolder)it.next();
141             if (h.getListener().equals(listener)) {
142                 return true;
143             }
144         }
145         return false;
146     }
147
148     /**
149      * Remove the flow execution listener from the listener list.
150      * @param listener the listener
151      */

152     public void removeListener(FlowExecutionListener listener) {
153         Iterator JavaDoc it = listeners.iterator();
154         while (it.hasNext()) {
155             ConditionalFlowExecutionListenerHolder h = (ConditionalFlowExecutionListenerHolder)it.next();
156             if (h.getListener().equals(listener)) {
157                 it.remove();
158             }
159         }
160     }
161
162     /**
163      * Remove all listeners loadable by this loader.
164      */

165     public void removeAllListeners() {
166         listeners.clear();
167     }
168
169     /**
170      * Remove the criteria for the specified listener.
171      * @param listener the listener
172      * @param criteria the criteria
173      */

174     public void removeListenerCriteria(FlowExecutionListener listener, FlowExecutionListenerCriteria criteria) {
175         if (containsListener(listener)) {
176             ConditionalFlowExecutionListenerHolder listenerHolder = getHolder(listener);
177             listenerHolder.remove(criteria);
178             if (listenerHolder.isCriteriaSetEmpty()) {
179                 removeListener(listener);
180             }
181         }
182     }
183
184     /**
185      * Returns the array of flow execution listeners for specified flow.
186      * @param flowDefinition the flow definition associated with the execution
187      * to be listened to
188      * @return the flow execution listeners that apply
189      */

190     public FlowExecutionListener[] getListeners(FlowDefinition flowDefinition) {
191         Assert.notNull(flowDefinition, "The Flow to load listeners for cannot be null");
192         List JavaDoc listenersToAttach = new LinkedList JavaDoc();
193         for (Iterator JavaDoc it = listeners.iterator(); it.hasNext();) {
194             ConditionalFlowExecutionListenerHolder listenerHolder = (ConditionalFlowExecutionListenerHolder)it.next();
195             if (listenerHolder.listenerAppliesTo(flowDefinition)) {
196                 listenersToAttach.add(listenerHolder.getListener());
197             }
198         }
199         if (logger.isDebugEnabled()) {
200             logger.debug("Loaded [" + listenersToAttach.size() + "] of possible " + listeners.size()
201                     + " listeners for this execution request for flow '" + flowDefinition.getId()
202                     + "', the listeners to attach are " + StylerUtils.style(listenersToAttach));
203         }
204         return (FlowExecutionListener[])listenersToAttach.toArray(new FlowExecutionListener[listenersToAttach.size()]);
205     }
206
207     // internal helpers
208

209     /**
210      * Lookup the listener criteria holder for the listener provided.
211      * @param listener the listener
212      * @return the holder, or null if not found
213      */

214     protected ConditionalFlowExecutionListenerHolder getHolder(FlowExecutionListener listener) {
215         Iterator JavaDoc it = listeners.iterator();
216         while (it.hasNext()) {
217             ConditionalFlowExecutionListenerHolder next = (ConditionalFlowExecutionListenerHolder)it.next();
218             if (next.getListener().equals(listener)) {
219                 return next;
220             }
221         }
222         return null;
223     }
224
225     /**
226      * Decode given string value into one of the well known criteria types.
227      * @see FlowExecutionListenerCriteriaFactory
228      */

229     protected FlowExecutionListenerCriteria getCriteria(String JavaDoc value) {
230         if ("*".equals(value)) {
231             return new FlowExecutionListenerCriteriaFactory().allFlows();
232         }
233         else {
234             String JavaDoc[] flowIds = StringUtils.commaDelimitedListToStringArray(value);
235             for (int i = 0; i < flowIds.length; i++) {
236                 flowIds[i] = flowIds[i].trim();
237             }
238             return new FlowExecutionListenerCriteriaFactory().flows(flowIds);
239         }
240     }
241
242 }
Popular Tags