Commits

Anonymous committed a0108e9

add priority for annotations used by AnnotationWorkflowInterceptor
o suggested improvement added

Issue Number: XW-488

git-svn-id: http://svn.opensymphony.com/svn/xwork/branches/2.0@1417e221344d-f017-0410-9bd5-d282ab1896d7

  • Participants
  • Parent commits dde16e2
  • Branches 2.0, xwork_2_0_7

Comments (0)

Files changed (4)

src/java/com/opensymphony/xwork2/interceptor/annotations/After.java

  * <p/> <u>Annotation parameters:</u>
  *
  * <!-- START SNIPPET: parameters -->
- *
- * no parameters
- *
+ * <table class='confluenceTable'>
+ * <tr>
+ * <th class='confluenceTh'> Parameter </th>
+ * <th class='confluenceTh'> Required </th>
+ * <th class='confluenceTh'> Default </th>
+ * <th class='confluenceTh'> Notes </th>
+ * </tr>
+ * <tr>
+ * <td class='confluenceTd'>priority</td>
+ * <td class='confluenceTd'>no</td>
+ * <td class='confluenceTd'>10</td>
+ * <td class='confluenceTd'>Priority order of method execution</td>
+ * </tr>
+ * </table>
  * <!-- END SNIPPET: parameters -->
  *
  * <p/> <u>Example code:</u>
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.METHOD})
 public @interface After {
-
+    int priority() default 10;
 }

src/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java

 import java.lang.reflect.Method;
 import java.util.Collections;
 import java.util.List;
+import java.util.Comparator;
 
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.XWorkException;
  * @author Rainer Hermanns
  */
 public class AnnotationWorkflowInterceptor implements Interceptor, PreResultListener {
-
     /**
      * Discovers annotated methods on the action and calls them according to the workflow
      *
     public String intercept(ActionInvocation invocation) throws Exception {
         final Object action = invocation.getAction();
         invocation.addPreResultListener(this);
-        for (Method m : AnnotationUtils.findAnnotatedMethods(action.getClass(), Before.class)) {
-            // action superclass methods first then action methods
-            final String resultCode = (String) m.invoke(action, (Object[]) null);
-            if (resultCode != null) {
-                // shortcircuit execution
-                return resultCode;
+        List<Method> methods = AnnotationUtils.findAnnotatedMethods(action.getClass(), Before.class);
+        if (methods != null && methods.size() > 0) {
+            Collections.sort(methods, new Comparator<Method>() {
+                public int compare(Method method1, Method method2) {
+                    return method2.getAnnotation(Before.class).priority()
+                            - method1.getAnnotation(Before.class).priority();
+                }
+            });
+            for (Method m : methods) {
+                // action superclass methods first then action methods
+                final String resultCode = (String) m
+                        .invoke(action, (Object[]) null);
+                if (resultCode != null) {
+                    // shortcircuit execution
+                    return resultCode;
+                }
             }
         }
 
         String invocationResult = invocation.invoke();
 
         // invoke any @After methods
-        List<Method> list = AnnotationUtils.findAnnotatedMethods(action.getClass(), After.class);
-        // action methods first then action superclass methods
-        Collections.reverse(list);
-        for (Method m : list) {
-            m.invoke(action, (Object[]) null);
+        methods = AnnotationUtils.findAnnotatedMethods(action.getClass(), After.class);
+
+        if (methods != null && methods.size() > 0) {
+            // action methods first then action superclass methods
+            Collections.sort(methods, new Comparator<Method>() {
+                public int compare(Method method1, Method method2) {
+                    return method2.getAnnotation(After.class).priority()
+                            - method1.getAnnotation(After.class).priority();
+                }
+            });
+            for (Method m : methods) {
+                m.invoke(action, (Object[]) null);
+            }
         }
 
         return invocationResult;
     /**
      * Invokes any &#64;BeforeResult annotated methods
      *
-     * @see com.opensymphony.xwork2.interceptor.PreResultListener#beforeResult(com.opensymphony.xwork2.ActionInvocation, String)
+     * @see com.opensymphony.xwork2.interceptor.PreResultListener#beforeResult(com.opensymphony.xwork2.ActionInvocation,String)
      */
     public void beforeResult(ActionInvocation invocation, String resultCode) {
         Object action = invocation.getAction();
-        List<Method> methods = AnnotationUtils.findAnnotatedMethods(action.getClass(),
-                BeforeResult.class);
-        for (Method m : methods) {
-            try {
-                m.invoke(action, (Object[]) null);
-            } catch (Exception e) {
-                throw new XWorkException(e);
+        List<Method> methods = AnnotationUtils.findAnnotatedMethods(action.getClass(), BeforeResult.class);
+
+        if (methods != null && methods.size() > 0) {
+            Collections.sort(methods, new Comparator<Method>() {
+                public int compare(Method method1, Method method2) {
+                    return method2.getAnnotation(BeforeResult.class).priority()
+                            - method1.getAnnotation(BeforeResult.class).priority();
+                }
+            });
+            for (Method m : methods) {
+                try {
+                    m.invoke(action, (Object[]) null);
+                } catch (Exception e) {
+                    throw new XWorkException(e);
+                }
             }
         }
     }
-
 }

src/java/com/opensymphony/xwork2/interceptor/annotations/Before.java

  * <p/> <u>Annotation parameters:</u>
  *
  * <!-- START SNIPPET: parameters -->
- *
- * no parameters
- *
+ * <table class='confluenceTable'>
+ * <tr>
+ * <th class='confluenceTh'> Parameter </th>
+ * <th class='confluenceTh'> Required </th>
+ * <th class='confluenceTh'> Default </th>
+ * <th class='confluenceTh'> Notes </th>
+ * </tr>
+ * <tr>
+ * <td class='confluenceTd'>priority</td>
+ * <td class='confluenceTd'>no</td>
+ * <td class='confluenceTd'>10</td>
+ * <td class='confluenceTd'>Priority order of method execution</td>
+ * </tr>
+ * </table>
  * <!-- END SNIPPET: parameters -->
  *
  * <p/> <u>Example code:</u>
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.METHOD})
 public @interface Before {
-
+    int priority() default 10;
 }

src/java/com/opensymphony/xwork2/interceptor/annotations/BeforeResult.java

  * <p/> <u>Annotation parameters:</u>
  *
  * <!-- START SNIPPET: parameters -->
- *
- * no parameters
- *
+ * <table class='confluenceTable'>
+ * <tr>
+ * <th class='confluenceTh'> Parameter </th>
+ * <th class='confluenceTh'> Required </th>
+ * <th class='confluenceTh'> Default </th>
+ * <th class='confluenceTh'> Notes </th>
+ * </tr>
+ * <tr>
+ * <td class='confluenceTd'>priority</td>
+ * <td class='confluenceTd'>no</td>
+ * <td class='confluenceTd'>10</td>
+ * <td class='confluenceTd'>Priority order of method execution</td>
+ * </tr>
+ * </table>
  * <!-- END SNIPPET: parameters -->
  *
  * <p/> <u>Example code:</u>
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.METHOD})
 public @interface BeforeResult {
-
+    int priority() default 10;
 }