| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| AnnotationUtility |
|
| 3.857142857142857;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 | } |