Commits

Anonymous committed 8b5db6d

This commit was manufactured by cvs2svn to create branch 'xwork_1-2'.

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

Comments (0)

Files changed (3)

src/java/com/opensymphony/xwork/interceptor/PrefixMethodInvocationUtil.java

+/*
+ * Copyright (c) 2002-2006 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.xwork.interceptor;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.opensymphony.xwork.ActionInvocation;
+
+/**
+ * A utility class for invoking prefixed methods in action class.
+ * 
+ * Interceptors that made use of this class are 
+ * <ul>
+ * 	 <li>DefaultWorkflowInterceptor </li>
+ *   <li>PrepareInterceptor </li>
+ * </ul>
+ * 
+ * <p/>
+ * 
+ * <!-- START SNIPPET: javadocDefaultWorkflowInterceptor -->
+ * 
+ * <b>In DefaultWorkflowInterceptor</b>
+ * <p>applies only when action implements {@link com.opensymphony.xwork.Validateable}</p>
+ * <ol>
+ *    <li>if the action class have validate{MethodName}(), it will be invoked</li>
+ *    <li>else if the action class have validateDo{MethodName}(), it will be invoked</li>
+ *    <li>no matter if 1] or 2] is performed, if alwaysInvokeValidate property of the interceptor is "true" (which is by default "true"), validate() will be invoked.</li>
+ * </ol>
+ * 
+ * <!-- END SNIPPET: javadocDefaultWorkflowInterceptor -->
+ * 
+ * 
+ * <!-- START SNIPPET: javadocPrepareInterceptor -->
+ * 
+ * <b>In PrepareInterceptor</b>
+ * <p>Applies only when action implements Preparable</p>
+ * <ol>
+ *    <li>if the action class have prepare{MethodName}(), it will be invoked</li>
+ *    <li>else if the action class have prepareDo(MethodName()}(), it will be invoked</li>
+ *    <li>no matter if 1] or 2] is performed, if alwaysinvokePrepare property of the interceptor is "true" (which is by default "true"), prepare() will be invoked.</li>
+ * </ol>
+ * 
+ * <!-- END SNIPPET: javadocPrepareInterceptor -->
+ * 
+ * @author Philip Luppens
+ * @author tm_jee
+ * @version $Date$ $Id$
+ */
+public class PrefixMethodInvocationUtil {
+	
+	private static final Log _log = LogFactory.getLog(PrefixMethodInvocationUtil.class);
+
+	/**
+	 * This method will prefix <code>actionInvocation</code>'s <code>ActionProxy</code>'s
+	 * <code>method</code> with <code>prefixes</code> before invoking the prefixed method.
+	 * Order of the <code>prefixes</code> is important, as this method will return once 
+	 * a prefixed method is found in the action class.
+	 * 
+	 * <p/>
+	 * 
+	 * For example, with
+	 * <pre>
+	 *   invokePrefixMethod(actionInvocation, new String[] { "prepare", "prepareDo" });
+	 * </pre>
+	 * 
+	 * Assuming <code>actionInvocation.getProxy(),getMethod()</code> returns "submit", 
+	 * the order of invocation would be as follows:-
+	 * <ol>
+	 *   <li>prepareSubmit()</li>
+	 *   <li>prepareDoSubmit()</li>
+	 * </ol>
+	 * 
+	 * If <code>prepareSubmit()</code> exists, it will be invoked and this method 
+	 * will return, <code>prepareDoSubmit()</code> will NOT be invoked. 
+	 * 
+	 * <p/>
+	 * 
+	 * On the other hand, if <code>prepareDoSubmit()</code> does not exists, and 
+	 * <code>prepareDoSubmit()</code> exists, it will be invoked.
+	 * 
+	 * <p/>
+	 * 
+	 * If none of those two methods exists, nothing will be invoked.
+	 * 
+	 * @param actionInvocation
+	 * @param prefixes
+	 * @throws InvocationTargetException
+	 * @throws IllegalAccessException
+	 */
+	public static void invokePrefixMethod(ActionInvocation actionInvocation, String[] prefixes) throws InvocationTargetException, IllegalAccessException {
+		Object action = actionInvocation.getAction();
+		
+		String methodName = actionInvocation.getProxy().getMethod();
+		
+		if (methodName == null) {
+			 // TODO: clean me up
+			 /* if null returns (possible according to the docs), 
+			 * use the default execute - this should be a static somewhere ?
+			 */
+			methodName = "execute";
+		}
+		
+		Method method = getPrefixedMethod(prefixes, methodName, action);
+		if (method != null) {
+			method.invoke(action, new Object[0]);
+		}
+	}
+	
+	
+	/**
+	 * This method returns a {@link Method} in <code>action</code>. The method 
+	 * returned is found by searching for method in <code>action</code> whose method name
+	 * is equals to the result of appending each <code>prefixes</code>
+	 * to <code>methodName</code>. Only the first method found will be returned, hence
+	 * the order of <code>prefixes</code> is important. If none is found this method
+	 * will return null.
+	 * 
+	 * @param prefixes the prefixes to prefix the <code>methodName</code>
+	 * @param methodName the method name to be prefixed with <code>prefixes</code>
+	 * @param action the action class of which the prefixed method is to be search for.
+	 * @return a {@link Method} if one is found, else null.
+	 */
+	public static Method getPrefixedMethod(String[] prefixes, String methodName, Object action) {
+		assert(prefixes != null);
+		String capitalizedMethodName = capitalizeMethodName(methodName);
+		for (int a=0; a< prefixes.length; a++) {
+			String prefixedMethodName = prefixes[a]+capitalizedMethodName;
+			try {
+				Method method = action.getClass().getMethod(prefixedMethodName, new Class[0]);
+				return method;
+			}
+			catch(NoSuchMethodException e) {
+				// hmm -- OK, try next prefix
+				if (_log.isDebugEnabled()) {
+					_log.debug("cannot find method ["+prefixedMethodName+"] in action ["+action+"]");
+				}
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * This method capitalized the first character of <code>methodName</code>.
+	 * <p/>
+	 * 
+	 * eg.
+	 * <pre>
+	 *   capitalizeMethodName("someMethod");
+	 * </pre>
+	 * 
+	 * will return "SomeMethod".
+	 * 
+	 * @param methodName
+	 * @return
+	 */
+	public static String capitalizeMethodName(String methodName) {
+		assert(methodName != null);
+		return methodName = methodName.substring(0, 1).toUpperCase()
+							+ methodName.substring(1);
+	}
+}

src/test/com/opensymphony/xwork/interceptor/DefaultWorkflowInterceptorPrefixMethodInvocationTest.java

+/*
+ * Copyright (c) 2002-2006 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.xwork.interceptor;
+
+import org.easymock.MockControl;
+
+import com.opensymphony.xwork.Action;
+import com.opensymphony.xwork.ActionInvocation;
+import com.opensymphony.xwork.ActionProxy;
+import com.opensymphony.xwork.Validateable;
+import com.opensymphony.xwork.ValidationAware;
+
+import junit.framework.TestCase;
+
+/**
+ * Test DefaultWorkflowInterceptor's prefix method invocation capabilities.
+ * 
+ * @author tm_jee
+ * @version $Date$ $Id$
+ */
+public class DefaultWorkflowInterceptorPrefixMethodInvocationTest extends TestCase {
+
+	public void testPrefixMethodInvocation1() throws Exception {
+		
+		MockControl controlAction = MockControl.createControl(ValidateAction.class);
+		ValidateAction mockAction = (ValidateAction) controlAction.getMock();
+		mockAction.hasErrors();
+		controlAction.setReturnValue(true);
+		mockAction.validateDoSave();
+		controlAction.setVoidCallable(1);
+		mockAction.validate();
+		controlAction.setVoidCallable();
+		
+		MockControl controlActionProxy = MockControl.createControl(ActionProxy.class);
+		ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock();
+		mockActionProxy.getMethod();
+		controlActionProxy.setDefaultReturnValue("save");
+		
+		MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class);
+		ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock();
+		mockActionInvocation.getAction();
+		controlActionInvocation.setDefaultReturnValue(mockAction);
+		mockActionInvocation.getProxy();
+		controlActionInvocation.setDefaultReturnValue(mockActionProxy);
+		
+		
+		controlAction.replay();
+		controlActionProxy.replay();
+		controlActionInvocation.replay();
+		
+		DefaultWorkflowInterceptor interceptor = new DefaultWorkflowInterceptor();
+		String result = interceptor.intercept(mockActionInvocation);
+		
+		assertEquals(Action.INPUT, result);
+		controlAction.verify();
+		controlActionProxy.verify();
+		controlActionInvocation.verify();
+	}
+	
+	public void testPrefixMethodInvocation2() throws Exception {
+		MockControl controlAction = MockControl.createControl(ValidateAction.class);
+		ValidateAction mockAction = (ValidateAction) controlAction.getMock();
+		mockAction.hasErrors();
+		controlAction.setReturnValue(false);
+		mockAction.validateSubmit();
+		controlAction.setVoidCallable(1);
+		mockAction.validate();
+		controlAction.setVoidCallable();
+		
+		MockControl controlActionProxy = MockControl.createControl(ActionProxy.class);
+		ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock();
+		mockActionProxy.getMethod();
+		controlActionProxy.setDefaultReturnValue("submit");
+		
+		MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class);
+		ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock();
+		mockActionInvocation.getAction();
+		controlActionInvocation.setDefaultReturnValue(mockAction);
+		mockActionInvocation.getProxy();
+		controlActionInvocation.setDefaultReturnValue(mockActionProxy);
+		mockActionInvocation.invoke();
+		controlActionInvocation.setReturnValue("okok");
+		
+		
+		controlAction.replay();
+		controlActionProxy.replay();
+		controlActionInvocation.replay();
+		
+		DefaultWorkflowInterceptor interceptor = new DefaultWorkflowInterceptor();
+		String result = interceptor.intercept(mockActionInvocation);
+		
+		assertEquals("okok", result);
+		controlAction.verify();
+		controlActionProxy.verify();
+		controlActionInvocation.verify();
+	}
+	
+	private interface ValidateAction extends Action, Validateable, ValidationAware {
+		void validateDoSave();
+		void validateSubmit();
+		String submit();
+    }
+}

src/test/com/opensymphony/xwork/interceptor/PrefixMethodInvocationUtilTest.java

+/*
+ * Copyright (c) 2002-2006 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.xwork.interceptor;
+
+import java.lang.reflect.Method;
+
+import org.easymock.MockControl;
+
+import com.opensymphony.xwork.ActionInvocation;
+import com.opensymphony.xwork.ActionProxy;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for PrefixMethodInovcationUtil.
+ * 
+ * @author tm_jee
+ * @version $Date$ $Id$
+ */
+public class PrefixMethodInvocationUtilTest extends TestCase {
+
+	// === capitalizeMethodName ===
+	public void testCapitalizeMethodName() throws Exception {
+		assertEquals("SomeMethod", 
+				PrefixMethodInvocationUtil.capitalizeMethodName("someMethod"));
+		assertEquals("AnotherMethod", 
+				PrefixMethodInvocationUtil.capitalizeMethodName("anotherMethod"));
+	}
+	
+	// === getPrefixMethod ===
+	public void testGetPrefixMethod1() throws Exception {
+		Object action = new PrefixMethodInvocationUtilTest.Action1();
+		Method m = PrefixMethodInvocationUtil.getPrefixedMethod(
+				new String[] { "prepare", "prepareDo" }, "save", action);
+		assertNotNull(m);
+		assertEquals(m.getName(), "prepareSave");
+	}
+	
+	public void testGetPrefixMethod2() throws Exception {
+		Object action = new PrefixMethodInvocationUtilTest.Action1();
+		Method m = PrefixMethodInvocationUtil.getPrefixedMethod(
+				new String[] { "prepare", "prepareDo" }, "submit", action);
+		assertNotNull(m);
+		assertEquals(m.getName(), "prepareSubmit");
+	}
+	
+	public void testGetPrefixMethod3() throws Exception {
+		Object action = new PrefixMethodInvocationUtilTest.Action1();
+		Method m = PrefixMethodInvocationUtil.getPrefixedMethod(
+				new String[] { "prepare", "prepareDo" }, "cancel", action);
+		assertNotNull(m);
+		assertEquals(m.getName(), "prepareDoCancel");
+	}
+	
+	public void testGetPrefixMethod4() throws Exception {
+		Object action = new PrefixMethodInvocationUtilTest.Action1();
+		Method m = PrefixMethodInvocationUtil.getPrefixedMethod(
+				new String[] { "prepare", "prepareDo" }, "noSuchMethod", action);
+		assertNull(m);
+	}
+	
+	public void testGetPrefixMethod5() throws Exception {
+		Object action = new PrefixMethodInvocationUtilTest.Action1();
+		Method m = PrefixMethodInvocationUtil.getPrefixedMethod(
+				new String[] { "noSuchPrefix", "noSuchPrefixDo" }, "save", action);
+		assertNull(m);
+	}
+	
+	
+	// === invokePrefixMethod === 
+	public void testInvokePrefixMethod1() throws Exception {
+		PrefixMethodInvocationUtilTest.Action1 action = new PrefixMethodInvocationUtilTest.Action1();
+		
+		// ActionProxy
+		MockControl controlActionProxy = MockControl.createControl(ActionProxy.class);
+		ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock();		
+		mockActionProxy.getMethod();
+		controlActionProxy.setReturnValue("save");
+		
+		
+		// ActionInvocation
+		MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class);
+		ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock();
+		mockActionInvocation.getAction();
+		controlActionInvocation.setReturnValue(action);
+		mockActionInvocation.getProxy();
+		controlActionInvocation.setReturnValue(mockActionProxy);
+		
+		controlActionProxy.replay();
+		controlActionInvocation.replay();
+		
+		
+		PrefixMethodInvocationUtil.invokePrefixMethod(
+				mockActionInvocation, 
+				new String[] { "prepare", "prepareDo" });
+		
+		controlActionProxy.verify();
+		controlActionInvocation.verify();
+		
+		assertTrue(action.prepareSaveInvoked);
+		assertFalse(action.prepareDoSaveInvoked);
+		assertFalse(action.prepareSubmitInvoked);
+		assertFalse(action.prepareDoCancelInvoked);
+	}
+	
+	public void testInvokePrefixMethod2() throws Exception {
+		PrefixMethodInvocationUtilTest.Action1 action = new PrefixMethodInvocationUtilTest.Action1();
+		
+		// ActionProxy
+		MockControl controlActionProxy = MockControl.createControl(ActionProxy.class);
+		ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock();		
+		mockActionProxy.getMethod();
+		controlActionProxy.setReturnValue("submit");
+		
+		
+		// ActionInvocation
+		MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class);
+		ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock();
+		mockActionInvocation.getAction();
+		controlActionInvocation.setReturnValue(action);
+		mockActionInvocation.getProxy();
+		controlActionInvocation.setReturnValue(mockActionProxy);
+		
+		controlActionProxy.replay();
+		controlActionInvocation.replay();
+		
+		
+		PrefixMethodInvocationUtil.invokePrefixMethod(
+				mockActionInvocation, 
+				new String[] { "prepare", "prepareDo" });
+		
+		controlActionProxy.verify();
+		controlActionInvocation.verify();
+		
+		assertFalse(action.prepareSaveInvoked);
+		assertFalse(action.prepareDoSaveInvoked);
+		assertTrue(action.prepareSubmitInvoked);
+		assertFalse(action.prepareDoCancelInvoked);
+	}
+	
+	public void testInvokePrefixMethod3() throws Exception {
+		PrefixMethodInvocationUtilTest.Action1 action = new PrefixMethodInvocationUtilTest.Action1();
+		
+		// ActionProxy
+		MockControl controlActionProxy = MockControl.createControl(ActionProxy.class);
+		ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock();		
+		mockActionProxy.getMethod();
+		controlActionProxy.setReturnValue("cancel");
+		
+		
+		// ActionInvocation
+		MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class);
+		ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock();
+		mockActionInvocation.getAction();
+		controlActionInvocation.setReturnValue(action);
+		mockActionInvocation.getProxy();
+		controlActionInvocation.setReturnValue(mockActionProxy);
+		
+		controlActionProxy.replay();
+		controlActionInvocation.replay();
+		
+		
+		PrefixMethodInvocationUtil.invokePrefixMethod(
+				mockActionInvocation, 
+				new String[] { "prepare", "prepareDo" });
+		
+		controlActionProxy.verify();
+		controlActionInvocation.verify();
+		
+		assertFalse(action.prepareSaveInvoked);
+		assertFalse(action.prepareDoSaveInvoked);
+		assertFalse(action.prepareSubmitInvoked);
+		assertTrue(action.prepareDoCancelInvoked);
+	}
+		
+	public void testInvokePrefixMethod4() throws Exception {
+		PrefixMethodInvocationUtilTest.Action1 action = new PrefixMethodInvocationUtilTest.Action1();
+		
+		// ActionProxy
+		MockControl controlActionProxy = MockControl.createControl(ActionProxy.class);
+		ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock();		
+		mockActionProxy.getMethod();
+		controlActionProxy.setReturnValue("noSuchMethod");
+		
+		
+		// ActionInvocation
+		MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class);
+		ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock();
+		mockActionInvocation.getAction();
+		controlActionInvocation.setReturnValue(action);
+		mockActionInvocation.getProxy();
+		controlActionInvocation.setReturnValue(mockActionProxy);
+		
+		controlActionProxy.replay();
+		controlActionInvocation.replay();
+		
+		
+		PrefixMethodInvocationUtil.invokePrefixMethod(
+				mockActionInvocation, 
+				new String[] { "prepare", "prepareDo" });
+		
+		controlActionProxy.verify();
+		controlActionInvocation.verify();
+		
+		assertFalse(action.prepareSaveInvoked);
+		assertFalse(action.prepareDoSaveInvoked);
+		assertFalse(action.prepareSubmitInvoked);
+		assertFalse(action.prepareDoCancelInvoked);
+	}
+		
+	public void testInvokePrefixMethod5() throws Exception {
+		PrefixMethodInvocationUtilTest.Action1 action = new PrefixMethodInvocationUtilTest.Action1();
+		
+		// ActionProxy
+		MockControl controlActionProxy = MockControl.createControl(ActionProxy.class);
+		ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock();		
+		mockActionProxy.getMethod();
+		controlActionProxy.setReturnValue("save");
+		
+		
+		// ActionInvocation
+		MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class);
+		ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock();
+		mockActionInvocation.getAction();
+		controlActionInvocation.setReturnValue(action);
+		mockActionInvocation.getProxy();
+		controlActionInvocation.setReturnValue(mockActionProxy);
+		
+		controlActionProxy.replay();
+		controlActionInvocation.replay();
+		
+		
+		PrefixMethodInvocationUtil.invokePrefixMethod(
+				mockActionInvocation, 
+				new String[] { "noSuchPrefix", "noSuchPrefixDo" });
+		
+		controlActionProxy.verify();
+		controlActionInvocation.verify();
+		
+		assertFalse(action.prepareSaveInvoked);
+		assertFalse(action.prepareDoSaveInvoked);
+		assertFalse(action.prepareSubmitInvoked);
+		assertFalse(action.prepareDoCancelInvoked);
+	}
+	
+	
+	
+	
+	/**
+	 * Just a simple object for testing method invocation on its methods.
+	 * 
+	 * @author tm_jee
+	 * @version $Date$ $Id$
+	 */
+	public static class Action1 {
+		
+		boolean prepareSaveInvoked = false;
+		boolean prepareDoSaveInvoked = false;
+		boolean prepareSubmitInvoked = false;
+		boolean prepareDoCancelInvoked = false;
+		
+		
+		// save
+		public void prepareSave() {
+			prepareSaveInvoked = true;
+		}
+		public void prepareDoSave() {
+			prepareDoSaveInvoked = true;
+		}
+		
+		// submit
+		public void prepareSubmit() {
+			prepareSubmitInvoked = true;
+		}
+		
+		// cancel
+		public void prepareDoCancel() {
+			prepareDoCancelInvoked = true;
+		}
+	}
+}