- Revision
- 712
- Author
- mauro
- Date
- 2008-06-16 16:27:30 -0500 (Mon, 16 Jun 2008)
Log Message
WAFFLE-84: Added tests methods with list parameters with different generic types.
Modified Paths
Diff
Modified: trunk/waffle-core/src/main/java/org/codehaus/waffle/action/AbstractMethodDefinitionFinder.java (711 => 712)
--- trunk/waffle-core/src/main/java/org/codehaus/waffle/action/AbstractMethodDefinitionFinder.java 2008-06-16 18:46:58 UTC (rev 711) +++ trunk/waffle-core/src/main/java/org/codehaus/waffle/action/AbstractMethodDefinitionFinder.java 2008-06-16 21:27:30 UTC (rev 712) @@ -1,13 +1,9 @@ -/***************************************************************************** - * 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 * 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 * + **********************************************************************************************************************/ package org.codehaus.waffle.action; import static java.text.MessageFormat.format; @@ -38,7 +34,7 @@ /** * Abstract base implementation for all method definition finders - * + * * @author Michael Ward * @author Paul Hammant * @author Mauro Talevi @@ -56,21 +52,17 @@ private final MethodNameResolver methodNameResolver; private final ActionMonitor actionMonitor; - public AbstractMethodDefinitionFinder(ServletContext servletContext, - ArgumentResolver argumentResolver, - MethodNameResolver methodNameResolver, - StringTransmuter stringTransmuter, - ActionMonitor actionMonitor) { + public AbstractMethodDefinitionFinder(ServletContext servletContext, ArgumentResolver argumentResolver, + MethodNameResolver methodNameResolver, StringTransmuter stringTransmuter, ActionMonitor actionMonitor) { this.servletContext = servletContext; this.argumentResolver = argumentResolver; this.stringTransmuter = stringTransmuter; this.methodNameResolver = methodNameResolver; this.actionMonitor = actionMonitor; } - - public MethodDefinition find(Object controller, - HttpServletRequest request, - HttpServletResponse response) throws WaffleException { + + public MethodDefinition find(Object controller, HttpServletRequest request, HttpServletResponse response) + throws WaffleException { String methodName = methodNameResolver.resolve(request); if (methodName == null) { @@ -90,7 +82,8 @@ Class<?> controllerType = controller.getClass(); if (defaultMethodCache.containsKey(controllerType)) { // cache hit - MethodDefinition methodDefinition = buildDefaultMethodDefinition(defaultMethodCache.get(controllerType), request); + MethodDefinition methodDefinition = buildDefaultMethodDefinition(defaultMethodCache.get(controllerType), + request); actionMonitor.defaultActionMethodCached(controllerType, methodDefinition); return methodDefinition; } @@ -112,10 +105,8 @@ return actionMethod != null && actionMethod.asDefault(); } - private MethodDefinition findPragmaticActionMethod(Object controller, - String methodName, - HttpServletRequest request, - HttpServletResponse response) { + private MethodDefinition findPragmaticActionMethod(Object controller, String methodName, + HttpServletRequest request, HttpServletResponse response) { Iterator<String> iterator = Arrays.asList(methodName.split(PRAGMA_REGEX)).iterator(); methodName = iterator.next(); @@ -127,13 +118,15 @@ return methodDefinition; } - private MethodDefinition findActionMethod(Object controller, HttpServletRequest request, HttpServletResponse response, String methodName) { + private MethodDefinition findActionMethod(Object controller, HttpServletRequest request, + HttpServletResponse response, String methodName) { List<Method> methods = findMethods(controller.getClass(), methodName); List<MethodDefinition> methodDefinitions = findMethodDefinitions(request, response, methods); if (methodDefinitions.size() > 1) { - throw new AmbiguousActionSignatureMethodException("Method: '" + methodName + "' for controller: '" + controller.getClass() + "'"); + throw new AmbiguousActionSignatureMethodException("Method: '" + methodName + "' for controller: '" + + controller.getClass() + "'"); } else if (methodDefinitions.isEmpty()) { throw new NoMatchingActionMethodException(methodName, controller.getClass()); } @@ -143,7 +136,8 @@ return methodDefinition; } - private List<MethodDefinition> findMethodDefinitions(HttpServletRequest request, HttpServletResponse response, List<Method> methods) { + private List<MethodDefinition> findMethodDefinitions(HttpServletRequest request, HttpServletResponse response, + List<Method> methods) { List<MethodDefinition> methodDefinitions = new ArrayList<MethodDefinition>(); for (Method method : methods) { @@ -162,8 +156,9 @@ private MethodDefinition buildDefaultMethodDefinition(Method method, HttpServletRequest request) { MethodDefinition methodDefinition = new MethodDefinition(method); - if ( !isDefaultActionMethod(method) ){ - throw new NoDefaultActionMethodException("Method "+method+" is not annotated with @ActionMethod(asDefault=true)."); + if (!isDefaultActionMethod(method)) { + throw new NoDefaultActionMethodException("Method " + method + + " is not annotated with @ActionMethod(asDefault=true)."); } ActionMethod defaultActionMethod = method.getAnnotation(ActionMethod.class); List<String> arguments = new ArrayList<String>(defaultActionMethod.parameters().length); @@ -180,10 +175,8 @@ return methodDefinition; } - private MethodDefinition findPragmaticMethodDefinition(HttpServletRequest request, - HttpServletResponse response, - List<Method> methods, - List<Object> arguments) { + private MethodDefinition findPragmaticMethodDefinition(HttpServletRequest request, HttpServletResponse response, + List<Method> methods, List<Object> arguments) { List<MethodDefinition> methodDefinitions = new ArrayList<MethodDefinition>(); for (Method method : methods) { @@ -207,10 +200,8 @@ return methodDefinitions.get(0); // TODO ... should we cache the method? } - private MethodDefinition buildMethodDefinition(HttpServletRequest request, - HttpServletResponse response, - Method method, - List<Object> arguments) { + private MethodDefinition buildMethodDefinition(HttpServletRequest request, HttpServletResponse response, + Method method, List<Object> arguments) { Class<?>[] actualParameterTypes = method.getParameterTypes(); MethodDefinition methodDefinition = new MethodDefinition(method); @@ -258,10 +249,10 @@ // the types must be assignable to be considered a valid method (assume true if actualParameterType is null) if (methodArguments.get(i) != null) { - Class<?> type = methodArguments.get(i).getClass(); + Class<?> methodArgumentType = methodArguments.get(i).getClass(); - if (!isAssignableFrom(methodParameterType, type)) { - if (String.class.equals(type)) { + if (!isAssignableFrom(methodParameterType, 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); @@ -279,21 +270,21 @@ return true; } - private boolean isAssignableFrom(Type methodParameterType, Class<?> type) { - if ( methodParameterType instanceof Class ){ - return ((Class<?>)methodParameterType).isAssignableFrom(type); - } else if ( methodParameterType instanceof ParameterizedType ){ - Type rawType = ((ParameterizedType)methodParameterType).getRawType(); - return ((Class<?>)rawType).isAssignableFrom(type); + private boolean isAssignableFrom(Type methodParameterType, Class<?> methodArgumentType) { + if (methodParameterType instanceof Class) { + return ((Class<?>) methodParameterType).isAssignableFrom(methodArgumentType); + } else if (methodParameterType instanceof ParameterizedType) { + Type rawType = ((ParameterizedType) methodParameterType).getRawType(); + return ((Class<?>) rawType).isAssignableFrom(methodArgumentType); } return false; } - // Protected methods, accessible by subclasses + // Protected methods, accessible by subclasses /** * Wraps value in curly brackets to fit with default handling - * + * * @param value the argument value * @return A formatted argument */ @@ -303,8 +294,8 @@ /** * Resolves arguments by name - * - * @param request the HttpServletRequest + * + * @param request the HttpServletRequest * @param arguments the List of argument names * @return The List of resolved argument objects * @see ArgumentResolver @@ -320,12 +311,12 @@ return resolvedArguments; } - // Abstract methods - implementable by subclasses + // Abstract methods - implementable by subclasses /** * Returns the resolved list of method arguments. - * - * @param method the action method to be invoked + * + * @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 */ @@ -333,14 +324,12 @@ /** * Returns the methods matching the type and name - * - * @param type the Class in which to look for the method + * + * @param type the Class in which to look for the method * @param methodName the method name * @return A List of methods - * @throws NoMatchingActionMethodException - * if no methods match + * @throws NoMatchingActionMethodException if no methods match */ protected abstract List<Method> findMethods(Class<?> type, String methodName); - }
Modified: trunk/waffle-core/src/test/java/org/codehaus/waffle/action/AnnotatedMethodDefinitionFinderTest.java (711 => 712)
--- trunk/waffle-core/src/test/java/org/codehaus/waffle/action/AnnotatedMethodDefinitionFinderTest.java 2008-06-16 18:46:58 UTC (rev 711) +++ trunk/waffle-core/src/test/java/org/codehaus/waffle/action/AnnotatedMethodDefinitionFinderTest.java 2008-06-16 21:27:30 UTC (rev 712) @@ -1,5 +1,27 @@ package org.codehaus.waffle.action; +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.MethodDescriptor; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + import org.codehaus.waffle.action.annotation.ActionMethod; import org.codehaus.waffle.bind.StringTransmuter; import org.codehaus.waffle.context.ContextContainer; @@ -11,22 +33,9 @@ import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.integration.junit4.JMock; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; import org.junit.Test; import org.junit.runner.RunWith; -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.Collections; -import java.util.List; - /** * * @author Michael Ward @@ -511,6 +520,111 @@ } @Test + public void canConvertStringToListOfStrings() 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")); + } + }); + + final List<String> list = asList("one", "two"); + // Mock ArgumentResolver + final ArgumentResolver argumentResolver = mockery.mock(ArgumentResolver.class); + mockery.checking(new Expectations() { + { + one(argumentResolver).resolve(request, "{foobaz}"); + will(returnValue("one,two")); + } + }); + + // Mock StringTransmuter + final StringTransmuter stringTransmuter = mockery.mock(StringTransmuter.class); + mockery.checking(new Expectations() { + { + one(stringTransmuter).transmute("one,two", parameterTypeForMethod("listOfStrings")); + will(returnValue(list)); + } + }); + + SampleForMethodFinder sampleForMethodFinder = new SampleForMethodFinder(); + + MethodDefinitionFinder methodDefinitionFinder = new AnnotatedMethodDefinitionFinder(null, argumentResolver, + methodNameResolver, stringTransmuter, monitor); + MethodDefinition methodDefinition = methodDefinitionFinder.find(sampleForMethodFinder, request, response); + + assertEquals(list, methodDefinition.getMethodArguments().get(0)); + } + + @Test + public void canConvertStringToListOfIntegers() 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("methodListOfIntegers")); + } + }); + + final List<Integer> list = asList(1, 2); + // Mock ArgumentResolver + final ArgumentResolver argumentResolver = mockery.mock(ArgumentResolver.class); + mockery.checking(new Expectations() { + { + one(argumentResolver).resolve(request, "{foobaz}"); + will(returnValue("1,2")); + } + }); + + // Mock StringTransmuter + final StringTransmuter stringTransmuter = mockery.mock(StringTransmuter.class); + mockery.checking(new Expectations() { + { + one(stringTransmuter).transmute("1,2", parameterTypeForMethod("listOfIntegers")); + will(returnValue(list)); + } + }); + + SampleForMethodFinder sampleForMethodFinder = new SampleForMethodFinder(); + + MethodDefinitionFinder methodDefinitionFinder = new AnnotatedMethodDefinitionFinder(null, argumentResolver, + methodNameResolver, stringTransmuter, monitor); + MethodDefinition methodDefinition = methodDefinitionFinder.find(sampleForMethodFinder, request, response); + + assertEquals(list, methodDefinition.getMethodArguments().get(0)); + } + + protected Type parameterTypeForMethod(String methodName) throws IntrospectionException { + BeanInfo beanInfo = Introspector.getBeanInfo(WithListMethods.class); + for ( MethodDescriptor md : beanInfo.getMethodDescriptors() ){ + if ( md.getMethod().getName().equals(methodName) ){ + return md.getMethod().getGenericParameterTypes()[0]; + } + } + return null; + } + + private static interface WithListMethods { + void listOfIntegers(List<Integer> list); + void listOfStrings(List<String> list); + } + + @Test public void canDependOnRequest() throws Exception { // Mock HttpServletRequest final HttpServletRequest request = mockery.mock(HttpServletRequest.class);
Modified: trunk/waffle-core/src/test/java/org/codehaus/waffle/testmodel/SampleForMethodFinder.java (711 => 712)
--- trunk/waffle-core/src/test/java/org/codehaus/waffle/testmodel/SampleForMethodFinder.java 2008-06-16 18:46:58 UTC (rev 711) +++ trunk/waffle-core/src/test/java/org/codehaus/waffle/testmodel/SampleForMethodFinder.java 2008-06-16 21:27:30 UTC (rev 712) @@ -27,6 +27,8 @@ public Integer integer = null; public Float decimal = null; public boolean bool = false; + public List<String> listOfStrings; + public List<Integer> listOfIntegers; public HttpServletRequest request; public HttpServletResponse response; public HttpSession session; @@ -70,7 +72,18 @@ public void methodBoolean(boolean bool) { this.bool = bool; } + + @ActionMethod(parameters = {"foobaz"}) + public void methodListOfStrings(List<String> list) { + this.listOfStrings = list; + } + + @ActionMethod(parameters = {"foobaz"}) + public void methodListOfIntegers(List<Integer> list) { + this.listOfIntegers = list; + } + @ActionMethod public void methodDependsOnRequest(HttpServletRequest request) { this.request = request;
To unsubscribe from this list please visit:
