Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/sun/facelets/tag/jsf/ComponentSupport.java


1   /**
2    * Licensed under the Common Development and Distribution License,
3    * you may not use this file except in compliance with the License.
4    * You may obtain a copy of the License at
5    * 
6    *   http://www.sun.com/cddl/
7    *   
8    * Unless required by applicable law or agreed to in writing, software
9    * distributed under the License is distributed on an "AS IS" BASIS,
10   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
11   * implied. See the License for the specific language governing
12   * permissions and limitations under the License.
13   */
14  
15  package com.sun.facelets.tag.jsf;
16  
17  import java.io.IOException;
18  import java.util.ArrayList;
19  import java.util.Collection;
20  import java.util.Collections;
21  import java.util.Iterator;
22  import java.util.List;
23  import java.util.Locale;
24  
25  import javax.faces.FacesException;
26  import javax.faces.component.UIComponent;
27  import javax.faces.component.UIViewRoot;
28  import javax.faces.context.FacesContext;
29  
30  import com.sun.facelets.FaceletContext;
31  import com.sun.facelets.FaceletHandler;
32  import com.sun.facelets.tag.TagAttribute;
33  import com.sun.facelets.tag.TagAttributeException;
34  
35  /**
36   * 
37   * @author Jacob Hookom
38   * @version $Id: ComponentSupport.java,v 1.6 2006/05/31 04:11:58 jhook Exp $
39   */
40  public final class ComponentSupport {
41  
42      private final static String MARK_DELETED = "com.sun.facelets.MARK_DELETED";
43      public final static String MARK_CREATED = "com.sun.facelets.MARK_ID";
44      
45      /**
46       * Used in conjunction with markForDeletion where any UIComponent marked
47       * will be removed.
48       * 
49       * @param c
50       *            UIComponent to finalize
51       */
52      public static final void finalizeForDeletion(UIComponent c) {
53          // remove any existing marks of deletion
54          c.getAttributes().remove(MARK_DELETED);
55  
56          // finally remove any children marked as deleted
57          int sz = c.getChildCount();
58          if (sz > 0) {
59              UIComponent cc = null;
60              List cl = c.getChildren();
61              while (--sz >= 0) {
62                  cc = (UIComponent) cl.get(sz);
63                  if (cc.getAttributes().containsKey(MARK_DELETED)) {
64                      cl.remove(sz);
65                  }
66              }
67          }
68  
69          // remove any facets marked as deleted
70          if (c.getFacets().size() > 0) {
71              Collection col = c.getFacets().values();
72              UIComponent fc;
73              for (Iterator itr = col.iterator(); itr.hasNext();) {
74                  fc = (UIComponent) itr.next();
75                  if (fc.getAttributes().containsKey(MARK_DELETED)) {
76                      itr.remove();
77                  }
78              }
79          }
80      }
81      
82  
83      /**
84       * A lighter-weight version of UIComponent's findChild.
85       * 
86       * @param parent
87       *            parent to start searching from
88       * @param id
89       *            to match to
90       * @return UIComponent found or null
91       */
92      public static final UIComponent findChild(UIComponent parent, String id) {
93          int sz = parent.getChildCount();
94          if (sz > 0) {
95              UIComponent c = null;
96              List cl = parent.getChildren();
97              while (--sz >= 0) {
98                  c = (UIComponent) cl.get(sz);
99                  if (id.equals(c.getId())) {
100                     return c;
101                 }
102             }
103         }
104         return null;
105     }
106     
107     /**
108      * By TagId, find Child
109      * @param parent
110      * @param id
111      * @return
112      */
113     public static final UIComponent findChildByTagId(UIComponent parent, String id) {
114         int sz = parent.getChildCount();
115         if (sz > 0) {
116             UIComponent c = null;
117             List cl = parent.getChildren();
118             String cid = null;
119             while (--sz >= 0) {
120                 c = (UIComponent) cl.get(sz);
121                 cid = (String) c.getAttributes().get(MARK_CREATED);
122                 if (id.equals(cid)) {
123                     return c;
124                 }
125             }
126         }
127         return null;
128     }
129 
130     /**
131      * According to JSF 1.2 tag specs, this helper method will use the
132      * TagAttribute passed in determining the Locale intended.
133      * 
134      * @param ctx
135      *            FaceletContext to evaluate from
136      * @param attr
137      *            TagAttribute representing a Locale
138      * @return Locale found
139      * @throws TagAttributeException
140      *             if the Locale cannot be determined
141      */
142     public static final Locale getLocale(FaceletContext ctx, TagAttribute attr)
143             throws TagAttributeException {
144         Object obj = attr.getObject(ctx);
145         if (obj instanceof Locale) {
146             return (Locale) obj;
147         }
148         if (obj instanceof String) {
149             String s = (String) obj;
150             if (s.length() == 2) {
151                 return new Locale(s);
152             }
153             if (s.length() == 5) {
154                 return new Locale(s.substring(0, 2), s.substring(3, 5)
155                         .toUpperCase());
156             }
157             if (s.length() >= 7) {
158                 return new Locale(s.substring(0, 2), s.substring(3, 5)
159                         .toUpperCase(), s.substring(6, s.length()));
160             }
161             throw new TagAttributeException(attr, "Invalid Locale Specified: "
162                     + s);
163         } else {
164             throw new TagAttributeException(attr,
165                     "Attribute did not evaluate to a String or Locale: " + obj);
166         }
167     }
168 
169     /**
170      * Tries to walk up the parent to find the UIViewRoot, if not found, then go
171      * to FaceletContext's FacesContext for the view root.
172      * 
173      * @param ctx
174      *            FaceletContext
175      * @param parent
176      *            UIComponent to search from
177      * @return UIViewRoot instance for this evaluation
178      */
179     public static final UIViewRoot getViewRoot(FaceletContext ctx,
180             UIComponent parent) {
181         UIComponent c = parent;
182         do {
183             if (c instanceof UIViewRoot) {
184                 return (UIViewRoot) c;
185             } else {
186                 c = c.getParent();
187             }
188         } while (c != null);
189         return ctx.getFacesContext().getViewRoot();
190     }
191 
192     /**
193      * Marks all direct children and Facets with an attribute for deletion.
194      * 
195      * @see #finalizeForDeletion(UIComponent)
196      * @param c
197      *            UIComponent to mark
198      */
199     public static final void markForDeletion(UIComponent c) {
200         // flag this component as deleted
201         c.getAttributes().put(MARK_DELETED, Boolean.TRUE);
202 
203         // mark all children to be deleted
204         int sz = c.getChildCount();
205         if (sz > 0) {
206             UIComponent cc = null;
207             List cl = c.getChildren();
208             while (--sz >= 0) {
209                 cc = (UIComponent) cl.get(sz);
210                 if (cc.getAttributes().containsKey(MARK_CREATED)) {
211                     cc.getAttributes().put(MARK_DELETED, Boolean.TRUE);
212                 }
213             }
214         }
215 
216         // mark all facets to be deleted
217         if (c.getFacets().size() > 0) {
218             Collection col = c.getFacets().values();
219             UIComponent fc;
220             for (Iterator itr = col.iterator(); itr.hasNext();) {
221                 fc = (UIComponent) itr.next();
222                 if (fc.getAttributes().containsKey(MARK_CREATED)) {
223                     fc.getAttributes().put(MARK_DELETED, Boolean.TRUE);
224                 }
225             }
226         }
227     }
228     
229     public final static void encodeRecursive(FacesContext context,
230             UIComponent viewToRender) throws IOException, FacesException {
231         if (viewToRender.isRendered()) {
232             viewToRender.encodeBegin(context);
233             if (viewToRender.getRendersChildren()) {
234                 viewToRender.encodeChildren(context);
235             } else if (viewToRender.getChildCount() > 0) {
236                 Iterator kids = viewToRender.getChildren().iterator();
237                 while (kids.hasNext()) {
238                     UIComponent kid = (UIComponent) kids.next();
239                     encodeRecursive(context, kid);
240                 }
241             }
242             viewToRender.encodeEnd(context);
243         }
244     }
245     
246     public static void removeTransient(UIComponent c) {
247         UIComponent d, e;
248         if (c.getChildCount() > 0) {
249             for (Iterator itr = c.getChildren().iterator(); itr.hasNext();) {
250                 d = (UIComponent) itr.next();
251                 if (d.getFacets().size() > 0) {
252                     for (Iterator jtr = d.getFacets().values().iterator(); jtr
253                             .hasNext();) {
254                         e = (UIComponent) jtr.next();
255                         if (e.isTransient()) {
256                             jtr.remove();
257                         } else {
258                             removeTransient(e);
259                         }
260                     }
261                 }
262                 if (d.isTransient()) {
263                     itr.remove();
264                 } else {
265                     removeTransient(d);
266                 }
267             }
268         }
269         if (c.getFacets().size() > 0) {
270             for (Iterator itr = c.getFacets().values().iterator(); itr
271                     .hasNext();) {
272                 d = (UIComponent) itr.next();
273                 if (d.isTransient()) {
274                     itr.remove();
275                 } else {
276                     removeTransient(d);
277                 }
278             }
279         }
280     }
281     
282     /**
283      * Determine if the passed component is not null and if it's new
284      * to the tree.  This operation can be used for determining if attributes
285      * should be wired to the component.
286      * 
287      * @param component the component you wish to modify
288      * @return true if it's new
289      */
290     public final static boolean isNew(UIComponent component) {
291         return component != null && component.getParent() == null;
292     }
293 }