diff --git a/org.springframework.core/src/main/java/org/springframework/core/MethodParameter.java b/org.springframework.core/src/main/java/org/springframework/core/MethodParameter.java index 2f8743e251b..21715160a69 100644 --- a/org.springframework.core/src/main/java/org/springframework/core/MethodParameter.java +++ b/org.springframework.core/src/main/java/org/springframework/core/MethodParameter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,9 @@ package org.springframework.core; import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; +import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; @@ -39,9 +41,9 @@ import org.springframework.util.Assert; */ public class MethodParameter { - private Method method; + private final Method method; - private Constructor constructor; + private final Constructor constructor; private final int parameterIndex; @@ -62,6 +64,9 @@ public class MethodParameter { Map typeVariableMap; + private int hash; + + /** * Create a new MethodParameter for the given method, with nesting level 1. @@ -87,6 +92,7 @@ public class MethodParameter { this.method = method; this.parameterIndex = parameterIndex; this.nestingLevel = nestingLevel; + this.constructor = null; } /** @@ -111,6 +117,7 @@ public class MethodParameter { this.constructor = constructor; this.parameterIndex = parameterIndex; this.nestingLevel = nestingLevel; + this.method = null; } /** @@ -147,11 +154,27 @@ public class MethodParameter { return this.constructor; } + /** + * Returns the wrapped member. + * @return the member + */ + private Member getMember() { + return this.method != null ? this.method : this.constructor; + } + + /** + * Returns the wrapped annotated element. + * @return the annotated element + */ + private AnnotatedElement getAnnotatedElement() { + return this.method != null ? this.method : this.constructor; + } + /** * Return the class that declares the underlying Method or Constructor. */ public Class getDeclaringClass() { - return (this.method != null ? this.method.getDeclaringClass() : this.constructor.getDeclaringClass()); + return getMember().getDeclaringClass(); } /** @@ -209,7 +232,7 @@ public class MethodParameter { * Return the annotations associated with the target method/constructor itself. */ public Annotation[] getMethodAnnotations() { - return (this.method != null ? this.method.getAnnotations() : this.constructor.getAnnotations()); + return getAnnotatedElement().getAnnotations(); } /** @@ -219,8 +242,7 @@ public class MethodParameter { */ @SuppressWarnings("unchecked") public T getMethodAnnotation(Class annotationType) { - return (this.method != null ? this.method.getAnnotation(annotationType) : - (T) this.constructor.getAnnotation(annotationType)); + return getAnnotatedElement().getAnnotation(annotationType); } /** @@ -374,4 +396,36 @@ public class MethodParameter { } } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj != null && obj instanceof MethodParameter) { + MethodParameter other = (MethodParameter) obj; + + if (this.parameterIndex != other.parameterIndex) { + return false; + } + else if (this.getMember().equals(other.getMember())) { + return true; + } + else { + return false; + } + } + return false; + } + + + @Override + public int hashCode() { + int result = hash; + if (result == 0) { + result = getMember().hashCode(); + result = 31 * result + parameterIndex; + hash = result; + } + return result; + } } diff --git a/org.springframework.core/src/test/java/org/springframework/core/MethodParameterTests.java b/org.springframework.core/src/test/java/org/springframework/core/MethodParameterTests.java new file mode 100644 index 00000000000..2f1ce99bfd9 --- /dev/null +++ b/org.springframework.core/src/test/java/org/springframework/core/MethodParameterTests.java @@ -0,0 +1,85 @@ +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core; + +import java.lang.reflect.Method; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * @author Arjen Poutsma + */ +public class MethodParameterTests { + + private MethodParameter stringParameter; + + private MethodParameter longParameter; + + private MethodParameter intReturnType; + + @Before + public void setUp() throws NoSuchMethodException { + Method method = getClass().getMethod("method", String.class, Long.TYPE); + stringParameter = new MethodParameter(method, 0); + longParameter = new MethodParameter(method, 1); + intReturnType = new MethodParameter(method, -1); + } + + + + @Test + public void testEquals() throws NoSuchMethodException { + assertEquals(stringParameter, stringParameter); + assertEquals(longParameter, longParameter); + assertEquals(intReturnType, intReturnType); + + assertFalse(stringParameter.equals(longParameter)); + assertFalse(stringParameter.equals(intReturnType)); + assertFalse(longParameter.equals(stringParameter)); + assertFalse(longParameter.equals(intReturnType)); + assertFalse(intReturnType.equals(stringParameter)); + assertFalse(intReturnType.equals(longParameter)); + + Method method = getClass().getMethod("method", String.class, Long.TYPE); + MethodParameter methodParameter = new MethodParameter(method, 0); + assertEquals(stringParameter, methodParameter); + assertEquals(methodParameter, stringParameter); + assertFalse(longParameter.equals(methodParameter)); + assertFalse(methodParameter.equals(longParameter)); + } + + @Test + public void testHashCode() throws NoSuchMethodException { + assertEquals(stringParameter.hashCode(), stringParameter.hashCode()); + assertEquals(longParameter.hashCode(), longParameter.hashCode()); + assertEquals(intReturnType.hashCode(), intReturnType.hashCode()); + + Method method = getClass().getMethod("method", String.class, Long.TYPE); + MethodParameter methodParameter = new MethodParameter(method, 0); + assertEquals(stringParameter.hashCode(), methodParameter.hashCode()); + assertTrue(longParameter.hashCode() != methodParameter.hashCode()); + } + + + public int method(String p1, long p2) { + return 42; + } + +}