aboutsummaryrefslogtreecommitdiffstats
path: root/lint/libs/lint_checks/src/com/android/tools/lint/checks/NamespaceDetector.java
diff options
context:
space:
mode:
Diffstat (limited to 'lint/libs/lint_checks/src/com/android/tools/lint/checks/NamespaceDetector.java')
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/NamespaceDetector.java221
1 files changed, 0 insertions, 221 deletions
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/NamespaceDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/NamespaceDetector.java
deleted file mode 100644
index a4fc2f6..0000000
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/NamespaceDetector.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2012 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.checks;
-
-import static com.android.SdkConstants.ANDROID_PKG_PREFIX;
-import static com.android.SdkConstants.ANDROID_URI;
-import static com.android.SdkConstants.AUTO_URI;
-import static com.android.SdkConstants.URI_PREFIX;
-import static com.android.SdkConstants.XMLNS_PREFIX;
-
-import com.android.annotations.NonNull;
-import com.android.tools.lint.detector.api.Category;
-import com.android.tools.lint.detector.api.Issue;
-import com.android.tools.lint.detector.api.LayoutDetector;
-import com.android.tools.lint.detector.api.LintUtils;
-import com.android.tools.lint.detector.api.Scope;
-import com.android.tools.lint.detector.api.Severity;
-import com.android.tools.lint.detector.api.Speed;
-import com.android.tools.lint.detector.api.XmlContext;
-
-import org.w3c.dom.Attr;
-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 java.util.HashMap;
-import java.util.Map;
-
-/**
- * Checks for various issues related to XML namespaces
- */
-public class NamespaceDetector extends LayoutDetector {
- /** Typos in the namespace */
- public static final Issue TYPO = Issue.create(
- "NamespaceTypo", //$NON-NLS-1$
- "Looks for misspellings in namespace declarations",
-
- "Accidental misspellings in namespace declarations can lead to some very " +
- "obscure error messages. This check looks for potential misspellings to " +
- "help track these down.",
- Category.CORRECTNESS,
- 8,
- Severity.WARNING,
- NamespaceDetector.class,
- Scope.RESOURCE_FILE_SCOPE);
-
- /** Unused namespace declarations */
- public static final Issue UNUSED = Issue.create(
- "UnusedNamespace", //$NON-NLS-1$
- "Finds unused namespaces in XML documents",
-
- "Unused namespace declarations take up space and require processing that is not " +
- "necessary",
-
- Category.CORRECTNESS,
- 1,
- Severity.WARNING,
- NamespaceDetector.class,
- Scope.RESOURCE_FILE_SCOPE);
-
- /** Using custom namespace attributes in a library project */
- public static final Issue CUSTOMVIEW = Issue.create(
- "LibraryCustomView", //$NON-NLS-1$
- "Flags custom attributes in libraries, which must use the res-auto-namespace instead",
-
- "When using a custom view with custom attributes in a library project, the layout " +
- "must use the special namespace " + AUTO_URI + " instead of a URI which includes " +
- "the library project's own package. This will be used to automatically adjust the " +
- "namespace of the attributes when the library resources are merged into the " +
- "application project.",
- Category.CORRECTNESS,
- 6,
- Severity.ERROR,
- NamespaceDetector.class,
- Scope.RESOURCE_FILE_SCOPE);
-
- /** Prefix relevant for custom namespaces */
- private static final String XMLNS_ANDROID = "xmlns:android"; //$NON-NLS-1$
- private static final String XMLNS_A = "xmlns:a"; //$NON-NLS-1$
-
- private Map<String, Attr> mUnusedNamespaces;
- private boolean mCheckUnused;
- private boolean mCheckCustomAttrs;
-
- /** Constructs a new {@link NamespaceDetector} */
- public NamespaceDetector() {
- }
-
- @Override
- public @NonNull Speed getSpeed() {
- return Speed.FAST;
- }
-
- @Override
- public void visitDocument(@NonNull XmlContext context, @NonNull Document document) {
- boolean haveCustomNamespace = false;
- Element root = document.getDocumentElement();
- NamedNodeMap attributes = root.getAttributes();
- for (int i = 0, n = attributes.getLength(); i < n; i++) {
- Node item = attributes.item(i);
- if (item.getNodeName().startsWith(XMLNS_PREFIX)) {
- String value = item.getNodeValue();
-
- if (!value.equals(ANDROID_URI)) {
- Attr attribute = (Attr) item;
-
- if (value.startsWith(URI_PREFIX)) {
- haveCustomNamespace = true;
- if (mUnusedNamespaces == null) {
- mUnusedNamespaces = new HashMap<String, Attr>();
- }
- mUnusedNamespaces.put(item.getNodeName().substring(XMLNS_PREFIX.length()),
- attribute);
- }
-
- String name = attribute.getName();
- if (!name.equals(XMLNS_ANDROID) && !name.equals(XMLNS_A)) {
- continue;
- }
-
- if (!context.isEnabled(TYPO)) {
- continue;
- }
-
- if (name.equals(XMLNS_A)) {
- // For the "android" prefix we always assume that the namespace prefix
- // should be our expected prefix, but for the "a" prefix we make sure
- // that it's at least "close"; if you're bound it to something completely
- // different, don't complain.
- if (LintUtils.editDistance(ANDROID_URI, value) > 4) {
- continue;
- }
- }
-
- if (value.equalsIgnoreCase(ANDROID_URI)) {
- context.report(TYPO, attribute, context.getLocation(attribute),
- String.format(
- "URI is case sensitive: was \"%1$s\", expected \"%2$s\"",
- value, ANDROID_URI), null);
- } else {
- context.report(TYPO, attribute, context.getLocation(attribute),
- String.format(
- "Unexpected namespace URI bound to the \"android\" " +
- "prefix, was %1$s, expected %2$s", value, ANDROID_URI),
- null);
- }
- }
- }
- }
-
- if (haveCustomNamespace) {
- mCheckCustomAttrs = context.isEnabled(CUSTOMVIEW) && context.getProject().isLibrary();
- mCheckUnused = context.isEnabled(UNUSED);
- checkElement(context, document.getDocumentElement());
-
- if (mCheckUnused && mUnusedNamespaces.size() > 0) {
- for (Map.Entry<String, Attr> entry : mUnusedNamespaces.entrySet()) {
- String prefix = entry.getKey();
- Attr attribute = entry.getValue();
- context.report(UNUSED, attribute, context.getLocation(attribute),
- String.format("Unused namespace %1$s", prefix), null);
- }
- }
- }
- }
-
- private void checkElement(XmlContext context, Node node) {
- if (node.getNodeType() == Node.ELEMENT_NODE) {
- if (mCheckCustomAttrs) {
- String tag = node.getNodeName();
- if (tag.indexOf('.') != -1
- // Don't consider android.support.* and android.app.FragmentBreadCrumbs etc
- && !tag.startsWith(ANDROID_PKG_PREFIX)) {
- NamedNodeMap attributes = ((Element) node).getAttributes();
- for (int i = 0, n = attributes.getLength(); i < n; i++) {
- Attr attribute = (Attr) attributes.item(i);
- String uri = attribute.getNamespaceURI();
- if (uri != null && uri.length() > 0 && uri.startsWith(URI_PREFIX)
- && !uri.equals(ANDROID_URI)) {
- context.report(CUSTOMVIEW, attribute, context.getLocation(attribute),
- "When using a custom namespace attribute in a library project, " +
- "use the namespace \"" + AUTO_URI + "\" instead.", null);
- }
- }
- }
- }
-
- if (mCheckUnused) {
- NamedNodeMap attributes = ((Element) node).getAttributes();
- for (int i = 0, n = attributes.getLength(); i < n; i++) {
- Attr attribute = (Attr) attributes.item(i);
- String prefix = attribute.getPrefix();
- if (prefix != null) {
- mUnusedNamespaces.remove(prefix);
- }
- }
- }
-
- NodeList childNodes = node.getChildNodes();
- for (int i = 0, n = childNodes.getLength(); i < n; i++) {
- checkElement(context, childNodes.item(i));
- }
- }
- }
-}