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;
}
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();
}
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;
}
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;
}
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();
}
Aggregations