001 /*--------------------------------------------------------------------------+
002 $Id: FormalParameter.java 26283 2010-02-18 11:18:57Z juergens $
003 | |
004 | Copyright 2005-2010 Technische Universitaet Muenchen |
005 | |
006 | Licensed under the Apache License, Version 2.0 (the "License"); |
007 | you may not use this file except in compliance with the License. |
008 | You may obtain a copy of the License at |
009 | |
010 | http://www.apache.org/licenses/LICENSE-2.0 |
011 | |
012 | Unless required by applicable law or agreed to in writing, software |
013 | distributed under the License is distributed on an "AS IS" BASIS, |
014 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
015 | See the License for the specific language governing permissions and |
016 | limitations under the License. |
017 +--------------------------------------------------------------------------*/
018 package edu.tum.cs.commons.reflect;
019
020 import java.lang.annotation.Annotation;
021 import java.lang.reflect.Method;
022 import java.lang.reflect.Type;
023
024 /**
025 * This class models formal method parameters to allow convenient reflective
026 * access as the Java Reflection API does not model them explicitly.
027 *
028 * Instances of this class can be obtained via
029 * {@link ReflectionUtils#getFormalParameters(Method)}.
030 *
031 * @author Florian Deissenboeck
032 * @author $Author: juergens $
033 * @version $Rev: 26283 $
034 * @levd.rating GREEN Hash: 2D347E77304012F77E6CE9EA946F3982
035 *
036 * @see ReflectionUtils#getFormalParameters(Method)
037 * @see ReflectionUtils#invoke(Method, Object, java.util.Map)
038 */
039 public final class FormalParameter {
040
041 /** The method the parameter belongs to. */
042 private final Method method;
043
044 /** The position of the formal parameter within the methods parameter list. */
045 private final int position;
046
047 /**
048 * Create new formal parameter. This is called from
049 * {@link ReflectionUtils#getFormalParameters(Method)}.
050 */
051 /* package */FormalParameter(Method method, int position) {
052 this.method = method;
053 this.position = position;
054 }
055
056 /** Get the method that declares this formal parameter. */
057 public Method getMethod() {
058 return method;
059 }
060
061 /**
062 * Get parameter type.
063 */
064 public Class<?> getType() {
065 return method.getParameterTypes()[position];
066 }
067
068 /**
069 * Get generic parameter type.
070 */
071 public Type getGenericType() {
072 return method.getGenericParameterTypes()[position];
073 }
074
075 /**
076 * Get parameter annotations.
077 */
078 public Annotation[] getAnnotations() {
079 Annotation[][] annotations = method.getParameterAnnotations();
080 return annotations[position];
081 }
082
083 /**
084 * Get the position of the formal parameter within the methods parameter
085 * list.
086 */
087 public int getPosition() {
088 return position;
089 }
090
091 /**
092 * The hashcode is computed as the exclusive-or of the method's hashcode and
093 * (position+1).
094 */
095 @Override
096 public int hashCode() {
097 return method.hashCode() ^ (position + 1);
098 }
099
100 /**
101 * Returns this element's annotation for the specified type if such an
102 * annotation is present, else <code>null</code>.
103 */
104 @SuppressWarnings("unchecked")
105 public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
106 if (annotationClass == null)
107 throw new NullPointerException();
108
109 for (Annotation annotation : getAnnotations()) {
110 if (annotation.annotationType().equals(annotationClass)) {
111 return (A) annotation;
112 }
113 }
114
115 return null;
116 }
117
118 /**
119 * Returns <code>true</code> if an annotation of the specified type is
120 * defined for this formal parameter.
121 */
122 public boolean isAnnotationPresent(
123 Class<? extends Annotation> annotationClass) {
124 if (annotationClass == null)
125 throw new NullPointerException();
126
127 return getAnnotation(annotationClass) != null;
128 }
129
130 /**
131 * Two formal parameters are equal if their declaring methods and their
132 * position within the formal parameter list are equal.
133 */
134 @Override
135 public boolean equals(Object object) {
136 if (object == null || !(object instanceof FormalParameter)) {
137 return false;
138 }
139
140 if (object == this) {
141 return true;
142 }
143
144 FormalParameter otherFormalParameter = (FormalParameter) object;
145
146 return method.equals(otherFormalParameter.method)
147 && (position == otherFormalParameter.position);
148 }
149
150 /**
151 * Returns method name, position and type.
152 */
153 @Override
154 public String toString() {
155 return "Formal parameter #" + position + " of method '"
156 + method.getName() + "' (type: '" + getType().getName() + "')";
157 }
158 }