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.renderkit.html.util;
20  
21  import java.io.IOException;
22  import java.util.HashSet;
23  import java.util.Set;
24  
25  import javax.faces.application.StateManager;
26  import javax.faces.application.ViewHandler;
27  import javax.faces.component.UIComponent;
28  import javax.faces.context.FacesContext;
29  import javax.faces.context.ResponseWriter;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
34  import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
35  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
36  import org.apache.myfaces.shared_tomahawk.renderkit.html.util.FormInfo;
37  
38  /**
39   * Many JSF components can be used without an enclosing h:form. In this
40   * case, they need a dummy form to store data into and submit when
41   * communication with the server is necessary. These components can use
42   * methods on the <code>DummyFormRequestInfo</code> object accessable via this
43   * class to register parameters and get the name of a form to submit.
44   * <p/>
45   * Only one dummy form will be rendered into the response.
46   *
47   * @author Manfred Geiler (latest modification by $Author: paulsp $)
48   * @author Bruno Aranda
49   * @version $Revision: 491777 $ $Date: 2007-01-02 06:27:11 -0500 (Tue, 02 Jan 2007) $
50   */
51  public class DummyFormUtils {
52      private static final Log log = LogFactory.getLog(DummyFormUtils.class);
53  
54      public static final String DUMMY_FORM_NAME = "linkDummyForm";
55      private static final String DUMMY_FORM_ID = "linkDummyForm";
56  
57      /**
58       * Used to store the instance of <code>DummyFormRequestInfo</code> in the request map
59       */
60      public static final String DUMMY_FORM_INFO = DummyFormUtils.class.getName() + ".DUMMY_FORM_INFO";
61  
62  
63      public static String getDummyFormName() {
64          return DUMMY_FORM_NAME;
65      }
66  
67      /**
68       * When writeDummyForm is set to true, a <code>DummyFormRequestInfo</code> object will be instantiated
69       * and put in the request. Later, if this object is found, the dummyForm javascript will be rendered in the page
70       * before the end of the <code>body</code> tag
71       *
72       * @param facesContext
73       * @param writeDummyForm
74       */
75      public static void setWriteDummyForm(FacesContext facesContext, boolean writeDummyForm) {
76          if (!writeDummyForm) {
77              return;
78          }
79  
80          if (!isWriteDummyForm(facesContext)) {
81              DummyFormRequestInfo dummyFormInfo = new DummyFormRequestInfo();
82              facesContext.getExternalContext().getRequestMap().put(DUMMY_FORM_INFO, dummyFormInfo);
83          }
84      }
85  
86      /**
87       * Checks if the DummyFormRequestInfo is already in the request map.
88       *
89       * @param facesContext
90       * @return boolean true, if dummy form is to be written
91       */
92      public static boolean isWriteDummyForm(FacesContext facesContext) {
93          return facesContext.getExternalContext().getRequestMap().containsKey(DUMMY_FORM_INFO);
94      }
95  
96      /**
97       * Delegator method to add a parameter to the DummyFormRequestInfo object in the request
98       *
99       * @param facesContext
100      * @param paramName
101      */
102     public static void addDummyFormParameter(FacesContext facesContext, String paramName) {
103         if (isWriteDummyForm(facesContext)) {
104             DummyFormRequestInfo dummyFormInfo = (DummyFormRequestInfo) facesContext.getExternalContext().getRequestMap().get(DUMMY_FORM_INFO);
105             dummyFormInfo.addDummyFormParameter(paramName);
106         }
107         else {
108             if (log.isWarnEnabled()) {
109                 log.warn("Dummy Form parameter was not added because dummy form is not written");
110             }
111         }
112     }
113 
114     public static Set getDummyFormParameters(FacesContext facesContext) {
115         if (isWriteDummyForm(facesContext)) {
116             DummyFormRequestInfo dummyFormInfo = (DummyFormRequestInfo) facesContext.getExternalContext().getRequestMap().get(DUMMY_FORM_INFO);
117             return dummyFormInfo.getDummyFormParams();
118         }
119 
120         return new HashSet();
121     }
122 
123 
124     public static void writeDummyForm(ResponseWriter writer,
125                                       Set dummyFormParams) throws IOException {
126         FacesContext facesContext = FacesContext.getCurrentInstance();
127         ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
128         String viewId = facesContext.getViewRoot().getViewId();
129         String actionURL = viewHandler.getActionURL(facesContext, viewId);
130 
131         //write out dummy form
132         writer.startElement(org.apache.myfaces.shared_tomahawk.renderkit.html.HTML.FORM_ELEM, null);
133         writer.writeAttribute(org.apache.myfaces.shared_tomahawk.renderkit.html.HTML.ID_ATTR, DUMMY_FORM_ID, null);
134         writer.writeAttribute(HTML.NAME_ATTR, DUMMY_FORM_NAME, null);
135         writer.writeAttribute(HTML.STYLE_ATTR, "display:inline", null);
136         writer.writeAttribute(HTML.METHOD_ATTR, "post", null);
137         writer.writeURIAttribute(org.apache.myfaces.shared_tomahawk.renderkit.html.HTML.ACTION_ATTR,
138                                  facesContext.getExternalContext().encodeActionURL(actionURL),
139                                  null);
140         writer.flush();
141 
142         StateManager stateManager = facesContext.getApplication().getStateManager();
143         org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils.writePrettyLineSeparator(facesContext);
144 
145         //TODO: Optimize saveSerializedView call, because serialized view is built twice!
146         StateManager.SerializedView serializedView = stateManager.saveSerializedView(facesContext);
147         // Adam Winer - TOMAHAWK-253: Ideally, this code should be refactored so that the server-side code is also calling StateManager.writeState() too
148         //    it's a significant problem that DummyFormUtils has hardcoded knowledge of how the StateManager works.
149         if (stateManager.isSavingStateInClient(facesContext)) {
150             //render state parameters
151             stateManager.writeState(facesContext, serializedView);
152         }
153 
154         if (org.apache.myfaces.shared_tomahawk.config.MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isAutoScroll())
155         {
156             HtmlRendererUtils.renderAutoScrollHiddenInput(facesContext, writer);
157         }
158 
159         org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils.writePrettyLineSeparator(facesContext);
160         if (dummyFormParams != null) {
161             org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils.renderHiddenCommandFormParams(writer, dummyFormParams);
162             org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils.renderClearHiddenCommandFormParamsFunction(writer,
163                                                                                                                            DUMMY_FORM_NAME,
164                                                                                                                            dummyFormParams, null);
165         }
166         org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils.writePrettyLineSeparator(facesContext);
167 
168         writer.endElement(HTML.FORM_ELEM);
169     }
170 
171     public static FormInfo findNestingForm(UIComponent uiComponent, FacesContext facesContext) {
172         FormInfo formInfo = RendererUtils.findNestingForm(uiComponent, facesContext);
173         if (formInfo != null) {
174             return formInfo;
175         }
176 
177         DummyFormUtils.setWriteDummyForm(facesContext, true);
178         return new FormInfo(null, DUMMY_FORM_NAME);
179     }
180 }