View Javadoc

1   /*
2    * $Id: Form.java 651946 2008-04-27 13:41:38Z apetrelli $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  package org.apache.struts2.components;
23  
24  import com.opensymphony.xwork2.ObjectFactory;
25  import com.opensymphony.xwork2.config.Configuration;
26  import com.opensymphony.xwork2.config.RuntimeConfiguration;
27  import com.opensymphony.xwork2.config.entities.ActionConfig;
28  import com.opensymphony.xwork2.config.entities.InterceptorMapping;
29  import com.opensymphony.xwork2.inject.Inject;
30  import com.opensymphony.xwork2.interceptor.MethodFilterInterceptorUtil;
31  import com.opensymphony.xwork2.util.ValueStack;
32  import com.opensymphony.xwork2.validator.ActionValidatorManager;
33  import com.opensymphony.xwork2.validator.FieldValidator;
34  import com.opensymphony.xwork2.validator.ValidationInterceptor;
35  import com.opensymphony.xwork2.validator.Validator;
36  import org.apache.struts2.StrutsConstants;
37  import org.apache.struts2.views.annotations.StrutsTag;
38  import org.apache.struts2.views.annotations.StrutsTagAttribute;
39  
40  import javax.servlet.http.HttpServletRequest;
41  import javax.servlet.http.HttpServletResponse;
42  import java.util.*;
43  import java.util.Set;
44  
45  /***
46   * <!-- START SNIPPET: javadoc -->
47   * <p/>
48   * Renders HTML an input form.<p/>
49   * <p/>
50   * The remote form allows the form to be submitted without the page being refreshed. The results from the form
51   * can be inserted into any HTML element on the page.<p/>
52   * <p/>
53   * NOTE:<p/>
54   * The order / logic in determining the posting url of the generated HTML form is as follows:-
55   * <ol>
56   * <li>
57   * If the action attribute is not specified, then the current request will be used to
58   * determine the posting url
59   * </li>
60   * <li>
61   * If the action is given, Struts will try to obtain an ActionConfig. This will be
62   * successfull if the action attribute is a valid action alias defined struts.xml.
63   * </li>
64   * <li>
65   * If the action is given and is not an action alias defined in struts.xml, Struts
66   * will used the action attribute as if it is the posting url, separting the namespace
67   * from it and using UrlHelper to generate the final url.
68   * </li>
69   * </ol>
70   * <p/>
71   * <!-- END SNIPPET: javadoc -->
72   * <p/>
73   * <p/> <b>Examples</b>
74   * <p/>
75   * <pre>
76   * <!-- START SNIPPET: example -->
77   * <p/>
78   * &lt;s:form ... /&gt;
79   * <p/>
80   * <!-- END SNIPPET: example -->
81   * </pre>
82   *
83   */
84  @StrutsTag(
85      name="form",
86      tldTagClass="org.apache.struts2.views.jsp.ui.FormTag",
87      description="Renders an input form",
88      allowDynamicAttributes=true)
89  public class Form extends ClosingUIBean {
90      public static final String OPEN_TEMPLATE = "form";
91      public static final String TEMPLATE = "form-close";
92  
93      private int sequence = 0;
94  
95      protected String onsubmit;
96      protected String action;
97      protected String target;
98      protected String enctype;
99      protected String method;
100     protected String namespace;
101     protected String validate;
102     protected String portletMode;
103     protected String windowState;
104     protected String acceptcharset;
105     protected String focusElement;
106     
107     protected Configuration configuration;
108     protected ObjectFactory objectFactory;
109     protected UrlRenderer urlRenderer;
110     protected ActionValidatorManager actionValidatorManager;
111 
112     public Form(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
113         super(stack, request, response);
114     }
115 
116     protected boolean evaluateNameValue() {
117         return false;
118     }
119 
120     public String getDefaultOpenTemplate() {
121         return OPEN_TEMPLATE;
122     }
123 
124     protected String getDefaultTemplate() {
125         return TEMPLATE;
126     }
127 
128     @Inject
129     public void setConfiguration(Configuration configuration) {
130         this.configuration = configuration;
131     }
132 
133     @Inject
134     public void setObjectFactory(ObjectFactory objectFactory) {
135         this.objectFactory = objectFactory;
136     }
137     
138     @Inject
139     public void setUrlRenderer(UrlRenderer urlRenderer) {
140     	this.urlRenderer = urlRenderer;
141     }
142     
143     @Inject
144     public void setActionValidatorManager(ActionValidatorManager mgr) {
145         this.actionValidatorManager = mgr;
146     }
147 
148 
149     /*
150     * Revised for Portlet actionURL as form action, and add wwAction as hidden
151     * field. Refer to template.simple/form.vm
152     */
153     protected void evaluateExtraParams() {
154         super.evaluateExtraParams();
155 
156         //boolean isAjax = "ajax".equalsIgnoreCase(this.theme);
157 
158         if (validate != null) {
159             addParameter("validate", findValue(validate, Boolean.class));
160         }
161 
162         // calculate the action and namespace
163         /*String action = null;
164         if (this.action != null) {
165             // if it isn't specified, we'll make somethig up
166             action = findString(this.action);
167         }
168 
169         if (Dispatcher.getInstance().isPortletSupportActive() && PortletActionContext.isPortletRequest()) {
170             evaluateExtraParamsPortletRequest(namespace, action);
171         } else {
172             String namespace = determineNamespace(this.namespace, getStack(),
173                     request);
174             evaluateExtraParamsServletRequest(action, namespace, isAjax);
175         }*/
176 
177         if (onsubmit != null) {
178             addParameter("onsubmit", findString(onsubmit));
179         }
180 
181         if (target != null) {
182             addParameter("target", findString(target));
183         }
184 
185         if (enctype != null) {
186             addParameter("enctype", findString(enctype));
187         }
188 
189         if (method != null) {
190             addParameter("method", findString(method));
191         }
192 
193         if (acceptcharset != null) {
194             addParameter("acceptcharset", findString(acceptcharset));
195         }
196 
197         // keep a collection of the tag names for anything special the templates might want to do (such as pure client
198         // side validation)
199         if (!parameters.containsKey("tagNames")) {
200             // we have this if check so we don't do this twice (on open and close of the template)
201             addParameter("tagNames", new ArrayList());
202         }
203         
204         if (focusElement != null) {
205             addParameter("focusElement", findString(focusElement));
206         }
207     }
208 
209     /***
210      * Form component determine the its HTML element id as follows:-
211      * <ol>
212      *    <li>if an 'id' attribute is specified.</li>
213      *    <li>if an 'action' attribute is specified, it will be used as the id.</li>
214      * </ol>
215      */
216     protected void populateComponentHtmlId(Form form) {
217         if (id != null) {
218             addParameter("id", escape(id));
219         }
220 
221         // if no id given, it will be tried to generate it from the action attribute
222         // by the urlRenderer implementation
223         urlRenderer.renderFormUrl(this);
224     }
225 
226     /***
227      * Evaluate client side JavaScript Enablement.
228      * @param actionName the actioName to check for
229      * @param namespace the namespace to check for
230      * @param actionMethod the method to ckeck for
231      */
232     protected void evaluateClientSideJsEnablement(String actionName, String namespace, String actionMethod) {
233 
234         // Only evaluate if Client-Side js is to be enable when validate=true
235         Boolean validate = (Boolean) getParameters().get("validate");
236         if (validate != null && validate) {
237 
238             addParameter("performValidation", Boolean.FALSE);
239 
240             RuntimeConfiguration runtimeConfiguration = configuration.getRuntimeConfiguration();
241             ActionConfig actionConfig = runtimeConfiguration.getActionConfig(namespace, actionName);
242 
243             if (actionConfig != null) {
244                 List<InterceptorMapping> interceptors = actionConfig.getInterceptors();
245                 for (InterceptorMapping interceptorMapping : interceptors) {
246                     if (ValidationInterceptor.class.isInstance(interceptorMapping.getInterceptor())) {
247                         ValidationInterceptor validationInterceptor = (ValidationInterceptor) interceptorMapping.getInterceptor();
248 
249                         Set excludeMethods = validationInterceptor.getExcludeMethodsSet();
250                         Set includeMethods = validationInterceptor.getIncludeMethodsSet();
251 
252                         if (MethodFilterInterceptorUtil.applyMethod(excludeMethods, includeMethods, actionMethod)) {
253                             addParameter("performValidation", Boolean.TRUE);
254                         }
255                         return;
256                     }
257                 }
258             }
259         }
260     }
261 
262     public List getValidators(String name) {
263         Class actionClass = (Class) getParameters().get("actionClass");
264         if (actionClass == null) {
265             return Collections.EMPTY_LIST;
266         }
267 
268         List<Validator> all = actionValidatorManager.getValidators(actionClass, (String) getParameters().get("actionName"));
269         List<Validator> validators = new ArrayList<Validator>();
270         for (Validator validator : all) {
271             if (validator instanceof FieldValidator) {
272                 FieldValidator fieldValidator = (FieldValidator) validator;
273                 if (fieldValidator.getFieldName().equals(name)) {
274                     validators.add(fieldValidator);
275                 }
276             }
277         }
278 
279         return validators;
280     }
281 
282     /***
283      * Get a incrementing sequence unique to this <code>Form</code> component.
284      * It is used by <code>Form</code> component's child that might need a
285      * sequence to make them unique.
286      *
287      * @return int
288      */
289     protected int getSequence() {
290         return sequence++;
291     }
292 
293     @StrutsTagAttribute(description="HTML onsubmit attribute")
294     public void setOnsubmit(String onsubmit) {
295         this.onsubmit = onsubmit;
296     }
297 
298     @StrutsTagAttribute(description="Set action name to submit to, without .action suffix", defaultValue="current action")
299     public void setAction(String action) {
300         this.action = action;
301     }
302 
303     @StrutsTagAttribute(description="HTML form target attribute")
304     public void setTarget(String target) {
305         this.target = target;
306     }
307 
308     @StrutsTagAttribute(description="HTML form enctype attribute")
309     public void setEnctype(String enctype) {
310         this.enctype = enctype;
311     }
312 
313     @StrutsTagAttribute(description="HTML form method attribute")
314     public void setMethod(String method) {
315         this.method = method;
316     }
317 
318     @StrutsTagAttribute(description="Namespace for action to submit to", defaultValue="current namespace")
319     public void setNamespace(String namespace) {
320         this.namespace = namespace;
321     }
322 
323     @StrutsTagAttribute(description="Whether client side/remote validation should be performed. Only" +
324                 " useful with theme xhtml/ajax", type="Boolean", defaultValue="false")
325     public void setValidate(String validate) {
326         this.validate = validate;
327     }
328 
329     @StrutsTagAttribute(description="The portlet mode to display after the form submit")
330     public void setPortletMode(String portletMode) {
331         this.portletMode = portletMode;
332     }
333 
334     @StrutsTagAttribute(description="The window state to display after the form submit")
335     public void setWindowState(String windowState) {
336         this.windowState = windowState;
337     }
338 
339     @StrutsTagAttribute(description="The accepted charsets for this form. The values may be comma or blank delimited.")
340     public void setAcceptcharset(String acceptcharset) {
341         this.acceptcharset = acceptcharset;
342     }
343 
344     @StrutsTagAttribute(description="Id of element that will receive the focus when page loads.")
345     public void setFocusElement(String focusElement) {
346         this.focusElement = focusElement;
347     }
348 }