Home | History | Annotate | Download | only in api
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.tools.lint.detector.api;
     18 
     19 import com.android.annotations.NonNull;
     20 import com.android.annotations.Nullable;
     21 import com.android.tools.lint.client.api.Configuration;
     22 import com.google.common.annotations.Beta;
     23 
     24 import java.util.EnumSet;
     25 
     26 
     27 /**
     28  * An issue is a potential bug in an Android application. An issue is discovered
     29  * by a {@link Detector}, and has an associated {@link Severity}.
     30  * <p>
     31  * Issues and detectors are separate classes because a detector can discover
     32  * multiple different issues as it's analyzing code, and we want to be able to
     33  * different severities for different issues, the ability to suppress one but
     34  * not other issues from the same detector, and so on.
     35  * <p/>
     36  * <b>NOTE: This is not a public or final API; if you rely on this be prepared
     37  * to adjust your code for the next tools release.</b>
     38  */
     39 @Beta
     40 public final class Issue implements Comparable<Issue> {
     41     private final String mId;
     42     private final String mDescription;
     43     private final String mExplanation;
     44     private final Category mCategory;
     45     private final int mPriority;
     46     private final Severity mSeverity;
     47     private String mMoreInfoUrl;
     48     private boolean mEnabledByDefault = true;
     49     private final EnumSet<Scope> mScope;
     50     private final Class<? extends Detector> mClass;
     51 
     52     // Use factory methods
     53     private Issue(
     54             @NonNull String id,
     55             @NonNull String description,
     56             @NonNull String explanation,
     57             @NonNull Category category,
     58             int priority,
     59             @NonNull Severity severity,
     60             @NonNull Class<? extends Detector> detectorClass,
     61             @NonNull EnumSet<Scope> scope) {
     62         super();
     63         mId = id;
     64         mDescription = description;
     65         mExplanation = explanation;
     66         mCategory = category;
     67         mPriority = priority;
     68         mSeverity = severity;
     69         mClass = detectorClass;
     70         mScope = scope;
     71     }
     72 
     73     /**
     74      * Creates a new issue
     75      *
     76      * @param id the fixed id of the issue
     77      * @param description the quick summary of the issue (one line)
     78      * @param explanation a full explanation of the issue, with suggestions for
     79      *            how to fix it
     80      * @param category the associated category, if any
     81      * @param priority the priority, a number from 1 to 10 with 10 being most
     82      *            important/severe
     83      * @param severity the default severity of the issue
     84      * @param detectorClass the class of the detector to find this issue
     85      * @param scope the scope of files required to analyze this issue
     86      * @return a new {@link Issue}
     87      */
     88     @NonNull
     89     public static Issue create(
     90             @NonNull String id,
     91             @NonNull String description,
     92             @NonNull String explanation,
     93             @NonNull Category category,
     94             int priority,
     95             @NonNull Severity severity,
     96             @NonNull Class<? extends Detector> detectorClass,
     97             @NonNull EnumSet<Scope> scope) {
     98         return new Issue(id, description, explanation, category, priority, severity,
     99                 detectorClass, scope);
    100     }
    101 
    102     /**
    103      * Returns the unique id of this issue. These should not change over time
    104      * since they are used to persist the names of issues suppressed by the user
    105      * etc. It is typically a single camel-cased word.
    106      *
    107      * @return the associated fixed id, never null and always unique
    108      */
    109     @NonNull
    110     public String getId() {
    111         return mId;
    112     }
    113 
    114     /**
    115      * Briefly (one line) describes the kinds of checks performed by this rule
    116      *
    117      * @return a quick summary of the issue, never null
    118      */
    119     @NonNull
    120     public String getDescription() {
    121         return mDescription;
    122     }
    123 
    124     /**
    125      * Describes the error found by this rule, e.g.
    126      * "Buttons must define contentDescriptions". Preferably the explanation
    127      * should also contain a description of how the problem should be solved.
    128      * Additional info can be provided via {@link #getMoreInfo()}.
    129      *
    130      * @return an explanation of the issue, never null.
    131      */
    132     @NonNull
    133     public String getExplanation() {
    134         return mExplanation;
    135     }
    136 
    137     /**
    138      * The primary category of the issue
    139      *
    140      * @return the primary category of the issue, never null
    141      */
    142     @NonNull
    143     public Category getCategory() {
    144         return mCategory;
    145     }
    146 
    147     /**
    148      * Returns a priority, in the range 1-10, with 10 being the most severe and
    149      * 1 the least
    150      *
    151      * @return a priority from 1 to 10
    152      */
    153     public int getPriority() {
    154         return mPriority;
    155     }
    156 
    157     /**
    158      * Returns the default severity of the issues found by this detector (some
    159      * tools may allow the user to specify custom severities for detectors).
    160      * <p>
    161      * Note that even though the normal way for an issue to be disabled is for
    162      * the {@link Configuration} to return {@link Severity#IGNORE}, there is a
    163      * {@link #isEnabledByDefault()} method which can be used to turn off issues
    164      * by default. This is done rather than just having the severity as the only
    165      * attribute on the issue such that an issue can be configured with an
    166      * appropriate severity (such as {@link Severity#ERROR}) even when issues
    167      * are disabled by default for example because they are experimental or not
    168      * yet stable.
    169      *
    170      * @return the severity of the issues found by this detector
    171      */
    172     @NonNull
    173     public Severity getDefaultSeverity() {
    174         return mSeverity;
    175     }
    176 
    177     /**
    178      * Returns a link (a URL string) to more information, or null
    179      *
    180      * @return a link to more information, or null
    181      */
    182     @Nullable
    183     public String getMoreInfo() {
    184         return mMoreInfoUrl;
    185     }
    186 
    187     /**
    188      * Returns whether this issue should be enabled by default, unless the user
    189      * has explicitly disabled it.
    190      *
    191      * @return true if this issue should be enabled by default
    192      */
    193     public boolean isEnabledByDefault() {
    194         return mEnabledByDefault;
    195     }
    196 
    197     /**
    198      * Returns the scope required to analyze the code to detect this issue.
    199      * This is determined by the detectors which reports the issue.
    200      *
    201      * @return the required scope
    202      */
    203     @NonNull
    204     public EnumSet<Scope> getScope() {
    205         return mScope;
    206     }
    207 
    208     /**
    209      * Sorts the detectors alphabetically by id. This is intended to make it
    210      * convenient to store settings for detectors in a fixed order. It is not
    211      * intended as the order to be shown to the user; for that, a tool embedding
    212      * lint might consider the priorities, categories, severities etc of the
    213      * various detectors.
    214      *
    215      * @param other the {@link Issue} to compare this issue to
    216      */
    217     @Override
    218     public int compareTo(@NonNull Issue other) {
    219         return getId().compareTo(other.getId());
    220     }
    221 
    222     /**
    223      * Sets a more info URL string
    224      *
    225      * @param moreInfoUrl url string
    226      * @return this, for constructor chaining
    227      */
    228     @NonNull
    229     public Issue setMoreInfo(@NonNull String moreInfoUrl) {
    230         mMoreInfoUrl = moreInfoUrl;
    231         return this;
    232     }
    233 
    234     /**
    235      * Sets whether this issue is enabled by default.
    236      *
    237      * @param enabledByDefault whether the issue should be enabled by default
    238      * @return this, for constructor chaining
    239      */
    240     @NonNull
    241     public Issue setEnabledByDefault(boolean enabledByDefault) {
    242         mEnabledByDefault = enabledByDefault;
    243         return this;
    244     }
    245 
    246     /**
    247      * Returns the class of the detector to use to find this issue
    248      *
    249      * @return the class of the detector to use to find this issue
    250      */
    251     @NonNull
    252     public Class<? extends Detector> getDetectorClass() {
    253         return mClass;
    254     }
    255 
    256     @Override
    257     public String toString() {
    258         return mId;
    259     }
    260 }
    261