View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.component.html.util;
20  
21  import java.util.HashMap;
22  import java.util.Iterator;
23  import java.util.Map;
24  
25  import javax.faces.component.NamingContainer;
26  import javax.faces.component.UIComponent;
27  import javax.faces.component.UIData;
28  import javax.faces.component.UIParameter;
29  import javax.faces.context.FacesContext;
30  import javax.faces.lifecycle.LifecycleFactory;
31  import javax.faces.render.Renderer;
32  import javax.faces.webapp.FacesServlet;
33  import javax.servlet.ServletContext;
34  
35  import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
36  import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
37  
38  /**
39   * <p>Utility class for providing basic functionality to the HTML faces 
40   * extended components.<p>
41   * 
42   * @author Sean Schofield
43   * @version $Revision: 664580 $ $Date: 2008-06-08 19:21:01 -0500 (Sun, 08 Jun 2008) $
44   */
45  public final class HtmlComponentUtils
46  {
47      /**
48       * Constructor (Private)
49       */
50      private HtmlComponentUtils()
51      {}
52  
53      /**
54       * Gets the client id associated with the component.  Checks the forceId 
55       * attribute of the component (if present) and uses the orginally supplied 
56       * id value if that attribute is true.  Also performs the required call 
57       * to <code>convertClientId</code> on the {@link Renderer} argument.
58       * 
59       * @param component The component for which the client id is needed.
60       * @param renderer The renderer associated with the component.
61       * @param context Additional context information to help in the request.
62       * @return The clientId to use with the specified component.
63       */
64      public static String getClientId(UIComponent component,
65                                       Renderer renderer,
66                                       FacesContext context)
67      {
68  
69          //forceId enabled?
70          boolean forceId = RendererUtils.getBooleanValue(JSFAttr.FORCE_ID_ATTR,
71                  component.getAttributes().get(JSFAttr.FORCE_ID_ATTR),false);
72  
73          if (forceId && component.getId() != null)
74          {
75              String clientId = component.getId();
76  
77              /**
78               * See if there is a parent naming container.  If there is ...
79               */
80              UIComponent parentContainer = HtmlComponentUtils.findParentNamingContainer(component, false);
81              if (parentContainer != null)
82              {
83                  if (parentContainer instanceof UIData)
84                  {
85                      // see if the originally supplied id should be used
86                      boolean forceIdIndex = RendererUtils.getBooleanValue(JSFAttr.FORCE_ID_ATTR,
87                              component.getAttributes().get(JSFAttr.FORCE_ID_INDEX_ATTR),true);
88  
89                      // note: user may have specifically requested that we do not add the special forceId [index] suffix
90                      if (forceIdIndex)
91                      {
92                          int rowIndex = ( (UIData) parentContainer).getRowIndex();
93                          if (rowIndex != -1) {
94                              clientId = clientId + "[" + rowIndex + "]";
95                          }
96                      }
97                  }
98              }
99  
100             // JSF spec requires that renderer get a chance to convert the id
101             if (renderer != null)
102             {
103                 clientId = renderer.convertClientId(context, clientId);
104             }
105 
106             return clientId;
107         }
108         else
109         {
110             return null;
111         }
112     }
113 
114     /**
115      * Locates the {@link NamingContainer} associated with the givem 
116      * {@link UIComponent}.
117      * 
118      * @param component The component whose naming locator needs to be found.
119      * @param returnRootIfNotFound Whether or not the root should be returned 
120      *    if no naming container is found.
121      * @return The parent naming container (or root if applicable).
122      */
123     public static UIComponent findParentNamingContainer(UIComponent component,
124                                                         boolean returnRootIfNotFound)
125     {
126         UIComponent parent = component.getParent();
127         if (returnRootIfNotFound && parent == null)
128         {
129             return component;
130         }
131         while (parent != null)
132         {
133             if (parent instanceof NamingContainer) return parent;
134             if (returnRootIfNotFound)
135             {
136                 UIComponent nextParent = parent.getParent();
137                 if (nextParent == null)
138                 {
139                     return parent;  //Root
140                 }
141                 parent = nextParent;
142             }
143             else
144             {
145                 parent = parent.getParent();
146             }
147         }
148         return null;
149     }
150     
151     
152     /**
153      * The getParameterMap() is used for getting the parameters
154      * of a specific component.
155      * @param component
156      * @return the Map of the component.
157      */
158     public static Map getParameterMap(UIComponent component) {
159         Map result = new HashMap();
160         for (Iterator iter = component.getChildren().iterator(); iter.hasNext();) {
161             UIComponent child = (UIComponent) iter.next();
162             if (child instanceof UIParameter) {
163                 UIParameter uiparam = (UIParameter) child;
164                 Object value = uiparam.getValue();
165                 if (value != null) {
166                     result.put(uiparam.getName(), value);
167                 }
168             }
169         }
170         return result;
171     }   
172     
173     /**
174      * The getLifecycleId() is used for getting the id of 
175      * the Lifecycle from the ServletContext.
176      * @param context
177      * @return the id of the life cycle.
178      */ 
179     public static String getLifecycleId(ServletContext context) {
180         String lifecycleId = context
181                 .getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
182         return lifecycleId != null ? lifecycleId
183                 : LifecycleFactory.DEFAULT_LIFECYCLE;
184     }       
185 
186 }