diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/validator/AnnotationActionValidatorManager.java b/xwork-core/src/main/java/com/opensymphony/xwork2/validator/AnnotationActionValidatorManager.java index c83f85a5d..fc72cf952 100644 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/validator/AnnotationActionValidatorManager.java +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/validator/AnnotationActionValidatorManager.java @@ -75,7 +75,7 @@ public class AnnotationActionValidatorManager implements ActionValidatorManager } public List getValidators(Class clazz, String context, String method) { - final String validatorKey = buildValidatorKey(clazz); + final String validatorKey = buildValidatorKey(clazz, context); final List cfgs; if (validatorCache.containsKey(validatorKey)) { @@ -216,23 +216,36 @@ public class AnnotationActionValidatorManager implements ActionValidatorManager * @param clazz the action. * @return a validator key which is the class name plus context. */ - protected static String buildValidatorKey(Class clazz) { + protected static String buildValidatorKey(Class clazz, String context) { ActionInvocation invocation = ActionContext.getContext().getActionInvocation(); ActionProxy proxy = invocation.getProxy(); ActionConfig config = proxy.getConfig(); - //the key needs to use the name of the action from the config file, - //instead of the url, so wild card actions will have the same validator - //see WW-2996 StringBuilder sb = new StringBuilder(clazz.getName()); sb.append("/"); if (StringUtils.isNotBlank(config.getPackageName())) { sb.append(config.getPackageName()); sb.append("/"); } - sb.append(config.getName()); - sb.append("|"); - sb.append(proxy.getMethod()); + + // the key needs to use the name of the action from the config file, + // instead of the url, so wild card actions will have the same validator + // see WW-2996 + + // UPDATE: + // WW-3753 Using the config name instead of the context only for + // wild card actions to keep the flexibility provided + // by the original design (such as mapping different contexts + // to the same action and method if desired) + String configName = config.getName(); + if (configName.contains(ActionConfig.WILDCARD)) { + sb.append(configName); + sb.append("|"); + sb.append(proxy.getMethod()); + } else { + sb.append(context); + } + return sb.toString(); } diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/validator/ValidationInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/validator/ValidationInterceptor.java index b5c8973bc..34024875b 100644 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/validator/ValidationInterceptor.java +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/validator/ValidationInterceptor.java @@ -19,7 +19,6 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.Validateable; import com.opensymphony.xwork2.inject.Inject; -import com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; import com.opensymphony.xwork2.interceptor.PrefixMethodInvocationUtil; import com.opensymphony.xwork2.util.logging.Logger; @@ -206,7 +205,8 @@ public class ValidationInterceptor extends MethodFilterInterceptor { //the action name has to be from the url, otherwise validators that use aliases, like //MyActio-someaction-validator.xml will not be found, see WW-3194 - String context = proxy.getActionName(); + //UPDATE: see WW-3753 + String context = this.getValidationContext(proxy); String method = proxy.getMethod(); if (log.isDebugEnabled()) { @@ -264,5 +264,26 @@ public class ValidationInterceptor extends MethodFilterInterceptor { return invocation.invoke(); } + + /** + * Returns the context that will be used by the + * {@link ActionValidatorManager} to associate the action invocation with + * the appropriate {@link ValidatorConfig ValidatorConfigs}. + *

+ * The context returned is used in the pattern + * ActionClass-context-validation.xml + *

+ * The default context is the action name from the URL, but the method can + * be overridden to implement custom contexts. + *

+ * This can be useful in cases in which a single action and a single model + * require vastly different validation based on some condition. + * + * @return the Context + */ + protected String getValidationContext(ActionProxy proxy) { + // This method created for WW-3753 + return proxy.getActionName(); + } } diff --git a/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationActionValidatorManagerTest.java b/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationActionValidatorManagerTest.java index af9903749..52c3de4ba 100644 --- a/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationActionValidatorManagerTest.java +++ b/xwork-core/src/test/java/com/opensymphony/xwork2/validator/AnnotationActionValidatorManagerTest.java @@ -70,8 +70,8 @@ public class AnnotationActionValidatorManagerTest extends XWorkTestCase { } public void testBuildValidatorKey() { - String validatorKey = AnnotationActionValidatorManager.buildValidatorKey(SimpleAnnotationAction.class); - assertEquals(SimpleAnnotationAction.class.getName() + "/packageName/name|execute", validatorKey); + String validatorKey = AnnotationActionValidatorManager.buildValidatorKey(SimpleAnnotationAction.class, "name"); + assertEquals(SimpleAnnotationAction.class.getName() + "/packageName/name", validatorKey); } public void testBuildsValidatorsForAlias() {