Commits

Anonymous committed 7c9d9d6

Issue number: XW-465
Submitted by: Ruben Inoto

Fixed invocation of Proxied action class and created JUnit test

git-svn-id: http://svn.opensymphony.com/svn/xwork/branches/xwork_1-2@1327e221344d-f017-0410-9bd5-d282ab1896d7

  • Participants
  • Parent commits ae531f8
  • Branches xwork_1-2

Comments (0)

Files changed (5)

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

                 }
             }
 
-            if (action instanceof Proxy) {
-                try {
-                    return (String) Proxy.getInvocationHandler(action).invoke(action, method, new Object[0]);
-                } catch (Throwable throwable) {
-                    throwable.printStackTrace();
-                    throw new Exception("Error invoking on proxy: " + throwable.getMessage());
-                }
-            } else {
-                return (String) method.invoke(action, new Object[0]);
-            }
+            return (String) method.invoke(action, new Object[0]);
         } catch (NoSuchMethodException e) {
             throw new IllegalArgumentException("Neither " + methodName + "() nor it's doXxx() equivalent is defined in action " + getAction().getClass() + "");
         } catch (InvocationTargetException e) {

src/test/com/opensymphony/xwork/ProxyInvocationAction.java

+package com.opensymphony.xwork;
+
+public class ProxyInvocationAction extends ActionSupport implements ProxyInvocationInterface {
+    public String show() {
+        return "proxyResult";
+    }
+}

src/test/com/opensymphony/xwork/ProxyInvocationInterface.java

+package com.opensymphony.xwork;
+
+public interface ProxyInvocationInterface {
+    public String show();
+}

src/test/com/opensymphony/xwork/ProxyInvocationTest.java

+package com.opensymphony.xwork;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import com.opensymphony.xwork.config.entities.ActionConfig;
+
+/**
+ * Contribed by: Ruben Inoto
+ */
+public class ProxyInvocationTest extends TestCase {
+
+    /**
+     * Sets a ProxyObjectFactory as ObjectFactory (so the FooAction will always be retrieved
+     * as a FooProxy), and it tries to call invokeAction on the TestActionInvocation.
+     * 
+     * It should fail, because the Method got from the action (actually a FooProxy) 
+     * will be executed on the InvocationHandler of the action (so, in the action itself). 
+     */
+    public void testProxyInvocation() throws Exception {
+
+        ObjectFactory.setObjectFactory(new ProxyObjectFactory());
+
+        ActionProxy proxy = ActionProxyFactory.getFactory()
+            .createActionProxy("", "ProxyInvocation", createDummyContext());
+        TestActionInvocation invocation = new TestActionInvocation(proxy);
+
+        String result = invocation.invokeAction(proxy.getAction(), proxy
+            .getConfig());
+        assertEquals("proxyResult", result);
+
+    }
+
+    /** 
+     * Needed for the creation of the action proxy
+     */
+    private Map createDummyContext() {
+        Map params = new HashMap();
+        params.put("blah", "this is blah");
+        Map extraContext = new HashMap();
+        extraContext.put(ActionContext.PARAMETERS, params);
+        return extraContext;
+    }
+
+    /**
+     * Simple proxy that just invokes the method on the target on the invoke method
+     */
+    public class ProxyInvocationProxy implements InvocationHandler {
+
+        private Object target;
+
+        public ProxyInvocationProxy(Object target) {
+            this.target = target;
+        }
+
+        public Object invoke(Object proxy, Method m, Object[] args)
+            throws Throwable {
+            return m.invoke(target, args);
+        }
+    }
+
+    /**
+     * Subclass of DefaultActionInvocation, to provide a visible constructor
+     */
+    private class TestActionInvocation extends DefaultActionInvocation {
+        protected TestActionInvocation(ActionProxy proxy) throws Exception {
+            super(proxy);
+        }
+
+        public String invokeAction(Object action, ActionConfig actionConfig)
+            throws Exception {
+            return super.invokeAction(action, actionConfig);
+        }
+    }
+
+    /**
+     * ObjectFactory that returns a FooProxy in the buildBean if the clazz is FooAction 
+     */
+    private class ProxyObjectFactory extends ObjectFactory {
+
+        /**
+         * It returns an instance of the bean except if the class is FooAction. 
+         * In this case, it returns a FooProxy of it.
+         */
+        public Object buildBean(Class clazz, Map extraContext)
+            throws Exception {
+            Object bean = super.buildBean(clazz, extraContext);
+            if(clazz.equals(ProxyInvocationAction.class)) {
+                return Proxy.newProxyInstance(bean.getClass()
+                    .getClassLoader(), bean.getClass().getInterfaces(),
+                    new ProxyInvocationProxy(bean));
+
+            }
+            return bean;
+        }
+    }
+}

src/test/xwork.xml

             <interceptor-ref name="defaultStack"/>
         </action>
 
+        <action name="ProxyInvocation" method="show" class="com.opensymphony.xwork.ProxyInvocationAction"/>
+
         <action name="WildCard" class="com.opensymphony.xwork.SimpleAction">
             <param name="foo">17</param>
             <param name="bar">23</param>