Search in sources :

Example 36 with NonNull

use of com.android.annotations.NonNull in project bazel by bazelbuild.

the class FileUtils method readSegment.

/**
     * Reads a portion of a file to memory.
     *
     * @param file the file to read data from
     * @param start the offset in the file to start reading
     * @param length the number of bytes to read
     * @return the bytes read
     * @throws Exception failed to read the file
     */
@NonNull
public static byte[] readSegment(@NonNull File file, long start, int length) throws Exception {
    Preconditions.checkArgument(start >= 0, "start < 0");
    Preconditions.checkArgument(length >= 0, "length < 0");
    byte[] data;
    boolean threw = true;
    RandomAccessFile raf = new RandomAccessFile(file, "r");
    try {
        raf.seek(start);
        data = new byte[length];
        int tot = 0;
        while (tot < length) {
            int r = raf.read(data, tot, length - tot);
            if (r < 0) {
                throw new EOFException();
            }
            tot += r;
        }
        threw = false;
    } finally {
        Closeables.close(raf, threw);
    }
    return data;
}
Also used : RandomAccessFile(java.io.RandomAccessFile) EOFException(java.io.EOFException) NonNull(com.android.annotations.NonNull)

Example 37 with NonNull

use of com.android.annotations.NonNull in project buck by facebook.

the class ManifestMerger2 method instantRunReplacement.

@NonNull
private static XmlDocument instantRunReplacement(XmlDocument document) {
    Optional<XmlElement> applicationOptional = document.getByTypeAndKey(ManifestModel.NodeTypes.APPLICATION, null);
    if (applicationOptional.isPresent()) {
        XmlElement application = applicationOptional.get();
        Attr nameAttribute = application.getXml().getAttributeNodeNS(SdkConstants.ANDROID_URI, "name");
        if (nameAttribute != null) {
            String originalAppName = nameAttribute.getValue();
            if (BOOTSTRAP_APPLICATION.equals(originalAppName)) {
                return document;
            }
            application.getXml().setAttribute(SdkConstants.ATTR_NAME, originalAppName);
            application.getXml().setAttributeNS(SdkConstants.ANDROID_URI, nameAttribute.getName(), BOOTSTRAP_APPLICATION);
        } else {
            application.getXml().setAttributeNS(SdkConstants.ANDROID_URI, SdkConstants.ANDROID_NS_NAME_PREFIX + SdkConstants.ATTR_NAME, BOOTSTRAP_APPLICATION);
        }
    }
    return document.reparse();
}
Also used : Attr(org.w3c.dom.Attr) NonNull(com.android.annotations.NonNull)

Example 38 with NonNull

use of com.android.annotations.NonNull in project buck by facebook.

the class ManifestMerger2 method merge.

/**
     * Perform high level ordering of files merging and delegates actual merging to
     * {@link XmlDocument#merge(XmlDocument, com.android.manifmerger.MergingReport.Builder)}
     *
     * @return the merging activity report.
     * @throws MergeFailureException if the merging cannot be completed (for instance, if xml
     * files cannot be loaded).
     */
@NonNull
private MergingReport merge() throws MergeFailureException {
    // initiate a new merging report
    MergingReport.Builder mergingReportBuilder = new MergingReport.Builder(mLogger);
    SelectorResolver selectors = new SelectorResolver();
    // load all the libraries xml files up front to have a list of all possible node:selector
    // values.
    List<LoadedManifestInfo> loadedLibraryDocuments = loadLibraries(selectors, mergingReportBuilder);
    // load the main manifest file to do some checking along the way.
    LoadedManifestInfo loadedMainManifestInfo = load(new ManifestInfo(mManifestFile.getName(), mManifestFile, XmlDocument.Type.MAIN, Optional.<String>absent()), selectors, mergingReportBuilder);
    // first do we have a package declaration in the main manifest ?
    Optional<XmlAttribute> mainPackageAttribute = loadedMainManifestInfo.getXmlDocument().getPackage();
    if (!mainPackageAttribute.isPresent()) {
        mergingReportBuilder.addMessage(loadedMainManifestInfo.getXmlDocument().getSourceFile(), MergingReport.Record.Severity.ERROR, String.format("Main AndroidManifest.xml at %1$s manifest:package attribute " + "is not declared", loadedMainManifestInfo.getXmlDocument().getSourceFile().print(true)));
        return mergingReportBuilder.build();
    }
    // perform system property injection
    performSystemPropertiesInjection(mergingReportBuilder, loadedMainManifestInfo.getXmlDocument());
    // force the re-parsing of the xml as elements may have been added through system
    // property injection.
    loadedMainManifestInfo = new LoadedManifestInfo(loadedMainManifestInfo, loadedMainManifestInfo.getOriginalPackageName(), loadedMainManifestInfo.getXmlDocument().reparse());
    // invariant : xmlDocumentOptional holds the higher priority document and we try to
    // merge in lower priority documents.
    Optional<XmlDocument> xmlDocumentOptional = Optional.absent();
    for (File inputFile : mFlavorsAndBuildTypeFiles) {
        mLogger.info("Merging flavors and build manifest %s \n", inputFile.getPath());
        LoadedManifestInfo overlayDocument = load(new ManifestInfo(null, inputFile, XmlDocument.Type.OVERLAY, Optional.of(mainPackageAttribute.get().getValue())), selectors, mergingReportBuilder);
        // check package declaration.
        Optional<XmlAttribute> packageAttribute = overlayDocument.getXmlDocument().getPackage();
        // if both files declare a package name, it should be the same.
        if (loadedMainManifestInfo.getOriginalPackageName().isPresent() && packageAttribute.isPresent() && !loadedMainManifestInfo.getOriginalPackageName().get().equals(packageAttribute.get().getValue())) {
            // no suggestion for library since this is actually forbidden to change the
            // the package name per flavor.
            String message = mMergeType == MergeType.APPLICATION ? String.format("Overlay manifest:package attribute declared at %1$s value=(%2$s)\n" + "\thas a different value=(%3$s) " + "declared in main manifest at %4$s\n" + "\tSuggestion: remove the overlay declaration at %5$s " + "\tand place it in the build.gradle:\n" + "\t\tflavorName {\n" + "\t\t\tapplicationId = \"%2$s\"\n" + "\t\t}", packageAttribute.get().printPosition(), packageAttribute.get().getValue(), mainPackageAttribute.get().getValue(), mainPackageAttribute.get().printPosition(), packageAttribute.get().getSourceFile().print(true)) : String.format("Overlay manifest:package attribute declared at %1$s value=(%2$s)\n" + "\thas a different value=(%3$s) " + "declared in main manifest at %4$s", packageAttribute.get().printPosition(), packageAttribute.get().getValue(), mainPackageAttribute.get().getValue(), mainPackageAttribute.get().printPosition());
            mergingReportBuilder.addMessage(overlayDocument.getXmlDocument().getSourceFile(), MergingReport.Record.Severity.ERROR, message);
            return mergingReportBuilder.build();
        }
        overlayDocument.getXmlDocument().getRootNode().getXml().setAttribute("package", mainPackageAttribute.get().getValue());
        xmlDocumentOptional = merge(xmlDocumentOptional, overlayDocument, mergingReportBuilder);
        if (!xmlDocumentOptional.isPresent()) {
            return mergingReportBuilder.build();
        }
    }
    mLogger.info("Merging main manifest %s\n", mManifestFile.getPath());
    xmlDocumentOptional = merge(xmlDocumentOptional, loadedMainManifestInfo, mergingReportBuilder);
    if (!xmlDocumentOptional.isPresent()) {
        return mergingReportBuilder.build();
    }
    // force main manifest package into resulting merged file when creating a library manifest.
    if (mMergeType == MergeType.LIBRARY) {
        // extract the package name...
        String mainManifestPackageName = loadedMainManifestInfo.getXmlDocument().getRootNode().getXml().getAttribute("package");
        // save it in the selector instance.
        if (!Strings.isNullOrEmpty(mainManifestPackageName)) {
            xmlDocumentOptional.get().getRootNode().getXml().setAttribute("package", mainManifestPackageName);
        }
    }
    for (LoadedManifestInfo libraryDocument : loadedLibraryDocuments) {
        mLogger.info("Merging library manifest " + libraryDocument.getLocation());
        xmlDocumentOptional = merge(xmlDocumentOptional, libraryDocument, mergingReportBuilder);
        if (!xmlDocumentOptional.isPresent()) {
            return mergingReportBuilder.build();
        }
    }
    // done with proper merging phase, now we need to trim unwanted elements, placeholder
    // substitution and system properties injection.
    ElementsTrimmer.trim(xmlDocumentOptional.get(), mergingReportBuilder);
    if (mergingReportBuilder.hasErrors()) {
        return mergingReportBuilder.build();
    }
    if (!mOptionalFeatures.contains(Invoker.Feature.NO_PLACEHOLDER_REPLACEMENT)) {
        // do one last placeholder substitution, this is useful as we don't stop the build
        // when a library failed a placeholder substitution, but the element might have
        // been overridden so the problem was transient. However, with the final document
        // ready, all placeholders values must have been provided.
        performPlaceHolderSubstitution(loadedMainManifestInfo, xmlDocumentOptional.get(), mergingReportBuilder);
        if (mergingReportBuilder.hasErrors()) {
            return mergingReportBuilder.build();
        }
    }
    // perform system property injection.
    performSystemPropertiesInjection(mergingReportBuilder, xmlDocumentOptional.get());
    XmlDocument finalMergedDocument = xmlDocumentOptional.get();
    PostValidator.validate(finalMergedDocument, mergingReportBuilder);
    if (mergingReportBuilder.hasErrors()) {
        finalMergedDocument.getRootNode().addMessage(mergingReportBuilder, MergingReport.Record.Severity.WARNING, "Post merge validation failed");
    }
    // finally optional features handling.
    processOptionalFeatures(finalMergedDocument, mergingReportBuilder);
    MergingReport mergingReport = mergingReportBuilder.build();
    if (mReportFile.isPresent()) {
        writeReport(mergingReport);
    }
    return mergingReport;
}
Also used : File(java.io.File) NonNull(com.android.annotations.NonNull)

Example 39 with NonNull

use of com.android.annotations.NonNull in project buck by facebook.

the class ToolsInstructionsCleaner method cleanToolsReferences.

@NonNull
private static MergingReport.Result cleanToolsReferences(@NonNull ManifestMerger2.MergeType mergeType, @NonNull Element element, @NonNull ILogger logger) {
    NamedNodeMap namedNodeMap = element.getAttributes();
    if (namedNodeMap != null) {
        // make a copy of the original list of attributes as we will remove some during this
        // process.
        List<Node> attributes = new ArrayList<Node>();
        for (int i = 0; i < namedNodeMap.getLength(); i++) {
            attributes.add(namedNodeMap.item(i));
        }
        for (Node attribute : attributes) {
            if (SdkConstants.TOOLS_URI.equals(attribute.getNamespaceURI())) {
                // we need to special case when the element contained tools:node="remove"
                // since it also needs to be deleted unless it had a selector.
                // if this is tools:node="removeAll", we always delete the element whether or
                // not there is a tools:selector.
                boolean hasSelector = namedNodeMap.getNamedItemNS(SdkConstants.TOOLS_URI, "selector") != null;
                if (attribute.getLocalName().equals(NodeOperationType.NODE_LOCAL_NAME) && (attribute.getNodeValue().equals(REMOVE_ALL_OPERATION_XML_MAME) || (attribute.getNodeValue().equals(REMOVE_OPERATION_XML_MAME)) && !hasSelector)) {
                    if (element.getParentNode().getNodeType() == Node.DOCUMENT_NODE) {
                        logger.error(null, /* Throwable */
                        String.format("tools:node=\"%1$s\" not allowed on top level %2$s element", attribute.getNodeValue(), XmlNode.unwrapName(element)));
                        return ERROR;
                    } else {
                        element.getParentNode().removeChild(element);
                    }
                } else {
                    // libraries.
                    if (mergeType != ManifestMerger2.MergeType.LIBRARY) {
                        element.removeAttributeNS(attribute.getNamespaceURI(), attribute.getLocalName());
                    }
                }
            }
            // this could also be the xmlns:tools declaration.
            if (attribute.getNodeName().startsWith(SdkConstants.XMLNS_PREFIX) && SdkConstants.TOOLS_URI.equals(attribute.getNodeValue()) && mergeType != ManifestMerger2.MergeType.LIBRARY) {
                element.removeAttribute(attribute.getNodeName());
            }
        }
    }
    // make a copy of the element children since we will be removing some during
    // this process, we don't want side effects.
    NodeList childNodes = element.getChildNodes();
    ImmutableList.Builder<Element> childElements = ImmutableList.builder();
    for (int i = 0; i < childNodes.getLength(); i++) {
        Node node = childNodes.item(i);
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            childElements.add((Element) node);
        }
    }
    for (Element childElement : childElements.build()) {
        if (cleanToolsReferences(mergeType, childElement, logger) == ERROR) {
            return ERROR;
        }
    }
    return MergingReport.Result.SUCCESS;
}
Also used : NamedNodeMap(org.w3c.dom.NamedNodeMap) ImmutableList(com.google.common.collect.ImmutableList) Node(org.w3c.dom.Node) NodeList(org.w3c.dom.NodeList) Element(org.w3c.dom.Element) ArrayList(java.util.ArrayList) NonNull(com.android.annotations.NonNull)

Example 40 with NonNull

use of com.android.annotations.NonNull in project buck by facebook.

the class XmlElement method compareTo.

/**
     * Compares this element with another {@link XmlElement} ignoring all attributes belonging to
     * the {@link SdkConstants#TOOLS_URI} namespace.
     *
     * @param other the other element to compare against.
     * @return a {@link String} describing the differences between the two XML elements or
     * {@link Optional#absent()} if they are equals.
     */
@NonNull
public Optional<String> compareTo(Object other) {
    if (!(other instanceof XmlElement)) {
        return Optional.of("Wrong type");
    }
    XmlElement otherNode = (XmlElement) other;
    // compare element names
    if (getXml().getNamespaceURI() != null) {
        if (!getXml().getLocalName().equals(otherNode.getXml().getLocalName())) {
            return Optional.of(String.format("Element names do not match: %1$s versus %2$s", getXml().getLocalName(), otherNode.getXml().getLocalName()));
        }
        // compare element ns
        String thisNS = getXml().getNamespaceURI();
        String otherNS = otherNode.getXml().getNamespaceURI();
        if ((thisNS == null && otherNS != null) || (thisNS != null && !thisNS.equals(otherNS))) {
            return Optional.of(String.format("Element namespaces names do not match: %1$s versus %2$s", thisNS, otherNS));
        }
    } else {
        if (!getXml().getNodeName().equals(otherNode.getXml().getNodeName())) {
            return Optional.of(String.format("Element names do not match: %1$s versus %2$s", getXml().getNodeName(), otherNode.getXml().getNodeName()));
        }
    }
    // compare attributes, we do it twice to identify added/missing elements in both lists.
    Optional<String> message = checkAttributes(this, otherNode);
    if (message.isPresent()) {
        return message;
    }
    message = checkAttributes(otherNode, this);
    if (message.isPresent()) {
        return message;
    }
    // compare children
    @NonNull List<Node> expectedChildren = filterUninterestingNodes(getXml().getChildNodes());
    @NonNull List<Node> actualChildren = filterUninterestingNodes(otherNode.getXml().getChildNodes());
    if (expectedChildren.size() != actualChildren.size()) {
        if (expectedChildren.size() > actualChildren.size()) {
            // missing some.
            @NonNull List<String> missingChildrenNames = Lists.transform(expectedChildren, NODE_TO_NAME);
            missingChildrenNames.removeAll(Lists.transform(actualChildren, NODE_TO_NAME));
            return Optional.of(String.format("%1$s: Number of children do not match up: " + "expected %2$d versus %3$d at %4$s, missing %5$s", getId(), expectedChildren.size(), actualChildren.size(), otherNode.printPosition(), Joiner.on(",").join(missingChildrenNames)));
        } else {
            // extra ones.
            @NonNull List<String> extraChildrenNames = Lists.transform(actualChildren, NODE_TO_NAME);
            extraChildrenNames.removeAll(Lists.transform(expectedChildren, NODE_TO_NAME));
            return Optional.of(String.format("%1$s: Number of children do not match up: " + "expected %2$d versus %3$d at %4$s, extra elements found : %5$s", getId(), expectedChildren.size(), actualChildren.size(), otherNode.printPosition(), Joiner.on(",").join(expectedChildren)));
        }
    }
    for (Node expectedChild : expectedChildren) {
        if (expectedChild.getNodeType() == Node.ELEMENT_NODE) {
            @NonNull XmlElement expectedChildNode = new XmlElement((Element) expectedChild, mDocument);
            message = findAndCompareNode(otherNode, actualChildren, expectedChildNode);
            if (message.isPresent()) {
                return message;
            }
        }
    }
    return Optional.absent();
}
Also used : NonNull(com.android.annotations.NonNull) Node(org.w3c.dom.Node) NonNull(com.android.annotations.NonNull)

Aggregations

NonNull (com.android.annotations.NonNull)113 File (java.io.File)38 TextRange (com.intellij.openapi.util.TextRange)13 IOException (java.io.IOException)12 ArrayList (java.util.ArrayList)11 ImmutableList (com.google.common.collect.ImmutableList)8 Nullable (com.android.annotations.Nullable)7 DefaultPosition (com.android.tools.klint.detector.api.DefaultPosition)5 Position (com.android.tools.klint.detector.api.Position)5 Matcher (java.util.regex.Matcher)5 Pattern (java.util.regex.Pattern)5 SdkConstants (com.android.SdkConstants)4 OutputFile (com.android.build.OutputFile)4 Issue (com.android.tools.klint.detector.api.Issue)4 Position (com.android.tools.lint.detector.api.Position)4 FileUtils (com.android.utils.FileUtils)4 Splitter (com.google.common.base.Splitter)4 Module (com.intellij.openapi.module.Module)4 StringReader (java.io.StringReader)4 Node (org.w3c.dom.Node)4