aboutsummaryrefslogtreecommitdiffstats
path: root/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultConfiguration.java
diff options
context:
space:
mode:
Diffstat (limited to 'lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultConfiguration.java')
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultConfiguration.java453
1 files changed, 0 insertions, 453 deletions
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultConfiguration.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultConfiguration.java
deleted file mode 100644
index 5a8a973..0000000
--- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultConfiguration.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.lint.client.api;
-
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.tools.lint.detector.api.Context;
-import com.android.tools.lint.detector.api.Issue;
-import com.android.tools.lint.detector.api.Location;
-import com.android.tools.lint.detector.api.Project;
-import com.android.tools.lint.detector.api.Severity;
-import com.google.common.annotations.Beta;
-import com.google.common.io.Closeables;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXParseException;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-
-/**
- * Default implementation of a {@link Configuration} which reads and writes
- * configuration data into {@code lint.xml} in the project directory.
- * <p/>
- * <b>NOTE: This is not a public or final API; if you rely on this be prepared
- * to adjust your code for the next tools release.</b>
- */
-@Beta
-public class DefaultConfiguration extends Configuration {
- private final LintClient mClient;
- private static final String CONFIG_FILE_NAME = "lint.xml"; //$NON-NLS-1$
-
- // Lint XML File
- @NonNull
- private static final String TAG_ISSUE = "issue"; //$NON-NLS-1$
- @NonNull
- private static final String ATTR_ID = "id"; //$NON-NLS-1$
- @NonNull
- private static final String ATTR_SEVERITY = "severity"; //$NON-NLS-1$
- @NonNull
- private static final String ATTR_PATH = "path"; //$NON-NLS-1$
- @NonNull
- private static final String TAG_IGNORE = "ignore"; //$NON-NLS-1$
-
- private final Configuration mParent;
- protected final Project mProject;
- private final File mConfigFile;
- private boolean mBulkEditing;
-
- /** Map from id to list of project-relative paths for suppressed warnings */
- private Map<String, List<String>> mSuppressed;
-
- /**
- * Map from id to custom {@link Severity} override
- */
- private Map<String, Severity> mSeverity;
-
- protected DefaultConfiguration(
- @NonNull LintClient client,
- @Nullable Project project,
- @Nullable Configuration parent,
- @NonNull File configFile) {
- mClient = client;
- mProject = project;
- mParent = parent;
- mConfigFile = configFile;
- }
-
- protected DefaultConfiguration(
- @NonNull LintClient client,
- @NonNull Project project,
- @Nullable Configuration parent) {
- this(client, project, parent, new File(project.getDir(), CONFIG_FILE_NAME));
- }
-
- /**
- * Creates a new {@link DefaultConfiguration}
- *
- * @param client the client to report errors to etc
- * @param project the associated project
- * @param parent the parent/fallback configuration or null
- * @return a new configuration
- */
- @NonNull
- public static DefaultConfiguration create(
- @NonNull LintClient client,
- @NonNull Project project,
- @Nullable Configuration parent) {
- return new DefaultConfiguration(client, project, parent);
- }
-
- /**
- * Creates a new {@link DefaultConfiguration} for the given lint config
- * file, not affiliated with a project. This is used for global
- * configurations.
- *
- * @param client the client to report errors to etc
- * @param lintFile the lint file containing the configuration
- * @return a new configuration
- */
- @NonNull
- public static DefaultConfiguration create(@NonNull LintClient client, @NonNull File lintFile) {
- return new DefaultConfiguration(client, null /*project*/, null /*parent*/, lintFile);
- }
-
- @Override
- public boolean isIgnored(
- @NonNull Context context,
- @NonNull Issue issue,
- @Nullable Location location,
- @NonNull String message,
- @Nullable Object data) {
- ensureInitialized();
-
- String id = issue.getId();
- List<String> paths = mSuppressed.get(id);
- if (paths != null && location != null) {
- File file = location.getFile();
- String relativePath = context.getProject().getRelativePath(file);
- for (String suppressedPath : paths) {
- if (suppressedPath.equals(relativePath)) {
- return true;
- }
- }
- }
-
- if (mParent != null) {
- return mParent.isIgnored(context, issue, location, message, data);
- }
-
- return false;
- }
-
- @NonNull
- protected Severity getDefaultSeverity(@NonNull Issue issue) {
- if (!issue.isEnabledByDefault()) {
- return Severity.IGNORE;
- }
-
- return issue.getDefaultSeverity();
- }
-
- @Override
- @NonNull
- public Severity getSeverity(@NonNull Issue issue) {
- ensureInitialized();
-
- Severity severity = mSeverity.get(issue.getId());
- if (severity != null) {
- return severity;
- }
-
- if (mParent != null) {
- return mParent.getSeverity(issue);
- }
-
- return getDefaultSeverity(issue);
- }
-
- private void ensureInitialized() {
- if (mSuppressed == null) {
- readConfig();
- }
- }
-
- private void formatError(String message, Object... args) {
- if (args != null && args.length > 0) {
- message = String.format(message, args);
- }
- message = "Failed to parse lint.xml configuration file: " + message;
- LintDriver driver = new LintDriver(new IssueRegistry() {
- @Override @NonNull public List<Issue> getIssues() {
- return Collections.emptyList();
- }
- }, mClient);
- mClient.report(new Context(driver, mProject, mProject, mConfigFile),
- IssueRegistry.LINT_ERROR,
- mProject.getConfiguration().getSeverity(IssueRegistry.LINT_ERROR),
- Location.create(mConfigFile), message, null);
- }
-
- private void readConfig() {
- mSuppressed = new HashMap<String, List<String>>();
- mSeverity = new HashMap<String, Severity>();
-
- if (!mConfigFile.exists()) {
- return;
- }
-
- @SuppressWarnings("resource") // Eclipse doesn't know about Closeables.closeQuietly
- BufferedInputStream input = null;
- try {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- input = new BufferedInputStream(new FileInputStream(mConfigFile));
- InputSource source = new InputSource(input);
- factory.setNamespaceAware(false);
- factory.setValidating(false);
- DocumentBuilder builder = factory.newDocumentBuilder();
- Document document = builder.parse(source);
- NodeList issues = document.getElementsByTagName(TAG_ISSUE);
- for (int i = 0, count = issues.getLength(); i < count; i++) {
- Node node = issues.item(i);
- Element element = (Element) node;
- String id = element.getAttribute(ATTR_ID);
- if (id.length() == 0) {
- formatError("Invalid lint config file: Missing required issue id attribute");
- continue;
- }
-
- NamedNodeMap attributes = node.getAttributes();
- for (int j = 0, n = attributes.getLength(); j < n; j++) {
- Node attribute = attributes.item(j);
- String name = attribute.getNodeName();
- String value = attribute.getNodeValue();
- if (ATTR_ID.equals(name)) {
- // already handled
- } else if (ATTR_SEVERITY.equals(name)) {
- for (Severity severity : Severity.values()) {
- if (value.equalsIgnoreCase(severity.name())) {
- mSeverity.put(id, severity);
- break;
- }
- }
- } else {
- formatError("Unexpected attribute \"%1$s\"", name);
- }
- }
-
- // Look up ignored errors
- NodeList childNodes = element.getChildNodes();
- if (childNodes.getLength() > 0) {
- for (int j = 0, n = childNodes.getLength(); j < n; j++) {
- Node child = childNodes.item(j);
- if (child.getNodeType() == Node.ELEMENT_NODE) {
- Element ignore = (Element) child;
- String path = ignore.getAttribute(ATTR_PATH);
- if (path.length() == 0) {
- formatError("Missing required %1$s attribute under %2$s",
- ATTR_PATH, id);
- } else {
- List<String> paths = mSuppressed.get(id);
- if (paths == null) {
- paths = new ArrayList<String>(n / 2 + 1);
- mSuppressed.put(id, paths);
- }
- paths.add(path);
- }
- }
- }
- }
- }
- } catch (SAXParseException e) {
- formatError(e.getMessage());
- } catch (Exception e) {
- mClient.log(e, null);
- } finally {
- Closeables.closeQuietly(input);
- }
- }
-
- private void writeConfig() {
- try {
- // Write the contents to a new file first such that we don't clobber the
- // existing file if some I/O error occurs.
- File file = new File(mConfigFile.getParentFile(),
- mConfigFile.getName() + ".new"); //$NON-NLS-1$
-
- Writer writer = new BufferedWriter(new FileWriter(file));
- writer.write(
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + //$NON-NLS-1$
- "<lint>\n"); //$NON-NLS-1$
-
- if (mSuppressed.size() > 0 || mSeverity.size() > 0) {
- // Process the maps in a stable sorted order such that if the
- // files are checked into version control with the project,
- // there are no random diffs just because hashing algorithms
- // differ:
- Set<String> idSet = new HashSet<String>();
- for (String id : mSuppressed.keySet()) {
- idSet.add(id);
- }
- for (String id : mSeverity.keySet()) {
- idSet.add(id);
- }
- List<String> ids = new ArrayList<String>(idSet);
- Collections.sort(ids);
-
- for (String id : ids) {
- writer.write(" <"); //$NON-NLS-1$
- writer.write(TAG_ISSUE);
- writeAttribute(writer, ATTR_ID, id);
- Severity severity = mSeverity.get(id);
- if (severity != null) {
- writeAttribute(writer, ATTR_SEVERITY,
- severity.name().toLowerCase(Locale.US));
- }
-
- List<String> paths = mSuppressed.get(id);
- if (paths != null && paths.size() > 0) {
- writer.write('>');
- writer.write('\n');
- // The paths are already kept in sorted order when they are modified
- // by ignore(...)
- for (String path : paths) {
- writer.write(" <"); //$NON-NLS-1$
- writer.write(TAG_IGNORE);
- writeAttribute(writer, ATTR_PATH, path);
- writer.write(" />\n"); //$NON-NLS-1$
- }
- writer.write(" </"); //$NON-NLS-1$
- writer.write(TAG_ISSUE);
- writer.write('>');
- writer.write('\n');
- } else {
- writer.write(" />\n"); //$NON-NLS-1$
- }
- }
- }
-
- writer.write("</lint>"); //$NON-NLS-1$
- writer.close();
-
- // Move file into place: move current version to lint.xml~ (removing the old ~ file
- // if it exists), then move the new version to lint.xml.
- File oldFile = new File(mConfigFile.getParentFile(),
- mConfigFile.getName() + "~"); //$NON-NLS-1$
- if (oldFile.exists()) {
- oldFile.delete();
- }
- if (mConfigFile.exists()) {
- mConfigFile.renameTo(oldFile);
- }
- boolean ok = file.renameTo(mConfigFile);
- if (ok && oldFile.exists()) {
- oldFile.delete();
- }
- } catch (Exception e) {
- mClient.log(e, null);
- }
- }
-
- private static void writeAttribute(
- @NonNull Writer writer, @NonNull String name, @NonNull String value)
- throws IOException {
- writer.write(' ');
- writer.write(name);
- writer.write('=');
- writer.write('"');
- writer.write(value);
- writer.write('"');
- }
-
- @Override
- public void ignore(
- @NonNull Context context,
- @NonNull Issue issue,
- @Nullable Location location,
- @NonNull String message,
- @Nullable Object data) {
- // This configuration only supports suppressing warnings on a per-file basis
- if (location != null) {
- ignore(issue, location.getFile());
- }
- }
-
- /**
- * Marks the given issue and file combination as being ignored.
- *
- * @param issue the issue to be ignored in the given file
- * @param file the file to ignore the issue in
- */
- public void ignore(@NonNull Issue issue, @NonNull File file) {
- ensureInitialized();
-
- String path = mProject != null ? mProject.getRelativePath(file) : file.getPath();
-
- List<String> paths = mSuppressed.get(issue.getId());
- if (paths == null) {
- paths = new ArrayList<String>();
- mSuppressed.put(issue.getId(), paths);
- }
- paths.add(path);
-
- // Keep paths sorted alphabetically; makes XML output stable
- Collections.sort(paths);
-
- if (!mBulkEditing) {
- writeConfig();
- }
- }
-
- @Override
- public void setSeverity(@NonNull Issue issue, @Nullable Severity severity) {
- ensureInitialized();
-
- String id = issue.getId();
- if (severity == null) {
- mSeverity.remove(id);
- } else {
- mSeverity.put(id, severity);
- }
-
- if (!mBulkEditing) {
- writeConfig();
- }
- }
-
- @Override
- public void startBulkEditing() {
- mBulkEditing = true;
- }
-
- @Override
- public void finishBulkEditing() {
- mBulkEditing = false;
- writeConfig();
- }
-}