1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 import org.apache.commons.lang.xwork.StringUtils;
40
41 import javax.servlet.http.HttpServletRequest;
42 import javax.servlet.http.HttpServletResponse;
43 import java.util.*;
44 import java.util.Set;
45
46 /***
47 * <!-- START SNIPPET: javadoc -->
48 * <p/>
49 * Renders HTML an input form.<p/>
50 * <p/>
51 * The remote form allows the form to be submitted without the page being refreshed. The results from the form
52 * can be inserted into any HTML element on the page.<p/>
53 * <p/>
54 * NOTE:<p/>
55 * The order / logic in determining the posting url of the generated HTML form is as follows:-
56 * <ol>
57 * <li>
58 * If the action attribute is not specified, then the current request will be used to
59 * determine the posting url
60 * </li>
61 * <li>
62 * If the action is given, Struts will try to obtain an ActionConfig. This will be
63 * successfull if the action attribute is a valid action alias defined struts.xml.
64 * </li>
65 * <li>
66 * If the action is given and is not an action alias defined in struts.xml, Struts
67 * will used the action attribute as if it is the posting url, separting the namespace
68 * from it and using UrlHelper to generate the final url.
69 * </li>
70 * </ol>
71 * <p/>
72 * <!-- END SNIPPET: javadoc -->
73 * <p/>
74 * <p/> <b>Examples</b>
75 * <p/>
76 * <pre>
77 * <!-- START SNIPPET: example -->
78 * <p/>
79 * <s:form ... />
80 * <p/>
81 * <!-- END SNIPPET: example -->
82 * </pre>
83 *
84 */
85 @StrutsTag(
86 name="form",
87 tldTagClass="org.apache.struts2.views.jsp.ui.FormTag",
88 description="Renders an input form",
89 allowDynamicAttributes=true)
90 public class Form extends ClosingUIBean {
91 public static final String OPEN_TEMPLATE = "form";
92 public static final String TEMPLATE = "form-close";
93
94 private int sequence = 0;
95
96 protected String onsubmit;
97 protected String onreset;
98 protected String action;
99 protected String target;
100 protected String enctype;
101 protected String method;
102 protected String namespace;
103 protected String validate;
104 protected String portletMode;
105 protected String windowState;
106 protected String acceptcharset;
107 protected String focusElement;
108
109 protected Configuration configuration;
110 protected ObjectFactory objectFactory;
111 protected UrlRenderer urlRenderer;
112 protected ActionValidatorManager actionValidatorManager;
113
114 public Form(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
115 super(stack, request, response);
116 }
117
118 protected boolean evaluateNameValue() {
119 return false;
120 }
121
122 public String getDefaultOpenTemplate() {
123 return OPEN_TEMPLATE;
124 }
125
126 protected String getDefaultTemplate() {
127 return TEMPLATE;
128 }
129
130 @Inject
131 public void setConfiguration(Configuration configuration) {
132 this.configuration = configuration;
133 }
134
135 @Inject
136 public void setObjectFactory(ObjectFactory objectFactory) {
137 this.objectFactory = objectFactory;
138 }
139
140 @Inject
141 public void setUrlRenderer(UrlRenderer urlRenderer) {
142 this.urlRenderer = urlRenderer;
143 }
144
145 @Inject
146 public void setActionValidatorManager(ActionValidatorManager mgr) {
147 this.actionValidatorManager = mgr;
148 }
149
150
151
152
153
154
155 protected void evaluateExtraParams() {
156 super.evaluateExtraParams();
157 if (validate != null) {
158 addParameter("validate", findValue(validate, Boolean.class));
159 }
160
161 if (name == null) {
162
163 String id = (String) getParameters().get("id");
164 if (StringUtils.isNotEmpty(id)) {
165 addParameter("name", id);
166 }
167 }
168
169 if (onsubmit != null) {
170 addParameter("onsubmit", findString(onsubmit));
171 }
172
173 if (onreset != null) {
174 addParameter("onreset", findString(onreset));
175 }
176
177 if (target != null) {
178 addParameter("target", findString(target));
179 }
180
181 if (enctype != null) {
182 addParameter("enctype", findString(enctype));
183 }
184
185 if (method != null) {
186 addParameter("method", findString(method));
187 }
188
189 if (acceptcharset != null) {
190 addParameter("acceptcharset", findString(acceptcharset));
191 }
192
193
194
195 if (!parameters.containsKey("tagNames")) {
196
197 addParameter("tagNames", new ArrayList());
198 }
199
200 if (focusElement != null) {
201 addParameter("focusElement", findString(focusElement));
202 }
203 }
204
205 /***
206 * Form component determine the its HTML element id as follows:-
207 * <ol>
208 * <li>if an 'id' attribute is specified.</li>
209 * <li>if an 'action' attribute is specified, it will be used as the id.</li>
210 * </ol>
211 */
212 protected void populateComponentHtmlId(Form form) {
213 if (id != null) {
214 addParameter("id", escape(id));
215 }
216
217
218
219 urlRenderer.renderFormUrl(this);
220 }
221
222 /***
223 * Evaluate client side JavaScript Enablement.
224 * @param actionName the actioName to check for
225 * @param namespace the namespace to check for
226 * @param actionMethod the method to ckeck for
227 */
228 protected void evaluateClientSideJsEnablement(String actionName, String namespace, String actionMethod) {
229
230
231 Boolean validate = (Boolean) getParameters().get("validate");
232 if (validate != null && validate) {
233
234 addParameter("performValidation", Boolean.FALSE);
235
236 RuntimeConfiguration runtimeConfiguration = configuration.getRuntimeConfiguration();
237 ActionConfig actionConfig = runtimeConfiguration.getActionConfig(namespace, actionName);
238
239 if (actionConfig != null) {
240 List<InterceptorMapping> interceptors = actionConfig.getInterceptors();
241 for (InterceptorMapping interceptorMapping : interceptors) {
242 if (ValidationInterceptor.class.isInstance(interceptorMapping.getInterceptor())) {
243 ValidationInterceptor validationInterceptor = (ValidationInterceptor) interceptorMapping.getInterceptor();
244
245 Set excludeMethods = validationInterceptor.getExcludeMethodsSet();
246 Set includeMethods = validationInterceptor.getIncludeMethodsSet();
247
248 if (MethodFilterInterceptorUtil.applyMethod(excludeMethods, includeMethods, actionMethod)) {
249 addParameter("performValidation", Boolean.TRUE);
250 }
251 return;
252 }
253 }
254 }
255 }
256 }
257
258 public List getValidators(String name) {
259 Class actionClass = (Class) getParameters().get("actionClass");
260 if (actionClass == null) {
261 return Collections.EMPTY_LIST;
262 }
263
264 List<Validator> all = actionValidatorManager.getValidators(actionClass, (String) getParameters().get("actionName"));
265 List<Validator> validators = new ArrayList<Validator>();
266 for (Validator validator : all) {
267 if (validator instanceof FieldValidator) {
268 FieldValidator fieldValidator = (FieldValidator) validator;
269 if (fieldValidator.getFieldName().equals(name)) {
270 validators.add(fieldValidator);
271 }
272 }
273 }
274
275 return validators;
276 }
277
278 /***
279 * Get a incrementing sequence unique to this <code>Form</code> component.
280 * It is used by <code>Form</code> component's child that might need a
281 * sequence to make them unique.
282 *
283 * @return int
284 */
285 protected int getSequence() {
286 return sequence++;
287 }
288
289 @StrutsTagAttribute(description="HTML onsubmit attribute")
290 public void setOnsubmit(String onsubmit) {
291 this.onsubmit = onsubmit;
292 }
293
294 @StrutsTagAttribute(description="HTML onreset attribute")
295 public void setOnreset(String onreset) {
296 this.onreset = onreset;
297 }
298
299 @StrutsTagAttribute(description="Set action name to submit to, without .action suffix", defaultValue="current action")
300 public void setAction(String action) {
301 this.action = action;
302 }
303
304 @StrutsTagAttribute(description="HTML form target attribute")
305 public void setTarget(String target) {
306 this.target = target;
307 }
308
309 @StrutsTagAttribute(description="HTML form enctype attribute")
310 public void setEnctype(String enctype) {
311 this.enctype = enctype;
312 }
313
314 @StrutsTagAttribute(description="HTML form method attribute")
315 public void setMethod(String method) {
316 this.method = method;
317 }
318
319 @StrutsTagAttribute(description="Namespace for action to submit to", defaultValue="current namespace")
320 public void setNamespace(String namespace) {
321 this.namespace = namespace;
322 }
323
324 @StrutsTagAttribute(description="Whether client side/remote validation should be performed. Only" +
325 " useful with theme xhtml/ajax", type="Boolean", defaultValue="false")
326 public void setValidate(String validate) {
327 this.validate = validate;
328 }
329
330 @StrutsTagAttribute(description="The portlet mode to display after the form submit")
331 public void setPortletMode(String portletMode) {
332 this.portletMode = portletMode;
333 }
334
335 @StrutsTagAttribute(description="The window state to display after the form submit")
336 public void setWindowState(String windowState) {
337 this.windowState = windowState;
338 }
339
340 @StrutsTagAttribute(description="The accepted charsets for this form. The values may be comma or blank delimited.")
341 public void setAcceptcharset(String acceptcharset) {
342 this.acceptcharset = acceptcharset;
343 }
344
345 @StrutsTagAttribute(description="Id of element that will receive the focus when page loads.")
346 public void setFocusElement(String focusElement) {
347 this.focusElement = focusElement;
348 }
349 }