/* * JBoss, Home of Professional Open Source * Copyright 2011, Red Hat, Inc. and/or its affiliates, and individual * contributors by the @authors tag. See the copyright.txt in the * distribution for a full listing of individual contributors. * * 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.jboss.solder.reflection.annotated; 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 org.jboss.solder.reflection.Reflections; /** * An implementation of Member for parameters * * @author pmuir */ abstract class Parameter<X> implements AnnotatedElement { static <X> Parameter<X> create(Member declaringMember, int position) { if (declaringMember instanceof Method) { return new MethodParameter<X>((Method) declaringMember, position); } else if (declaringMember instanceof Constructor<?>) { return new ConstructorParameter<X>(Reflections.<Constructor<X>>cast(declaringMember), position); } else { throw new IllegalArgumentException("Can only process members of type Method and Constructor, cannot process " + declaringMember); } } private static class MethodParameter<X> extends Parameter<X> { private final Method declaringMethod; private MethodParameter(Method declaringMethod, int position) { super(position); this.declaringMethod = declaringMethod; } @Override public Method getDeclaringMember() { return declaringMethod; } public Annotation[] getAnnotations() { if (declaringMethod.getParameterAnnotations().length > getPosition()) { return declaringMethod.getParameterAnnotations()[getPosition()]; } else { return Reflections.EMPTY_ANNOTATION_ARRAY; } } @Override public Type getBaseType() { if (declaringMethod.getGenericParameterTypes().length > getPosition()) { return declaringMethod.getGenericParameterTypes()[getPosition()]; } else { return declaringMethod.getParameterTypes()[getPosition()]; } } } private static class ConstructorParameter<X> extends Parameter<X> { private final Constructor<X> declaringConstructor; private ConstructorParameter(Constructor<X> declaringConstructor, int position) { super(position); this.declaringConstructor = declaringConstructor; } @Override public Constructor<X> getDeclaringMember() { return declaringConstructor; } public Annotation[] getAnnotations() { if (declaringConstructor.getParameterAnnotations().length > getPosition()) { return declaringConstructor.getParameterAnnotations()[getPosition()]; } else { return Reflections.EMPTY_ANNOTATION_ARRAY; } } @Override public Type getBaseType() { if (declaringConstructor.getGenericParameterTypes().length > getPosition()) { return declaringConstructor.getGenericParameterTypes()[getPosition()]; } else { return declaringConstructor.getParameterTypes()[getPosition()]; } } } private final int position; Parameter(int position) { this.position = position; } public abstract Member getDeclaringMember(); public int getPosition() { return position; } @Override public int hashCode() { int hash = 1; hash = hash * 31 + getDeclaringMember().hashCode(); hash = hash * 31 + Integer.valueOf(position).hashCode(); return hash; } @Override public boolean equals(Object obj) { if (obj instanceof Parameter<?>) { Parameter<?> that = (Parameter<?>) obj; return this.getDeclaringMember().equals(that.getDeclaringMember()) && this.getPosition() == that.getPosition(); } else { return false; } } public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { for (Annotation annotation : getAnnotations()) { if (annotation.annotationType().equals(annotationClass)) { return annotationClass.cast(annotation); } } return null; } public Annotation[] getDeclaredAnnotations() { return getAnnotations(); } public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { return getAnnotation(annotationClass) != null; } public abstract Type getBaseType(); }