KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > core > controller > ControllerElement


1 /* ====================================================================
2  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3  *
4  * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by Jcorporate Ltd.
21  * (http://www.jcorporate.com/)."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. "Jcorporate" and product names such as "Expresso" must
26  * not be used to endorse or promote products derived from this
27  * software without prior written permission. For written permission,
28  * please contact info@jcorporate.com.
29  *
30  * 5. Products derived from this software may not be called "Expresso",
31  * or other Jcorporate product names; nor may "Expresso" or other
32  * Jcorporate product names appear in their name, without prior
33  * written permission of Jcorporate Ltd.
34  *
35  * 6. No product derived from this software may compete in the same
36  * market space, i.e. framework, without prior written permission
37  * of Jcorporate Ltd. For written permission, please contact
38  * partners@jcorporate.com.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Jcorporate Ltd. Contributions back
56  * to the project(s) are encouraged when you make modifications.
57  * Please send them to support@jcorporate.com. For more information
58  * on Jcorporate Ltd. and its products, please see
59  * <http://www.jcorporate.com/>.
60  *
61  * Portions of this software are based upon other open source
62  * products and are subject to their respective licenses.
63  */

64
65 /**
66  * Copyright 1999, 2000, 2001 Jcorporate Ltd.
67  */

68 package com.jcorporate.expresso.core.controller;
69
70 import com.jcorporate.expresso.core.misc.StringUtil;
71 import com.jcorporate.expresso.kernel.util.ClassLocator;
72 import com.jcorporate.expresso.kernel.util.FastStringBuffer;
73 import org.w3c.dom.NamedNodeMap JavaDoc;
74 import org.w3c.dom.Node JavaDoc;
75 import org.w3c.dom.NodeList JavaDoc;
76
77 import java.util.Enumeration JavaDoc;
78 import java.util.HashMap JavaDoc;
79 import java.util.Iterator JavaDoc;
80 import java.util.Map JavaDoc;
81 import java.util.Vector JavaDoc;
82
83
84 /**
85  * A ControllerElement is the superclass for the three types of objects that are
86  * produced by a Controller when it transitions from one state to another.
87  * Output, Input and Transition objects all extend this class, and share the
88  * behaviors specified here.
89  * IMPORTANT NOTE: We don't use Logging (e.g. log4j) in this object, as it
90  * is sometimes stored in session when the server shuts down, and must be able
91  * to re-instantiate from the serialized form without needing to wait for
92  * ConfigManager to be initialized.
93  */

94 public class ControllerElement
95         implements Cloneable JavaDoc,
96         java.io.Serializable JavaDoc {
97
98     /**
99      * Short name for the element
100      */

101     private String JavaDoc name;
102
103     /**
104      * Label to identify the element
105      */

106     private String JavaDoc label;
107
108     /**
109      * Type - a descriptive categorization of the output type so that
110      * automatic formatters have a chance of figuring out how to render
111      * the element.
112      */

113     private String JavaDoc type;
114
115     /**
116      * Longer description of the element (optional)
117      */

118     private String JavaDoc description;
119
120     /**
121      * How many lines does this element consist of?
122      */

123     private int lines = 1;
124
125     /**
126      * Nested items, if any
127      */

128     private Vector JavaDoc nested = null;
129
130
131     /**
132      * Parent object within which this object is nested
133      */

134     private ControllerElement parent = null;
135
136     /**
137      * Display length of the item
138      */

139     private int displayLength = 60;
140
141     /**
142      * The attributes of this ControllerElement object
143      */

144     private HashMap JavaDoc attributes = null;
145
146     /* The ControllerResponse that contains this ControllerElement */
147     private ControllerResponse myResponse = null;
148
149     /**
150      * A map of nested elements keyed by name. May be incomplete if the
151      * developer does not use unique names.
152      */

153     private Map JavaDoc mappedNested = null;
154
155
156     /**
157      * Returns the contents of this controller element
158      *
159      * @return Vector of nested content
160      */

161     public Vector JavaDoc getContents() {
162         return getNested();
163     } /* getContents() */
164
165
166     /**
167      * Default constructor
168      */

169     protected ControllerElement() {
170     }
171
172     /**
173      * Add a nested item to this element
174      *
175      * @param e A ControllerElement to nest inside this element
176      */

177     public void addNested(ControllerElement e) {
178         if (nested == null) {
179             nested = new Vector JavaDoc(3);
180         }
181
182         if (mappedNested == null) {
183             mappedNested = new HashMap JavaDoc(3);
184         }
185
186
187         nested.addElement(e);
188         mappedNested.put(e.getName(), e);
189
190         e.setParent(this);
191         ControllerResponse cr = getControllerResponse();
192         if (cr != null) {
193             e.setControllerResponse(getControllerResponse());
194         }
195     } /* addNested(ControllerElement) */
196
197
198     /**
199      * Internal method used by allNested to gather all of the items nested
200      * within an item recursively.
201      *
202      * @param t the source ControllerElement to return from
203      * @return java.util.Vector
204      */

205     private Vector JavaDoc addNestedFrom(ControllerElement t) {
206         Vector JavaDoc v = new Vector JavaDoc();
207
208         Vector JavaDoc tVec = t.getNestedOrNull();
209         if (tVec == null) {
210             return v;
211         }
212
213         ControllerElement oneElement = null;
214
215         for (Enumeration JavaDoc e = tVec.elements(); e.hasMoreElements();) {
216             oneElement = (ControllerElement) e.nextElement();
217             v.addElement(oneElement);
218
219             for (Enumeration JavaDoc e2 = addNestedFrom(oneElement).elements();
220                  e2.hasMoreElements();) {
221                 v.addElement(e2.nextElement());
222             }
223         } /* for each nested element */
224
225
226         return v;
227     } /* addNestedFrom(ControllerElement) */
228
229     /**
230      * Return the nested items from this item
231      *
232      * @return java.util.Vector
233      */

234     public Vector JavaDoc allNested() {
235         Vector JavaDoc v = new Vector JavaDoc();
236
237         for (Enumeration JavaDoc e = addNestedFrom(this).elements();
238              e.hasMoreElements();) {
239             v.addElement(e.nextElement());
240         }
241
242         return v;
243     } /* allNested() */
244
245     /**
246      * Shouldn't be normally called directly.
247      *
248      * @return created or null of the creation fails.
249      * @throws CloneNotSupportedException as per the API spec.
250      */

251     public Object JavaDoc clone()
252             throws java.lang.CloneNotSupportedException JavaDoc {
253         Object JavaDoc o = null;
254         String JavaDoc className = getClass().getName();
255
256         try {
257             Class JavaDoc c = ClassLocator.loadClass(className);
258             o = c.newInstance();
259         } catch (ClassNotFoundException JavaDoc cn) {
260             throw new IllegalArgumentException JavaDoc("State object '" + className +
261                     "' not found");
262         } catch (InstantiationException JavaDoc ie) {
263             throw new IllegalArgumentException JavaDoc("State object '" + className +
264                     "' cannot be instantiated");
265         } catch (IllegalArgumentException JavaDoc e) {
266             throw new IllegalArgumentException JavaDoc("State object '" + className +
267                     "' cannot be instantiated (IllegalArgumentException)");
268         } catch (IllegalAccessException JavaDoc iae) {
269             throw new IllegalArgumentException JavaDoc("llegal access loading " +
270                     "State object '" + className +
271                     "'");
272         }
273         synchronized (this) {
274             ControllerElement ce = (ControllerElement) o;
275             Vector JavaDoc v = this.getNestedOrNull();
276             if (v != null) {
277                 for (Enumeration JavaDoc e = v.elements(); e.hasMoreElements();) {
278                     ControllerElement oneNested = (ControllerElement) e.nextElement();
279                     ce.addNested((ControllerElement) oneNested.clone());
280                 }
281             }
282
283             String JavaDoc oneKey = null;
284             HashMap JavaDoc attribs = getAttributes();
285
286             if (attribs != null) {
287                 for (Iterator JavaDoc e2 = attribs.keySet().iterator(); e2.hasNext();) {
288                     oneKey = (String JavaDoc) e2.next();
289                     ce.setAttribute(oneKey, (String JavaDoc) attribs.get(oneKey));
290                 }
291             }
292
293             ce.description = description;
294             ce.displayLength = displayLength;
295             ce.label = label;
296             ce.lines = lines;
297             ce.name = name;
298             ce.parent = parent;
299             ce.type = type;
300         }
301
302
303         return o;
304     } /* clone() */
305
306
307     /**
308      * Base Class 'deserialization' from XML given a DOM Node N.
309      *
310      * @param n A <code>DOM Node</code> object.
311      * @return an instantiated ControllerElement
312      */

313     public static ControllerElement fromXML(Node JavaDoc n)
314             throws ControllerException {
315         ControllerElement ce = new ControllerElement();
316
317         return fromXML(n, ce);
318     }
319
320     /**
321      * Return a controller element based upon the xml fragment
322      *
323      * @param n The DOM node that represents the controller-element
324      * @param ce The created controller element subclass
325      * @return an instantiated ControllerElement
326      * @throws ControllerException if fragment is not a controller element
327      */

328     protected static ControllerElement fromXML(Node JavaDoc n, ControllerElement ce)
329             throws ControllerException {
330         if (!n.getNodeName().equals("controller-element")) {
331             throw new ControllerException("Failed To Get DOM Node of " +
332                     " type 'controller-element' Got " +
333                     n.getNodeName() + " instead.");
334         }
335
336         NamedNodeMap JavaDoc nm = n.getAttributes();
337
338         /**
339          * Load up all the Controller Element Attributes
340          */

341         Node JavaDoc attribute;
342         attribute = nm.getNamedItem("name");
343
344         if (attribute != null) {
345             ce.name = attribute.getNodeValue();
346         }
347
348         attribute = nm.getNamedItem("description");
349
350         if (attribute != null) {
351             ce.description = attribute.getNodeValue();
352         }
353
354         attribute = nm.getNamedItem("display-length");
355
356         if (attribute != null) {
357             try {
358                 ce.displayLength = Integer.parseInt(attribute.getNodeValue());
359             } catch (NumberFormatException JavaDoc nfe) {
360             }
361         }
362
363         attribute = nm.getNamedItem("label");
364
365         if (attribute != null) {
366             ce.label = attribute.getNodeValue();
367         }
368
369         attribute = nm.getNamedItem("lines");
370
371         if (attribute != null) {
372             try {
373                 ce.lines = Integer.parseInt(attribute.getNodeValue());
374             } catch (NumberFormatException JavaDoc nfe) {
375             }
376         }
377
378         attribute = nm.getNamedItem("name");
379
380         if (attribute != null) {
381             ce.name = attribute.getNodeValue();
382         }
383
384         attribute = nm.getNamedItem("type");
385
386         if (attribute != null) {
387             ce.type = attribute.getNodeValue();
388         }
389
390         NodeList JavaDoc nl = n.getChildNodes();
391
392         /**
393          * Iterate through all the child nodes and get the element-attributes
394          * nodes
395          */

396         for (int i = 0; i < nl.getLength(); i++) {
397             Node JavaDoc currentNode = nl.item(i);
398
399             if (currentNode.getNodeName().equals("element-attributes")) {
400                 NodeList JavaDoc attrnl = currentNode.getChildNodes();
401
402                 for (int j = 0; j < attrnl.getLength(); j++) {
403                     Node JavaDoc oneNode = attrnl.item(j);
404
405                     if (oneNode.getNodeName().equals("element-attribute")) {
406                         NamedNodeMap JavaDoc attrs = oneNode.getAttributes();
407                         String JavaDoc key = attrs.getNamedItem("name").getNodeValue();
408                         String JavaDoc value = attrs.getNamedItem("value").getNodeValue();
409
410                         if (key != null) {
411                             if (value == null) {
412                                 value = ("");
413                             }
414                             if (ce.attributes == null) {
415                                 ce.attributes = new HashMap JavaDoc();
416                             }
417
418                             ce.attributes.put(key, value);
419                         }
420                     }
421                 }
422             } else if (currentNode.getNodeName().equals("nested-outputs")) {
423                 NodeList JavaDoc nestedNodes = currentNode.getChildNodes();
424
425                 for (int k = 0; k < nestedNodes.getLength(); k++) {
426                     Node JavaDoc oneNode = nestedNodes.item(k);
427
428                     if (oneNode.getNodeName().equals("output")) {
429                         ce.addNested(Output.fromXML(nestedNodes.item(k)));
430                     }
431                 }
432             } else if (currentNode.getNodeName().equals("nested-inputs")) {
433                 NodeList JavaDoc nestedNodes = currentNode.getChildNodes();
434
435                 for (int k = 0; k < nestedNodes.getLength(); k++) {
436                     Node JavaDoc oneNode = nestedNodes.item(k);
437
438                     if (oneNode.getNodeName().equals("input")) {
439                         ce.addNested(Input.fromXML(nestedNodes.item(k)));
440                     }
441                 }
442             } else if (currentNode.getNodeName().equals("nested-blocks")) {
443                 NodeList JavaDoc nestedNodes = currentNode.getChildNodes();
444
445                 for (int k = 0; k < nestedNodes.getLength(); k++) {
446                     Node JavaDoc oneNode = nestedNodes.item(k);
447
448                     if (oneNode.getNodeName().equals("block")) {
449                         ce.addNested(Block.fromXML(nestedNodes.item(k)));
450                     }
451                 }
452             } else if (currentNode.getNodeName().equals("nested-transitions")) {
453                 NodeList JavaDoc nestedNodes = currentNode.getChildNodes();
454
455                 for (int k = 0; k < nestedNodes.getLength(); k++) {
456                     Node JavaDoc oneNode = nestedNodes.item(k);
457
458                     if (oneNode.getNodeName().equals("transition")) {
459                         ce.addNested(Transition.fromXML(nestedNodes.item(k)));
460                     }
461                 }
462             }
463         } /* For each Child Node */
464
465
466         return ce;
467     }
468
469     /**
470      * Get the value of an "attribute" for this ControllerElement item.
471      * The attributes can
472      * be any set of named values that the client and Controller are
473      * both aware of.
474      *
475      * @param att The name of the attribute whose value is wanted
476      * @return The value of the specified attribtue, if it exists, else
477      * null
478      */

479     public String JavaDoc getAttribute(String JavaDoc att) {
480         if (attributes == null) {
481             return "";
482         }
483         return StringUtil.notNull((String JavaDoc) attributes.get(att));
484     } /* getAttribute(String) */
485
486     /**
487      * Return the entire Hashtable of attribute values for this ControllerElement
488      *
489      * @return A Hashtable of name/value pairs for this ControllerElement object
490      */

491     public HashMap JavaDoc getAttributes() {
492         if (attributes == null) {
493             attributes = new HashMap JavaDoc();
494         }
495         return attributes;
496     } /* getAttributes() */
497
498     /**
499      * Same as above but will return null if no attributes have ever been set.
500      *
501      * @return HashMap or <i>null</i>
502      */

503     public HashMap JavaDoc getAttributesOrNull() {
504         return attributes;
505     }
506
507     /*
508      * get the contained item of this name
509      * @param name name of item to be fetched
510      * @return content associated with name, or null
511      */

512     public ControllerElement getContent(String JavaDoc name) {
513         ControllerElement t = null;
514         Vector JavaDoc v = this.getNestedOrNull();
515         if (v != null) {
516             for (Enumeration JavaDoc e = v.elements(); e.hasMoreElements();) {
517                 t = (ControllerElement) e.nextElement();
518
519                 if (t.getName().equals(name)) {
520                     return t;
521                 }
522             }
523         }
524
525         return null;
526     } /* getContent(String) */
527
528     /**
529      * Get the description of this element
530      *
531      * @return A String description of this element as specified by the
532      * controller
533      */

534     public String JavaDoc getDescription() {
535         return StringUtil.notNull(description);
536     } /* getDescription() */
537
538     /**
539      * Get the display length suggested by the controller for this
540      * item.
541      *
542      * @return The display length suggested for this item
543      */

544     public int getDisplayLength() {
545         return displayLength;
546     } /* getDisplayLength() */
547
548     /**
549      * Get the label of this element
550      *
551      * @return The label of this element
552      */

553     public String JavaDoc getLabel() {
554         return StringUtil.notNull(label);
555     } /* getLabel() */
556
557     /**
558      * Get the suggested number of lines for this item
559      *
560      * @return integer
561      */

562     public int getLines() {
563         return lines;
564     } /* getLines() */
565
566     /**
567      * Get the name of this element.
568      * title and name are synonymous--easier for JSTL
569      *
570      * @return The name of this element
571      */

572     public String JavaDoc getName() {
573         return StringUtil.notNull(name);
574     } /* getName() */
575
576     /**
577      * Get the name of this element.
578      * title and name are synonymous--easier for JSTL
579      *
580      * @return The name of this element
581      */

582     public String JavaDoc getTitle() {
583         return StringUtil.notNull(name);
584     }
585
586     /**
587      * Return the entire Vector of nested elements in this element
588      *
589      * @return A Vector of the objects nested within this element
590      */

591     public Vector JavaDoc getNested() {
592         if (nested == null) {
593             nested = new Vector JavaDoc();
594         }
595
596         return nested;
597     } /* getNested() */
598
599
600     /**
601      * A method to support JSTL 1.0 usage; returns the size of the
602      * nested controller elements.
603      * <p/>
604      * <p> In JSTL 1.0 it is not possible to the retrieve sizes of
605      * collections directly without using a wrapper or a custom tag
606      * action. </p>
607      *
608      * @return size of all nested controller elements
609      */

610     public int getNestedCount() {
611         return getNested().size();
612     } /* getNestedCount() */
613
614     /**
615      * Same as getNested. <b>But</b> does not allocate a Vector if there aren't
616      * any values.
617      *
618      * @return java.util.Vector or null if nested Vector doesn't exist yet.
619      */

620     public Vector JavaDoc getNestedOrNull() {
621         if (nested == null) {
622             return null;
623         }
624
625         return nested;
626     }
627
628
629     /**
630      * Retrieve the iterator to all tested objects.
631      *
632      * @return
633      */

634     public Iterator JavaDoc getNestedIterator() {
635         return getNested().iterator();
636     }
637
638     /**
639      * Return the "parent" of this element - e.g. the element that this
640      * element is nested within
641      *
642      * @return the parent element or possibly null if there is no parent
643      */

644     public ControllerElement getParent() {
645         return parent;
646     } /* getParent() */
647
648     /**
649      * Returns whatever the type is
650      *
651      * @return java.lang.String
652      */

653     public String JavaDoc getType() {
654         return type;
655     }
656
657     /**
658      * Remove this item from the "nested" items of it's parent. After
659      * this method, the item is still valid, but is no longer nested within
660      * it's parent
661      *
662      * @throws ControllerException if the current item is not nested
663      */

664     public void remove()
665             throws ControllerException {
666         if (parent == null) {
667             String JavaDoc myName = (this.getClass().getName() + ".remove()");
668             throw new ControllerException(myName +
669                     " :This item is not nested " +
670                     "in another item - cannot remove");
671         }
672
673         parent.removeNested(this);
674     } /* remove() */
675
676
677     /**
678      * Remove an element from the nested elements for this item
679      *
680      * @param elementToRemove The element to be removed from the list of
681      * nested items.
682      * @throws ControllerException if there is no such item nested in this item
683      */

684     public void removeNested(ControllerElement elementToRemove)
685             throws ControllerException {
686         if (nested.removeElement(elementToRemove)) {
687             return;
688         }
689
690         String JavaDoc myName = (this.getClass().getName() +
691                 ".removeNested(ControllerElement)");
692         throw new ControllerException(myName + "No such nested element as '" +
693                 elementToRemove.getName() +
694                 "' in Output " + getName());
695     } /* removeNested(ControllerElement) */
696
697
698     /**
699      * Set the named attribute of this Output to the given value
700      *
701      * @param attrib The name of an "attribtue" for this ControllerElement item
702      * @param val The value for this attribute
703      */

704     public void setAttribute(String JavaDoc attrib, String JavaDoc val) {
705         if (attributes == null) {
706             attributes = new HashMap JavaDoc();
707         }
708         attributes.put(attrib, val);
709     } /* setAttributes(String, String) */
710
711     /**
712      * Used by the controller to set the description of this element
713      *
714      * @param newDescription The description being set by this object
715      */

716     public void setDescription(String JavaDoc newDescription) {
717         description = newDescription;
718     } /* setDescription(String) */
719
720     /**
721      * Set the suggested display length (in caracters) for this
722      * Controller element
723      *
724      * @param newLength The specified length for display of this element
725      */

726     public void setDisplayLength(int newLength) {
727         displayLength = newLength;
728     } /* setDisplayLength(int) */
729
730     /**
731      * Set a label for this element
732      *
733      * @param newLabel The new label for this element
734      */

735     public void setLabel(String JavaDoc newLabel) {
736         label = newLabel;
737     } /* setLabel(String) */
738
739     /**
740      * Set the display number of lines suggested for this item
741      *
742      * @param newLines The number of lines to specify
743      */

744     public void setLines(int newLines) {
745         lines = newLines;
746     } /* setLines(int) */
747
748     /**
749      * Used by the controller to set the name of this element
750      *
751      * @param newName The new name for this element
752      */

753     public void setName(String JavaDoc newName) {
754         name = newName;
755     } /* setName(String) */
756
757     /**
758      * Set the "parent" of this element - e.g. the element that this
759      * element is nested within
760      *
761      * @param t The ControllerElement that has this element as a nested item
762      */

763     public void setParent(ControllerElement t) {
764         parent = t;
765     } /* setParent(ControllerElement) */
766
767     /**
768      * Sets the descriptive data type for this ControllerElement
769      *
770      * @param s a new java.lang.String
771      */

772     public void setType(String JavaDoc s) {
773         type = s;
774     }
775
776     /**
777      * Convert the object to an xml fragment.
778      *
779      * @param stream a pre-allocated FastStringBuffer to append to
780      * @return the in parameter stream.
781      */

782     public FastStringBuffer toXML(FastStringBuffer stream) {
783         stream.append("<controller-element");
784
785         if (name != null && name.length() > 0) {
786             stream.append(" name=\"");
787             stream.append(StringUtil.xmlEscape(name));
788             stream.append("\"");
789         }
790         if (label != null && label.length() > 0) {
791             stream.append(" label=\"");
792             stream.append(StringUtil.xmlEscape(label));
793             stream.append("\"");
794         }
795         if (type != null && type.length() > 0) {
796             stream.append(" type=\"");
797             stream.append(StringUtil.xmlEscape(type));
798             stream.append("\"");
799         }
800         if (description != null && description.length() > 0) {
801             stream.append(" description=\"");
802             stream.append(StringUtil.xmlEscape(description));
803             stream.append("\"");
804         }
805         if (displayLength > 0) {
806             stream.append(" display-length=\"");
807             stream.append(displayLength);
808             stream.append("\"");
809         }
810         if (lines > 0) {
811             stream.append(" lines=\"");
812             stream.append(lines);
813             stream.append("\"");
814         }
815
816         stream.append(">\n");
817
818         if (attributes != null && !attributes.isEmpty()) {
819             stream.append("\t<element-attributes>\n");
820
821             for (Iterator JavaDoc i = attributes.keySet().iterator(); i.hasNext();) {
822                 String JavaDoc key = (String JavaDoc) i.next();
823                 String JavaDoc value = null;
824
825                 if (key != null) {
826                     value = (String JavaDoc) attributes.get(key);
827
828                     //
829
//All null values go to empty strings
830
//
831
if (value == null) {
832                         value = "";
833                     }
834
835                     stream.append("\t<element-attribute name=\"");
836                     stream.append(StringUtil.xmlEscape(key));
837                     stream.append("\" value=\"");
838                     stream.append(StringUtil.xmlEscape(value));
839                     stream.append("\"/>\n");
840                 }
841             }
842
843             stream.append("\t</element-attributes>\n");
844         }
845
846         /* Now deal with nested elements */
847         Vector JavaDoc nestedBlocks = new Vector JavaDoc();
848         Vector JavaDoc nestedOutputs = new Vector JavaDoc();
849         Vector JavaDoc nestedTransitions = new Vector JavaDoc();
850         Vector JavaDoc nestedInputs = new Vector JavaDoc();
851         Vector JavaDoc nested = this.getNestedOrNull();
852         ControllerElement ce = null;
853         if (nested != null) {
854             for (Enumeration JavaDoc en = nested.elements(); en.hasMoreElements();) {
855                 ce = (ControllerElement) en.nextElement();
856
857                 if (ce instanceof Input) {
858                     nestedInputs.addElement(ce);
859                 }
860                 if (ce instanceof Output) {
861                     nestedOutputs.addElement(ce);
862                 }
863                 if (ce instanceof Transition) {
864                     nestedTransitions.addElement(ce);
865                 }
866                 if (ce instanceof Block) {
867                     nestedBlocks.addElement(ce);
868                 }
869             }
870         }
871         if (nestedOutputs.size() > 0) {
872             stream.append(" <nested-outputs>\n");
873
874             Output oneOutput = null;
875
876             for (Enumeration JavaDoc eno = nestedOutputs.elements();
877                  eno.hasMoreElements();) {
878                 oneOutput = (Output) eno.nextElement();
879                 stream = oneOutput.toXML(stream);
880             }
881
882             stream.append(" </nested-outputs>\n");
883         }
884         if (nestedInputs.size() > 0) {
885             stream.append(" <nested-inputs>\n");
886
887             Input oneInput = null;
888
889             for (Enumeration JavaDoc eni = nestedInputs.elements();
890                  eni.hasMoreElements();) {
891                 oneInput = (Input) eni.nextElement();
892                 stream = oneInput.toXML(stream);
893             }
894
895             stream.append(" </nested-inputs>\n");
896         }
897         if (nestedTransitions.size() > 0) {
898             stream.append(" <nested-transitions>\n");
899
900             Transition oneTransition = null;
901
902             for (Enumeration JavaDoc ent = nestedTransitions.elements();
903                  ent.hasMoreElements();) {
904                 oneTransition = (Transition) ent.nextElement();
905                 stream = oneTransition.toXML(stream);
906             }
907
908             stream.append(" </nested-transitions>\n");
909         }
910         if (nestedBlocks.size() > 0) {
911             stream.append(" <nested-blocks>\n");
912
913             Block oneBlock = null;
914
915             for (Enumeration JavaDoc enb = nestedBlocks.elements();
916                  enb.hasMoreElements();) {
917                 oneBlock = (Block) enb.nextElement();
918                 stream = oneBlock.toXML(stream);
919             }
920
921             stream.append(" </nested-blocks>\n");
922         }
923
924         stream.append("</controller-element>\n");
925
926         return stream;
927     }
928
929     /**
930      * Return a specific Element nested within this Element
931      *
932      * @param nestedName the name of the element to retrieve
933      * @return An Element with the specified name or null if it doesn't exist
934      */

935     public ControllerElement getNested(String JavaDoc nestedName)
936             throws ControllerException {
937         ControllerElement oneElement = null;
938         Vector JavaDoc v = getNestedOrNull();
939
940         if (v == null) {
941             return null;
942         }
943
944         for (Enumeration JavaDoc e = v.elements(); e.hasMoreElements();) {
945             oneElement = (ControllerElement) e.nextElement();
946
947             if (oneElement.getName().equals(nestedName)) {
948                 return oneElement;
949             }
950         } /* for each element nested */
951
952
953         return null;
954     } /* getNested(String) */
955
956     /**
957      * Return a Map of all nested elements keyed by controllerElement name.
958      * Useful for JSTL iteration of the Map.
959      */

960     public Map JavaDoc getNestedMap() {
961         if (mappedNested == null) {
962             mappedNested = new HashMap JavaDoc();
963         }
964         return mappedNested;
965     }
966
967
968     /**
969      * Called by the ControllerResponse to hand itself back to this
970      * element so that it can be accessed by the elements as required
971      *
972      * @param newResponse the new Response.
973      */

974     public synchronized void setControllerResponse(ControllerResponse newResponse) {
975         myResponse = newResponse;
976
977         Vector JavaDoc allNested = getNestedOrNull();
978
979         if (allNested == null) {
980             return;
981         }
982
983         ControllerElement ce = null;
984
985         int size = allNested.size();
986         for (int i = 0; i < size; i++) {
987             ce = (ControllerElement) allNested.get(i);
988             ce.setControllerResponse(newResponse);
989         }
990     }
991
992     protected ControllerResponse getControllerResponse() {
993         return myResponse;
994     }
995 }
996
997 /* ControllerElement */
998
Popular Tags