1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
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 package com.android.ide.eclipse.adt.internal.lint;
17 
18 import com.android.annotations.NonNull;
19 import com.android.annotations.Nullable;
20 import com.android.ide.eclipse.adt.AdtPlugin;
21 import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
22 import com.android.tools.lint.client.api.Configuration;
23 import com.android.tools.lint.client.api.IssueRegistry;
24 import com.android.tools.lint.detector.api.Context;
25 import com.android.tools.lint.detector.api.Issue;
26 import com.android.tools.lint.detector.api.Location;
27 import com.android.tools.lint.detector.api.Severity;
28 
29 import org.eclipse.jface.preference.IPreferenceStore;
30 
31 import java.util.ArrayList;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 
37 /** Global (non-project-specific) configuration for Lint in Eclipse */
38 class GlobalLintConfiguration extends Configuration {
39     private static final GlobalLintConfiguration sInstance = new GlobalLintConfiguration();
40 
41     private Map<Issue, Severity> mSeverities;
42     private boolean mBulkEditing;
43 
GlobalLintConfiguration()44     private GlobalLintConfiguration() {
45     }
46 
47     /**
48      * Obtain a reference to the singleton
49      *
50      * @return the singleton configuration
51      */
52     @NonNull
get()53     public static GlobalLintConfiguration get() {
54         return sInstance;
55     }
56 
57     @Override
getSeverity(@onNull Issue issue)58     public Severity getSeverity(@NonNull Issue issue) {
59         if (mSeverities == null) {
60             IssueRegistry registry = EclipseLintClient.getRegistry();
61             mSeverities = new HashMap<Issue, Severity>();
62             IPreferenceStore store = getStore();
63             String assignments = store.getString(AdtPrefs.PREFS_LINT_SEVERITIES);
64             if (assignments != null && assignments.length() > 0) {
65                 for (String assignment : assignments.split(",")) { //$NON-NLS-1$
66                     String[] s = assignment.split("="); //$NON-NLS-1$
67                     if (s.length == 2) {
68                         Issue d = registry.getIssue(s[0]);
69                         if (d != null) {
70                             Severity severity = Severity.valueOf(s[1]);
71                             if (severity != null) {
72                                 mSeverities.put(d, severity);
73                             }
74                         }
75                     }
76                 }
77             }
78         }
79 
80         Severity severity = mSeverities.get(issue);
81         if (severity != null) {
82             return severity;
83         }
84 
85         if (!issue.isEnabledByDefault()) {
86             return Severity.IGNORE;
87         }
88 
89         return issue.getDefaultSeverity();
90     }
91 
getStore()92     private IPreferenceStore getStore() {
93         IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
94         return store;
95     }
96 
97     @Override
ignore(@onNull Context context, @NonNull Issue issue, @Nullable Location location, @NonNull String message)98     public void ignore(@NonNull Context context, @NonNull Issue issue,
99             @Nullable Location location, @NonNull String message) {
100         throw new UnsupportedOperationException(
101                 "Can't ignore() in global configurations"); //$NON-NLS-1$
102     }
103 
104     @Override
setSeverity(@onNull Issue issue, @Nullable Severity severity)105     public void setSeverity(@NonNull Issue issue, @Nullable Severity severity) {
106         if (mSeverities == null) {
107             // Force initialization
108             getSeverity(issue);
109         }
110 
111         if (severity == null) {
112             mSeverities.remove(issue);
113         } else {
114             mSeverities.put(issue, severity);
115         }
116 
117         if (!mBulkEditing) {
118             setSeverities(mSeverities);
119         }
120     }
121 
122     /**
123      * Sets the custom severities for the given issues, in bulk.
124      *
125      * @param severities a map from detector to severity to use from now on
126      * @return true if something changed from the current settings
127      */
setSeverities(Map<Issue, Severity> severities)128     private boolean setSeverities(Map<Issue, Severity> severities) {
129         mSeverities = severities;
130 
131         String value = "";
132         if (severities.size() > 0) {
133             List<Issue> sortedKeys = new ArrayList<Issue>(severities.keySet());
134             Collections.sort(sortedKeys);
135 
136             StringBuilder sb = new StringBuilder(severities.size() * 20);
137             for (Issue issue : sortedKeys) {
138                 Severity severity = severities.get(issue);
139                 if (severity != issue.getDefaultSeverity()) {
140                     if (sb.length() > 0) {
141                         sb.append(',');
142                     }
143                     sb.append(issue.getId());
144                     sb.append('=');
145                     sb.append(severity.name());
146                 }
147             }
148 
149             value = sb.toString();
150         }
151 
152         IPreferenceStore store = getStore();
153         String previous = store.getString(AdtPrefs.PREFS_LINT_SEVERITIES);
154         boolean changed = !value.equals(previous);
155         if (changed) {
156             if (value.length() == 0) {
157                 store.setToDefault(AdtPrefs.PREFS_LINT_SEVERITIES);
158             } else {
159                 store.setValue(AdtPrefs.PREFS_LINT_SEVERITIES, value);
160             }
161         }
162 
163         return changed;
164     }
165 
166     @Override
startBulkEditing()167     public void startBulkEditing() {
168         mBulkEditing = true;
169     }
170 
171     @Override
finishBulkEditing()172     public void finishBulkEditing() {
173         mBulkEditing = false;
174         setSeverities(mSeverities);
175     }
176 }