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 }