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 }