1 /*
2 * $Id: AnnotationValidationInterceptor.java 663335 2008-06-04 18:15:36Z 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.interceptor.validation;
23
24 import java.lang.reflect.Method;
25 import java.util.Arrays;
26 import java.util.Collection;
27
28 import org.apache.commons.lang.ArrayUtils;
29
30 import com.opensymphony.xwork2.ActionInvocation;
31 import com.opensymphony.xwork2.util.AnnotationUtils;
32 import com.opensymphony.xwork2.validator.ValidationInterceptor;
33
34 /**
35 * Extends the xwork validation interceptor to also check for a @SkipValidation
36 * annotation, and if found, don't validate this action method
37 */
38 public class AnnotationValidationInterceptor extends ValidationInterceptor {
39
40 /** Auto-generated serialization id */
41 private static final long serialVersionUID = 1813272797367431184L;
42
43 protected String doIntercept(ActionInvocation invocation) throws Exception {
44
45 Object action = invocation.getAction();
46 if (action != null) {
47 Method method = getActionMethod(action.getClass(), invocation.getProxy().getMethod());
48 Collection<Method> annotatedMethods = AnnotationUtils.getAnnotatedMethods(action.getClass(), SkipValidation.class);
49 if (annotatedMethods.contains(method))
50 return invocation.invoke();
51
52 //check if method overwites an annotated method
53 Class clazz = action.getClass().getSuperclass();
54 while (clazz != null) {
55 annotatedMethods = AnnotationUtils.getAnnotatedMethods(clazz, SkipValidation.class);
56 if (annotatedMethods != null) {
57 for (Method annotatedMethod : annotatedMethods) {
58 if (annotatedMethod.getName().equals(method.getName())
59 && Arrays.equals(annotatedMethod.getParameterTypes(), method.getParameterTypes())
60 && Arrays.equals(annotatedMethod.getExceptionTypes(), method.getExceptionTypes()))
61 return invocation.invoke();
62 }
63 }
64 clazz = clazz.getSuperclass();
65 }
66 }
67
68 return super.doIntercept(invocation);
69 }
70
71 // FIXME: This is copied from DefaultActionInvocation but should be exposed through the interface
72 protected Method getActionMethod(Class actionClass, String methodName) throws NoSuchMethodException {
73 Method method;
74 try {
75 method = actionClass.getMethod(methodName, new Class[0]);
76 } catch (NoSuchMethodException e) {
77 // hmm -- OK, try doXxx instead
78 try {
79 String altMethodName = "do" + methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
80 method = actionClass.getMethod(altMethodName, new Class[0]);
81 } catch (NoSuchMethodException e1) {
82 // throw the original one
83 throw e;
84 }
85 }
86 return method;
87 }
88 }