From 6d544118e37fec4a0204783be59b506675c5f7ad Mon Sep 17 00:00:00 2001 From: Raphael Moll Date: Tue, 5 Jun 2012 22:45:46 -0700 Subject: Manifest Merger: rework interface to collect errors. Change-Id: Ib8add07a611d4d496004567fb23b8c5d38b6e487 --- .../src/com/android/ant/ManifestMergerTask.java | 3 +- .../src/com/android/manifmerger/IMergerLog.java | 164 +++++++++++++++ manifmerger/src/com/android/manifmerger/Main.java | 2 +- .../com/android/manifmerger/ManifestMerger.java | 220 +++++++++++---------- .../src/com/android/manifmerger/MergerLog.java | 151 ++++++++++++++ .../src/com/android/manifmerger/XmlUtils.java | 89 +++++++-- .../manifmerger/ManifestMergerTestCase.java | 19 +- .../android/manifmerger/data/10_activity_merge.xml | 4 +- .../android/manifmerger/data/11_activity_dup.xml | 6 +- .../com/android/manifmerger/data/12_alias_dup.xml | 6 +- .../android/manifmerger/data/13_service_dup.xml | 6 +- .../android/manifmerger/data/14_receiver_dup.xml | 6 +- .../android/manifmerger/data/15_provider_dup.xml | 6 +- .../manifmerger/data/21_uses_lib_errors.xml | 4 +- .../android/manifmerger/data/26_permission_dup.xml | 12 +- .../data/33_uses_sdk_minsdk_conflict.xml | 6 +- .../data/36_uses_sdk_targetsdk_warning.xml | 2 +- .../manifmerger/data/41_uses_feat_errors.xml | 4 +- .../data/47_uses_feat_gles_conflict.xml | 4 +- .../manifmerger/data/50_uses_conf_warning.xml | 2 +- .../data/52_support_screens_warning.xml | 2 +- .../manifmerger/data/54_compat_screens_warning.xml | 6 +- .../manifmerger/data/56_support_gltext_warning.xml | 2 +- 23 files changed, 549 insertions(+), 177 deletions(-) create mode 100755 manifmerger/src/com/android/manifmerger/IMergerLog.java create mode 100755 manifmerger/src/com/android/manifmerger/MergerLog.java diff --git a/anttasks/src/com/android/ant/ManifestMergerTask.java b/anttasks/src/com/android/ant/ManifestMergerTask.java index 5921939..ef0dfce 100644 --- a/anttasks/src/com/android/ant/ManifestMergerTask.java +++ b/anttasks/src/com/android/ant/ManifestMergerTask.java @@ -17,6 +17,7 @@ package com.android.ant; import com.android.manifmerger.ManifestMerger; +import com.android.manifmerger.MergerLog; import com.android.sdklib.StdSdkLog; import com.android.sdklib.io.FileOp; @@ -123,7 +124,7 @@ public class ManifestMergerTask extends SingleDependencyTask { } else { System.out.println(String.format("Merging manifests from project and %d libraries.", libraries.size())); - ManifestMerger merger = new ManifestMerger(new StdSdkLog()); + ManifestMerger merger = new ManifestMerger(MergerLog.wrapSdkLog(new StdSdkLog())); if (merger.process( new File(mOutManifest), appManifestFile, diff --git a/manifmerger/src/com/android/manifmerger/IMergerLog.java b/manifmerger/src/com/android/manifmerger/IMergerLog.java new file mode 100755 index 0000000..5402dd4 --- /dev/null +++ b/manifmerger/src/com/android/manifmerger/IMergerLog.java @@ -0,0 +1,164 @@ +/* + * 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.manifmerger; + +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; + + +/** + * Logger interface for the {@link ManifestMerger}. + */ +public interface IMergerLog { + + /** Severity of the error message. */ + public enum Severity { + /** + * A very low severity information. This does not stop processing. + * Clients might want to have a "not verbose" flag to not display this. + */ + INFO, + /** + * A warning. This does not stop processing. + * */ + WARNING, + /** + * A fatal error. + * The merger does not stop on errors, in an attempt to accumulate as much + * info as possible to return to the user. However in case even one error + * is generated the output should not be used, if any. + */ + ERROR + } + + /** + * Logs an error that occurred at a specific single manifest. + * + * @param severity Whether this is an actual error or a mere warning. + * @param location A file and line location of where the error was detected. + * @param message A message string, suitable for {@link String#format(String, Object...)}. + * @param msgParams The optional parameters for the {@code message} string. + */ + public abstract void error( + @NonNull Severity severity, + @NonNull FileAndLine location, + @NonNull String message, + Object...msgParams); + + /** + * Logs a conflict, that is an error that happens when comparing 2 manifests. + * + * @param severity Whether this is an actual error or a mere warning. + * @param location1 A file and line location of where the error was detected. + * By convention, location1 is generally the main manifest location. + * @param location2 A file and line location of where the error was detected. + * By convention, location2 is generally a library location. + * @param message A message string, suitable for {@link String#format(String, Object...)}. + * @param msgParams The optional parameters for the {@code message} string. + */ + public abstract void conflict( + @NonNull Severity severity, + @NonNull FileAndLine location1, + @NonNull FileAndLine location2, + @NonNull String message, + Object...msgParams); + + /** + * Information about the file and line number where an error ocurred. + */ + public static class FileAndLine { + private final String mFilePath; + private final int mLine; + + /** + * Constructs a new {@link FileAndLine}. + * + * @param filePath The file path. This is typically a file path when the + * merge is initiated via the {@code process(File...)} interface. + * When using the {@code process(Document...)} interface, this will be + * one of the magic constants {@link IMergerLog#LIBRARY} or + * {@link IMergerLog#MAIN_MANIFEST}. When that fails, null is used. + * @param line The line number where the error occurred in the XML file. + * Zero is used when the line number isn't known (e.g. when the error + * happens at the document level rather than on a specific element.) + */ + public FileAndLine(@Nullable String filePath, int line) { + mFilePath = filePath; + mLine = line; + } + + /** + * Returns the file path. + *

+ * This is typically a file path when the merge is initiated via the + * {@code process(File...)} interface. + * When using the {@code process(Document...)} interface, this will be + * one of the magic constants {@link IMergerLog#LIBRARY} or + * {@link IMergerLog#MAIN_MANIFEST}. + * When that fails, null is used. + */ + public @Nullable String getFileName() { + return mFilePath; + } + + /** + * Returns the line number where the error occurred in the XML file. + * Zero is used when the line number isn't known (e.g. when the error + * happens at the document level rather than on a specific element.) + */ + public int getLine() { + return mLine; + } + + /** + * Displays the information in the form "file:line". + */ + @Override + public String toString() { + String name = mFilePath; + if (MAIN_MANIFEST.equals(name)) { + name = "main manifest"; // translatable + } else if (LIBRARY.equals(name)) { + name = "library"; // translatable + } else if (name == null) { + name = "(Unknown)"; // translatable + } + if (mLine <= 0) { + return name; + } else { + return name + ':' + mLine; + } + } + } + + /** + * The reference to the "main manifest" used in {@link FileAndLine} when the + * path to the main manifest file isn't known. This happens when the + * {@link ManifestMerger} is called with the {@code process(Document...)} + * interface. + */ + public static final String MAIN_MANIFEST = "@main"; //$NON-NLS-1$ + + /** + * The reference to "a library" used in {@link FileAndLine} when the + * path to the library file isn't known. This happens when the + * {@link ManifestMerger} is called with the {@code process(Document...)} + * interface. + */ + public static final String LIBRARY = "@library"; //$NON-NLS-1$ + +} diff --git a/manifmerger/src/com/android/manifmerger/Main.java b/manifmerger/src/com/android/manifmerger/Main.java index e2e6f30..93057fc 100644 --- a/manifmerger/src/com/android/manifmerger/Main.java +++ b/manifmerger/src/com/android/manifmerger/Main.java @@ -56,7 +56,7 @@ public class Main { // Create a new ManifestMerger and call its process method. // It will take care of validating its own arguments. - ManifestMerger mm = new ManifestMerger(mSdkLog); + ManifestMerger mm = new ManifestMerger(MergerLog.wrapSdkLog(mSdkLog)); String[] libPaths = mArgvParser.getParamLibs(); File[] libFiles = new File[libPaths.length]; diff --git a/manifmerger/src/com/android/manifmerger/ManifestMerger.java b/manifmerger/src/com/android/manifmerger/ManifestMerger.java index 8dfd398..229faa3 100755 --- a/manifmerger/src/com/android/manifmerger/ManifestMerger.java +++ b/manifmerger/src/com/android/manifmerger/ManifestMerger.java @@ -18,7 +18,8 @@ package com.android.manifmerger; import com.android.annotations.NonNull; import com.android.annotations.Nullable; -import com.android.sdklib.ISdkLog; +import com.android.manifmerger.IMergerLog.FileAndLine; +import com.android.manifmerger.IMergerLog.Severity; import com.android.sdklib.SdkConstants; import com.android.sdklib.xml.AndroidXPathFactory; @@ -44,7 +45,7 @@ import javax.xml.xpath.XPathExpressionException; /** * Merges a library manifest into a main application manifest. *

- * To use, create with {@link ManifestMerger#ManifestMerger(ISdkLog)} then + * To use, create with {@link ManifestMerger#ManifestMerger(IMergerLog)} then * call {@link ManifestMerger#process(File, File, File[])}. *

*

 Merge operations:
@@ -116,7 +117,7 @@ import javax.xml.xpath.XPathExpressionException;
 public class ManifestMerger {
 
     /** Logger object. Never null. */
-    private ISdkLog mSdkLog;
+    private IMergerLog mLog;
     private XPath mXPath;
     private Document mMainDoc;
 
@@ -124,8 +125,8 @@ public class ManifestMerger {
     private String NS_PREFIX = AndroidXPathFactory.DEFAULT_NS_PREFIX;
     private int destMinSdk;
 
-    public ManifestMerger(ISdkLog log) {
-        mSdkLog = log;
+    public ManifestMerger(IMergerLog log) {
+        mLog = log;
     }
 
     /**
@@ -143,14 +144,14 @@ public class ManifestMerger {
      * @return True if the merge was completed, false otherwise.
      */
     public boolean process(File outputFile, File mainFile, File[] libraryFiles) {
-        Document mainDoc = XmlUtils.parseDocument(mainFile, mSdkLog);
+        Document mainDoc = XmlUtils.parseDocument(mainFile, mLog);
         if (mainDoc == null) {
             return false;
         }
 
         boolean success = process(mainDoc, libraryFiles);
 
-        if (!XmlUtils.printXmlFile(mainDoc, outputFile, mSdkLog)) {
+        if (!XmlUtils.printXmlFile(mainDoc, outputFile, mLog)) {
             success = false;
         }
         return success;
@@ -164,18 +165,19 @@ public class ManifestMerger {
      *
      * @param mainDoc The document to merge into. Will be modified in-place.
      * @param libraryFiles The library manifest paths to read. Must not be null.
-     * @return True on success, false if any error occurred (printed to the {@link ISdkLog}).
+     * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
      */
     public boolean process(Document mainDoc, File[] libraryFiles) {
 
         boolean success = true;
         mMainDoc = mainDoc;
+        XmlUtils.decorateDocument(mainDoc, IMergerLog.MAIN_MANIFEST);
 
         String prefix = XmlUtils.lookupNsPrefix(mainDoc, SdkConstants.NS_RESOURCES);
         mXPath = AndroidXPathFactory.newXPath(prefix);
 
         for (File libFile : libraryFiles) {
-            Document libDoc = XmlUtils.parseDocument(libFile, mSdkLog);
+            Document libDoc = XmlUtils.parseDocument(libFile, mLog);
             if (libDoc == null || !mergeLibDoc(libDoc)) {
                 success = false;
             }
@@ -194,17 +196,19 @@ public class ManifestMerger {
      *
      * @param mainDoc The document to merge into. Will be modified in-place.
      * @param libraryDocs The library manifest documents to merge in. Must not be null.
-     * @return True on success, false if any error occurred (printed to the {@link ISdkLog}).
+     * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
      */
     public boolean process(@NonNull Document mainDoc, @NonNull Document... libraryDocs) {
 
         boolean success = true;
         mMainDoc = mainDoc;
+        XmlUtils.decorateDocument(mainDoc, IMergerLog.MAIN_MANIFEST);
 
         String prefix = XmlUtils.lookupNsPrefix(mainDoc, SdkConstants.NS_RESOURCES);
         mXPath = AndroidXPathFactory.newXPath(prefix);
 
         for (Document libDoc : libraryDocs) {
+            XmlUtils.decorateDocument(libDoc, IMergerLog.LIBRARY);
             if (!mergeLibDoc(libDoc)) {
                 success = false;
             }
@@ -222,7 +226,7 @@ public class ManifestMerger {
      * See {@link ManifestMerger} for merge details.
      *
      * @param libDoc The library document to merge from. Must not be null.
-     * @return True on success, false if any error occurred (printed to the {@link ISdkLog}).
+     * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
      */
     private boolean mergeLibDoc(Document libDoc) {
 
@@ -320,7 +324,7 @@ public class ManifestMerger {
      *
      * @param path The XPath of the elements to merge from the library. Must not be null.
      * @param libDoc The library document to merge from. Must not be null.
-     * @return True on success, false if any error occurred (printed to the {@link ISdkLog}).
+     * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
      */
     private boolean doNotMergeCheckEqual(String path, Document libDoc) {
 
@@ -336,10 +340,11 @@ public class ManifestMerger {
             }
 
             if (!found) {
-                mSdkLog.warning("[%1$s] %2$s missing from %3$s:\n%4$s",
-                        fileLineInfo(src, "library"),
+                mLog.conflict(Severity.WARNING,
+                        xmlFileAndLine(mMainDoc),
+                        xmlFileAndLine(src),
+                        "%1$s defined in library, missing from main manifest:\n%2$s",
                         path,
-                        xmlFileName(mMainDoc, "main manifest"),
                         XmlUtils.dump(src, false /*nextSiblings*/));
             }
         }
@@ -361,7 +366,7 @@ public class ManifestMerger {
      * @param libDoc The library document to merge from. Must not be null.
      * @param warnDups When true, will print a warning when a library definition is already
      *   present in the destination and is equal.
-     * @return True on success, false if any error occurred (printed to the {@link ISdkLog}).
+     * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
      */
     private boolean mergeNewOrEqual(
             String path,
@@ -376,8 +381,9 @@ public class ManifestMerger {
         Element parent = findFirstElement(mMainDoc, parentPath);
         assert parent != null;
         if (parent == null) {
-            mSdkLog.error(null, "[%1$s] Could not find element %2$s.",
-                    xmlFileName(mMainDoc, "main manifest"),
+            mLog.error(Severity.ERROR,
+                    xmlFileAndLine(mMainDoc),
+                    "Could not find element %1$s.",
                     parentPath);
             return false;
         }
@@ -388,8 +394,9 @@ public class ManifestMerger {
             Attr attr = src.getAttributeNodeNS(NS_URI, keyAttr);
             String name = attr == null ? "" : attr.getNodeValue();  //$NON-NLS-1$
             if (name.length() == 0) {
-                mSdkLog.error(null, "[%1$s] Undefined '%2$s' attribute in %3$s.",
-                        fileLineInfo(src, "library"),
+                mLog.error(Severity.ERROR,
+                        xmlFileAndLine(src),
+                        "Undefined '%1$s' attribute in %2$s.",
                         keyAttr, path);
                 success = false;
                 continue;
@@ -399,8 +406,9 @@ public class ManifestMerger {
             List dests = findElements(mMainDoc, path, keyAttr, name);
             if (dests.size() > 1) {
                 // This should not be happening. We'll just use the first one found in this case.
-                mSdkLog.warning("[%1$s] has more than one %2$s[@%3$s=%4$s] element.",
-                        fileLineInfo(dests.get(0), "main manifest"),
+                mLog.error(Severity.WARNING,
+                        xmlFileAndLine(dests.get(0)),
+                        "Manifest has more than one %1$s[@%2$s=%3$s] element.",
                         path, keyAttr, name);
             }
             for (Element dest : dests) {
@@ -409,18 +417,19 @@ public class ManifestMerger {
                 if (compareElements(src, dest, false, diff, keyAttr)) {
                     // Same element. Skip.
                     if (warnDups) {
-                        mSdkLog.printf("[%1$s, %2$s] Skipping identical %3$s[@%4$s=%5$s] element.",
-                                fileLineInfo(src, "library"),
-                                fileLineInfo(dest, "main manifest"),
+                        mLog.conflict(Severity.INFO,
+                                xmlFileAndLine(dest),
+                                xmlFileAndLine(src),
+                                "Skipping identical %1$s[@%2$s=%3$s] element.",
                                 path, keyAttr, name);
                     }
                     continue nextSource;
                 } else {
                     // Print the diff we got from the comparison.
-                    mSdkLog.error(null,
-                            "[%1$s, %2$s] Trying to merge incompatible %3$s[@%4$s=%5$s] element:\n%6$s",
-                            fileLineInfo(src, "library"),
-                            fileLineInfo(dest, "main manifest"),
+                    mLog.conflict(Severity.ERROR,
+                            xmlFileAndLine(dest),
+                            xmlFileAndLine(src),
+                            "Trying to merge incompatible %1$s[@%2$s=%3$s] element:\n%4$s",
                             path, keyAttr, name, diff.toString());
                     success = false;
                     continue nextSource;
@@ -454,7 +463,7 @@ public class ManifestMerger {
      * @param alternateKeyAttr When non-null, this is an alternate valid key attribute. If the
      *   default key attribute is missing, we won't output a warning if the alternate one is
      *   present.
-     * @return True on success, false if any error occurred (printed to the {@link ISdkLog}).
+     * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
      */
     private boolean mergeAdjustRequired(
             String path,
@@ -470,8 +479,9 @@ public class ManifestMerger {
         Element parent = findFirstElement(mMainDoc, parentPath);
         assert parent != null;
         if (parent == null) {
-            mSdkLog.error(null, "[%1$s] Could not find element %2$s.",
-                    xmlFileName(mMainDoc, "main manifest"),
+            mLog.error(Severity.ERROR,
+                    xmlFileAndLine(mMainDoc),
+                    "Could not find element %1$s.",
                     parentPath);
             return false;
         }
@@ -491,8 +501,9 @@ public class ManifestMerger {
                     }
                 }
 
-                mSdkLog.error(null, "[%1$s] Undefined '%2$s' attribute in %3$s.",
-                        fileLineInfo(src, "library"),
+                mLog.error(Severity.ERROR,
+                        xmlFileAndLine(src),
+                        "Undefined '%1$s' attribute in %2$s.",
                         keyAttr, path);
                 success = false;
                 continue;
@@ -502,16 +513,18 @@ public class ManifestMerger {
             List dests = findElements(mMainDoc, path, keyAttr, name);
             if (dests.size() > 1) {
                 // This should not be happening. We'll just use the first one found in this case.
-                mSdkLog.warning("[%1$s] has more than one %2$s[@%3$s=%4$s] element.",
-                        fileLineInfo(dests.get(0), "main manifest"),
+                mLog.error(Severity.WARNING,
+                        xmlFileAndLine(dests.get(0)),
+                        "Manifest has more than one %1$s[@%2$s=%3$s] element.",
                         path, keyAttr, name);
             }
             if (dests.size() > 0) {
                 attr = src.getAttributeNodeNS(NS_URI, requiredAttr);
                 String value = attr == null ? "true" : attr.getNodeValue();    //$NON-NLS-1$
                 if (value == null || !(value.equals("true") || value.equals("false"))) {
-                    mSdkLog.warning("[%1$s] Invalid attribute '%2$s' in %3$s[@%4$s=%5$s] element:\nExpected 'true' or 'false' but found '%6$s'.",
-                            fileLineInfo(src, "library"),
+                    mLog.error(Severity.WARNING,
+                            xmlFileAndLine(src),
+                            "Invalid attribute '%1$s' in %2$s[@%3$s=%4$s] element:\nExpected 'true' or 'false' but found '%5$s'.",
                             requiredAttr, path, keyAttr, name, value);
                     continue;
                 }
@@ -523,8 +536,9 @@ public class ManifestMerger {
                     attr = dest.getAttributeNodeNS(NS_URI, requiredAttr);
                     value = attr == null ? "true" : attr.getNodeValue();    //$NON-NLS-1$
                     if (value == null || !(value.equals("true") || value.equals("false"))) {
-                        mSdkLog.warning("[%1$s] Invalid attribute '%2$s' in %3$s[@%4$s=%5$s] element:\nExpected 'true' or 'false' but found '%6$s'.",
-                                fileLineInfo(dest, "main manifest"),
+                        mLog.error(Severity.WARNING,
+                                xmlFileAndLine(dest),
+                                "Invalid attribute '%1$s' in %2$s[@%3$s=%4$s] element:\nExpected 'true' or 'false' but found '%5$s'.",
                                 requiredAttr, path, keyAttr, name, value);
                         continue;
                     }
@@ -548,7 +562,7 @@ public class ManifestMerger {
                             // but experience shows that it would create a new prefix out of the
                             // blue instead of looking it up.
                             //
-                            // Attr a = d.getOwnerDocument().createAttributeNS(NS_URI, requiredAttr);
+                            // Attr a=d.getOwnerDocument().createAttributeNS(NS_URI, requiredAttr);
                             // String prefix = d.lookupPrefix(NS_URI);
                             // if (prefix != null) {
                             //     a.setPrefix(prefix);
@@ -603,7 +617,7 @@ public class ManifestMerger {
      * 
* * @param libDoc The library document to merge from. Must not be null. - * @return True on success, false if any error occurred (printed to the {@link ISdkLog}). + * @return True on success, false if any error occurred (printed to the {@link IMergerLog}). */ private boolean checkGlEsVersion(Document libDoc) { @@ -611,8 +625,9 @@ public class ManifestMerger { Element parent = findFirstElement(mMainDoc, parentPath); assert parent != null; if (parent == null) { - mSdkLog.error(null, "[%1$s] Could not find element %2$s.", - xmlFileName(mMainDoc, "main manifest"), + mLog.error(Severity.ERROR, + xmlFileAndLine(mMainDoc), + "Could not find element %1$s.", parentPath); return false; } @@ -639,16 +654,17 @@ public class ManifestMerger { destGlEsVersion = version; destNode = dest; } else if (version < 0x00010000) { - mSdkLog.warning("[%1$s] Ignoring because it's smaller than 1.0.", - fileLineInfo(dest, "main manifest"), + mLog.error(Severity.WARNING, + xmlFileAndLine(dest), + "Ignoring because it's smaller than 1.0.", value); } } catch (NumberFormatException e) { // Note: NumberFormatException.toString() has no interesting information // so we don't output it. - mSdkLog.error(null, - "[%1$s] Failed to parse : must be an integer in the form 0x00020001.", - fileLineInfo(dest, "main manifest"), + mLog.error(Severity.ERROR, + xmlFileAndLine(dest), + "Failed to parse : must be an integer in the form 0x00020001.", value); result = false; } @@ -676,16 +692,17 @@ public class ManifestMerger { srcGlEsVersion = version; srcNode = src; } else if (version < 0x00010000) { - mSdkLog.warning("[%1$s] Ignoring because it's smaller than 1.0.", - fileLineInfo(src, "library"), + mLog.error(Severity.WARNING, + xmlFileAndLine(src), + "Ignoring because it's smaller than 1.0.", value); } } catch (NumberFormatException e) { // Note: NumberFormatException.toString() has no interesting information // so we don't output it. - mSdkLog.error(null, - "[%1$s] Failed to parse : must be an integer in the form 0x00020001.", - fileLineInfo(src, "library"), + mLog.error(Severity.ERROR, + xmlFileAndLine(src), + "Failed to parse : must be an integer in the form 0x00020001.", value); result = false; } @@ -693,10 +710,10 @@ public class ManifestMerger { } if (srcNode != null && destGlEsVersion < srcGlEsVersion) { - mSdkLog.warning( - "[%1$s, %2$s] Main manifest has but library uses glEsVersion='0x%4$08x'%5$s", - fileLineInfo(srcNode, "library"), - fileLineInfo(destNode == null ? mMainDoc : destNode, "main manifest"), + mLog.conflict(Severity.WARNING, + xmlFileAndLine(destNode == null ? mMainDoc : destNode), + xmlFileAndLine(srcNode), + "Main manifest has but library uses glEsVersion='0x%2$08x'%3$s", destGlEsVersion, srcGlEsVersion, destNode != null ? "" : //$NON-NLS-1$ @@ -716,7 +733,7 @@ public class ManifestMerger { * - {@code @maxSdkVersion}: obsolete, ignored. Not used in comparisons and not merged. * * @param libDoc The library document to merge from. Must not be null. - * @return True on success, false if any error occurred (printed to the {@link ISdkLog}). + * @return True on success, false if any error occurred (printed to the {@link IMergerLog}). */ private boolean checkSdkVersion(Document libDoc) { @@ -749,10 +766,10 @@ public class ManifestMerger { destMinSdk = destValue.get(); if (destMinSdk < srcValue.get()) { - mSdkLog.error(null, - "[%1$s, %2$s] Main manifest has but library uses minSdkVersion='%4$d'%5$s", - fileLineInfo(srcUsesSdk == null ? libDoc : srcUsesSdk, "library"), - fileLineInfo(destUsesSdk == null ? mMainDoc : destUsesSdk, "main manifest"), + mLog.conflict(Severity.ERROR, + xmlFileAndLine(destUsesSdk == null ? mMainDoc : destUsesSdk), + xmlFileAndLine(srcUsesSdk == null ? libDoc : srcUsesSdk), + "Main manifest has but library uses minSdkVersion='%2$d'%3$s", destMinSdk, srcValue.get(), !destImplied.get() ? "" : //$NON-NLS-1$ @@ -784,10 +801,10 @@ public class ManifestMerger { int destTargetSdk = destImplied.get() ? destMinSdk : destValue.get(); if (destTargetSdk < srcValue.get()) { - mSdkLog.warning( - "[%1$s, %2$s] Main manifest has but library uses targetSdkVersion='%4$d'%5$s", - fileLineInfo(srcUsesSdk == null ? libDoc : srcUsesSdk, "library"), - fileLineInfo(destUsesSdk == null ? mMainDoc : destUsesSdk, "main manifest"), + mLog.conflict(Severity.WARNING, + xmlFileAndLine(destUsesSdk == null ? mMainDoc : destUsesSdk), + xmlFileAndLine(srcUsesSdk == null ? libDoc : srcUsesSdk), + "Main manifest has but library uses targetSdkVersion='%2$d'%3$s", destTargetSdk, srcValue.get(), !destImplied.get() ? "" : //$NON-NLS-1$ @@ -831,9 +848,9 @@ public class ManifestMerger { } catch (NumberFormatException e) { // Note: NumberFormatException.toString() has no interesting information // so we don't output it. - mSdkLog.error(null, - "[%1$s] Failed to parse : must be an integer number.", - fileLineInfo(destUsesSdk == null ? mMainDoc : destUsesSdk, "main manifest"), + mLog.error(Severity.ERROR, + xmlFileAndLine(destUsesSdk == null ? mMainDoc : destUsesSdk), + "Failed to parse : must be an integer number.", attr, s); return false; @@ -849,9 +866,9 @@ public class ManifestMerger { srcImplied.set(false); } } catch (NumberFormatException e) { - mSdkLog.error(null, - "[%1$s] Failed to parse : must be an integer number.", - fileLineInfo(srcUsesSdk == null ? libDoc : srcUsesSdk, "library"), + mLog.error(Severity.ERROR, + xmlFileAndLine(srcUsesSdk == null ? libDoc : srcUsesSdk), + "Failed to parse : must be an integer number.", attr, s); return false; @@ -1206,12 +1223,16 @@ public class ManifestMerger { } if (result != null) { - mSdkLog.error(null, + mLog.error(Severity.ERROR, + xmlFileAndLine(doc), "Unexpected Node type %s when evaluating %s", //$NON-NLS-1$ result.getClass().getName(), path); } } catch (XPathExpressionException e) { - mSdkLog.error(e, "XPath error on expr %s", path); //$NON-NLS-1$ + mLog.error(Severity.ERROR, + xmlFileAndLine(doc), + "XPath error on expr %s: %s", //$NON-NLS-1$ + path, e.toString()); } return null; } @@ -1243,7 +1264,7 @@ public class ManifestMerger { * @param doc The document where to find the expression. * @param path The XPath expression. Only {@link Element}s nodes will be returned. * @param attrName The name of the optional attribute to match. Can be null. - * @param attrValue The value of the optiona attribute to match. + * @param attrValue The value of the optional attribute to match. * Can be null if {@code attrName} is null, otherwise must be non-null. * @return A list of {@link Element} found, possibly empty but never null. * @@ -1272,7 +1293,8 @@ public class ManifestMerger { if (n instanceof Element) { elements.add((Element) n); } else { - mSdkLog.error(null, + mLog.error(Severity.ERROR, + xmlFileAndLine(doc), "Unexpected Node type %s when evaluating %s", //$NON-NLS-1$ n.getClass().getName(), path); } @@ -1280,43 +1302,29 @@ public class ManifestMerger { } } catch (XPathExpressionException e) { - mSdkLog.error(e, "XPath error on expr %s", path); //$NON-NLS-1$ + mLog.error(Severity.ERROR, + xmlFileAndLine(doc), + "XPath error on expr %s: %s", //$NON-NLS-1$ + path, e.toString()); } return elements; } /** - * Tries to returns the base filename used from which the XML was parsed. - * @param node Any node from a document parsed by {@link XmlUtils#parseDocument(File, ISdkLog)}. - * @param defaultName The string to return if the XML filename cannot be determined. - * @return The base filename used from which the XML was parsed or the default name. - */ - private String xmlFileName(Node node, String defaultName) { - File f = XmlUtils.extractXmlFilename(node); - if (f != null) { - return f.getName(); - } else { - return defaultName; - } - } - - /** - * Tries to returns the base filename & line number from which the XML node was parsed. + * Returns a new {@link FileAndLine} structure that identifies + * the base filename & line number from which the XML node was parsed. + *

+ * When the line number is unknown (e.g. if a {@link Document} instance is given) + * then line number 0 will be used. * - * @param node Any node from a document parsed by {@link XmlUtils#parseDocument(File, ISdkLog)}. - * @param defaultName The string to return if the XML filename cannot be determined. - * @return The base filename used from which the XML was parsed with the line number - * (if available) or the default name. + * @param node The node or document where the error occurs. Must not be null. + * @return A new non-null {@link FileAndLine} combining the file name and line number. */ - private String fileLineInfo(Node node, String defaultName) { - String name = xmlFileName(node, defaultName); - int line = XmlUtils.extractLineNumber(node); - if (line <= 0) { - return name; - } else { - return name + ':' + line; - } + private @NonNull FileAndLine xmlFileAndLine(@NonNull Node node) { + String name = XmlUtils.extractXmlFilename(node); + int line = XmlUtils.extractLineNumber(node); // 0 in case of error or unknown + return new FileAndLine(name, line); } } diff --git a/manifmerger/src/com/android/manifmerger/MergerLog.java b/manifmerger/src/com/android/manifmerger/MergerLog.java new file mode 100755 index 0000000..417e6bb --- /dev/null +++ b/manifmerger/src/com/android/manifmerger/MergerLog.java @@ -0,0 +1,151 @@ +/* + * 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.manifmerger; + +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; +import com.android.sdklib.ISdkLog; + + +/** + * Helper to create {@link IMergerLog} instances with specific purposes. + */ +public abstract class MergerLog { + + /** + * Create a new instance of a {@link MergerLog} that prints to an {@link ISdkLog}. + * + * @param sdkLog A non-null {@link ISdkLog}. + * @return A new IMergerLog. + */ + public static IMergerLog wrapSdkLog(final @NonNull ISdkLog sdkLog) { + return new IMergerLog() { + @Override + public void error( + Severity severity, + FileAndLine location, + String message, + Object...msgParams) { + + switch(severity) { + case INFO: + sdkLog.printf( + "[%1$s] %2$s", //$NON-NLS-1$ + location, + String.format(message, msgParams)); + break; + case WARNING: + sdkLog.warning( + "[%1$s] %2$s", //$NON-NLS-1$ + location, + String.format(message, msgParams)); + break; + case ERROR: + sdkLog.error(null /*throwable*/, + "[%1$s] %2$s", //$NON-NLS-1$ + location, + String.format(message, msgParams)); + break; + } + } + + @Override + public void conflict(Severity severity, + FileAndLine location1, + FileAndLine location2, + String message, + Object...msgParams) { + + switch(severity) { + case INFO: + sdkLog.printf( + "[%1$s, %2$s] %3$s", //$NON-NLS-1$ + location1, + location2, + String.format(message, msgParams)); + break; + case WARNING: + sdkLog.warning( + "[%1$s, %2$s] %3$s", //$NON-NLS-1$ + location1, + location2, + String.format(message, msgParams)); + break; + case ERROR: + sdkLog.error(null /*throwable*/, + "[%1$s, %2$s] %3$s", //$NON-NLS-1$ + location1, + location2, + String.format(message, msgParams)); + break; + } + }; + }; + } + + /* + * Creates a new instance of a {@link MergerLog} that wraps another {@link IMergerLog} + * and overrides the {@link FileAndLine} locations with the arguments specified. + *

+ * An example of usage would be merging temporary files yet associating the errors + * with the original files. + * + * @param parentLog A non-null IMergerLog to wrap. + * @param filePath1 The file path to override in location1 (for errors and conflicts). + * @param filePath2 An optional file path to override in location2 (for conflicts). + * @return A new IMergerLog. + */ + public static IMergerLog mergerLogOverrideLocation( + final @NonNull IMergerLog parentLog, + final @Nullable String filePath1, + final @Nullable String... filePath2) { + return new IMergerLog() { + @Override + public void error( + Severity severity, + FileAndLine location, + String message, + Object...msgParams) { + + if (filePath1 != null) { + location = new FileAndLine(filePath1, location.getLine()); + } + + parentLog.error(severity, location, message, msgParams); + } + + @Override + public void conflict(Severity severity, + FileAndLine location1, + FileAndLine location2, + String message, + Object...msgParams) { + + if (filePath1 != null) { + location1 = new FileAndLine(filePath1, location1.getLine()); + } + + if (filePath2 != null && filePath2.length > 0) { + location2 = new FileAndLine(filePath2[0], location2.getLine()); + } + + parentLog.conflict(severity, location1, location2, message, msgParams); + }; + }; + } + +} diff --git a/manifmerger/src/com/android/manifmerger/XmlUtils.java b/manifmerger/src/com/android/manifmerger/XmlUtils.java index 93df59c..40ddfda 100755 --- a/manifmerger/src/com/android/manifmerger/XmlUtils.java +++ b/manifmerger/src/com/android/manifmerger/XmlUtils.java @@ -18,6 +18,8 @@ package com.android.manifmerger; import com.android.annotations.NonNull; import com.android.annotations.Nullable; +import com.android.manifmerger.IMergerLog.FileAndLine; +import com.android.manifmerger.IMergerLog.Severity; import com.android.sdklib.ISdkLog; import org.w3c.dom.Attr; @@ -52,8 +54,9 @@ import javax.xml.transform.stream.StreamResult; */ class XmlUtils { - private static final String DATA_ORIGIN_FILE = "origin_file"; //$NON-NLS-1$ - private static final String DATA_LINE_NUMBER = "line#"; //$NON-NLS-1$ + private static final String DATA_ORIGIN_FILE = "manif.merger.file"; //$NON-NLS-1$ + private static final String DATA_FILE_NAME = "manif.merger.filename"; //$NON-NLS-1$ + private static final String DATA_LINE_NUMBER = "manif.merger.line#"; //$NON-NLS-1$ /** * Parses the given XML file as a DOM document. @@ -68,7 +71,7 @@ class XmlUtils { * @return A new DOM {@link Document}, or null. */ @Nullable - static Document parseDocument(@NonNull final File xmlFile, @NonNull final ISdkLog log) { + static Document parseDocument(@NonNull final File xmlFile, @NonNull final IMergerLog log) { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); InputSource is = new InputSource(new FileReader(xmlFile)); @@ -80,15 +83,24 @@ class XmlUtils { builder.setErrorHandler(new ErrorHandler() { @Override public void warning(SAXParseException e) { - log.printf("Warning when parsing %s: %s", xmlFile.getName(), e.toString()); + log.error(Severity.WARNING, + new FileAndLine(xmlFile.getName(), 0), + "Warning when parsing: %1$s", + e.toString()); } @Override public void fatalError(SAXParseException e) { - log.printf("Fatal error when parsing %s: %s", xmlFile.getName(), e.toString()); + log.error(Severity.ERROR, + new FileAndLine(xmlFile.getName(), 0), + "Fatal error when parsing: %1$s", + xmlFile.getName(), e.toString()); } @Override public void error(SAXParseException e) { - log.printf("Error when parsing %s: %s", xmlFile.getName(), e.toString()); + log.error(Severity.ERROR, + new FileAndLine(xmlFile.getName(), 0), + "Error when parsing: %1$s", + e.toString()); } }); @@ -99,10 +111,15 @@ class XmlUtils { return doc; } catch (FileNotFoundException e) { - log.error(null, "XML file not found: %s", xmlFile.getName()); + log.error(Severity.ERROR, + new FileAndLine(xmlFile.getName(), 0), + "XML file not found"); } catch (Exception e) { - log.error(e, "Failed to parse XML file: %s", xmlFile.getName()); + log.error(Severity.ERROR, + new FileAndLine(xmlFile.getName(), 0), + "Failed to parse XML file: %1$s", + e.toString()); } return null; @@ -118,7 +135,9 @@ class XmlUtils { * @return A new DOM {@link Document}, or null. */ @Nullable - static Document parseDocument(@NonNull String xml, @NonNull ISdkLog log) { + static Document parseDocument(@NonNull String xml, + @NonNull IMergerLog log, + @NonNull FileAndLine errorContext) { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); InputSource is = new InputSource(new StringReader(xml)); @@ -129,28 +148,50 @@ class XmlUtils { findLineNumbers(doc, 1); return doc; } catch (Exception e) { - log.error(e, "Failed to parse XML string"); + log.error(Severity.ERROR, errorContext, "Failed to parse XML string"); } return null; } /** - * Extracts the origin {@link File} that {@link #parseDocument(File, ISdkLog)} - * added to the XML document. + * Decorates the document with the specified file name, which can be + * retrieved later by calling {@link #extractLineNumber(Node)}. + *

+ * It also tries to add line number information, with the caveat that the + * current implementation is a gross approximation. + *

+ * There is no need to call this after calling one of the {@code parseDocument()} + * methods since they already decorated their own document. + * + * @param doc The document to decorate. + * @param fileName The name to retrieve later for that document. + */ + static void decorateDocument(@NonNull Document doc, @NonNull String fileName) { + doc.setUserData(DATA_FILE_NAME, fileName, null /*handler*/); + findLineNumbers(doc, 1); + } + + /** + * Extracts the origin {@link File} that {@link #parseDocument(File, IMergerLog)} + * added to the XML document or the string added by * - * @param xmlNode Any node from a document returned by {@link #parseDocument(File, ISdkLog)}. + * @param xmlNode Any node from a document returned by {@link #parseDocument(File, IMergerLog)}. * @return The {@link File} object used to create the document or null. */ @Nullable - static File extractXmlFilename(@Nullable Node xmlNode) { + static String extractXmlFilename(@Nullable Node xmlNode) { if (xmlNode != null && xmlNode.getNodeType() != Node.DOCUMENT_NODE) { xmlNode = xmlNode.getOwnerDocument(); } if (xmlNode != null) { Object data = xmlNode.getUserData(DATA_ORIGIN_FILE); if (data instanceof File) { - return (File) data; + return ((File) data).getName(); + } + data = xmlNode.getUserData(DATA_FILE_NAME); + if (data instanceof String) { + return (String) data; } } @@ -163,7 +204,7 @@ class XmlUtils { * already have lost all the information about whitespace between attributes. *

* Also we don't even try to deal with \n vs \r vs \r\n insanity. This only counts - * the \n occuring in text nodes to determine line advances, which is clearly flawed. + * the \n occurring in text nodes to determine line advances, which is clearly flawed. *

* However it's good enough for testing, and we'll replace it by a PositionXmlParser * once it's moved into com.android.util. @@ -192,7 +233,7 @@ class XmlUtils { /** * Extracts the line number that {@link #findLineNumbers} added to the XML nodes. * - * @param xmlNode Any node from a document returned by {@link #parseDocument(File, ISdkLog)}. + * @param xmlNode Any node from a document returned by {@link #parseDocument(File, IMergerLog)}. * @return The line number if found or 0. */ static int extractLineNumber(@Nullable Node xmlNode) { @@ -230,7 +271,7 @@ class XmlUtils { static boolean printXmlFile( @NonNull Document doc, @NonNull File outFile, - @NonNull ISdkLog log) { + @NonNull IMergerLog log) { // Quick thing based on comments from http://stackoverflow.com/questions/139076 try { Transformer tf = TransformerFactory.newInstance().newTransformer(); @@ -242,7 +283,10 @@ class XmlUtils { tf.transform(new DOMSource(doc), new StreamResult(outFile)); return true; } catch (TransformerException e) { - log.error(e, "Failed to write XML file: %s", outFile); + log.error(Severity.ERROR, + new FileAndLine(outFile.getName(), 0), + "Failed to write XML file: %1$s", + e.toString()); return false; } } @@ -258,7 +302,7 @@ class XmlUtils { */ static String printXmlString( @NonNull Document doc, - @NonNull ISdkLog log) { + @NonNull IMergerLog log) { try { Transformer tf = TransformerFactory.newInstance().newTransformer(); tf.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); //$NON-NLS-1$ @@ -270,7 +314,10 @@ class XmlUtils { tf.transform(new DOMSource(doc), new StreamResult(sw)); return sw.toString(); } catch (TransformerException e) { - log.error(e, "Failed to write XML file"); + log.error(Severity.ERROR, + new FileAndLine(extractXmlFilename(doc), 0), + "Failed to write XML file: %1$s", + e.toString()); return null; } } diff --git a/manifmerger/tests/src/com/android/manifmerger/ManifestMergerTestCase.java b/manifmerger/tests/src/com/android/manifmerger/ManifestMergerTestCase.java index a3f0448..13302e7 100755 --- a/manifmerger/tests/src/com/android/manifmerger/ManifestMergerTestCase.java +++ b/manifmerger/tests/src/com/android/manifmerger/ManifestMergerTestCase.java @@ -17,6 +17,7 @@ package com.android.manifmerger; import com.android.annotations.NonNull; +import com.android.manifmerger.IMergerLog.FileAndLine; import com.android.sdklib.mock.MockLog; import org.w3c.dom.Document; @@ -375,7 +376,8 @@ abstract class ManifestMergerTestCase extends TestCase { */ void processTestFiles(TestFiles testFiles) throws Exception { MockLog log = new MockLog(); - ManifestMerger merger = new ManifestMerger(log); + IMergerLog mergerLog = MergerLog.wrapSdkLog(log); + ManifestMerger merger = new ManifestMerger(mergerLog); boolean processOK = merger.process(testFiles.getActualResult(), testFiles.getMain(), testFiles.getLibs()); @@ -400,20 +402,19 @@ abstract class ManifestMergerTestCase extends TestCase { // Test result XML. There should always be one created // since the process action does not stop on errors. log.clear(); - Document document = XmlUtils.parseDocument(testFiles.getActualResult(), log); + Document document = XmlUtils.parseDocument(testFiles.getActualResult(), mergerLog); assertNotNull(document); assert document != null; // for Eclipse null analysis - String actual = XmlUtils.printXmlString( - document, - log); + String actual = XmlUtils.printXmlString(document, mergerLog); assertEquals("Error parsing actual result XML", "[]", log.toString()); log.clear(); - document = XmlUtils.parseDocument(testFiles.getExpectedResult(), log); + document = XmlUtils.parseDocument( + testFiles.getExpectedResult(), + mergerLog, + new FileAndLine("", 0)); assertNotNull(document); assert document != null; - String expected = XmlUtils.printXmlString( - document, - log); + String expected = XmlUtils.printXmlString(document, mergerLog); assertEquals("Error parsing expected result XML", "[]", log.toString()); assertEquals("Error comparing expected to actual result", expected, actual); diff --git a/manifmerger/tests/src/com/android/manifmerger/data/10_activity_merge.xml b/manifmerger/tests/src/com/android/manifmerger/data/10_activity_merge.xml index 56c0b53..b37ae66 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/10_activity_merge.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/10_activity_merge.xml @@ -374,5 +374,5 @@ @errors -P [ManifestMergerTest2_lib2_activity.xml:6, ManifestMergerTest0_main.xml:31] Skipping identical /manifest/application/activity[@name=com.example.LibActivity] element. -P [ManifestMergerTest3_lib3_alias.xml:19, ManifestMergerTest0_main.xml] Skipping identical /manifest/application/activity[@name=com.example.LibActivity2] element. +P [ManifestMergerTest0_main.xml:31, ManifestMergerTest2_lib2_activity.xml:6] Skipping identical /manifest/application/activity[@name=com.example.LibActivity] element. +P [ManifestMergerTest0_main.xml, ManifestMergerTest3_lib3_alias.xml:19] Skipping identical /manifest/application/activity[@name=com.example.LibActivity2] element. diff --git a/manifmerger/tests/src/com/android/manifmerger/data/11_activity_dup.xml b/manifmerger/tests/src/com/android/manifmerger/data/11_activity_dup.xml index 48c7b27..dc2b28b 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/11_activity_dup.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/11_activity_dup.xml @@ -368,17 +368,17 @@ @errors -E [ManifestMergerTest1_lib1_widget.xml:16, ManifestMergerTest0_main.xml:32] Trying to merge incompatible /manifest/application/activity[@name=com.example.WidgetConfigurationUI] element: +E [ManifestMergerTest0_main.xml:32, ManifestMergerTest1_lib1_widget.xml:16] Trying to merge incompatible /manifest/application/activity[@name=com.example.WidgetConfigurationUI] element: -- ++ (end reached) -E [ManifestMergerTest2_lib2_activity.xml:6, ManifestMergerTest0_main.xml:38] Trying to merge incompatible /manifest/application/activity[@name=com.example.LibActivity] element: +E [ManifestMergerTest0_main.xml:38, ManifestMergerTest2_lib2_activity.xml:6] Trying to merge incompatible /manifest/application/activity[@name=com.example.LibActivity] element: @android:icon = @drawable/lib_activity_icon @android:label = @string/lib_activity_name @android:name = com.example.LibActivity -- @android:theme = @style/Lib.Theme -E [ManifestMergerTest3_lib3_alias.xml:19, ManifestMergerTest0_main.xml] Trying to merge incompatible /manifest/application/activity[@name=com.example.LibActivity2] element: +E [ManifestMergerTest0_main.xml, ManifestMergerTest3_lib3_alias.xml:19] Trying to merge incompatible /manifest/application/activity[@name=com.example.LibActivity2] element: diff --git a/manifmerger/tests/src/com/android/manifmerger/data/12_alias_dup.xml b/manifmerger/tests/src/com/android/manifmerger/data/12_alias_dup.xml index e96c8a2..cfc2082 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/12_alias_dup.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/12_alias_dup.xml @@ -190,14 +190,14 @@ @errors -P [ManifestMergerTest1_lib1.xml:6, ManifestMergerTest0_main.xml:6] Skipping identical /manifest/application/activity-alias[@name=com.example.alias.MyActivity1] element. -E [ManifestMergerTest1_lib1.xml:14, ManifestMergerTest0_main.xml:13] Trying to merge incompatible /manifest/application/activity-alias[@name=com.example.alias.MyActivity2] element: +P [ManifestMergerTest0_main.xml:6, ManifestMergerTest1_lib1.xml:6] Skipping identical /manifest/application/activity-alias[@name=com.example.alias.MyActivity1] element. +E [ManifestMergerTest0_main.xml:13, ManifestMergerTest1_lib1.xml:14] Trying to merge incompatible /manifest/application/activity-alias[@name=com.example.alias.MyActivity2] element: ++ @android:icon = @drawable/alias_icon2 ++ @android:label = @string/alias_name2 @android:name = com.example.alias.MyActivity2 @android:targetActivity = com.example.MainActivity2 -E [ManifestMergerTest2_lib2.xml:6, ManifestMergerTest0_main.xml] Trying to merge incompatible /manifest/application/activity-alias[@name=com.example.alias.MyActivity3] element: +E [ManifestMergerTest0_main.xml, ManifestMergerTest2_lib2.xml:6] Trying to merge incompatible /manifest/application/activity-alias[@name=com.example.alias.MyActivity3] element: @android:icon = @drawable/alias_icon3 @android:label = @string/alias_name3 diff --git a/manifmerger/tests/src/com/android/manifmerger/data/13_service_dup.xml b/manifmerger/tests/src/com/android/manifmerger/data/13_service_dup.xml index bc7c0c9..d735b92 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/13_service_dup.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/13_service_dup.xml @@ -144,12 +144,12 @@ @errors -P [ManifestMergerTest1_lib1.xml:6, ManifestMergerTest0_main.xml:6] Skipping identical /manifest/application/service[@name=com.example.AppService1] element. -E [ManifestMergerTest1_lib1.xml:9, ManifestMergerTest0_main.xml:8] Trying to merge incompatible /manifest/application/service[@name=com.example.AppService2] element: +P [ManifestMergerTest0_main.xml:6, ManifestMergerTest1_lib1.xml:6] Skipping identical /manifest/application/service[@name=com.example.AppService1] element. +E [ManifestMergerTest0_main.xml:8, ManifestMergerTest1_lib1.xml:9] Trying to merge incompatible /manifest/application/service[@name=com.example.AppService2] element: -- ++ (end reached) -E [ManifestMergerTest2_lib2.xml:6, ManifestMergerTest0_main.xml] Trying to merge incompatible /manifest/application/service[@name=com.example.AppService3] element: +E [ManifestMergerTest0_main.xml, ManifestMergerTest2_lib2.xml:6] Trying to merge incompatible /manifest/application/service[@name=com.example.AppService3] element: -- (end reached) ++ diff --git a/manifmerger/tests/src/com/android/manifmerger/data/14_receiver_dup.xml b/manifmerger/tests/src/com/android/manifmerger/data/14_receiver_dup.xml index 328f1fc..91f3bf0 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/14_receiver_dup.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/14_receiver_dup.xml @@ -163,12 +163,12 @@ @errors -P [ManifestMergerTest1_lib1.xml:6, ManifestMergerTest0_main.xml:6] Skipping identical /manifest/application/receiver[@name=com.example.AppReceiver1] element. -E [ManifestMergerTest1_lib1.xml:13, ManifestMergerTest0_main.xml:12] Trying to merge incompatible /manifest/application/receiver[@name=com.example.AppReceiver2] element: +P [ManifestMergerTest0_main.xml:6, ManifestMergerTest1_lib1.xml:6] Skipping identical /manifest/application/receiver[@name=com.example.AppReceiver1] element. +E [ManifestMergerTest0_main.xml:12, ManifestMergerTest1_lib1.xml:13] Trying to merge incompatible /manifest/application/receiver[@name=com.example.AppReceiver2] element: ++ @android:icon = @drawable/app_icon @android:name = com.example.AppReceiver2 -E [ManifestMergerTest2_lib2.xml:6, ManifestMergerTest0_main.xml] Trying to merge incompatible /manifest/application/receiver[@name=com.example.AppReceiver3] element: +E [ManifestMergerTest0_main.xml, ManifestMergerTest2_lib2.xml:6] Trying to merge incompatible /manifest/application/receiver[@name=com.example.AppReceiver3] element: diff --git a/manifmerger/tests/src/com/android/manifmerger/data/15_provider_dup.xml b/manifmerger/tests/src/com/android/manifmerger/data/15_provider_dup.xml index 91fe270..9f6e5fa 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/15_provider_dup.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/15_provider_dup.xml @@ -132,13 +132,13 @@ @errors -P [ManifestMergerTest1_lib1.xml:6, ManifestMergerTest0_main.xml:6] Skipping identical /manifest/application/provider[@name=com.example.Provider1] element. -E [ManifestMergerTest1_lib1.xml:9, ManifestMergerTest0_main.xml:8] Trying to merge incompatible /manifest/application/provider[@name=com.example.Provider2] element: +P [ManifestMergerTest0_main.xml:6, ManifestMergerTest1_lib1.xml:6] Skipping identical /manifest/application/provider[@name=com.example.Provider1] element. +E [ManifestMergerTest0_main.xml:8, ManifestMergerTest1_lib1.xml:9] Trying to merge incompatible /manifest/application/provider[@name=com.example.Provider2] element: -- @android:authorities = com.example.android.apis.app.thingy2 -- @android:enabled = @bool/someConditionalValue2 @android:name = com.example.Provider2 -E [ManifestMergerTest2_lib2.xml:6, ManifestMergerTest0_main.xml] Trying to merge incompatible /manifest/application/provider[@name=com.example.Provider3] element: +E [ManifestMergerTest0_main.xml, ManifestMergerTest2_lib2.xml:6] Trying to merge incompatible /manifest/application/provider[@name=com.example.Provider3] element: @android:authorities = com.example.android.apis.app.thingy3 ++ @android:enabled = @bool/someConditionalValue diff --git a/manifmerger/tests/src/com/android/manifmerger/data/21_uses_lib_errors.xml b/manifmerger/tests/src/com/android/manifmerger/data/21_uses_lib_errors.xml index da244c6..aa35bdd 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/21_uses_lib_errors.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/21_uses_lib_errors.xml @@ -196,7 +196,7 @@ E [ManifestMergerTest1_lib1.xml:7] Undefined 'name' attribute in /manifest/appli E [ManifestMergerTest1_lib1.xml:8] Undefined 'name' attribute in /manifest/application/uses-library. W [ManifestMergerTest0_main.xml:12] Invalid attribute 'required' in /manifest/application/uses-library[@name=com.example.SomeLibrary2_RequiredTrue] element: Expected 'true' or 'false' but found 'booh!'. -W [ManifestMergerTest0_main.xml:15] has more than one /manifest/application/uses-library[@name=com.example.SomeLibrary3_RequiredFalse] element. +W [ManifestMergerTest0_main.xml:15] Manifest has more than one /manifest/application/uses-library[@name=com.example.SomeLibrary3_RequiredFalse] element. W [ManifestMergerTest1_lib1.xml:17] Invalid attribute 'required' in /manifest/application/uses-library[@name=com.example.SomeLibrary4_RequiredFalse] element: Expected 'true' or 'false' but found 'foo'. -W [ManifestMergerTest0_main.xml:15] has more than one /manifest/application/uses-library[@name=com.example.SomeLibrary3_RequiredFalse] element. +W [ManifestMergerTest0_main.xml:15] Manifest has more than one /manifest/application/uses-library[@name=com.example.SomeLibrary3_RequiredFalse] element. diff --git a/manifmerger/tests/src/com/android/manifmerger/data/26_permission_dup.xml b/manifmerger/tests/src/com/android/manifmerger/data/26_permission_dup.xml index e4be0e2..7d94c41 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/26_permission_dup.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/26_permission_dup.xml @@ -264,7 +264,7 @@ @errors -E [ManifestMergerTest1_lib1.xml:4, ManifestMergerTest0_main.xml:12] Trying to merge incompatible /manifest/permission[@name=com.example.DangerWillRobinson] element: +E [ManifestMergerTest0_main.xml:12, ManifestMergerTest1_lib1.xml:4] Trying to merge incompatible /manifest/permission[@name=com.example.DangerWillRobinson] element: -- @android:description = Different description here ++ @android:description = Insert boring description here @@ -274,30 +274,30 @@ E [ManifestMergerTest1_lib1.xml:4, ManifestMergerTest0_main.xml:12] Trying to me @android:name = com.example.DangerWillRobinson @android:permissionGroup = com.example.MasterControlPermission @android:protectionLevel = dangerous -E [ManifestMergerTest1_lib1.xml:8, ManifestMergerTest0_main.xml:14] Trying to merge incompatible /manifest/permission[@name=com.example.WhatWereYouThinking] element: +E [ManifestMergerTest0_main.xml:14, ManifestMergerTest1_lib1.xml:8] Trying to merge incompatible /manifest/permission[@name=com.example.WhatWereYouThinking] element: @android:name = com.example.WhatWereYouThinking @android:permissionGroup = com.example.MasterControlPermission -- @android:protectionLevel = normal ++ @android:protectionLevel = signatureOrSystem -E [ManifestMergerTest1_lib1.xml:5, ManifestMergerTest0_main.xml:16] Trying to merge incompatible /manifest/permission-group[@name=com.example.MasterControlPermission] element: +E [ManifestMergerTest0_main.xml:16, ManifestMergerTest1_lib1.xml:5] Trying to merge incompatible /manifest/permission-group[@name=com.example.MasterControlPermission] element: @android:description = Nobody expects... ++ @android:icon = @drawable/ignored_icon @android:label = the Spanish Inquisition @android:name = com.example.MasterControlPermission -E [ManifestMergerTest1_lib1.xml:6, ManifestMergerTest0_main.xml:18] Trying to merge incompatible /manifest/permission-tree[@name=com.example.PermTree] element: +E [ManifestMergerTest0_main.xml:18, ManifestMergerTest1_lib1.xml:6] Trying to merge incompatible /manifest/permission-tree[@name=com.example.PermTree] element: ++ @android:label = This is not a label -- @android:label = This is not the same label @android:name = com.example.PermTree -E [ManifestMergerTest2_lib2.xml:6, ManifestMergerTest0_main.xml] Trying to merge incompatible /manifest/permission[@name=com.example.Permission1] element: +E [ManifestMergerTest0_main.xml, ManifestMergerTest2_lib2.xml:6] Trying to merge incompatible /manifest/permission[@name=com.example.Permission1] element: @android:name = com.example.Permission1 @android:permissionGroup = com.example.Permission1 ++ @android:protectionLevel = normal -- @android:protectionLevel = system -E [ManifestMergerTest2_lib2.xml:7, ManifestMergerTest0_main.xml] Trying to merge incompatible /manifest/permission-tree[@name=com.example.PermTree1] element: +E [ManifestMergerTest0_main.xml, ManifestMergerTest2_lib2.xml:7] Trying to merge incompatible /manifest/permission-tree[@name=com.example.PermTree1] element: -- @android:description = Extra description @android:name = com.example.PermTree1 diff --git a/manifmerger/tests/src/com/android/manifmerger/data/33_uses_sdk_minsdk_conflict.xml b/manifmerger/tests/src/com/android/manifmerger/data/33_uses_sdk_minsdk_conflict.xml index 0d0ab87..6984d26 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/33_uses_sdk_minsdk_conflict.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/33_uses_sdk_minsdk_conflict.xml @@ -99,11 +99,11 @@ @errors -E [ManifestMergerTest1_lib1.xml:4, ManifestMergerTest0_main.xml:4] Main manifest has but library uses minSdkVersion='4' +E [ManifestMergerTest0_main.xml:4, ManifestMergerTest1_lib1.xml:4] Main manifest has but library uses minSdkVersion='4' Note: main manifest lacks a declaration, which defaults to value 1. -E [ManifestMergerTest2_lib2.xml:3, ManifestMergerTest0_main.xml:4] Main manifest has but library uses minSdkVersion='10' +E [ManifestMergerTest0_main.xml:4, ManifestMergerTest2_lib2.xml:3] Main manifest has but library uses minSdkVersion='10' Note: main manifest lacks a declaration, which defaults to value 1. -E [ManifestMergerTest3_lib3.xml:3, ManifestMergerTest0_main.xml:4] Main manifest has but library uses minSdkVersion='11' +E [ManifestMergerTest0_main.xml:4, ManifestMergerTest3_lib3.xml:3] Main manifest has but library uses minSdkVersion='11' Note: main manifest lacks a declaration, which defaults to value 1. E [ManifestMergerTest4_lib4_parsingError.xml:4] Failed to parse : must be an integer number. E [ManifestMergerTest5_lib5_parsingError.xml:4] Failed to parse : must be an integer number. diff --git a/manifmerger/tests/src/com/android/manifmerger/data/36_uses_sdk_targetsdk_warning.xml b/manifmerger/tests/src/com/android/manifmerger/data/36_uses_sdk_targetsdk_warning.xml index 2e87e19..303855b 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/36_uses_sdk_targetsdk_warning.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/36_uses_sdk_targetsdk_warning.xml @@ -70,4 +70,4 @@ @errors -W [ManifestMergerTest1_lib1.xml:4, ManifestMergerTest0_main.xml:4] Main manifest has but library uses targetSdkVersion='11' +W [ManifestMergerTest0_main.xml:4, ManifestMergerTest1_lib1.xml:4] Main manifest has but library uses targetSdkVersion='11' diff --git a/manifmerger/tests/src/com/android/manifmerger/data/41_uses_feat_errors.xml b/manifmerger/tests/src/com/android/manifmerger/data/41_uses_feat_errors.xml index 85eaf1d..b052462 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/41_uses_feat_errors.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/41_uses_feat_errors.xml @@ -199,7 +199,7 @@ E [ManifestMergerTest1_lib1.xml:5] Undefined 'name' attribute in /manifest/uses- E [ManifestMergerTest1_lib1.xml:6] Undefined 'name' attribute in /manifest/uses-feature. W [ManifestMergerTest0_main.xml:10] Invalid attribute 'required' in /manifest/uses-feature[@name=com.example.SomeFeature2_RequiredTrue] element: Expected 'true' or 'false' but found 'booh!'. -W [ManifestMergerTest0_main.xml:13] has more than one /manifest/uses-feature[@name=com.example.SomeFeature3_RequiredFalse] element. +W [ManifestMergerTest0_main.xml:13] Manifest has more than one /manifest/uses-feature[@name=com.example.SomeFeature3_RequiredFalse] element. W [ManifestMergerTest1_lib1.xml:15] Invalid attribute 'required' in /manifest/uses-feature[@name=com.example.SomeFeature4_RequiredFalse] element: Expected 'true' or 'false' but found 'foo'. -W [ManifestMergerTest0_main.xml:13] has more than one /manifest/uses-feature[@name=com.example.SomeFeature3_RequiredFalse] element. +W [ManifestMergerTest0_main.xml:13] Manifest has more than one /manifest/uses-feature[@name=com.example.SomeFeature3_RequiredFalse] element. diff --git a/manifmerger/tests/src/com/android/manifmerger/data/47_uses_feat_gles_conflict.xml b/manifmerger/tests/src/com/android/manifmerger/data/47_uses_feat_gles_conflict.xml index 05f468f..f369a5c 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/47_uses_feat_gles_conflict.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/47_uses_feat_gles_conflict.xml @@ -151,10 +151,10 @@ @errors -W [ManifestMergerTest1_lib1.xml:4, ManifestMergerTest0_main.xml:1] Main manifest has but library uses glEsVersion='0x00020001' +W [ManifestMergerTest0_main.xml:1, ManifestMergerTest1_lib1.xml:4] Main manifest has but library uses glEsVersion='0x00020001' Note: main manifest lacks a declaration, and thus defaults to glEsVersion=0x00010000. W [ManifestMergerTest2_lib2.xml:12] Ignoring because it's smaller than 1.0. W [ManifestMergerTest2_lib2.xml:15] Ignoring because it's smaller than 1.0. E [ManifestMergerTest2_lib2.xml:21] Failed to parse : must be an integer in the form 0x00020001. -W [ManifestMergerTest2_lib2.xml:18, ManifestMergerTest0_main.xml:1] Main manifest has but library uses glEsVersion='0xffffffff' +W [ManifestMergerTest0_main.xml:1, ManifestMergerTest2_lib2.xml:18] Main manifest has but library uses glEsVersion='0xffffffff' Note: main manifest lacks a declaration, and thus defaults to glEsVersion=0x00010000. diff --git a/manifmerger/tests/src/com/android/manifmerger/data/50_uses_conf_warning.xml b/manifmerger/tests/src/com/android/manifmerger/data/50_uses_conf_warning.xml index 4b79dc6..e8c0a09 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/50_uses_conf_warning.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/50_uses_conf_warning.xml @@ -151,7 +151,7 @@ @errors -W [ManifestMergerTest2_lib2.xml:4] /manifest/uses-configuration missing from ManifestMergerTest0_main.xml: +W [ManifestMergerTest0_main.xml:1, ManifestMergerTest2_lib2.xml:4] /manifest/uses-configuration defined in library, missing from main manifest: @android:reqFiveWayNav = false @android:reqNavigation = trackball diff --git a/manifmerger/tests/src/com/android/manifmerger/data/52_support_screens_warning.xml b/manifmerger/tests/src/com/android/manifmerger/data/52_support_screens_warning.xml index 737144a..6659000 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/52_support_screens_warning.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/52_support_screens_warning.xml @@ -152,7 +152,7 @@ @errors -W [ManifestMergerTest2_lib2.xml:4] /manifest/supports-screens missing from ManifestMergerTest0_main.xml: +W [ManifestMergerTest0_main.xml:1, ManifestMergerTest2_lib2.xml:4] /manifest/supports-screens defined in library, missing from main manifest: @android:resizeable = false @android:smallScreens = false diff --git a/manifmerger/tests/src/com/android/manifmerger/data/54_compat_screens_warning.xml b/manifmerger/tests/src/com/android/manifmerger/data/54_compat_screens_warning.xml index 35085fd..b93ea99 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/54_compat_screens_warning.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/54_compat_screens_warning.xml @@ -171,7 +171,7 @@ @errors -W [ManifestMergerTest2_lib2.xml:4] /manifest/compatible-screens missing from ManifestMergerTest0_main.xml: +W [ManifestMergerTest0_main.xml:1, ManifestMergerTest2_lib2.xml:4] /manifest/compatible-screens defined in library, missing from main manifest: @android:screenDensity = ldpi @@ -179,12 +179,12 @@ W [ManifestMergerTest2_lib2.xml:4] /manifest/compatible-screens missing from Man @android:screenDensity = mdpi @android:screenSize = normal -W [ManifestMergerTest2_lib2.xml:9] /manifest/compatible-screens missing from ManifestMergerTest0_main.xml: +W [ManifestMergerTest0_main.xml:1, ManifestMergerTest2_lib2.xml:9] /manifest/compatible-screens defined in library, missing from main manifest: @android:screenDensity = ldpi @android:screenSize = small -W [ManifestMergerTest2_lib2.xml:13] /manifest/compatible-screens missing from ManifestMergerTest0_main.xml: +W [ManifestMergerTest0_main.xml:1, ManifestMergerTest2_lib2.xml:13] /manifest/compatible-screens defined in library, missing from main manifest: @android:screenDensity = ldpi diff --git a/manifmerger/tests/src/com/android/manifmerger/data/56_support_gltext_warning.xml b/manifmerger/tests/src/com/android/manifmerger/data/56_support_gltext_warning.xml index 9cc5089..5882cfc 100755 --- a/manifmerger/tests/src/com/android/manifmerger/data/56_support_gltext_warning.xml +++ b/manifmerger/tests/src/com/android/manifmerger/data/56_support_gltext_warning.xml @@ -143,6 +143,6 @@ @errors -W [ManifestMergerTest2_lib2.xml:4] /manifest/supports-gl-texture missing from ManifestMergerTest0_main.xml: +W [ManifestMergerTest0_main.xml:1, ManifestMergerTest2_lib2.xml:4] /manifest/supports-gl-texture defined in library, missing from main manifest: @android:name = some.gl.texture3 -- cgit v1.1