001    /*
002     * Copyright 2002-2006 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * 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, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    
017    package org.springframework.richclient.util;
018    
019    import java.lang.annotation.Annotation;
020    import java.util.Collection;
021    import java.util.Map;
022    import java.util.LinkedHashMap;
023    import java.beans.PropertyDescriptor;
024    
025    /**
026     * General utility methods for working with annotations.
027     *
028     * @author andy
029     * @since May 8, 2006 4:57:20 PM
030     */
031    public class AnnotationUtils {
032    
033        /**
034         * Retrieves all annotations present on the specified property.  This
035         * method will gather the annotations present on both the getter and the
036         * setter of the property.  If a particular Annotation type appears on
037         * both the getter and setter, then the instance appearing on the Getter
038         * will override (replace) the instance appearing on the Setter.
039         *
040         * @param property
041         * @return collection containing all annotations present on the specified
042         *         property.  This method will never return <code>null</code>,
043         *         but will return an empty Collection if no annotations appear
044         *         on the property.
045         */
046        public static Collection<Annotation> getAnnotationsFor(final PropertyDescriptor property) {
047            // The Map is used to satisfy the contract of this method: that
048            // annotations on the getter replace annotations of the same type on
049            // the setter.  The equals and hashcode implementation on annotations
050            // prevent us from using a HashSet, as we want to compare based on
051            // type, not on type and content.
052            // LinkedHashMap is used to return the annotations in the same order
053            // they are declared.
054            final Map<Class<?>,Annotation> collector = new LinkedHashMap<Class<?>,Annotation>();
055            
056            if(property.getWriteMethod() != null) {
057                for(final Annotation annotation : property.getWriteMethod().getAnnotations()) {
058                    collector.put(annotation.annotationType(), annotation);
059                }
060            }
061            if(property.getReadMethod() != null) {
062                for(final Annotation annotation : property.getReadMethod().getAnnotations()) {
063                    collector.put(annotation.annotationType(), annotation);
064                }
065            }
066            
067            return collector.values();
068        }
069    }