1 /*
2 * Copyright (c) 2002-2007 by OpenSymphony
3 * All rights reserved.
4 */
5 package com.opensymphony.xwork2.interceptor;
6
7 import com.opensymphony.xwork2.Action;
8 import com.opensymphony.xwork2.ActionInvocation;
9 import com.opensymphony.xwork2.ValidationAware;
10 import com.opensymphony.xwork2.interceptor.annotations.InputConfig;
11 import com.opensymphony.xwork2.util.logging.Logger;
12 import com.opensymphony.xwork2.util.logging.LoggerFactory;
13
14 import java.lang.reflect.Method;
15
16 /**
17 * <!-- START SNIPPET: description -->
18 * <p/>
19 * An interceptor that makes sure there are not validation errors before allowing the interceptor chain to continue.
20 * <b>This interceptor does not perform any validation</b>.
21 * <p/>
22 * <p/>This interceptor does nothing if the name of the method being invoked is specified in the <b>excludeMethods</b>
23 * parameter. <b>excludeMethods</b> accepts a comma-delimited list of method names. For example, requests to
24 * <b>foo!input.action</b> and <b>foo!back.action</b> will be skipped by this interceptor if you set the
25 * <b>excludeMethods</b> parameter to "input, back".
26 * <p/>
27 * <b>Note:</b> As this method extends off MethodFilterInterceptor, it is capable of
28 * deciding if it is applicable only to selective methods in the action class. This is done by adding param tags
29 * for the interceptor element, naming either a list of excluded method names and/or a list of included method
30 * names, whereby includeMethods overrides excludedMethods. A single * sign is interpreted as wildcard matching
31 * all methods for both parameters.
32 * See {@link MethodFilterInterceptor} for more info.
33 * <p/>
34 * <!-- END SNIPPET: description -->
35 * <p/>
36 * <p/> <u>Interceptor parameters:</u>
37 * <p/>
38 * <!-- START SNIPPET: parameters -->
39 * <p/>
40 * <ul>
41 * <p/>
42 * <li>inputResultName - Default to "input". Determine the result name to be returned when
43 * an action / field error is found.</li>
44 * <p/>
45 * </ul>
46 * <p/>
47 * <!-- END SNIPPET: parameters -->
48 * <p/>
49 * <p/> <u>Extending the interceptor:</u>
50 * <p/>
51 * <p/>
52 * <p/>
53 * <!-- START SNIPPET: extending -->
54 * <p/>
55 * There are no known extension points for this interceptor.
56 * <p/>
57 * <!-- END SNIPPET: extending -->
58 * <p/>
59 * <p/> <u>Example code:</u>
60 * <p/>
61 * <pre>
62 * <!-- START SNIPPET: example -->
63 * <p/>
64 * <action name="someAction" class="com.examples.SomeAction">
65 * <interceptor-ref name="params"/>
66 * <interceptor-ref name="validation"/>
67 * <interceptor-ref name="workflow"/>
68 * <result name="success">good_result.ftl</result>
69 * </action>
70 * <p/>
71 * <-- In this case myMethod as well as mySecondMethod of the action class
72 * will not pass through the workflow process -->
73 * <action name="someAction" class="com.examples.SomeAction">
74 * <interceptor-ref name="params"/>
75 * <interceptor-ref name="validation"/>
76 * <interceptor-ref name="workflow">
77 * <param name="excludeMethods">myMethod,mySecondMethod</param>
78 * </interceptor-ref name="workflow">
79 * <result name="success">good_result.ftl</result>
80 * </action>
81 * <p/>
82 * <-- In this case, the result named "error" will be used when
83 * an action / field error is found -->
84 * <-- The Interceptor will only be applied for myWorkflowMethod method of action
85 * classes, since this is the only included method while any others are excluded -->
86 * <action name="someAction" class="com.examples.SomeAction">
87 * <interceptor-ref name="params"/>
88 * <interceptor-ref name="validation"/>
89 * <interceptor-ref name="workflow">
90 * <param name="inputResultName">error</param>
91 * <param name="excludeMethods">*</param>
92 * <param name="includeMethods">myWorkflowMethod</param>
93 * </interceptor-ref>
94 * <result name="success">good_result.ftl</result>
95 * </action>
96 * <p/>
97 * <!-- END SNIPPET: example -->
98 * </pre>
99 *
100 * @author Jason Carreira
101 * @author Rainer Hermanns
102 * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
103 * @author Philip Luppens
104 * @author tm_jee
105 */
106 public class DefaultWorkflowInterceptor extends MethodFilterInterceptor {
107
108 private static final long serialVersionUID = 7563014655616490865L;
109
110 private static final Logger LOG = LoggerFactory.getLogger(DefaultWorkflowInterceptor.class);
111
112 private String inputResultName = Action.INPUT;
113
114 /**
115 * Set the <code>inputResultName</code> (result name to be returned when
116 * a action / field error is found registered). Default to {@link Action#INPUT}
117 *
118 * @param inputResultName what result name to use when there was validation error(s).
119 */
120 public void setInputResultName(String inputResultName) {
121 this.inputResultName = inputResultName;
122 }
123
124 /**
125 * Intercept {@link ActionInvocation} and returns a <code>inputResultName</code>
126 * when action / field errors is found registered.
127 *
128 * @return String result name
129 */
130 @Override
131 protected String doIntercept(ActionInvocation invocation) throws Exception {
132 Object action = invocation.getAction();
133
134 if (action instanceof ValidationAware) {
135 ValidationAware validationAwareAction = (ValidationAware) action;
136
137 if (validationAwareAction.hasErrors()) {
138 if (LOG.isDebugEnabled()) {
139 LOG.debug("Errors on action " + validationAwareAction + ", returning result name 'input'");
140 }
141
142 String resultName = inputResultName;
143
144 if (action instanceof ValidationWorkflowAware) {
145 resultName = ((ValidationWorkflowAware) action).getInputResultName();
146 }
147
148 InputConfig annotation = action.getClass().getMethod(invocation.getProxy().getMethod(), new Class[0]).getAnnotation(InputConfig.class);
149 if (annotation != null) {
150 if (!annotation.methodName().equals("")) {
151 Method method = action.getClass().getMethod(annotation.methodName());
152 resultName = (String) method.invoke(action);
153 } else {
154 resultName = annotation.resultName();
155 }
156 }
157
158
159 return resultName;
160 }
161 }
162
163 return invocation.invoke();
164 }
165
166 }