001/*
002 * SonarQube
003 * Copyright (C) 2009-2017 SonarSource SA
004 * mailto:info AT sonarsource DOT com
005 *
006 * This program is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019 */
020package org.sonar.api.utils;
021
022import org.apache.commons.lang.ClassUtils;
023
024import java.lang.annotation.Annotation;
025import java.util.List;
026
027/**
028 * A utility class for annotations
029 *
030 * @since 1.11
031 */
032public final class AnnotationUtils {
033
034  private AnnotationUtils() {
035  }
036
037  /**
038   * Searches for a class annotation. All inheritance tree is analysed.
039   * 
040   * @since 3.1
041   */
042  public static <A extends Annotation> A getAnnotation(Object objectOrClass, Class<A> annotationClass) {
043    Class<?> initialClass = objectOrClass instanceof Class<?> ? (Class<?>) objectOrClass : objectOrClass.getClass();
044    
045    for (Class<?> aClass = initialClass; aClass != null; aClass = aClass.getSuperclass()) {
046      A result = aClass.getAnnotation(annotationClass);
047      if (result != null) {
048        return result;
049      }
050    }
051
052    for (Class<?> anInterface : (List<Class<?>>) ClassUtils.getAllInterfaces(initialClass)) {
053      A result = anInterface.getAnnotation(annotationClass);
054      if (result != null) {
055        return result;
056      }
057    }
058
059    return null;
060  }
061
062  /**
063   * Searches for a class annotation. All inheritance tree is analysed.
064   * 
065   * @deprecated  As of 3.1, replaced by {@link #getAnnotation(Object,Class)}
066   */
067  @Deprecated
068  public static <A> A getClassAnnotation(Object object, Class<A> annotationClass) {
069    return (A) getAnnotation(object, (Class<? extends Annotation>) annotationClass);
070  }
071}