001/* 002 * Copyright (C) 2012 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.reflect; 018 019import static com.google.common.base.Preconditions.checkNotNull; 020 021import com.google.common.annotations.Beta; 022import com.google.common.collect.FluentIterable; 023import com.google.common.collect.ImmutableList; 024 025import java.lang.annotation.Annotation; 026import java.lang.reflect.AnnotatedElement; 027 028import javax.annotation.Nullable; 029 030/** 031 * Represents a method or constructor parameter. 032 * 033 * @author Ben Yu 034 * @since 14.0 035 */ 036@Beta 037public final class Parameter implements AnnotatedElement { 038 039 private final Invokable<?, ?> declaration; 040 private final int position; 041 private final TypeToken<?> type; 042 private final ImmutableList<Annotation> annotations; 043 044 Parameter( 045 Invokable<?, ?> declaration, 046 int position, 047 TypeToken<?> type, 048 Annotation[] annotations) { 049 this.declaration = declaration; 050 this.position = position; 051 this.type = type; 052 this.annotations = ImmutableList.copyOf(annotations); 053 } 054 055 /** Returns the type of the parameter. */ 056 public TypeToken<?> getType() { 057 return type; 058 } 059 060 /** Returns the {@link Invokable} that declares this parameter. */ 061 public Invokable<?, ?> getDeclaringInvokable() { 062 return declaration; 063 } 064 065 @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) { 066 return getAnnotation(annotationType) != null; 067 } 068 069 @Override 070 @Nullable 071 public <A extends Annotation> A getAnnotation(Class<A> annotationType) { 072 checkNotNull(annotationType); 073 for (Annotation annotation : annotations) { 074 if (annotationType.isInstance(annotation)) { 075 return annotationType.cast(annotation); 076 } 077 } 078 return null; 079 } 080 081 @Override public Annotation[] getAnnotations() { 082 return getDeclaredAnnotations(); 083 } 084 085 /** 086 * @since 18.0 087 */ 088 // @Override on JDK8 089 public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) { 090 return getDeclaredAnnotationsByType(annotationType); 091 } 092 093 /** 094 * @since 18.0 095 */ 096 // @Override on JDK8 097 @Override public Annotation[] getDeclaredAnnotations() { 098 return annotations.toArray(new Annotation[annotations.size()]); 099 } 100 101 /** 102 * @since 18.0 103 */ 104 // @Override on JDK8 105 @Nullable 106 public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationType) { 107 checkNotNull(annotationType); 108 return FluentIterable.from(annotations) 109 .filter(annotationType) 110 .first() 111 .orNull(); 112 } 113 114 /** 115 * @since 18.0 116 */ 117 // @Override on JDK8 118 public <A extends Annotation> A[] 119 getDeclaredAnnotationsByType(Class<A> annotationType) { 120 return FluentIterable.from(annotations) 121 .filter(annotationType) 122 .toArray(annotationType); 123 } 124 125 @Override public boolean equals(@Nullable Object obj) { 126 if (obj instanceof Parameter) { 127 Parameter that = (Parameter) obj; 128 return position == that.position && declaration.equals(that.declaration); 129 } 130 return false; 131 } 132 133 @Override public int hashCode() { 134 return position; 135 } 136 137 @Override public String toString() { 138 return type + " arg" + position; 139 } 140}