2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to you under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * $Id: ComponentBean.java 516834 2007-03-11 01:33:36Z gvanmatre $
20   */
21  package org.apache.shale.clay.config.beans;
22  
23  import java.io.Serializable;
24  import java.util.Collection;
25  import java.util.Iterator;
26  import java.util.Map;
27  import java.util.TreeSet;
28  
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  import org.apache.shale.util.Messages;
32  
33  /***
34   * <p>This is the base class of most of the metadata that is used by the
35   * {@link org.apache.shale.clay.component.Clay} component to build
36   * a component subtree.
37   *
38   * <dl>
39   * <dt> There are three sources that populate this object:
40   * <dd> {@link org.apache.shale.clay.config.ClayXmlParser} - from XML config files
41   * <dd> {@link org.apache.shale.clay.parser.builder.Builder} - extending classes
42   * <dd> {@link org.apache.shale.clay.component.Clay} - <code>shapeValidator</code>
43   *      a <code>validator</code> style of event method binding
44   * </dl>
45   * </p>
46   */
47  public class ComponentBean extends AbstractBean implements Comparable, Serializable {
48  
49      /***
50       * <p>Unique id used by the Serializable interface.</p>
51       */
52      private static final long serialVersionUID = 3907217039524312373L;
53  
54      /***
55       * <p>Common Logging utility class.</p>
56       */
57      private static Log log;
58      static {
59          log = LogFactory.getLog(ComponentBean.class);
60      }
61  
62      /***
63       * <p>A class scoped unique sequence counter.</p>
64       */
65      private static long uniqueSequence = -1;
66  
67      /***
68       * @return the next <code>uniqueSequence</code>
69       */
70      private synchronized long generateId() {
71         return ++uniqueSequence;
72      }
73  
74      /***
75       * <p>The config beans unique sequence.  The value is
76       * populated from a call to <code>generateId</code>.</p>
77       */
78      private long jspId = -1;
79  
80      /***
81       * <p>Returns a unique id that will stick to the config bean.
82       * It represents its compositional relationship within the subtree.
83       * This is clay's version of the <code>JspIdConsumer</code>
84       * in JSP 2.1.</p>
85       *
86       * @return unique id for a view element
87       */
88      public long getJspId() {
89         if (jspId == -1) {
90             jspId = generateId();
91         }
92  
93         return jspId;
94      }
95  
96      /***
97       * <p>
98       * Message resources for this class.
99       * </p>
100      */
101     private static Messages messages = new Messages(
102             "org.apache.shale.clay.Bundle", ComponentBean.class
103             .getClassLoader());
104 
105     /***
106      * <p>Unique id that points to component meta information.</p>
107      */
108     private String jsfid = null;
109 
110     /***
111      * <p>This value pair collection is used to set the property values for JSF object
112      * implementing <code>UIComponent, Validator, ValueChangeListener, ActionListener
113      * and Converter</code>.
114      * </p>
115      */
116     private Map attributes = new Attributes();
117 
118     /***
119      * <p>An object reference that shows a generalization relationship through the
120      * metadata.  The <code>extends</code> attribute will hold the <code>jsfid</code>
121      * of the parent this instance extends.
122      * </p>
123      */
124     private ComponentBean isAParent = null;
125 
126     /***
127      * <p>An object reference that shows a composition relationship.  This reference
128      * will point to the parent that holds this object instance in one of it's collections.
129      *</p>
130      */
131     private ComponentBean hasAParent = null;
132 
133     /***
134      * <p>The <code>componentType</code> relates to a JSF component type used use to instantiate
135      * the component using abstract factories.  For component's like <code>ActionListener and
136      * ValueChangeListener</code>, that are not registered in the faces configuration file, the
137      * <code>componentType</code> is the fully qualified class name.
138      * </p>
139      */
140     private String componentType = null;
141 
142     /***
143      * <p>The <code>jsfid</code> of the meta component parent.</p>
144      */
145     private String extendsElementId = null;
146 
147     /***
148      * <p>Child meta components that form composition under another meta
149      * component instance.  Each instance in this set will be a instance
150      * of {@link ElementBean} and uniquely identified by <code>renderId</code>
151      * </p>
152      */
153     private Collection children = new TreeSet();
154 
155     /***
156      *  <p>Boolean flag indicates the meta inheritance of this component
157      *  has been resolved.</p>
158      */
159     private boolean isInheritanceFinal = false;
160 
161     /***
162      *  <p>Reference to an associated {@link ComponentBean} that is an instance of
163      *  {@link ConverterBean} and is used to instantiate a JSF <code>Converter</code>.
164      *  </p>
165      */
166     private ComponentBean converter = null;
167 
168     /***
169      *  <p>Reference to a set of associated {@link ComponentBean} that is an instance of
170      *  {@link ValidatorBean} and is used to instantiate a JSF <code>Validator</code>.
171      *  </p>
172      */
173     private TreeSet validators = new TreeSet();
174 
175     /***
176      *  <p>Reference to a set of associated {@link ComponentBean} that is an instance of
177      *  {@link ValueChangeListenerBean} and is used to instantiate a JSF <code>ValueChangeListener</code>.
178      *  </p>
179      */
180     private TreeSet valueChangeListeners = new TreeSet();
181 
182     /***
183      *  <p>Reference to a set of associated {@link ComponentBean} that is an instance of
184      *  {@link ActionListenerBean} and is used to instantiate a JSF <code>ActionListener</code>.
185      *  </p>
186      */
187     private TreeSet actionListeners = new TreeSet();
188 
189     /***
190      * <p>This attribute used when defining the template style of page composition where the
191      * body of the HTML element is rendered by the component ignoring the HTML.
192      */
193     private String allowBody = null;
194 
195     /***
196      * <p>Use this property to add the component to the parent's facet collection rather than
197      * the default children collection.</p>
198      */
199     private String facetName = null;
200 
201     /***
202      * <p>The replacement symbol table for the component meta-data.</p>
203      */
204     private Map symbols = new Attributes();
205 
206     /***
207      * <p>This property only applies when using the {@link org.apache.shale.clay.component.Clay}
208      * template features.  A <code>true</code> value is returned if the HTML child nodes under
209      * the node that this meta component is bound to should be rendered; otherwise, a <code>"false"</code>
210      * value is returned indicating the child nodes should be ignored.
211      * </p>
212      *
213      * @return literal string "true" if allow body is on
214      */
215     public String getAllowBody() {
216         return allowBody;
217     }
218 
219     /***
220      * <p>This property only applies when using the {@link org.apache.shale.clay.component.Clay}
221      * template features.  Sets a Boolean string value that indicating if the child HTML nodes
222      * under the node that this component is bound to should render or ignore its child nodes.
223      * </p>
224      *
225      * @param allowBody indicates how the child markup nodes are processed
226      *
227      */
228     public void setAllowBody(String allowBody) {
229         this.allowBody = allowBody;
230     }
231 
232     /***
233      * <p>Returns a boolean representation of the <code>allowBody</code> property.
234      * The default is <code>true</code></p>
235      *
236      * @return <code>true</code> if allowBody has a literal string value of "true"
237      */
238     public boolean getIsBodyAllowed() {
239        boolean f = true;
240        try {
241            if (allowBody != null) {
242                f = Boolean.valueOf(allowBody).booleanValue();
243            }
244        } catch (Exception e) {
245            f = true;
246        }
247 
248        return f;
249     }
250 
251   /***
252    * <p>Returns the facet name that will be used as the identifier when adding the
253    * component to the parent facets collection.</p>
254    *
255    * @return facetName
256    */
257    public String getFacetName() {
258       return facetName;
259    }
260 
261    /***
262     * <p>Sets the facet name that will be used as the identifier when adding the
263     * component to the parent facets collection.</p>
264     *
265     * @param facetName component grouping
266     */
267    public void setFacetName(String facetName) {
268       this.facetName = facetName;
269    }
270 
271    /***
272     * @return a value list of the object's state
273     */
274    public String toString() {
275         StringBuffer buff = new StringBuffer();
276         buff.append("jsfid=\"").append(jsfid).append(
277                 "\" componentType=\"").append(componentType).append(
278                 "\" extends=\"").append(extendsElementId).append("\"")
279                 .append(" allowBody=\"").append(allowBody)
280                 .append("\" ").append("facetName=\"").append(facetName)
281                 .append("\"");
282 
283         return buff.toString();
284     }
285 
286     /***
287      * <p>Returns the component type that is used to instantiate the associated
288      * JSF component.<p>
289      *
290      * @return component type
291      */
292     public String getComponentType() {
293         return componentType;
294     }
295 
296     /***
297      * <p>Returns the <code>jsfid</code> of the meta component that this
298      * instance inherits from.<p>
299      *
300      * @return extended jsfid
301      */
302     public String getExtends() {
303         return extendsElementId;
304     }
305 
306     /***
307      * <p>Sets the component type uses by abstract factories to instantiate
308      * associated JSF resources.</p>
309      *
310      * @param componentType used to create a JSF resource
311      */
312     public void setComponentType(String componentType) {
313         this.componentType = componentType;
314     }
315 
316     /***
317      * <p>Sets the <code>jsfid</code> of the meta component that this meta
318      * component inherits from.
319      * </p>
320      *
321      * @param extendsElementId extending jsfid
322      */
323     public void setExtends(String extendsElementId) {
324         this.extendsElementId = extendsElementId;
325     }
326 
327     /***
328      * <p>Returns a <code>Iterator</code> to the <code>children</code> set.
329      * Each item in the set is uniquely identified by its
330      * <code>renderId</code> property and an instance of {@link ElementBean}.
331      * </p>
332      *
333      * @return iterator for the children collection
334      */
335     public Iterator getChildrenIterator() {
336 
337         return children.iterator();
338     }
339 
340     /***
341      *<p>Returns a set of children that are instances of {@link ElementBean}.
342      *</p>
343      *
344      * @return children collection
345      */
346     public Collection getChildren() {
347         return children;
348     }
349 
350     /***
351      * <p>Merges two sets of children {@link org.apache.shale.clay.config.beans.ElementBean}. Items in the source
352      * collection will replace those in the target with the same <code>renderId</code>
353      * </p>
354      *
355      * @param collection of child components
356      */
357     public void setChildren(Collection collection) {
358         children.addAll(collection);
359     }
360 
361     /***
362      * <p>Adds a child {@link org.apache.shale.clay.config.beans.ElementBean} to the <code>children</code> set and
363      * fixes up the composition parent relationship.</p>
364      *
365      * @param obj element bean added as a child
366      */
367     public void addChild(ElementBean obj) {
368         if (obj.getJsfid() != null) {
369             obj.setHasAParent(this);
370             children.add(obj);
371         } else {
372             log.error(messages.getMessage("missing.jsfid.error", new Object[] {"ElementBean.jsfid", getJsfid()}));
373         }
374     }
375 
376     /***
377      * <p>This <code>Comparable</code> implementation makes the
378      * <code>jsfid</code> attribute the unique identifier for the object in a
379      * set.</p>
380      *
381      * @param obj target object to compare to
382      * @return weighted value based on the jsfid property
383      */
384     public int compareTo(Object obj) {
385         return ((ComponentBean) obj).getJsfid().compareTo(
386                 getJsfid());
387     }
388 
389     /***
390      * <p>Gets a meta converter bean used to instantiate a jsf <code>Converter</code>.</p>
391      *
392      * @return converter assigned to the component
393      */
394     public ComponentBean getConverter() {
395         return converter;
396     }
397 
398     /***
399      * <p>Adds a {@link ConverterBean} and assigns the composition parent.</p>
400      *
401      * @param bean converter assigned to this component
402      */
403     public void addConverter(ConverterBean bean) {
404         if (bean.getJsfid() != null) {
405             bean.setHasAParent(this);
406             converter = bean;
407         } else {
408             log.error(messages.getMessage("missing.jsfid.error", new Object[] {"ConverterBean.jsfid", getJsfid()}));
409         }
410     }
411 
412     /***
413      * <p>Returns a <code>Collection</code> of meta validators used to create jsf <code>Validator</code>
414      * object instances.
415      *
416      * @return collection of validators
417      */
418     public Collection getValidators() {
419         return validators;
420     }
421 
422     /***
423      * <p>Adds a collection of {@link ValidatorBean} to the <code>validator</code> set.  Each
424      * instance is uniquely identified in the collection by the <code>jsfid</code>.
425      * </p>
426      *
427      * @param collection of validators added to the component
428      */
429     public void setValidators(Collection collection) {
430         validators.addAll(collection);
431     }
432 
433     /***
434      * <p>Returns a <code>Iterator</code> to the <code>validator</code> set.  Each
435      * object will be an instance of {@link ValidatorBean}.
436      * </p>
437      *
438      * @return Iterator of the components validators collection
439      */
440     public Iterator getValidatorIterator() {
441 
442         return validators.iterator();
443     }
444 
445     /***
446      * <p>Adds a {@link ValidatorBean} and assigns the composition parent.</p>
447      *
448      * @param bean validator to add to the component
449      */
450     public void addValidator(ValidatorBean bean) {
451         if (bean.getJsfid() != null) {
452             validators.add(bean);
453         } else {
454             log.error(messages.getMessage("missing.jsfid.error",
455                     new Object[] {"ValidatorBean.jsfid", getJsfid()}));
456         }
457     }
458 
459     /***
460      * <p>Returns a <code>Iterator</code> to the <code>valueChangeListeners</code> set.
461      * Each {@link ValueChangeListenerBean} in the collection is uniquely identified
462      * by <code>jsfid</code>.
463      *</p>
464      *
465      * @return collection of value change listeners
466      */
467     public Collection getValueChangeListeners() {
468         return valueChangeListeners;
469     }
470 
471     /***
472      * <p>Merges a collection of {@link org.apache.shale.clay.config.beans.ValueChangeListenerBean} where items in the
473      * source collection with the same <code>jsfid</code> will override items
474      * in the target set with the same identifier.
475      * </p>
476      *
477      * @param collection of value change listeners added to the component
478      */
479     public void setValueChangeListeners(Collection collection) {
480         valueChangeListeners.addAll(collection);
481     }
482 
483     /***
484      * <p>Returns a <code>Iterator</code> for the <code>valueChangeListener</code> set
485      * of {@link ValueChangeListenerBean}.<p>
486      *
487      * @return iterator for the collection of value change listeners
488      */
489     public Iterator getValueChangeListenerIterator() {
490         return valueChangeListeners.iterator();
491     }
492 
493     /***
494      * <p>Adds a {@link ValueChangeListenerBean} to the set where each instance is
495      * uniquely identified by <code>jsfid</code>.</p>
496      *
497      * @param bean value change listener added to the components collection of listeners
498      */
499     public void addValueChangeListener(ValueChangeListenerBean bean) {
500         if (bean.getJsfid() != null) {
501             valueChangeListeners.add(bean);
502         } else {
503             log.error(messages.getMessage("missing.jsfid.error",
504                     new Object[] {"ValueChangeListenerBean.jsfid", getJsfid()}));
505         }
506     }
507 
508     /***
509      * <p>Returns a <code>Collection</code> of {@link ActionListenerBean}. </p>
510      *
511      * @return collection of the component's action listeners
512      */
513     public Collection getActionListeners() {
514         return actionListeners;
515     }
516 
517     /***
518      * <p>Merges two collections where items in the source collection will override
519      * those in the target collection of {@link ActionListenerBean} by the <code>jsfid</code>
520      * property.</p>
521      *
522      * @param collection of action listeners added to the components set
523      */
524     public void setActionListeners(Collection collection) {
525         actionListeners.addAll(collection);
526     }
527 
528     /***
529      * <p>Returns an <code>Iterator</code> for the <code>actionListeners</code> set of
530      * {@link ActionListenerBean}.
531      * </p>
532      *
533      * @return iterator of the component's action listeners set
534      */
535     public Iterator getActionListenerIterator() {
536 
537         return actionListeners.iterator();
538     }
539 
540     /***
541      * <p>Adds an {@link ActionListenerBean} to the <code>actionListeners</code> set.  Each
542      * instance is uniquely identified by the <code>jsfid</code> property.
543      * </p>
544      *
545      * @param bean action listener added to the component
546      */
547     public void addActionListener(ActionListenerBean bean) {
548         if (bean.getJsfid() != null) {
549             actionListeners.add(bean);
550         } else {
551             log.error(messages.getMessage("missing.jsfid.error",
552               new Object[] {"ActionListenerBean.jsfid", getJsfid()}));
553         }
554     }
555 
556     /***
557      * <p>This inner class provides implementation for an <code>Iterator</code> handeling
558      * {@link AttributeBean} objects in the <code>attributes</code> collection.
559      * </p>
560      *
561      * @return iterator for the components attributes Map
562      */
563     public Iterator getAttributeIterator() {
564 
565         return new Iterator() {
566             /***
567              * <p>Graps a <code>Iterator</code> instance of the attributes entry set</p>
568              */
569             private Iterator entrySet = getAttributes().entrySet().iterator();
570             /***
571              * <p>Decorates the <code>Iterator</code> of the private <code>entrySet</code></p>
572              */
573             public boolean hasNext() {
574                 return entrySet.hasNext();
575             }
576             /***
577              * <p>Returns the next {@link AttributeBean} in the Map collection</p>
578              */
579             public Object next() {
580                 Map.Entry e = (Map.Entry) entrySet.next();
581                 return e.getValue();
582             }
583 
584             /***
585              * <p>This method is not applicable for this class and has an empty
586              * method body but has to be implemented to realize the <code>Iterator</code>
587              * interface.
588              * </p>
589              */
590             public void remove() {
591             }
592         };
593 
594     }
595 
596     /***
597      * <p>Returns a {@link AttributeBean} by the classes <code>name</code> property.</p>
598      *
599      * @param key attribute name
600      * @return attribute bean for the key
601      */
602     public AttributeBean getAttribute(String key) {
603         return (AttributeBean) getAttributes().get(key);
604     }
605 
606     /***
607      * <p>Adds a {@link AttributeBean} to the <code>attributes</code> Map collection where
608      * the <code>name</code> property is the key identifier in the value pair relationship.
609      * </p>
610      *
611      * @param obj attribute bean added to the attributes Map
612      */
613     public void addAttribute(AttributeBean obj) {
614         if (obj.getName() != null) {
615             obj.setHasAParent(this);
616             attributes.put(obj.getName(), obj);
617         } else {
618             log.error(messages.getMessage("missing.jsfid.error", new Object[] {"AttributeBean.jsfid", getJsfid()}));
619         }
620 
621     }
622 
623     /***
624      * <p>Returns the a <code>Map</code> collection of {@link AttributeBean} objects.</p>
625      *
626      * @return attributes map
627      */
628     public Map getAttributes() {
629 
630         return attributes;
631     }
632 
633     /***
634      * <p>Returns the unique meta component identifier.</p>
635      *
636      * @return jsfid
637      */
638     public String getJsfid() {
639         return jsfid;
640     }
641 
642     /***
643      * <p>Merges a set of {@link AttributeBean} where items in the source
644      * collection override items in the target collection by the object's
645      * <code>jsfid</code> property.
646      * </p>
647      *
648      * @param map of attributes to be merged
649      */
650     public void setAttributes(Map map) {
651         attributes.putAll(map);
652     }
653 
654     /***
655      * <p>Sets the unique meta component identifier.</p>
656      *
657      * @param jsfid identifier
658      */
659     public void setJsfid(String jsfid) {
660         this.jsfid = jsfid;
661     }
662 
663     /***
664      * <p>Returns the parent component that aggregates this object.</p>
665      *
666      * @return composition parent
667      */
668     public ComponentBean getHasAParent() {
669         return hasAParent;
670     }
671 
672     /***
673      * <p>Returns the parent component that generalizes this object.</p>
674      *
675      * @return inheritance parent
676      */
677     public ComponentBean getIsAParent() {
678         return isAParent;
679     }
680 
681     /***
682      * <p>Sets the parent that owns this component.</p>
683      *
684      * @param bean composition parent
685      */
686     public void setHasAParent(ComponentBean bean) {
687         hasAParent = bean;
688     }
689 
690     /***
691      * <p>Sets the component that this instance extends.</p>
692      *
693      * @param bean inheritance parent
694      */
695     public void setIsAParent(ComponentBean bean) {
696         isAParent = bean;
697     }
698 
699     /***
700      * <p>Returns a xpath like string describing how this component
701      * fits into the overall composition.</p>
702      *
703      * @return composition client id
704      */
705     public StringBuffer getHasAClientId() {
706         StringBuffer id = null;
707 
708         if (getHasAParent() != null) {
709             id = getHasAParent().getHasAClientId();
710         } else {
711             id = new StringBuffer();
712         }
713 
714         id.append("/").append(getJsfid());
715 
716         return id;
717     }
718 
719     /***
720      * <p>Returns an xpath like string that describes the heritage
721      * of this component.</p>
722      *
723      * @return inheritance client id
724      */
725     public StringBuffer getIsAClientId() {
726         StringBuffer id = new StringBuffer();
727 
728         ComponentBean parent = getIsAParent();
729         while (parent != null) {
730             id.insert(0, parent.getJsfid() + (id.length() > 0 ? ":" : ""));
731             parent = parent.getIsAParent();
732         }
733         parent = null;
734 
735         return id;
736     }
737 
738     /***
739      * <p>Returns a boolean flag indicating that the meta inheritances
740      * has been resolved.</p>
741      *
742      * @return <code>true</code> if inheritance has been resolved
743      */
744     public boolean isInheritanceFinal() {
745         return isInheritanceFinal;
746     }
747 
748     /***
749      * <p>Sets a boolean flag indicating that the meta inheritances
750      * have been resolved.</p>
751      *
752      * @param b <code>true</code> if inheritance has been resolved
753      */
754     public void setInheritanceFinal(boolean b) {
755         isInheritanceFinal = b;
756     }
757 
758     /***
759      * <p>Returns the identifier that will populate the JSF <code>UIComponent.id</code>
760      *  property and is used to name the component within the tree.
761      * </p>
762      *
763      * @return component's id
764      */
765     public String getId() {
766         AttributeBean attr = (AttributeBean) attributes.get("id");
767         if (attr != null) {
768            return attr.getValue();
769         }
770 
771         return null;
772     }
773 
774     /***
775      * <p>Sets the identifier that is used to populate the JSF <code>UIComponent.id</code>
776      * property. </p>
777      *
778      * @param id component's identifier
779      */
780     public void setId(String id) {
781         AttributeBean attr = new AttributeBean();
782         attr.setBindingType(AttributeBean.BINDING_TYPE_NONE);
783         attr.setValue(id);
784         attr.setName("id");
785         addAttribute(attr);
786     }
787 
788     /***
789      * <p>Adds a symbol identified by the
790      * {@link SymbolBean} to the symbols collection.</p>
791      *
792      * @param symbol added to the symbols Map
793      */
794     public void addSymbol(SymbolBean symbol) {
795        if (symbol.getName() != null && symbol.getName().length() > 0) {
796             StringBuffer buff = new StringBuffer(symbol.getName());
797             if (buff.charAt(0) != '@') {
798                buff.insert(0, '@');
799                symbol.setName(buff.toString());
800             }
801 
802             symbols.put(symbol.getName(), symbol);
803         }
804     }
805 
806     /***
807      * <p>Returns the replacement symbols assigned to the component.
808      * The key value represents the literal replacement string.
809      * The value Map property represents target {@link SymbolBean}.</p>
810      *
811      * @return map of symbols
812      */
813     public Map getSymbols() {
814        return symbols;
815     }
816 
817     /***
818      * <p>Returns a {@link SymbolBean} from the <code>symbols</code>
819      * Map by <code>name</code>.  Prepends a '@' character to the
820      * <code>name</code> if it doesn't exist.</p>
821      *
822      * @param name of the symbol
823      * @return symbol bean identified by name
824      */
825     public SymbolBean getSymbol(String name) {
826         StringBuffer tmp = new StringBuffer(name);
827         if (tmp.charAt(0) != '@') {
828             tmp.insert(0, '@');
829         }
830 
831         SymbolBean symbol = (SymbolBean) symbols.get(tmp.toString());
832 
833         return symbol;
834     }
835 
836 }
837