Coverage Report - com.puppycrawl.tools.checkstyle.api.AnnotationUtility
 
Classes in this File Line Coverage Branch Coverage Complexity
AnnotationUtility
60%
20/33
60%
18/30
3.857
 
 1  
 ////////////////////////////////////////////////////////////////////////////////
 2  
 // checkstyle: Checks Java source code for adherence to a set of rules.
 3  
 // Copyright (C) 2001-2014  Oliver Burn
 4  
 //
 5  
 // This library is free software; you can redistribute it and/or
 6  
 // modify it under the terms of the GNU Lesser General Public
 7  
 // License as published by the Free Software Foundation; either
 8  
 // version 2.1 of the License, or (at your option) any later version.
 9  
 //
 10  
 // This library is distributed in the hope that it will be useful,
 11  
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  
 // Lesser General Public License for more details.
 14  
 //
 15  
 // You should have received a copy of the GNU Lesser General Public
 16  
 // License along with this library; if not, write to the Free Software
 17  
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 18  
 ////////////////////////////////////////////////////////////////////////////////
 19  
 package com.puppycrawl.tools.checkstyle.api;
 20  
 
 21  
 
 22  
 /**
 23  
  * Contains utility methods designed to work with annotations.
 24  
  *
 25  
  * @author Travis Schneeberger
 26  
  */
 27  
 public final class AnnotationUtility
 28  
 {
 29  
     /**
 30  
      * private utility constructor.
 31  
      * @throws UnsupportedOperationException if called
 32  
      */
 33  
     private AnnotationUtility()
 34  0
     {
 35  0
         throw new UnsupportedOperationException("do not instantiate.");
 36  
     }
 37  
 
 38  
     /**
 39  
      * Checks to see if the AST is annotated with
 40  
      * the passed in annotation.
 41  
      *
 42  
      * <p>
 43  
      * This method will not look for imports or package
 44  
      * statements to detect the passed in annotation.
 45  
      * </p>
 46  
      *
 47  
      * <p>
 48  
      * To check if an AST contains a passed in annotation
 49  
      * taking into account fully-qualified names
 50  
      * (ex: java.lang.Override, Override)
 51  
      * this method will need to be called twice. Once for each
 52  
      * name given.
 53  
      * </p>
 54  
      *
 55  
      * @param aAST the current node
 56  
      * @param aAnnotation the annotation name to check for
 57  
      * @return true if contains the annotation
 58  
      * @throws NullPointerException if the aAST or
 59  
      * aAnnotation is null
 60  
      */
 61  
     public static boolean containsAnnotation(final DetailAST aAST,
 62  
         String aAnnotation)
 63  
     {
 64  120
         return AnnotationUtility.getAnnotation(aAST, aAnnotation) != null;
 65  
     }
 66  
 
 67  
     /**
 68  
      * Checks to see if the AST is annotated with
 69  
      * any annotation.
 70  
      *
 71  
      * @param aAST the current node
 72  
      * @return true if contains an annotation
 73  
      * @throws NullPointerException if the aAST is null
 74  
      */
 75  
     public static boolean containsAnnotation(final DetailAST aAST)
 76  
     {
 77  3
         final DetailAST holder = AnnotationUtility.getAnnotationHolder(aAST);
 78  3
         return holder != null && holder.branchContains(TokenTypes.ANNOTATION);
 79  
     }
 80  
 
 81  
     /**
 82  
      * Gets the AST that holds a series of annotations for the
 83  
      * potentially annotated AST.  Returns <code>null</code>
 84  
      * the passed in AST is not have an Annotation Holder.
 85  
      *
 86  
      * @param aAST the current node
 87  
      * @return the Annotation Holder
 88  
      * @throws NullPointerException if the aAST is null
 89  
      */
 90  
     public static DetailAST getAnnotationHolder(DetailAST aAST)
 91  
     {
 92  669
         if (aAST == null) {
 93  0
             throw new NullPointerException("the aAST is null");
 94  
         }
 95  
 
 96  
         final DetailAST annotationHolder;
 97  
 
 98  669
         if (aAST.getType() == TokenTypes.ENUM_CONSTANT_DEF
 99  
             || aAST.getType() == TokenTypes.PACKAGE_DEF)
 100  
         {
 101  25
             annotationHolder = aAST.findFirstToken(TokenTypes.ANNOTATIONS);
 102  
         }
 103  
         else {
 104  644
             annotationHolder = aAST.findFirstToken(TokenTypes.MODIFIERS);
 105  
         }
 106  
 
 107  669
         return annotationHolder;
 108  
     }
 109  
 
 110  
     /**
 111  
      * Checks to see if the AST is annotated with
 112  
      * the passed in annotation and return the AST
 113  
      * representing that annotation.
 114  
      *
 115  
      * <p>
 116  
      * This method will not look for imports or package
 117  
      * statements to detect the passed in annotation.
 118  
      * </p>
 119  
      *
 120  
      * <p>
 121  
      * To check if an AST contains a passed in annotation
 122  
      * taking into account fully-qualified names
 123  
      * (ex: java.lang.Override, Override)
 124  
      * this method will need to be called twice. Once for each
 125  
      * name given.
 126  
      * </p>
 127  
      *
 128  
      * @param aAST the current node
 129  
      * @param aAnnotation the annotation name to check for
 130  
      * @return the AST representing that annotation
 131  
      * @throws NullPointerException if the aAST or
 132  
      * aAnnotation is null
 133  
      */
 134  
     public static DetailAST getAnnotation(final DetailAST aAST,
 135  
         String aAnnotation)
 136  
     {
 137  666
         if (aAST == null) {
 138  0
             throw new NullPointerException("the aAST is null");
 139  
         }
 140  
 
 141  666
         if (aAnnotation == null) {
 142  0
             throw new NullPointerException("the aAnnotation is null");
 143  
         }
 144  
 
 145  666
         if (aAnnotation.trim().length() == 0) {
 146  0
             throw new IllegalArgumentException("the aAnnotation"
 147  
                 + "is empty or spaces");
 148  
         }
 149  
 
 150  666
         final DetailAST holder = AnnotationUtility.getAnnotationHolder(aAST);
 151  
 
 152  666
         for (DetailAST child = holder.getFirstChild();
 153  1176
             child != null; child = child.getNextSibling())
 154  
         {
 155  637
             if (child.getType() == TokenTypes.ANNOTATION) {
 156  447
                 final DetailAST at = child.getFirstChild();
 157  447
                 final String aName =
 158  
                     FullIdent.createFullIdent(at.getNextSibling()).getText();
 159  447
                 if (aAnnotation.equals(aName)) {
 160  382
                     return child;
 161  
                 }
 162  
             }
 163  
         }
 164  
 
 165  284
         return null;
 166  
     }
 167  
 
 168  
     /**
 169  
      * Checks to see what the passed in AST (representing
 170  
      * an annotation) is annotating.
 171  
      *
 172  
      * @param aAST the AST representing an annotation.
 173  
      * @return the AST the annotation is annotating.
 174  
      * @throws NullPointerException if the aAST is null
 175  
      * @throws IllegalArgumentException if the aAST is not
 176  
      * an {@link TokenTypes#ANNOTATION}
 177  
      */
 178  
     public static DetailAST annotatingWhat(DetailAST aAST)
 179  
     {
 180  0
         if (aAST == null) {
 181  0
             throw new NullPointerException("the aAST is null");
 182  
         }
 183  
 
 184  0
         if (aAST.getType() != TokenTypes.ANNOTATION) {
 185  0
             throw new IllegalArgumentException(
 186  
                 "The aAST is not an annotation. AST: " + aAST);
 187  
         }
 188  
 
 189  0
         return aAST.getParent().getParent();
 190  
     }
 191  
 
 192  
     /**
 193  
      * Checks to see if the passed in AST (representing
 194  
      * an annotation) is annotating the passed in type.
 195  
      * @param aAST the AST representing an annotation
 196  
      * @param aTokenType the passed in type
 197  
      * @return true if the annotation is annotating a type
 198  
      * equal to the passed in type
 199  
      * @throws NullPointerException if the aAST is null
 200  
      * @throws IllegalArgumentException if the aAST is not
 201  
      * an {@link TokenTypes#ANNOTATION}
 202  
      */
 203  
     public static boolean isAnnotatingType(DetailAST aAST, int aTokenType)
 204  
     {
 205  0
         final DetailAST ast = AnnotationUtility.annotatingWhat(aAST);
 206  0
         return ast.getType() == aTokenType;
 207  
     }
 208  
 }