Commits

Anonymous committed df96ccd

XW-120: Added PreResultListener to be able to get call backs after the Action is executed but before the Result is executed.

git-svn-id: http://svn.opensymphony.com/svn/xwork/trunk@104e221344d-f017-0410-9bd5-d282ab1896d7

  • Participants
  • Parent commits eee3422

Comments (0)

Files changed (4)

File src/java/com/opensymphony/xwork/ActionInvocation.java

     OgnlValueStack getStack();
 
     /**
+     * Register a com.opensymphony.xwork.PreResultListener to be notified after the Action is executed and before the
+     * Result is executed. The ActionInvocation implementation must guarantee that listeners will be called in the order
+     * in which they are registered. Listener registration and execution does not need to be thread-safe.
+     * @param listener
+     */
+    void addPreResultListener(PreResultListener listener);
+
+    /**
      * Invokes the next step in processing this ActionInvocation. If there are more
      * Interceptors, this will call the next one. If Interceptors choose not to short-circuit
      * ActionInvocation processing and return their own return code, they will call

File src/java/com/opensymphony/xwork/DefaultActionInvocation.java

 
     protected Action action;
     protected ActionProxy proxy;
+    protected List preResultListeners;
     protected Map extraContext;
     ActionContext invocationContext;
     Iterator interceptors;
         return stack;
     }
 
+    /**
+     * Register a com.opensymphony.xwork.PreResultListener to be notified after the Action is executed and before the
+     * Result is executed. The ActionInvocation implementation must guarantee that listeners will be called in the order
+     * in which they are registered. Listener registration and execution does not need to be thread-safe.
+     * @param listener
+     */
+    public void addPreResultListener(PreResultListener listener) {
+        if (preResultListeners == null) {
+            preResultListeners = new ArrayList(1);
+        }
+
+        preResultListeners.add(listener);
+    }
+
     public String invoke() throws Exception {
         if (executed) {
             throw new IllegalStateException("Action has already executed");
             }
         }
 
+        if (preResultListeners != null) {
+            for (Iterator iterator = preResultListeners.iterator();
+                    iterator.hasNext();) {
+                PreResultListener listener = (PreResultListener) iterator.next();
+                listener.beforeResult(this, resultCode);
+            }
+        }
+
         if (!executed) {
             // now execute the result, if we're supposed to
             if (proxy.getExecuteResult()) {

File src/java/com/opensymphony/xwork/PreResultListener.java

+/*
+ * Copyright (c) 2002-2003 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.xwork;
+
+
+/**
+ * PreResultListeners may be registered with an ActionInvocation to get a callback after the Action has been executed
+ * but before the Result is executed.
+ * @author Jason Carreira
+ * Date: Nov 13, 2003 10:55:02 PM
+ */
+public interface PreResultListener {
+    //~ Methods ////////////////////////////////////////////////////////////////
+
+    void beforeResult(ActionInvocation invocation, String resultCode);
+}

File src/test/com/opensymphony/xwork/PreResultListenerTest.java

+/*
+ * Copyright (c) 2002-2003 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.xwork;
+
+import com.mockobjects.dynamic.C;
+import com.mockobjects.dynamic.Mock;
+
+import com.opensymphony.xwork.config.Configuration;
+import com.opensymphony.xwork.config.ConfigurationException;
+import com.opensymphony.xwork.config.ConfigurationManager;
+import com.opensymphony.xwork.config.ConfigurationProvider;
+import com.opensymphony.xwork.config.entities.ActionConfig;
+import com.opensymphony.xwork.config.entities.PackageConfig;
+
+import junit.framework.TestCase;
+
+import java.util.HashMap;
+
+
+/**
+ * PreResultListenerTest
+ * @author Jason Carreira
+ * Date: Nov 13, 2003 11:16:43 PM
+ */
+public class PreResultListenerTest extends TestCase {
+    //~ Instance fields ////////////////////////////////////////////////////////
+
+    private int count = 1;
+
+    //~ Methods ////////////////////////////////////////////////////////////////
+
+    public void testPreResultListenersAreCalled() throws Exception {
+        ActionProxy proxy = new DefaultActionProxy("package", "action", new HashMap(), false);
+        ActionInvocation invocation = proxy.getInvocation();
+        Mock preResultListenerMock1 = new Mock(PreResultListener.class);
+        preResultListenerMock1.expect("beforeResult", C.args(C.eq(invocation), C.eq(Action.SUCCESS)));
+        invocation.addPreResultListener((PreResultListener) preResultListenerMock1.proxy());
+        proxy.execute();
+        preResultListenerMock1.verify();
+    }
+
+    public void testPreResultListenersAreCalledInOrder() throws Exception {
+        ActionProxy proxy = new DefaultActionProxy("package", "action", new HashMap(), false);
+        ActionInvocation invocation = proxy.getInvocation();
+        CountPreResultListener listener1 = new CountPreResultListener();
+        CountPreResultListener listener2 = new CountPreResultListener();
+        invocation.addPreResultListener(listener1);
+        invocation.addPreResultListener(listener2);
+        proxy.execute();
+        assertNotNull(listener1.getMyOrder());
+        assertNotNull(listener2.getMyOrder());
+        assertEquals(listener1.getMyOrder().intValue() + 1, listener2.getMyOrder().intValue());
+    }
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        ConfigurationManager.clearConfigurationProviders();
+        ConfigurationManager.addConfigurationProvider(new ConfigurationProvider() {
+                public void destroy() {
+                }
+
+                /**
+                 * Initializes the configuration object.
+                 */
+                public void init(Configuration configuration) throws ConfigurationException {
+                    PackageConfig packageConfig = new PackageConfig("package");
+                    ActionConfig actionConfig = new ActionConfig(null, SimpleFooAction.class, null, null, null);
+                    packageConfig.addActionConfig("action", actionConfig);
+                    configuration.addPackageConfig("package", packageConfig);
+                }
+
+                /**
+                 * Tells whether the ConfigurationProvider should reload its configuration
+                 * @return
+                 */
+                public boolean needsReload() {
+                    return false;
+                }
+            });
+        ConfigurationManager.getConfiguration().reload();
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        ConfigurationManager.destroyConfiguration();
+    }
+
+    //~ Inner Classes //////////////////////////////////////////////////////////
+
+    private class CountPreResultListener implements PreResultListener {
+        private Integer myOrder = null;
+
+        public Integer getMyOrder() {
+            return myOrder;
+        }
+
+        public void beforeResult(ActionInvocation invocation, String resultCode) {
+            myOrder = new Integer(count++);
+        }
+    }
+}