001    package org.apache.commons.digester3.annotations.reflect;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import static java.lang.System.arraycopy;
023    
024    import java.lang.annotation.Annotation;
025    import java.lang.reflect.AnnotatedElement;
026    
027    /**
028     * Class to supply the missing Java {@code AnnotatedElement} for method arguments.
029     * 
030     * @since 2.1
031     */
032    public final class MethodArgument
033        implements AnnotatedElement
034    {
035    
036        /**
037         * The method argument index.
038         */
039        private final int index;
040    
041        /**
042         * The method argument type.
043         */
044        private final Class<?> parameterType;
045    
046        /**
047         * The method argument annotations.
048         */
049        private final Annotation[] annotations;
050    
051        /**
052         * Creates a new method argument as {@code AnnotatedElement}.
053         * 
054         * @param index the method argument index.
055         * @param parameterType the method argument type.
056         * @param annotations the method argument annotations.
057         */
058        public MethodArgument( int index, Class<?> parameterType, Annotation[] annotations )
059        {
060            if ( parameterType == null )
061            {
062                throw new IllegalArgumentException( "Argument 'parameterType' must be not null" );
063            }
064            if ( annotations == null )
065            {
066                throw new IllegalArgumentException( "Argument 'annotations' must be not null" );
067            }
068    
069            this.index = index;
070            this.parameterType = parameterType;
071            this.annotations = new Annotation[annotations.length];
072    
073            arraycopy( annotations, 0, this.annotations, 0, annotations.length );
074        }
075    
076        /**
077         * Returns the method argument index.
078         * 
079         * @return the method argument index.
080         */
081        public int getIndex()
082        {
083            return this.index;
084        }
085    
086        /**
087         * Returns the method argument type.
088         * 
089         * @return the method argument type.
090         */
091        public Class<?> getParameterType()
092        {
093            return this.parameterType;
094        }
095    
096        /**
097         * {@inheritDoc}
098         */
099        public <T extends Annotation> T getAnnotation( Class<T> annotationType )
100        {
101            for ( Annotation annotation : this.annotations )
102            {
103                if ( annotationType == annotation.annotationType() )
104                {
105                    return annotationType.cast( annotation );
106                }
107            }
108            return null;
109        }
110    
111        /**
112         * {@inheritDoc}
113         */
114        public Annotation[] getAnnotations()
115        {
116            return this.getAnnotationsArrayCopy();
117        }
118    
119        /**
120         * {@inheritDoc}
121         */
122        public Annotation[] getDeclaredAnnotations()
123        {
124            return this.getAnnotationsArrayCopy();
125        }
126    
127        /**
128         * Returns an annotations array, copy of the declared annotations in this method argument.
129         * 
130         * @return an annotations array, copy of the declared annotations in this method argument.
131         */
132        private Annotation[] getAnnotationsArrayCopy()
133        {
134            Annotation[] annotations = new Annotation[this.annotations.length];
135            System.arraycopy( this.annotations, 0, annotations, 0, annotations.length );
136            return annotations;
137        }
138    
139        /**
140         * {@inheritDoc}
141         */
142        public boolean isAnnotationPresent( Class<? extends Annotation> annotationType )
143        {
144            for ( Annotation annotation : this.annotations )
145            {
146                if ( annotationType == annotation.annotationType() )
147                {
148                    return true;
149                }
150            }
151            return false;
152        }
153    
154    }