KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > faces > component > UIComponentBase


1 /*
2  * Copyright 2004 The Apache Software Foundation.
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 javax.faces.component;
17
18 import javax.faces.FactoryFinder;
19 import javax.faces.context.FacesContext;
20 import javax.faces.el.ValueBinding;
21 import javax.faces.event.AbortProcessingException;
22 import javax.faces.event.FacesEvent;
23 import javax.faces.event.FacesListener;
24 import javax.faces.render.RenderKit;
25 import javax.faces.render.RenderKitFactory;
26 import javax.faces.render.Renderer;
27 import java.io.IOException JavaDoc;
28 import java.io.Serializable JavaDoc;
29 import java.lang.reflect.Array JavaDoc;
30 import java.util.*;
31
32
33 /**
34  * see Javadoc of JSF Specification
35  *
36  * @author Manfred Geiler (latest modification by $Author: matzew $)
37  * @version $Revision: 1.15 $ $Date: 2005/03/20 17:26:37 $
38  * $Log: UIComponentBase.java,v $
39  * Revision 1.15 2005/03/20 17:26:37 matzew
40  * Component identifiers must obey the following syntax restrictions:
41  *
42  * * Must not be a zero-length String.
43  * * First character must be a letter or an underscore ('_').
44  * * Subsequent characters must be a letter, a digit, an underscore ('_'), or a dash ('-').
45  *
46  * For more see JSF spec.
47  *
48  * Revision 1.14 2004/12/27 04:11:11 mmarinschek
49  * Data Table stores the state of facets of children; script tag is rendered with type attribute instead of language attribute, popup works better as a column in a data table
50  *
51  * Revision 1.13 2004/08/27 10:45:55 manolito
52  * log a warning when getClientId implicitly creates a component id
53  *
54  * Revision 1.12 2004/07/01 22:00:50 mwessendorf
55  * ASF switch
56  *
57  * Revision 1.11 2004/05/03 10:28:03 manolito
58  * getClientId automatically creates id now
59  *
60  */

61 public abstract class UIComponentBase
62         extends UIComponent
63 {
64     private _ComponentAttributesMap _attributesMap = null;
65     private Map _valueBindingMap = null;
66     private List _childrenList = null;
67     private Map _facetMap = null;
68     private List _facesListeners = null;
69     private String JavaDoc _clientId = null;
70     private String JavaDoc _id = null;
71     private UIComponent _parent = null;
72     private boolean _transient = false;
73
74     public UIComponentBase()
75     {
76     }
77
78     public Map getAttributes()
79     {
80         if (_attributesMap == null)
81         {
82             _attributesMap = new _ComponentAttributesMap(this);
83         }
84         return _attributesMap;
85     }
86
87     public ValueBinding getValueBinding(String JavaDoc name)
88     {
89         if (name == null) throw new NullPointerException JavaDoc("name");
90         if (_valueBindingMap == null)
91         {
92             return null;
93         }
94         else
95         {
96             return (ValueBinding)_valueBindingMap.get(name);
97         }
98     }
99
100     public void setValueBinding(String JavaDoc name,
101                                 ValueBinding binding)
102     {
103         if (name == null) throw new NullPointerException JavaDoc("name");
104         if (_valueBindingMap == null)
105         {
106             _valueBindingMap = new HashMap();
107         }
108         _valueBindingMap.put(name, binding);
109     }
110
111     /**
112      * @param context
113      * @return
114      */

115     public String JavaDoc getClientId(FacesContext context)
116     {
117         if (context == null) throw new NullPointerException JavaDoc("context");
118                  
119         if (_clientId != null) return _clientId;
120
121         boolean idWasNull = false;
122         String JavaDoc id = getId();
123         if (id == null)
124         {
125             //Although this is an error prone side effect, we automatically create a new id
126
//just to be compatible to the RI
127
UIViewRoot viewRoot = context.getViewRoot();
128             if (viewRoot != null)
129             {
130                 id = viewRoot.createUniqueId();
131             }
132             else
133             {
134                 context.getExternalContext().log("ERROR: Cannot automatically create an id for component of type " + getClass().getName() + " because there is no viewRoot in the current facesContext!");
135                 id = "ERROR";
136             }
137             //We remember that the id was null and log a warning down below
138
idWasNull = true;
139         }
140
141         UIComponent namingContainer = _ComponentUtils.findParentNamingContainer(this, false);
142         if (namingContainer != null)
143         {
144             _clientId = namingContainer.getClientId(context) + NamingContainer.SEPARATOR_CHAR + id;
145         }
146         else
147         {
148             _clientId = id;
149         }
150
151         Renderer renderer = getRenderer(context);
152         if (renderer != null)
153         {
154             _clientId = renderer.convertClientId(context, _clientId);
155         }
156
157         if (idWasNull)
158         {
159             context.getExternalContext().log("WARNING: Component " + _clientId + " just got an automatic id, because there was no id assigned yet. " +
160                                              "If this component was created dynamically (i.e. not by a JSP tag) you should assign it an " +
161                                              "explicit static id or assign it the id you get from the createUniqueId from the current UIViewRoot " +
162                                              "component right after creation!");
163         }
164
165         return _clientId;
166     }
167
168     public String JavaDoc getId()
169     {
170         return _id;
171     }
172
173     public void setId(String JavaDoc id)
174     {
175         isIdValid(id);
176         _id = id;
177         _clientId = null;
178     }
179
180     public UIComponent getParent()
181     {
182         return _parent;
183     }
184
185     public void setParent(UIComponent parent)
186     {
187         _parent = parent;
188     }
189
190     public boolean getRendersChildren()
191     {
192         Renderer renderer = getRenderer(getFacesContext());
193         if (renderer != null)
194         {
195             return renderer.getRendersChildren();
196         }
197         else
198         {
199             return false;
200         }
201     }
202
203     public List getChildren()
204     {
205         if (_childrenList == null)
206         {
207             _childrenList = new _ComponentChildrenList(this);
208         }
209         return _childrenList;
210     }
211
212     public int getChildCount()
213     {
214         return _childrenList == null ? 0 : _childrenList.size();
215     }
216
217
218     /**
219      * @param expr
220      * @return
221      */

222     public UIComponent findComponent(String JavaDoc expr)
223     {
224         if (expr == null) throw new NullPointerException JavaDoc("expr");
225         if (expr.length() == 0) throw new IllegalArgumentException JavaDoc("empty expr"); //TODO: not specified!
226

227         UIComponent findBase;
228         if (expr.charAt(0) == NamingContainer.SEPARATOR_CHAR)
229         {
230             findBase = _ComponentUtils.getRootComponent(this);
231             expr = expr.substring(1);
232         }
233         else
234         {
235             if (this instanceof NamingContainer)
236             {
237                 findBase = this;
238             }
239             else
240             {
241                 findBase = _ComponentUtils.findParentNamingContainer(this, true /* root if not found */);
242             }
243         }
244
245         int separator = expr.indexOf(NamingContainer.SEPARATOR_CHAR);
246         if (separator == -1)
247         {
248             return _ComponentUtils.findComponent(findBase, expr);
249         }
250         else
251         {
252             findBase = _ComponentUtils.findComponent(findBase, expr.substring(0, separator));
253             if (findBase == null)
254             {
255                 return null;
256             }
257             else
258             {
259                 return findBase.findComponent(expr.substring(separator + 1));
260             }
261         }
262     }
263
264
265     public Map getFacets()
266     {
267         if (_facetMap == null)
268         {
269             _facetMap = new _ComponentFacetMap(this);
270         }
271         return _facetMap;
272     }
273
274     public UIComponent getFacet(String JavaDoc name)
275     {
276         return _facetMap == null ? null : (UIComponent)_facetMap.get(name);
277     }
278
279     public Iterator getFacetsAndChildren()
280     {
281         return new _FacetsAndChildrenIterator(_facetMap, _childrenList);
282     }
283
284     public void broadcast(FacesEvent event)
285             throws AbortProcessingException
286     {
287         if (event == null) throw new NullPointerException JavaDoc("event");
288         if (_facesListeners == null) return;
289         for (Iterator it = _facesListeners.iterator(); it.hasNext(); )
290         {
291             FacesListener facesListener = (FacesListener)it.next();
292             if (event.isAppropriateListener(facesListener))
293             {
294                 event.processListener(facesListener);
295             }
296         }
297     }
298
299     public void decode(FacesContext context)
300     {
301         if (context == null) throw new NullPointerException JavaDoc("context");
302         Renderer renderer = getRenderer(context);
303         if (renderer != null)
304         {
305             renderer.decode(context, this);
306         }
307     }
308
309     public void encodeBegin(FacesContext context)
310             throws IOException JavaDoc
311     {
312         if (context == null) throw new NullPointerException JavaDoc("context");
313         if (!isRendered()) return;
314         Renderer renderer = getRenderer(context);
315         if (renderer != null)
316         {
317             renderer.encodeBegin(context, this);
318         }
319     }
320
321     public void encodeChildren(FacesContext context)
322             throws IOException JavaDoc
323     {
324         if (context == null) throw new NullPointerException JavaDoc("context");
325         if (!isRendered()) return;
326         Renderer renderer = getRenderer(context);
327         if (renderer != null)
328         {
329             renderer.encodeChildren(context, this);
330         }
331     }
332
333     public void encodeEnd(FacesContext context)
334             throws IOException JavaDoc
335     {
336         if (context == null) throw new NullPointerException JavaDoc("context");
337         if (!isRendered()) return;
338         Renderer renderer = getRenderer(context);
339         if (renderer != null)
340         {
341             renderer.encodeEnd(context, this);
342         }
343     }
344
345     protected void addFacesListener(FacesListener listener)
346     {
347         if (listener == null) throw new NullPointerException JavaDoc("listener");
348         if (_facesListeners == null)
349         {
350             _facesListeners = new ArrayList();
351         }
352         _facesListeners.add(listener);
353     }
354
355     protected FacesListener[] getFacesListeners(Class JavaDoc clazz)
356     {
357         if (_facesListeners == null)
358         {
359             return (FacesListener[])Array.newInstance(clazz, 0);
360         }
361         List lst = null;
362         for (Iterator it = _facesListeners.iterator(); it.hasNext(); )
363         {
364             FacesListener facesListener = (FacesListener)it.next();
365             if (clazz.isAssignableFrom(facesListener.getClass()))
366             {
367                 if (lst == null) lst = new ArrayList();
368                 lst.add(facesListener);
369             }
370         }
371         if (lst == null)
372         {
373             return (FacesListener[])Array.newInstance(clazz, 0);
374         }
375         else
376         {
377             return (FacesListener[])lst.toArray((FacesListener[])Array.newInstance(clazz, lst.size()));
378         }
379     }
380
381     protected void removeFacesListener(FacesListener listener)
382     {
383         if (_facesListeners != null)
384         {
385             _facesListeners.remove(listener);
386         }
387     }
388
389     public void queueEvent(FacesEvent event)
390     {
391         if (event == null) throw new NullPointerException JavaDoc("event");
392         UIComponent parent = getParent();
393         if (parent == null)
394         {
395             throw new IllegalStateException JavaDoc("component is not a descendant of a UIViewRoot");
396         }
397         parent.queueEvent(event);
398     }
399
400     public void processDecodes(FacesContext context)
401     {
402         if (context == null) throw new NullPointerException JavaDoc("context");
403         if (!isRendered()) return;
404         for (Iterator it = getFacetsAndChildren(); it.hasNext(); )
405         {
406             UIComponent childOrFacet = (UIComponent)it.next();
407             childOrFacet.processDecodes(context);
408         }
409         try
410         {
411             decode(context);
412         }
413         catch (RuntimeException JavaDoc e)
414         {
415             context.renderResponse();
416             throw e;
417         }
418     }
419
420     public void processValidators(FacesContext context)
421     {
422         if (context == null) throw new NullPointerException JavaDoc("context");
423         if (!isRendered()) return;
424         for (Iterator it = getFacetsAndChildren(); it.hasNext(); )
425         {
426             UIComponent childOrFacet = (UIComponent)it.next();
427             childOrFacet.processValidators(context);
428         }
429     }
430
431     public void processUpdates(FacesContext context)
432     {
433         if (context == null) throw new NullPointerException JavaDoc("context");
434         if (!isRendered()) return;
435         for (Iterator it = getFacetsAndChildren(); it.hasNext(); )
436         {
437             UIComponent childOrFacet = (UIComponent)it.next();
438             childOrFacet.processUpdates(context);
439         }
440     }
441
442     public Object JavaDoc processSaveState(FacesContext context)
443     {
444         if (context == null) throw new NullPointerException JavaDoc("context");
445         if (isTransient()) return null;
446         Map facetMap = null;
447         for (Iterator it = getFacets().entrySet().iterator(); it.hasNext(); )
448         {
449             Map.Entry entry = (Map.Entry)it.next();
450             if (facetMap == null) facetMap = new HashMap();
451             UIComponent component = (UIComponent)entry.getValue();
452             if (!component.isTransient())
453             {
454                 facetMap.put(entry.getKey(), component.processSaveState(context));
455             }
456         }
457         List childrenList = null;
458         if (getChildCount() > 0)
459         {
460             for (Iterator it = getChildren().iterator(); it.hasNext(); )
461             {
462                 UIComponent child = (UIComponent)it.next();
463                 if (!child.isTransient())
464                 {
465                     if (childrenList == null) childrenList = new ArrayList(getChildCount());
466                     childrenList.add(child.processSaveState(context));
467                 }
468             }
469         }
470         return new Object JavaDoc[] {saveState(context),
471                              facetMap,
472                              childrenList};
473     }
474
475     public void processRestoreState(FacesContext context,
476                                     Object JavaDoc state)
477     {
478         if (context == null) throw new NullPointerException JavaDoc("context");
479         Object JavaDoc myState = ((Object JavaDoc[])state)[0];
480         Map facetMap = (Map)((Object JavaDoc[])state)[1];
481         List childrenList = (List)((Object JavaDoc[])state)[2];
482         for (Iterator it = getFacets().entrySet().iterator(); it.hasNext(); )
483         {
484             Map.Entry entry = (Map.Entry)it.next();
485             Object JavaDoc facetState = facetMap.get(entry.getKey());
486             if (facetState != null)
487             {
488                 ((UIComponent)entry.getValue()).processRestoreState(context, facetState);
489             }
490             else
491             {
492                 context.getExternalContext().log("No state found to restore facet " + entry.getKey());
493             }
494         }
495         if (getChildCount() > 0)
496         {
497             int idx = 0;
498             for (Iterator it = getChildren().iterator(); it.hasNext(); )
499             {
500                 UIComponent child = (UIComponent)it.next();
501                 Object JavaDoc childState = childrenList.get(idx++);
502                 if (childState != null)
503                 {
504                     child.processRestoreState(context, childState);
505                 }
506                 else
507                 {
508                     context.getExternalContext().log("No state found to restore child of component " + getId());
509                 }
510             }
511         }
512         restoreState(context, myState);
513     }
514
515     protected FacesContext getFacesContext()
516     {
517         return FacesContext.getCurrentInstance();
518     }
519
520     protected Renderer getRenderer(FacesContext context)
521     {
522         if (context == null) throw new NullPointerException JavaDoc("context");
523         String JavaDoc rendererType = getRendererType();
524         if (rendererType == null) return null;
525         String JavaDoc renderKitId = context.getViewRoot().getRenderKitId();
526         RenderKitFactory rkf = (RenderKitFactory)FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
527         RenderKit renderKit = rkf.getRenderKit(context, renderKitId);
528         Renderer renderer = renderKit.getRenderer(getFamily(), rendererType);
529         if (renderer == null)
530         {
531             getFacesContext().getExternalContext().log("No Renderer found for component " + getClientId(context) + " (component-family=" + getFamily() + ", renderer-type=" + rendererType + ")");
532         }
533         return renderer;
534     }
535
536     public boolean isTransient()
537     {
538         return _transient;
539     }
540
541     public void setTransient(boolean transientFlag)
542     {
543         _transient = transientFlag;
544     }
545
546
547     public static Object JavaDoc saveAttachedState(FacesContext context,
548                                            Object JavaDoc attachedObject)
549     {
550         if (attachedObject == null) return null;
551         if (attachedObject instanceof List)
552         {
553             ArrayList lst = new ArrayList(((List)attachedObject).size());
554             for (Iterator it = ((List)attachedObject).iterator(); it.hasNext(); )
555             {
556                 lst.add(saveAttachedState(context, it.next()));
557             }
558             return new _AttachedListStateWrapper(lst);
559         }
560         else if (attachedObject instanceof StateHolder)
561         {
562             if (((StateHolder)attachedObject).isTransient())
563             {
564                 return null;
565             }
566             else
567             {
568                 return new _AttachedStateWrapper(attachedObject.getClass(),
569                                                  ((StateHolder)attachedObject).saveState(context));
570             }
571         }
572         else if (attachedObject instanceof Serializable JavaDoc)
573         {
574             return attachedObject;
575         }
576         else
577         {
578             return new _AttachedStateWrapper(attachedObject.getClass(), null);
579         }
580     }
581
582     public static Object JavaDoc restoreAttachedState(FacesContext context,
583                                               Object JavaDoc stateObj)
584             throws IllegalStateException JavaDoc
585     {
586         if (context == null) throw new NullPointerException JavaDoc("context");
587         if (stateObj == null) return null;
588         if (stateObj instanceof _AttachedListStateWrapper)
589         {
590             List lst = ((_AttachedListStateWrapper)stateObj).getWrappedStateList();
591             List restoredList = new ArrayList(lst.size());
592             for (Iterator it = lst.iterator(); it.hasNext(); )
593             {
594                 restoredList.add(restoreAttachedState(context, it.next()));
595             }
596             return restoredList;
597         }
598         else if (stateObj instanceof _AttachedStateWrapper)
599         {
600             Class JavaDoc clazz = ((_AttachedStateWrapper)stateObj).getClazz();
601             Object JavaDoc restoredObject = null;
602             try
603             {
604                 restoredObject = clazz.newInstance();
605             }
606             catch (InstantiationException JavaDoc e)
607             {
608                 throw new RuntimeException JavaDoc("Could not restore StateHolder of type " + clazz.getName() + " (missing no-args constructor?)", e);
609             }
610             catch (IllegalAccessException JavaDoc e)
611             {
612                 throw new RuntimeException JavaDoc(e);
613             }
614             if (restoredObject instanceof StateHolder)
615             {
616                 Object JavaDoc wrappedState = ((_AttachedStateWrapper)stateObj).getWrappedStateObject();
617                 ((StateHolder)restoredObject).restoreState(context, wrappedState);
618             }
619             return restoredObject;
620         }
621         else
622         {
623             return stateObj;
624         }
625     }
626
627
628     public Object JavaDoc saveState(FacesContext context)
629     {
630         Object JavaDoc values[] = new Object JavaDoc[7];
631         values[0] = _id;
632         values[1] = _rendered;
633         values[2] = _rendererType;
634         values[3] = _clientId;
635         values[4] = saveAttributesMap();
636         values[5] = saveAttachedState(context, _facesListeners);
637         values[6] = saveValueBindingMap(context);
638         return ((Object JavaDoc) (values));
639     }
640
641     public void restoreState(FacesContext context, Object JavaDoc state)
642     {
643         Object JavaDoc values[] = (Object JavaDoc[])state;
644         _id = (String JavaDoc)values[0];
645         _rendered = (Boolean JavaDoc)values[1];
646         _rendererType = (String JavaDoc)values[2];
647         _clientId = (String JavaDoc)values[3];
648         restoreAttributesMap(values[4]);
649         _facesListeners = (List)restoreAttachedState(context, values[5]);
650         restoreValueBindingMap(context, values[6]);
651     }
652
653
654     private Object JavaDoc saveAttributesMap()
655     {
656         if (_attributesMap != null)
657         {
658             return _attributesMap.getUnderlyingMap();
659         }
660         else
661         {
662             return null;
663         }
664     }
665
666     private void restoreAttributesMap(Object JavaDoc stateObj)
667     {
668         if (stateObj != null)
669         {
670             _attributesMap = new _ComponentAttributesMap(this, (Map)stateObj);
671         }
672         else
673         {
674             _attributesMap = null;
675         }
676     }
677
678     private Object JavaDoc saveValueBindingMap(FacesContext context)
679     {
680         if (_valueBindingMap != null)
681         {
682             int initCapacity = (_valueBindingMap.size() * 4 + 3) / 3;
683             HashMap stateMap = new HashMap(initCapacity);
684             for (Iterator it = _valueBindingMap.entrySet().iterator(); it.hasNext(); )
685             {
686                 Map.Entry entry = (Map.Entry)it.next();
687                 stateMap.put(entry.getKey(),
688                              saveAttachedState(context, entry.getValue()));
689             }
690             return stateMap;
691         }
692         else
693         {
694             return null;
695         }
696     }
697
698     private void restoreValueBindingMap(FacesContext context, Object JavaDoc stateObj)
699     {
700         if (stateObj != null)
701         {
702             Map stateMap = (Map)stateObj;
703             int initCapacity = (stateMap.size() * 4 + 3) / 3;
704             _valueBindingMap = new HashMap(initCapacity);
705             for (Iterator it = stateMap.entrySet().iterator(); it.hasNext(); )
706             {
707                 Map.Entry entry = (Map.Entry)it.next();
708                 _valueBindingMap.put(entry.getKey(),
709                                      restoreAttachedState(context, entry.getValue()));
710             }
711         }
712         else
713         {
714             _valueBindingMap = null;
715         }
716     }
717
718
719     /**
720      * @param string the component id, that should be a vaild one.
721      */

722     private void isIdValid(String JavaDoc string) {
723
724         //is there any component identifier ?
725
if(string == null)
726             return;
727  
728         //Component identifiers must obey the following syntax restrictions:
729
//1. Must not be a zero-length String.
730
if(string.length()==0){
731             throw new IllegalArgumentException JavaDoc("component identifier must not be a zero-length String");
732         }
733
734         //let's look at all chars inside of the ID if it is a valid ID!
735
char[] chars = string.toCharArray();
736         for (int i = 0; i < chars.length; i++) {
737             char tmpChar = chars[i];
738
739             //2. First character must be a letter or an underscore ('_').
740
if(i==0){
741                 if(!Character.isLetter(tmpChar) && tmpChar !='_'){
742                     throw new IllegalArgumentException JavaDoc("component identifier's first character must be a letter or an underscore ('_')! But it is \""+tmpChar+"\"");
743                 }
744             }else{
745
746                 //3. Subsequent characters must be a letter, a digit, an underscore ('_'), or a dash ('-').
747
if(!Character.isDigit(tmpChar) && !Character.isLetter(tmpChar) && tmpChar !='-' && tmpChar !='_'){
748                     throw new IllegalArgumentException JavaDoc("Subsequent characters of component identifier must be a letter, a digit, an underscore ('_'), or a dash ('-')! But component identifier contains \""+tmpChar+"\"");
749                 }
750             }
751         }
752         
753     }
754
755     
756     
757     //------------------ GENERATED CODE BEGIN (do not modify!) --------------------
758

759     private static final boolean DEFAULT_RENDERED = true;
760
761     private Boolean JavaDoc _rendered = null;
762     private String JavaDoc _rendererType = null;
763
764
765
766     public void setRendered(boolean rendered)
767     {
768         _rendered = Boolean.valueOf(rendered);
769     }
770
771     public boolean isRendered()
772     {
773         if (_rendered != null) return _rendered.booleanValue();
774         ValueBinding vb = getValueBinding("rendered");
775         Boolean JavaDoc v = vb != null ? (Boolean JavaDoc)vb.getValue(getFacesContext()) : null;
776         return v != null ? v.booleanValue() : DEFAULT_RENDERED;
777     }
778
779     public void setRendererType(String JavaDoc rendererType)
780     {
781         _rendererType = rendererType;
782     }
783
784     public String JavaDoc getRendererType()
785     {
786         if (_rendererType != null) return _rendererType;
787         ValueBinding vb = getValueBinding("rendererType");
788         return vb != null ? (String JavaDoc)vb.getValue(getFacesContext()) : null;
789     }
790
791
792     //------------------ GENERATED CODE END ---------------------------------------
793
}
794
Popular Tags