KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icesoft > faces > renderkit > dom_html_basic > FormRenderer


1 /*
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * "The contents of this file are subject to the Mozilla Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
11  * License for the specific language governing rights and limitations under
12  * the License.
13  *
14  * The Original Code is ICEfaces 1.5 open source software code, released
15  * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
16  * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
17  * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
18  *
19  * Contributor(s): _____________________.
20  *
21  * Alternatively, the contents of this file may be used under the terms of
22  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
23  * License), in which case the provisions of the LGPL License are
24  * applicable instead of those above. If you wish to allow use of your
25  * version of this file only under the terms of the LGPL License and not to
26  * allow others to use your version of this file under the MPL, indicate
27  * your decision by deleting the provisions above and replace them with
28  * the notice and other provisions required by the LGPL License. If you do
29  * not delete the provisions above, a recipient may use your version of
30  * this file under either the MPL or the LGPL License."
31  *
32  */

33
34 package com.icesoft.faces.renderkit.dom_html_basic;
35
36 import com.icesoft.faces.context.BridgeFacesContext;
37 import com.icesoft.faces.context.DOMContext;
38 import com.icesoft.faces.context.effects.CurrentStyle;
39 import com.icesoft.util.SeamUtilities;
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.w3c.dom.Element JavaDoc;
43
44 import javax.faces.FacesException;
45 import javax.faces.component.UIComponent;
46 import javax.faces.component.UIForm;
47 import javax.faces.context.FacesContext;
48 import java.io.IOException JavaDoc;
49 import java.util.HashMap JavaDoc;
50 import java.util.Iterator JavaDoc;
51 import java.util.Map JavaDoc;
52
53 public class FormRenderer extends DomBasicRenderer {
54
55     public static final String JavaDoc COMMAND_LINK_HIDDEN_FIELD =
56             "command_link_hidden_field";
57     private static final String JavaDoc COMMAND_LINK_HIDDEN_FIELDS_KEY =
58             "com.icesoft.faces.FormRequiredHidden";
59     public static final String JavaDoc FOCUS_HIDDEN_FIELD = "focus_hidden_field";
60     public static final String JavaDoc VIEWNUMBER_HIDDEN_FIELD = "viewNumber";
61
62
63     private static final Log log = LogFactory.getLog(FormRenderer.class);
64
65     public void decode(FacesContext facesContext, UIComponent uiComponent) {
66         validateParameters(facesContext, uiComponent, UIForm.class);
67         UIForm uiForm = (UIForm) uiComponent;
68         Map JavaDoc requestParameterMap =
69                 facesContext.getExternalContext().getRequestParameterMap();
70         String JavaDoc formClientId = uiForm.getClientId(facesContext);
71         if (requestParameterMap.containsKey(formClientId) ||
72             uiComponent.getAttributes().containsKey("fileUploaded")) {
73             uiForm.setSubmitted(true);
74         } else {
75             uiForm.setSubmitted(false);
76         }
77     }
78
79     public void encodeBegin(FacesContext facesContext, UIComponent uiComponent)
80             throws IOException JavaDoc {
81
82         validateParameters(facesContext, uiComponent, UIForm.class);
83         validateNestingForm(uiComponent);
84         DOMContext domContext =
85                 DOMContext.attachDOMContext(facesContext, uiComponent);
86         String JavaDoc formClientId = uiComponent.getClientId(facesContext);
87
88         if (!domContext.isInitialized()) {
89             Element JavaDoc root = domContext.createElement("form");
90
91             domContext.setRootNode(root);
92             root.setAttribute("id", formClientId);
93             root.setAttribute("method", "post");
94             String JavaDoc action = null;
95             // can't use a string constant we need to pass in the form id
96
// form id is not accessible in the form action attribute
97
action = "iceSubmit('" + formClientId + "');";
98             root.setAttribute("action", action);
99
100             String JavaDoc styleClass =
101                     (String JavaDoc) uiComponent.getAttributes().get("styleClass");
102             if (styleClass != null) {
103                 root.setAttribute("class", styleClass);
104             }
105             String JavaDoc acceptcharset =
106                     (String JavaDoc) uiComponent.getAttributes().get("acceptcharset");
107             if (acceptcharset != null) {
108                 root.setAttribute("accept-charset", acceptcharset);
109             }
110             //redirect form submits
111
String JavaDoc redirectScript = "'" + formClientId +"'.asExtendedElement().captureAndRedirectSubmit();";
112             Element JavaDoc scriptElement = (Element JavaDoc) root.appendChild(domContext.createElement("script"));
113             scriptElement.setAttribute("language", "javascript");
114             scriptElement.appendChild(domContext.createTextNode(redirectScript));
115             root.appendChild(scriptElement);
116
117             // this hidden field will be checked in the decode method to
118
// determine if this form has been submitted.
119
Element JavaDoc formHiddenField = domContext.createElement("input");
120             formHiddenField.setAttribute("type", "hidden");
121             formHiddenField.setAttribute("name", formClientId);
122             formHiddenField.setAttribute("value", formClientId);
123             root.appendChild(formHiddenField);
124
125             // Only render the css update field once. Rendering more then one will cause
126
// a duplicate ID error
127
Element JavaDoc cssUpdateField = domContext.createElement(HTML.INPUT_ELEM);
128             cssUpdateField.setAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN);
129             cssUpdateField.setAttribute(HTML.NAME_ATTR,
130                                         CurrentStyle.CSS_UPDATE_FIELD);
131             cssUpdateField.setAttribute(HTML.VALUE_ATTR, "");
132             root.appendChild(cssUpdateField);
133
134             // support for VIEWNUMBER_HIDDEN_FIELD
135
if (!domContext.isStreamWriting()) {
136                 Element JavaDoc viewNumberElement = domContext.createElement("input");
137                 viewNumberElement.setAttribute("type", "hidden");
138                 viewNumberElement.setAttribute("name", VIEWNUMBER_HIDDEN_FIELD);
139                 viewNumberElement.setAttribute("value",
140                                                ((BridgeFacesContext) facesContext).getViewNumber());
141                 root.appendChild(viewNumberElement);
142             }
143         }
144
145         // This has to occur outside the isInitialized test, as it has to happen
146
// all the time, even if the form otherwise has not changed.
147
Element JavaDoc root = (Element JavaDoc) domContext.getRootNode();
148
149         String JavaDoc conversationId = SeamUtilities.getSeamConversationId();
150         if (conversationId != null) {
151             String JavaDoc conversationParamName =
152                     SeamUtilities.getConversationIdParameterName();
153
154             Element JavaDoc conversationIDElement =
155                     domContext.createElement(HTML.INPUT_ELEM);
156             if (log.isDebugEnabled()) {
157                 log.debug("Embedding Seam Param - name: " + conversationParamName +
158                           ", value: " + conversationId);
159             }
160             conversationIDElement
161                     .setAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN);
162             conversationIDElement
163                     .setAttribute(HTML.NAME_ATTR, conversationParamName);
164
165             conversationIDElement.setAttribute(HTML.VALUE_ATTR, conversationId);
166             root.appendChild(conversationIDElement);
167
168         }
169
170         String JavaDoc flowId = SeamUtilities.getSpringFlowId();
171         if (flowId != null) {
172             String JavaDoc flowParamName =
173                     SeamUtilities.getFlowIdParameterName();
174
175             Element JavaDoc flowIDElement =
176                     domContext.createElement(HTML.INPUT_ELEM);
177             if (log.isDebugEnabled()) {
178                 log.debug("Embedding Spring Param - name: " + flowParamName +
179                           ", value: " + flowId);
180             }
181             String JavaDoc flowParamId = formClientId + ":" + flowParamName;
182             flowIDElement
183                     .setAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN);
184             flowIDElement
185                     .setAttribute(HTML.NAME_ATTR, flowParamName);
186             flowIDElement
187                     .setAttribute(HTML.ID_ATTR, flowParamId);
188
189             flowIDElement.setAttribute(HTML.VALUE_ATTR, flowId);
190             root.appendChild(flowIDElement);
191
192         }
193
194
195         String JavaDoc contextClass = facesContext.getClass().toString();
196         root.setAttribute("context_type", contextClass);
197
198         PassThruAttributeRenderer
199                 .renderAttributes(facesContext, uiComponent, null);
200         facesContext.getApplication().getViewHandler().writeState(facesContext);
201
202         // don't override user-defined value
203
String JavaDoc userDefinedValue = root.getAttribute("onsubmit");
204         if (userDefinedValue == null || userDefinedValue.equalsIgnoreCase("")) {
205             root.setAttribute("onsubmit", "return false;");
206         }
207         addHiddenField(facesContext, FOCUS_HIDDEN_FIELD);
208
209         try {
210             domContext.startNode(facesContext, uiComponent, root);
211         } catch (IOException JavaDoc ioe) {
212             ioe.printStackTrace();
213         }
214         domContext.stepInto(uiComponent);
215     }
216
217     public void encodeChildren(FacesContext facesContext,
218                                UIComponent uiComponent) {
219         validateParameters(facesContext, uiComponent, UIForm.class);
220     }
221
222     public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
223             throws IOException JavaDoc {
224         validateParameters(facesContext, uiComponent, UIForm.class);
225
226         // render needed hidden fields added by CommandLinkRenderer (and perhaps
227
// other renderers as well)
228
DOMContext domContext =
229                 DOMContext.getDOMContext(facesContext, uiComponent);
230         // set static class variable for support of myfaces command link
231
renderCommandLinkHiddenFields(facesContext, uiComponent);
232         domContext.stepOver();
233         domContext.endNode(facesContext, uiComponent, domContext.getRootNode());
234     }
235
236
237     /**
238      * @param facesContext
239      * @param uiComponent
240      * Render any required hidden fields. There is a list
241      * (on the request map of the external context) of
242      * 'required hidden fields'. Hidden fields can be
243      * contributed by the CommandLinkRenderer. Contribution
244      * is made during rendering of this form's commandLink
245      * children so we have to wait for the child renderers
246      * to complete their work before we render the hidden
247      * fields. Therefore, this method should be called from
248      * the form's encodeEnd method. We can assume that the
249      * hidden fields are the last fields in the form because
250      * they are rendered in the FormRenderer's encodeEnd
251      * method. Note that the CommandLinkRenderer adds one
252      * hidden field that indicates the id of the link that
253      * was clicked to submit the form ( in case there are
254      * multiple commandLinks on a page) and one hidden field
255      * for each of its UIParameter children.
256      */

257     private static void renderCommandLinkHiddenFields(FacesContext facesContext,
258                                                       UIComponent uiComponent) {
259         Map JavaDoc commandLinkHiddenFields = getCommandLinkFields(facesContext);
260         if (commandLinkHiddenFields != null) {
261             renderRequiredCommandLinkHiddenFields(uiComponent, facesContext,
262                                                   commandLinkHiddenFields);
263             resetCommandLinkFieldsInRequestMap(facesContext);
264         }
265     }
266
267     /**
268      * @param facesContext
269      */

270     private static void resetCommandLinkFieldsInRequestMap(
271             FacesContext facesContext) {
272         Map JavaDoc requestMap = facesContext.getExternalContext().getRequestMap();
273         requestMap.put(COMMAND_LINK_HIDDEN_FIELDS_KEY, null);
274     }
275
276     /**
277      * @param uiComponent
278      * @param facesContext
279      * @param map
280      */

281     private static void renderRequiredCommandLinkHiddenFields(
282             UIComponent uiComponent,
283             FacesContext facesContext, Map JavaDoc map) {
284         DOMContext domContext =
285                 DOMContext.getDOMContext(facesContext, uiComponent);
286         Element JavaDoc root = (Element JavaDoc) domContext.getRootNode();
287         Iterator JavaDoc commandLinkFields = map.entrySet().iterator();
288         while (commandLinkFields.hasNext()) {
289             Map.Entry JavaDoc nextField = (Map.Entry JavaDoc) commandLinkFields.next();
290             if (COMMAND_LINK_HIDDEN_FIELD.equals(nextField.getValue())) {
291                 Element JavaDoc next = domContext.createElement("input");
292                 next.setAttribute("type", "hidden");
293                 next.setAttribute("name", nextField.getKey().toString());
294                 root.appendChild(next);
295             }
296         }
297     }
298
299     /**
300      * @param facesContext
301      * @param fieldName
302      */

303     public static void addHiddenField(FacesContext facesContext,
304                                       String JavaDoc fieldName) {
305         addHiddenField(facesContext, fieldName, COMMAND_LINK_HIDDEN_FIELD);
306     }
307
308     /**
309      * @param facesContext
310      * @param fieldName
311      * @param value
312      */

313     //make this method public when we modify the hidden field rendering
314
//to accept arbitrary hidden fields
315
private static void addHiddenField(FacesContext facesContext,
316                                        String JavaDoc fieldName, String JavaDoc value) {
317         Map JavaDoc hiddenFieldMap = getCommandLinkFields(facesContext);
318         if (hiddenFieldMap == null) {
319             hiddenFieldMap = createCommandLinkFieldsOnRequestMap(facesContext);
320         }
321         if (!hiddenFieldMap.containsKey(fieldName)) {
322             hiddenFieldMap.put(fieldName, value);
323         }
324     }
325
326     /**
327      * @param facesContext
328      * @return Map the hiddenFieldMap
329      */

330     private static Map JavaDoc getCommandLinkFields(FacesContext facesContext) {
331         Map JavaDoc requestMap = facesContext.getExternalContext().getRequestMap();
332         Map JavaDoc hiddenFieldMap =
333                 (Map JavaDoc) requestMap.get(COMMAND_LINK_HIDDEN_FIELDS_KEY);
334         if (hiddenFieldMap == null) {
335             hiddenFieldMap = new HashMap JavaDoc();
336             requestMap.put(COMMAND_LINK_HIDDEN_FIELDS_KEY, hiddenFieldMap);
337         }
338         return hiddenFieldMap;
339     }
340
341     /**
342      * @param facesContext
343      * @return Map hiddenFieldMap
344      */

345     private static Map JavaDoc createCommandLinkFieldsOnRequestMap(
346             FacesContext facesContext) {
347         Map JavaDoc requestMap = facesContext.getExternalContext().getRequestMap();
348         Map JavaDoc hiddenFieldMap =
349                 (Map JavaDoc) requestMap.get(COMMAND_LINK_HIDDEN_FIELDS_KEY);
350         if (hiddenFieldMap == null) {
351             hiddenFieldMap = new HashMap JavaDoc();
352             requestMap.put(COMMAND_LINK_HIDDEN_FIELDS_KEY, hiddenFieldMap);
353         }
354         return hiddenFieldMap;
355     }
356     private void validateNestingForm(UIComponent uiComponent) throws IOException JavaDoc{
357         UIComponent parent = uiComponent.getParent();
358         if (parent == null) {
359             return;
360         }
361         if (parent instanceof UIForm){
362             throw new FacesException("Nested form found on the page. The form " +
363                     "action element can not be nested");
364         }
365         validateNestingForm(parent);
366     }
367 }
368
Popular Tags