- Revision
- 722
- Author
- mauro
- Date
- 2008-06-17 09:32:52 -0500 (Tue, 17 Jun 2008)
Log Message
Refactored ParanamerMethodDefinitionFinder to not use generic parameter types.
Modified Paths
- trunk/waffle-core/src/main/java/org/codehaus/waffle/action/AbstractMethodDefinitionFinder.java
- trunk/waffle-core/src/main/java/org/codehaus/waffle/action/ParanamerMethodDefinitionFinder.java
- trunk/waffle-core/src/test/java/org/codehaus/waffle/action/AbstractMethodDefinitionFinderTest.java
- trunk/waffle-core/src/test/java/org/codehaus/waffle/action/AnnotatedMethodDefinitionFinderTest.java
- trunk/waffle-core/src/test/java/org/codehaus/waffle/action/ParanamerMethodDefinitionFinderTest.java
Diff
Modified: trunk/waffle-core/src/main/java/org/codehaus/waffle/action/AbstractMethodDefinitionFinder.java (721 => 722)
--- trunk/waffle-core/src/main/java/org/codehaus/waffle/action/AbstractMethodDefinitionFinder.java 2008-06-17 14:22:29 UTC (rev 721) +++ trunk/waffle-core/src/main/java/org/codehaus/waffle/action/AbstractMethodDefinitionFinder.java 2008-06-17 14:32:52 UTC (rev 722) @@ -228,7 +228,7 @@ } } - if (hasEquivalentParameterTypes(methodDefinition)) { + if (hasEquivalentParameterTypes(methodDefinition, stringTransmuter)) { return methodDefinition; } } @@ -236,7 +236,7 @@ throw new NoValidActionMethodException(method.getName()); } - private boolean hasEquivalentParameterTypes(MethodDefinition methodDefinition) { + protected boolean hasEquivalentParameterTypes(MethodDefinition methodDefinition, StringTransmuter stringTransmuter) { Type[] methodParameterTypes = methodDefinition.getMethod().getGenericParameterTypes(); List<Object> methodArguments = methodDefinition.getMethodArguments();
Modified: trunk/waffle-core/src/main/java/org/codehaus/waffle/action/ParanamerMethodDefinitionFinder.java (721 => 722)
--- trunk/waffle-core/src/main/java/org/codehaus/waffle/action/ParanamerMethodDefinitionFinder.java 2008-06-17 14:22:29 UTC (rev 721) +++ trunk/waffle-core/src/main/java/org/codehaus/waffle/action/ParanamerMethodDefinitionFinder.java 2008-06-17 14:32:52 UTC (rev 722) @@ -1,53 +1,82 @@ -/***************************************************************************** - * Copyright (c) 2005-2008 Michael Ward * - * All rights reserved. * - * ------------------------------------------------------------------------- * - * The software in this package is published under the terms of the BSD * - * style license a copy of which has been included with this distribution in * - * the LICENSE.txt file. * - * * - * Original code by: Michael Ward * - *****************************************************************************/ +/* + * Copyright (c) 2005-2008 Michael Ward + */ package org.codehaus.waffle.action; -import com.thoughtworks.paranamer.CachingParanamer; -import com.thoughtworks.paranamer.ParameterNamesNotFoundException; -import com.thoughtworks.paranamer.Paranamer; -import org.codehaus.waffle.bind.StringTransmuter; -import org.codehaus.waffle.monitor.ActionMonitor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; +import org.codehaus.waffle.bind.StringTransmuter; +import org.codehaus.waffle.monitor.ActionMonitor; + +import com.thoughtworks.paranamer.CachingParanamer; +import com.thoughtworks.paranamer.ParameterNamesNotFoundException; +import com.thoughtworks.paranamer.Paranamer; + /** - * <p>Pananamer-based method definition finder, which can be used in alternative to - * other definition finders, eg [EMAIL PROTECTED] AnnotatedMethodDefinitionFinder}.</p> - * <br/><br/> - * <b>Note</b>: Pragmatic method calls will always take precedence. + * <p> + * Pananamer-based method definition finder, which can be used in alternative to other definition finders, eg + * [EMAIL PROTECTED] AnnotatedMethodDefinitionFinder}. + * </p> + * <br/><br/> <b>Note</b>: Pragmatic method calls will always take precedence. * - * @author Paul Hammant + * @author Paul Hammant * @see AnnotatedMethodDefinitionFinder */ public class ParanamerMethodDefinitionFinder extends AbstractOgnlMethodDefinitionFinder { private final CachingParanamer paranamer = new CachingParanamer(); - - public ParanamerMethodDefinitionFinder(ServletContext servletContext, - ArgumentResolver argumentResolver, - MethodNameResolver methodNameResolver, - StringTransmuter stringTransmuter, - ActionMonitor actionMonitor) { + + public ParanamerMethodDefinitionFinder(ServletContext servletContext, ArgumentResolver argumentResolver, + MethodNameResolver methodNameResolver, StringTransmuter stringTransmuter, ActionMonitor actionMonitor) { super(servletContext, argumentResolver, methodNameResolver, stringTransmuter, actionMonitor); } /** - * Uses [EMAIL PROTECTED] Paranamer} to determine the parameter names to use to resolve the - * argument values. - * + * Overriden to allow Paranamer to not use generic parameter types. + */ + protected boolean hasEquivalentParameterTypes(MethodDefinition methodDefinition, StringTransmuter stringTransmuter) { + Class<?>[] methodParameterTypes = methodDefinition.getMethod().getParameterTypes(); + List<Object> methodArguments = methodDefinition.getMethodArguments(); + + if (methodParameterTypes.length != methodArguments.size()) { + return false; // different signatures lengths + } + + for (int i = 0; i < methodParameterTypes.length; i++) { + Class<?> methodParameterType = methodParameterTypes[i]; + + // the types must be assignable to be considered a valid method (assume true if actualParameterType is null) + if (methodArguments.get(i) != null) { + Class<?> methodArgumentType = methodArguments.get(i).getClass(); + + if (!methodParameterType.isAssignableFrom(methodArgumentType)) { + if (String.class.equals(methodArgumentType)) { + try { + // Can the String be converted to the parameter type? If so convert it... + String value = (String) methodArguments.get(i); + methodArguments.set(i, stringTransmuter.transmute(value, methodParameterType)); + } catch (Exception e) { + return false; // Can't convert String value + } + } else { + return false; + } + } + } + } + + return true; + } + + /** + * Uses [EMAIL PROTECTED] Paranamer} to determine the parameter names to use to resolve the argument values. + * * @param method the action method to be invoked * @param request the HttpServetRequest * @return the resolved list of arguments needed to satisfy the action method invocation @@ -55,10 +84,10 @@ protected List<Object> getArguments(Method method, HttpServletRequest request) { Class<?>[] parameterTypes = method.getParameterTypes(); String[] parameterNames = null; - + try { parameterNames = paranamer.lookupParameterNames(method); - } catch ( ParameterNamesNotFoundException e ){ + } catch (ParameterNamesNotFoundException e) { Class<?> declaringClass = method.getDeclaringClass(); int rc = paranamer.areParameterNamesAvailable(declaringClass, method.getName()); if (rc == Paranamer.NO_PARAMETER_NAMES_LIST) { @@ -66,14 +95,17 @@ rc = paranamer.areParameterNamesAvailable(declaringClass, method.getName()); parameterNames = paranamer.lookupParameterNames(method); } - if (rc == Paranamer.NO_PARAMETER_NAMES_LIST ) { - throw new MatchingActionMethodException("No parameter names list found by paranamer "+paranamer); - } else if (rc == Paranamer.NO_PARAMETER_NAMES_FOR_CLASS ) { - throw new MatchingActionMethodException("No parameter names found for class '" + declaringClass.getName() + "' by paranamer "+paranamer); + if (rc == Paranamer.NO_PARAMETER_NAMES_LIST) { + throw new MatchingActionMethodException("No parameter names list found by paranamer " + paranamer); + } else if (rc == Paranamer.NO_PARAMETER_NAMES_FOR_CLASS) { + throw new MatchingActionMethodException("No parameter names found for class '" + + declaringClass.getName() + "' by paranamer " + paranamer); } else if (rc == Paranamer.NO_PARAMETER_NAMES_FOR_CLASS_AND_MEMBER) { - throw new MatchingActionMethodException("No parameter names found for class '" + declaringClass.getName() + "' and method '" + method.getName()+ "' by paranamer "+paranamer); - // } else if (rc == Paranamer.PARAMETER_NAMES_FOUND ){ - // throw new MatchingMethodException("Invalid parameter names list for paranamer "+paranamer); + throw new MatchingActionMethodException("No parameter names found for class '" + + declaringClass.getName() + "' and method '" + method.getName() + "' by paranamer " + + paranamer); + // } else if (rc == Paranamer.PARAMETER_NAMES_FOUND ){ + // throw new MatchingActionMethodException("Invalid parameter names list for paranamer "+paranamer); } } List<String> arguments = new ArrayList<String>(parameterNames.length);
Modified: trunk/waffle-core/src/test/java/org/codehaus/waffle/action/AbstractMethodDefinitionFinderTest.java (721 => 722)
--- trunk/waffle-core/src/test/java/org/codehaus/waffle/action/AbstractMethodDefinitionFinderTest.java 2008-06-17 14:22:29 UTC (rev 721) +++ trunk/waffle-core/src/test/java/org/codehaus/waffle/action/AbstractMethodDefinitionFinderTest.java 2008-06-17 14:32:52 UTC (rev 722) @@ -12,7 +12,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import javax.servlet.ServletContext; @@ -536,53 +535,8 @@ assertSame(servletContext, methodDefinition.getMethodArguments().get(0)); } + @Test - public void canUseCustomStringTransmuter() throws Exception { - // Mock HttpServletRequest - final HttpServletRequest request = mockery.mock(HttpServletRequest.class); - - // Mock HttpServletResponse - final HttpServletResponse response = mockery.mock(HttpServletResponse.class); - - // Mock MethodNameResolver - final MethodNameResolver methodNameResolver = mockery.mock(MethodNameResolver.class); - mockery.checking(new Expectations() { - { - one(methodNameResolver).resolve(with(same(request))); - will(returnValue("methodListOfStrings|blah")); - } - }); - - // Mock ArgumentResolver - final ArgumentResolver argumentResolver = mockery.mock(ArgumentResolver.class); - mockery.checking(new Expectations() { - { - one(argumentResolver).resolve(request, "blah"); - will(returnValue("blah")); - } - }); - - // Mock StringTransmuter - final StringTransmuter stringTransmuter = mockery.mock(StringTransmuter.class); - mockery.checking(new Expectations() { - { - one(stringTransmuter).transmute("blah", - parameterTypeForMethod(ControllerWithListMethods.class, "listOfStrings")); - will(returnValue(Collections.EMPTY_LIST)); - } - }); - // new OgnlValueConverterFinder(new OgnlValueConverter(typeConverter)) - - FakeControllerWithMethodDefinitions controller = new FakeControllerWithMethodDefinitions(); - MethodDefinitionFinder methodDefinitionFinder = newMethodDefinitionFinder(null, argumentResolver, - methodNameResolver, stringTransmuter); - MethodDefinition methodDefinition = methodDefinitionFinder.find(controller, request, response); - - Method expectedMethod = FakeControllerWithMethodDefinitions.class.getMethod("methodListOfStrings", List.class); - assertEquals(expectedMethod, methodDefinition.getMethod()); - } - - @Test public void canConvertStringToInteger() throws Exception { // Mock HttpServletRequest final HttpServletRequest request = mockery.mock(HttpServletRequest.class);
Modified: trunk/waffle-core/src/test/java/org/codehaus/waffle/action/AnnotatedMethodDefinitionFinderTest.java (721 => 722)
--- trunk/waffle-core/src/test/java/org/codehaus/waffle/action/AnnotatedMethodDefinitionFinderTest.java 2008-06-17 14:22:29 UTC (rev 721) +++ trunk/waffle-core/src/test/java/org/codehaus/waffle/action/AnnotatedMethodDefinitionFinderTest.java 2008-06-17 14:32:52 UTC (rev 722) @@ -4,6 +4,7 @@ import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import javax.servlet.ServletContext; @@ -111,4 +112,50 @@ methodDefinitionFinder.find(controller, request, response); } + @Test + public void canUseCustomStringTransmuter() throws Exception { + // Mock HttpServletRequest + final HttpServletRequest request = mockery.mock(HttpServletRequest.class); + + // Mock HttpServletResponse + final HttpServletResponse response = mockery.mock(HttpServletResponse.class); + + // Mock MethodNameResolver + final MethodNameResolver methodNameResolver = mockery.mock(MethodNameResolver.class); + mockery.checking(new Expectations() { + { + one(methodNameResolver).resolve(with(same(request))); + will(returnValue("methodListOfStrings|blah")); + } + }); + + // Mock ArgumentResolver + final ArgumentResolver argumentResolver = mockery.mock(ArgumentResolver.class); + mockery.checking(new Expectations() { + { + one(argumentResolver).resolve(request, "blah"); + will(returnValue("blah")); + } + }); + + // Mock StringTransmuter + final StringTransmuter stringTransmuter = mockery.mock(StringTransmuter.class); + mockery.checking(new Expectations() { + { + one(stringTransmuter).transmute("blah", + parameterTypeForMethod(ControllerWithListMethods.class, "listOfStrings")); + will(returnValue(Collections.EMPTY_LIST)); + } + }); + // new OgnlValueConverterFinder(new OgnlValueConverter(typeConverter)) + + FakeControllerWithMethodDefinitions controller = new FakeControllerWithMethodDefinitions(); + MethodDefinitionFinder methodDefinitionFinder = newMethodDefinitionFinder(null, argumentResolver, + methodNameResolver, stringTransmuter); + MethodDefinition methodDefinition = methodDefinitionFinder.find(controller, request, response); + + Method expectedMethod = FakeControllerWithMethodDefinitions.class.getMethod("methodListOfStrings", List.class); + assertEquals(expectedMethod, methodDefinition.getMethod()); + } + }
Modified: trunk/waffle-core/src/test/java/org/codehaus/waffle/action/ParanamerMethodDefinitionFinderTest.java (721 => 722)
--- trunk/waffle-core/src/test/java/org/codehaus/waffle/action/ParanamerMethodDefinitionFinderTest.java 2008-06-17 14:22:29 UTC (rev 721) +++ trunk/waffle-core/src/test/java/org/codehaus/waffle/action/ParanamerMethodDefinitionFinderTest.java 2008-06-17 14:32:52 UTC (rev 722) @@ -4,6 +4,7 @@ import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import javax.servlet.ServletContext; @@ -16,6 +17,7 @@ import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.integration.junit4.JMock; +import org.junit.Test; import org.junit.runner.RunWith; /** @@ -34,7 +36,7 @@ stringTransmuter, new SilentMonitor()); } - // [EMAIL PROTECTED] + //[EMAIL PROTECTED] public void canFindMethodWhenParameterAssignable() throws Exception { // Mock HttpServletRequest final HttpServletRequest request = mockery.mock(HttpServletRequest.class); @@ -110,4 +112,49 @@ methodDefinitionFinder.find(controller, request, response); } + @Test + public void canUseCustomStringTransmuter() throws Exception { + // Mock HttpServletRequest + final HttpServletRequest request = mockery.mock(HttpServletRequest.class); + + // Mock HttpServletResponse + final HttpServletResponse response = mockery.mock(HttpServletResponse.class); + + // Mock MethodNameResolver + final MethodNameResolver methodNameResolver = mockery.mock(MethodNameResolver.class); + mockery.checking(new Expectations() { + { + one(methodNameResolver).resolve(with(same(request))); + will(returnValue("methodListOfStrings|blah")); + } + }); + + // Mock ArgumentResolver + final ArgumentResolver argumentResolver = mockery.mock(ArgumentResolver.class); + mockery.checking(new Expectations() { + { + one(argumentResolver).resolve(request, "blah"); + will(returnValue("blah")); + } + }); + + // Mock StringTransmuter + final StringTransmuter stringTransmuter = mockery.mock(StringTransmuter.class); + mockery.checking(new Expectations() { + { + one(stringTransmuter).transmute("blah", List.class); + will(returnValue(Collections.EMPTY_LIST)); + } + }); + // new OgnlValueConverterFinder(new OgnlValueConverter(typeConverter)) + + FakeControllerWithMethodDefinitions controller = new FakeControllerWithMethodDefinitions(); + MethodDefinitionFinder methodDefinitionFinder = newMethodDefinitionFinder(null, argumentResolver, + methodNameResolver, stringTransmuter); + MethodDefinition methodDefinition = methodDefinitionFinder.find(controller, request, response); + + Method expectedMethod = FakeControllerWithMethodDefinitions.class.getMethod("methodListOfStrings", List.class); + assertEquals(expectedMethod, methodDefinition.getMethod()); + } + }
To unsubscribe from this list please visit:
