View Javadoc

1   /*
2    * $Id: Form.java 676692 2008-07-14 19:01:44Z musachy $
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 onreset;
97      protected String action;
98      protected String target;
99      protected String enctype;
100     protected String method;
101     protected String namespace;
102     protected String validate;
103     protected String portletMode;
104     protected String windowState;
105     protected String acceptcharset;
106     protected String focusElement;
107 
108     protected Configuration configuration;
109     protected ObjectFactory objectFactory;
110     protected UrlRenderer urlRenderer;
111     protected ActionValidatorManager actionValidatorManager;
112 
113     public Form(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
114         super(stack, request, response);
115     }
116 
117     protected boolean evaluateNameValue() {
118         return false;
119     }
120 
121     public String getDefaultOpenTemplate() {
122         return OPEN_TEMPLATE;
123     }
124 
125     protected String getDefaultTemplate() {
126         return TEMPLATE;
127     }
128 
129     @Inject
130     public void setConfiguration(Configuration configuration) {
131         this.configuration = configuration;
132     }
133 
134     @Inject
135     public void setObjectFactory(ObjectFactory objectFactory) {
136         this.objectFactory = objectFactory;
137     }
138 
139     @Inject
140     public void setUrlRenderer(UrlRenderer urlRenderer) {
141     	this.urlRenderer = urlRenderer;
142     }
143 
144     @Inject
145     public void setActionValidatorManager(ActionValidatorManager mgr) {
146         this.actionValidatorManager = mgr;
147     }
148 
149 
150     /*
151     * Revised for Portlet actionURL as form action, and add wwAction as hidden
152     * field. Refer to template.simple/form.vm
153     */
154     protected void evaluateExtraParams() {
155         super.evaluateExtraParams();
156 
157         //boolean isAjax = "ajax".equalsIgnoreCase(this.theme);
158 
159         if (validate != null) {
160             addParameter("validate", findValue(validate, Boolean.class));
161         }
162 
163         // calculate the action and namespace
164         /*String action = null;
165         if (this.action != null) {
166             // if it isn't specified, we'll make somethig up
167             action = findString(this.action);
168         }
169 
170         if (Dispatcher.getInstance().isPortletSupportActive() && PortletActionContext.isPortletRequest()) {
171             evaluateExtraParamsPortletRequest(namespace, action);
172         } else {
173             String namespace = determineNamespace(this.namespace, getStack(),
174                     request);
175             evaluateExtraParamsServletRequest(action, namespace, isAjax);
176         }*/
177 
178         if (onsubmit != null) {
179             addParameter("onsubmit", findString(onsubmit));
180         }
181 
182         if (onreset != null) {
183             addParameter("onreset", findString(onreset));
184         }
185 
186         if (target != null) {
187             addParameter("target", findString(target));
188         }
189 
190         if (enctype != null) {
191             addParameter("enctype", findString(enctype));
192         }
193 
194         if (method != null) {
195             addParameter("method", findString(method));
196         }
197 
198         if (acceptcharset != null) {
199             addParameter("acceptcharset", findString(acceptcharset));
200         }
201 
202         // keep a collection of the tag names for anything special the templates might want to do (such as pure client
203         // side validation)
204         if (!parameters.containsKey("tagNames")) {
205             // we have this if check so we don't do this twice (on open and close of the template)
206             addParameter("tagNames", new ArrayList());
207         }
208 
209         if (focusElement != null) {
210             addParameter("focusElement", findString(focusElement));
211         }
212     }
213 
214     /***
215      * Form component determine the its HTML element id as follows:-
216      * <ol>
217      *    <li>if an 'id' attribute is specified.</li>
218      *    <li>if an 'action' attribute is specified, it will be used as the id.</li>
219      * </ol>
220      */
221     protected void populateComponentHtmlId(Form form) {
222         if (id != null) {
223             addParameter("id", escape(id));
224         }
225 
226         // if no id given, it will be tried to generate it from the action attribute
227         // by the urlRenderer implementation
228         urlRenderer.renderFormUrl(this);
229     }
230 
231     /***
232      * Evaluate client side JavaScript Enablement.
233      * @param actionName the actioName to check for
234      * @param namespace the namespace to check for
235      * @param actionMethod the method to ckeck for
236      */
237     protected void evaluateClientSideJsEnablement(String actionName, String namespace, String actionMethod) {
238 
239         // Only evaluate if Client-Side js is to be enable when validate=true
240         Boolean validate = (Boolean) getParameters().get("validate");
241         if (validate != null && validate) {
242 
243             addParameter("performValidation", Boolean.FALSE);
244 
245             RuntimeConfiguration runtimeConfiguration = configuration.getRuntimeConfiguration();
246             ActionConfig actionConfig = runtimeConfiguration.getActionConfig(namespace, actionName);
247 
248             if (actionConfig != null) {
249                 List<InterceptorMapping> interceptors = actionConfig.getInterceptors();
250                 for (InterceptorMapping interceptorMapping : interceptors) {
251                     if (ValidationInterceptor.class.isInstance(interceptorMapping.getInterceptor())) {
252                         ValidationInterceptor validationInterceptor = (ValidationInterceptor) interceptorMapping.getInterceptor();
253 
254                         Set excludeMethods = validationInterceptor.getExcludeMethodsSet();
255                         Set includeMethods = validationInterceptor.getIncludeMethodsSet();
256 
257                         if (MethodFilterInterceptorUtil.applyMethod(excludeMethods, includeMethods, actionMethod)) {
258                             addParameter("performValidation", Boolean.TRUE);
259                         }
260                         return;
261                     }
262                 }
263             }
264         }
265     }
266 
267     public List getValidators(String name) {
268         Class actionClass = (Class) getParameters().get("actionClass");
269         if (actionClass == null) {
270             return Collections.EMPTY_LIST;
271         }
272 
273         List<Validator> all = actionValidatorManager.getValidators(actionClass, (String) getParameters().get("actionName"));
274         List<Validator> validators = new ArrayList<Validator>();
275         for (Validator validator : all) {
276             if (validator instanceof FieldValidator) {
277                 FieldValidator fieldValidator = (FieldValidator) validator;
278                 if (fieldValidator.getFieldName().equals(name)) {
279                     validators.add(fieldValidator);
280                 }
281             }
282         }
283 
284         return validators;
285     }
286 
287     /***
288      * Get a incrementing sequence unique to this <code>Form</code> component.
289      * It is used by <code>Form</code> component's child that might need a
290      * sequence to make them unique.
291      *
292      * @return int
293      */
294     protected int getSequence() {
295         return sequence++;
296     }
297 
298     @StrutsTagAttribute(description="HTML onsubmit attribute")
299     public void setOnsubmit(String onsubmit) {
300         this.onsubmit = onsubmit;
301     }
302 
303     @StrutsTagAttribute(description="HTML onreset attribute")
304     public void setOnreset(String onreset) {
305         this.onreset = onreset;
306     }
307 
308     @StrutsTagAttribute(description="Set action name to submit to, without .action suffix", defaultValue="current action")
309     public void setAction(String action) {
310         this.action = action;
311     }
312 
313     @StrutsTagAttribute(description="HTML form target attribute")
314     public void setTarget(String target) {
315         this.target = target;
316     }
317 
318     @StrutsTagAttribute(description="HTML form enctype attribute")
319     public void setEnctype(String enctype) {
320         this.enctype = enctype;
321     }
322 
323     @StrutsTagAttribute(description="HTML form method attribute")
324     public void setMethod(String method) {
325         this.method = method;
326     }
327 
328     @StrutsTagAttribute(description="Namespace for action to submit to", defaultValue="current namespace")
329     public void setNamespace(String namespace) {
330         this.namespace = namespace;
331     }
332 
333     @StrutsTagAttribute(description="Whether client side/remote validation should be performed. Only" +
334                 " useful with theme xhtml/ajax", type="Boolean", defaultValue="false")
335     public void setValidate(String validate) {
336         this.validate = validate;
337     }
338 
339     @StrutsTagAttribute(description="The portlet mode to display after the form submit")
340     public void setPortletMode(String portletMode) {
341         this.portletMode = portletMode;
342     }
343 
344     @StrutsTagAttribute(description="The window state to display after the form submit")
345     public void setWindowState(String windowState) {
346         this.windowState = windowState;
347     }
348 
349     @StrutsTagAttribute(description="The accepted charsets for this form. The values may be comma or blank delimited.")
350     public void setAcceptcharset(String acceptcharset) {
351         this.acceptcharset = acceptcharset;
352     }
353 
354     @StrutsTagAttribute(description="Id of element that will receive the focus when page loads.")
355     public void setFocusElement(String focusElement) {
356         this.focusElement = focusElement;
357     }
358 }