KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > inversoft > verge > mvc > controller > actionflow > config > BaseNode


1 /*
2  * Copyright (c) 2003, Inversoft
3  *
4  * This software is distribuable under the GNU Lesser General Public License.
5  * For more information visit gnu.org.
6  */

7 package com.inversoft.verge.mvc.controller.actionflow.config;
8
9
10 import java.util.ArrayList JavaDoc;
11 import java.util.HashMap JavaDoc;
12 import java.util.Iterator JavaDoc;
13 import java.util.List JavaDoc;
14 import java.util.Map JavaDoc;
15
16 import org.jdom.Element;
17
18 import com.inversoft.util.StringTools;
19 import com.inversoft.verge.mvc.controller.actionflow.NodeExecutor;
20
21
22 /**
23  * This class is the base class for all Node objects
24  * that might be used in the ActionFlow system. Although it
25  * is not required that a Node extend from this class,
26  * this class is provided to reducing coding efforts.
27  *
28  * @author Brian Pontarelli
29  * @since 2.0
30  * @version 2.0
31  */

32 public class BaseNode implements Node {
33
34     /**
35      * This class is a simple struct used for passing BaseNode values
36      * around
37      */

38     public static class BaseValues {
39         public String JavaDoc name;
40         public String JavaDoc type;
41         public String JavaDoc className;
42         public String JavaDoc repositoryId;
43         public boolean defaultEntry;
44         public boolean exitPoint;
45         public NodeExecutor executor;
46         public boolean longTxnEnabled;
47         public String JavaDoc longTxnStartURL;
48         public String JavaDoc longTxnEndURL;
49         public String JavaDoc longTxnCategory;
50     }
51
52
53     /**
54      * The Map used to store the ActionLinks
55      */

56     protected Map JavaDoc namedLinks;
57
58     /**
59      * The List used to store the RegexLinks
60      */

61     protected List JavaDoc regexLinks;
62
63     /**
64      * The namespace this node belongs to
65      */

66     protected Namespace namespace;
67
68     /**
69      * The base values for this node
70      */

71     protected BaseValues values;
72
73     /**
74      * The Element that describes this Node
75      */

76     private Element element;
77
78
79     /**
80      * Constructs a new <code>BaseNode</code> with the given name, namespace,
81      * class name, default entry point flag, exit point flag and executor.
82      *
83      * @param name The name of the Node
84      * @param type The type of the Node
85      * @param namespace The namespace this Node belongs to
86      * @param className (optional) The name of the class that is the Node
87      * implementation
88      * @param repositoryId (optional) The repository id that corresponds to the
89      * implementation of this Node
90      * @param defaultEntry (optional) Sets if this Node is the default entry
91      * point for the namespace it lives in
92      * @param exitPoint (optional) Sets if this Node is an exit point
93      * @param executor (optional) The NodeExecutor used to execute the
94      * implementation of the Node
95      * @asserts If name or type are empty or null and if namespace is null
96      */

97     public BaseNode(String JavaDoc name, String JavaDoc type, Namespace namespace, String JavaDoc className,
98             String JavaDoc repositoryId, boolean defaultEntry, boolean exitPoint,
99             NodeExecutor executor) {
100         assert (!StringTools.isEmpty(name)) : "name is null or empty";
101         assert (!StringTools.isEmpty(type)) : "type is null or empty";
102         assert (namespace != null) : "namespace == null";
103
104         values = new BaseValues();
105         values.repositoryId = repositoryId;
106         values.name = name;
107         values.type = type;
108         values.className = className;
109         values.defaultEntry = defaultEntry;
110         values.exitPoint = exitPoint;
111         values.executor = executor;
112         this.namespace = namespace;
113         this.namedLinks = new HashMap JavaDoc();
114         this.regexLinks = new ArrayList JavaDoc();
115     }
116
117     /**
118      * Constructs a new <code>BaseNode</code> using the information in the
119      * {@link BaseNode.BaseValues BaseNode.BaseValues} given.
120      *
121      * @param values The BaseValues that contains the values for this Node
122      * @param namespace The Namespace this Node belongs to
123      * @asserts If values is null or namespace is null
124      */

125     public BaseNode(BaseNode.BaseValues values, Namespace namespace) {
126         assert (values != null) : "values == null";
127         assert (namespace != null) : "namespace == null";
128         assert (values.name != null) : "values.name == null";
129         assert (values.type != null) : "values.type == null";
130
131         this.values = values;
132         this.namespace = namespace;
133         this.namedLinks = new HashMap JavaDoc();
134         this.regexLinks = new ArrayList JavaDoc();
135     }
136
137     /**
138      * Constructs a new <code>BaseNode</code> that is identical to the given
139      * <code>BaseNode</code>.
140      *
141      * @param orig The original BaseNode to copy the values from
142      * @asserts If orig is null
143      */

144     public BaseNode(BaseNode orig) {
145         assert (orig != null) : "orig == null";
146
147         this.values = orig.values;
148         this.namespace = orig.namespace;
149         this.element = orig.element;
150         this.namedLinks = orig.namedLinks;
151         this.regexLinks = orig.regexLinks;
152     }
153
154
155     /**
156      * Returns the name of the Node
157      *
158      * @return The name of the Node
159      */

160     public String JavaDoc getName() {
161         return values.name;
162     }
163
164     /**
165      * Returns the type of the Node
166      *
167      * @return The type of the Node
168      */

169     public String JavaDoc getType() {
170         return values.type;
171     }
172
173     /**
174      * Returns the namespace that this Node is a part of
175      *
176      * @return The namespace of this Node
177      */

178     public Namespace getNamespace() {
179         return namespace;
180     }
181
182     /**
183      * <p>
184      * Returns the name of the class of this Node. This is the name of the class
185      * that this Node describes. This is also the class that the
186      * ActionFlow system may instantiate during execution and will be called.
187      * </p>
188      *
189      * <p>
190      * This is an optional value for the configuration. The reason for this is
191      * that the construction and execution of the Nodes is extensible and
192      * therefore the implementation may not need to use the class name or the
193      * repository id in order to locate or instantiate the Node.
194      * </p>
195      *
196      * @return The class name of the Node or null if it is not specified
197      */

198     public String JavaDoc getClassName() {
199         return values.className;
200     }
201
202     /**
203      * <p>
204      * Returns the repository id of this Node. This repository id may be used by
205      * the ActionFlow system to locate the Node during execution.
206      * </p>
207      *
208      * <p>
209      * This is an optional value for the configuration. The reason for this is
210      * that the construction and execution of the Nodes is extensible and
211      * therefore the implementation may not need to use the class name or the
212      * repository id in order to locate or instantiate the Node.
213      * </p>
214      *
215      * @return The repository id of the Node or null if it is not specified
216      */

217     public String JavaDoc getRepositoryId() {
218         return values.repositoryId;
219     }
220
221     /**
222      * Returns whether or not the Node described by this Node is the default
223      * entry Node for the ActionFlow namespace it is defined it. There can only
224      * be one default entry Node per namespace.
225      *
226      * @return True if this Node is the default entry Node, false otherwise
227      */

228     public boolean isDefaultEntry() {
229         return values.defaultEntry;
230     }
231
232     /**
233      * Always returns false so that in order to participate in wildcard type of
234      * entry sub-classes must override this method.
235      *
236      * @param name The name to check for entry node acceptance
237      * @return false
238      */

239     public boolean acceptEntry(String JavaDoc name) {
240         return false;
241     }
242
243     /**
244      * Returns whether or not the Node described by this Node is an exit
245      * Node. Exit Nodes are always executed, but execution stops after they complete.
246      * If this flag is set, the
247      * {@link com.inversoft.verge.mvc.controller.actionflow.ActionFlowExecutor
248      * ActionFlowExecutor}
249      * will not execute anything after the Node is finished executing.
250      *
251      * @return True if this Node is an exit point, false otherwise
252      */

253     public boolean isExitPoint() {
254         return values.exitPoint;
255     }
256
257     /**
258      * Returns the complete list of action links for the Node described by this
259      * Node.
260      *
261      * @return The list of action links
262      */

263     public Link [] getLinks() {
264         List JavaDoc list = new ArrayList JavaDoc(regexLinks);
265         list.addAll(namedLinks.values());
266         return (Link []) list.toArray(new Link [0]);
267     }
268
269     /**
270      * Returns the Link for the Node described by this Node that has
271      * the given action. The action is the String that the Link is associated
272      * with or an action that a particular Link accepts or an instance of an
273      * Exception that was thrown from the Node.
274      *
275      * @param action The action to find a Link for
276      * @return The Link for the given action or null
277      * @asserts If action is empty or null
278      */

279     public Link findLink(Object JavaDoc action) {
280
281         assert (action != null) : "action == null";
282
283         Link link = null;
284
285         // Search the namedLinks if the action is an Exception. This continues
286
// until the Throwable Class is hit because ExceptionLinks only work for
287
// Exceptions and if Throwable is hit, it did not find a suitable Link.
288
// If it didn't find a suitable Link return null because Exceptions are
289
// not treated as Strings at all
290
if (action instanceof Exception JavaDoc) {
291             Class JavaDoc currentClass = action.getClass();
292             while (currentClass != Throwable JavaDoc.class) {
293
294                 link = (Link) namedLinks.get(currentClass);
295                 if (link != null) {
296                     return link;
297                 }
298
299                 currentClass = currentClass.getSuperclass();
300             }
301
302             return null;
303         }
304
305         // Assume it is a string and look it up again
306
link = (Link) namedLinks.get(action);
307         if (link != null) {
308             return link;
309         }
310
311         // Search the regex links
312
Iterator JavaDoc iter = regexLinks.iterator();
313         while (iter.hasNext()) {
314             link = (Link) iter.next();
315             if (link.acceptAction(action)) {
316                 return link;
317             }
318         }
319
320         return null;
321     }
322
323     /**
324      * Adds the given Link to the the Node described by this Node.
325      * This can be used at runtime to change or augment the behavior of the
326      * ActionFlow system. If there is already an Link stored in this Node
327      * with the same action, it is replaced and returned.
328      *
329      * @param link The Link to add
330      * @return The old Link for the action, or null
331      * @asserts If link is null or of a type not supported by BaseNode
332      */

333     public Link addLink(Link link) {
334
335         assert (link != null) : "link == null";
336
337         Link old = null;
338         if (link instanceof ActionLink) {
339             old = (Link) namedLinks.put(((ActionLink) link).getAction(), link);
340         } else if (link instanceof RegexLink) {
341             regexLinks.add(link);
342         } else if (link instanceof ExceptionLink) {
343
344             // Hash the exception link based on the Class of the exception
345
old = (Link) namedLinks.put(
346                 ((ExceptionLink) link).getException().getClass(), link);
347         } else {
348             assert (false) : "The Link is a type not supported by BaseNode";
349         }
350
351         return old;
352     }
353
354     /**
355      * Returns the NodeExecutor used to execute the Node described by this
356      * Node
357      *
358      * @return The NodeExecutor for this Node
359      */

360     public NodeExecutor getExecutor() {
361         return values.executor;
362     }
363
364     /**
365      * Sets the executor used to execute the Node described by this Node
366      *
367      * @param executor The NodeExecutor for this Node
368      * @asserts If executor is null
369      */

370     public void setExecutor(NodeExecutor executor) {
371
372         assert (executor != null) : "executor == null";
373         values.executor = executor;
374     }
375
376     /**
377      * Returns whether or not long transaction support is enabled for the given
378      * Node or not. This is a configurable property of every type of Node allowing
379      * any node to be enabled for long transactions.
380      *
381      * @return True if the node is enabled for long transactions, false otherwise
382      */

383     public boolean isLongTxnEnabled() {
384         return values.longTxnEnabled;
385     }
386
387     /**
388      * Returns the URL that is displayed to the user when a long transaction is
389      * started. This URL must be local and includable dynamically on the server
390      * side.
391      *
392      * @return The long transaction start URL or null
393      */

394     public String JavaDoc getLongTxnStartURL() {
395         return values.longTxnStartURL;
396     }
397
398     /**
399      * Returns the URL that is rendered in order to redirect the user out of a
400      * long transaction in order to end the long transaction. This URL must be
401      * local and includable dynamically on the server side.
402      *
403      * @return The long transaction end URL or null
404      */

405     public String JavaDoc getLongTxnEndURL() {
406         return values.longTxnEndURL;
407     }
408
409     /**
410      * Returns the category that is available to the long transaction end URL in
411      * order to handle production deployments. This must be a valid category for
412      * use by the {@link com.inversoft.verge.util.url.URLGenerator URLGenerator}.
413      *
414      * @return The long transaction category or null
415      */

416     public String JavaDoc getLongTxnCategory() {
417         return values.longTxnCategory;
418     }
419
420
421     //-------------------------------------------------------------------------
422
// Element storage for post building
423
//-------------------------------------------------------------------------
424

425
426     /**
427      * Gets The Element that describes this Node
428      *
429      * @return The Element that describes this Node
430      */

431     public Element getElement() {
432         return element;
433     }
434
435     /**
436      * Sets The Element that describes this Node
437      *
438      * @param element The Element that describes this Node
439      */

440     public void setElement(Element element) {
441         this.element = element;
442     }
443
444     /**
445      * Returns a String representation of this Node.
446      *
447      * @return A String containing the name and type of the node
448      */

449     public String JavaDoc toString() {
450         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
451         buf.append("Node: [").append(values.name).append(" ").append(values.type);
452         buf.append("]");
453         return buf.toString();
454     }
455 }
Popular Tags