001/* $Id: MethodArgument.java 992060 2010-09-02 19:09:47Z simonetripodi $
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements.  See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License.  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 */
018package org.apache.commons.digester.annotations.reflect;
019
020import java.lang.annotation.Annotation;
021import java.lang.reflect.AnnotatedElement;
022
023/**
024 * Class to supply the missing Java {@code AnnotatedElement} for method
025 * arguments.
026 *
027 * @since 2.1
028 */
029public final class MethodArgument implements AnnotatedElement {
030
031    /**
032     * The method argument index.
033     */
034    private final int index;
035
036    /**
037     * The method argument type.
038     */
039    private final Class<?> parameterType;
040
041    /**
042     * The method argument annotations.
043     */
044    private final Annotation[] annotations;
045
046    /**
047     * Creates a new method argument as {@code AnnotatedElement}.
048     *
049     * @param index the method argument index.
050     * @param parameterType the method argument type.
051     * @param annotations the method argument annotations.
052     */
053    public MethodArgument(int index, Class<?> parameterType, Annotation[] annotations) {
054        this.index = index;
055        this.parameterType = parameterType;
056        this.annotations = annotations;
057    }
058
059    /**
060     * Returns the method argument index.
061     *
062     * @return the method argument index.
063     */
064    public int getIndex() {
065        return this.index;
066    }
067
068    /**
069     * Returns the method argument type.
070     *
071     * @return the method argument type.
072     */
073    public Class<?> getParameterType() {
074        return this.parameterType;
075    }
076
077    /**
078     * {@inheritDoc}
079     */
080    public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
081        for (Annotation annotation : this.annotations) {
082            if (annotationType == annotation.annotationType()) {
083                return annotationType.cast(annotation);
084            }
085        }
086        return null;
087    }
088
089    /**
090     * {@inheritDoc}
091     */
092    public Annotation[] getAnnotations() {
093        return this.getAnnotationsArrayCopy();
094    }
095
096    /**
097     * {@inheritDoc}
098     */
099    public Annotation[] getDeclaredAnnotations() {
100        return this.getAnnotationsArrayCopy();
101    }
102
103    /**
104     * Returns an annotations array, copy of the declared annotations in this
105     * method argument.
106     *
107     * @return an annotations array, copy of the declared annotations in this
108     *         method argument.
109     */
110    private Annotation[] getAnnotationsArrayCopy() {
111        Annotation[] annotations = new Annotation[this.annotations.length];
112        System.arraycopy(this.annotations, 0, annotations, 0, annotations.length);
113        return annotations;
114    }
115
116    /**
117     * {@inheritDoc}
118     */
119    public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
120        for (Annotation annotation : this.annotations) {
121            if (annotationType == annotation.annotationType()) {
122                return true;
123            }
124        }
125        return false;
126    }
127
128}