aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/android/java/com/google/devtools/build/android/aapt2
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2018-01-08 15:15:58 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2018-01-08 15:18:06 -0800
commit233807ec94189c4a322c203322163a154d90aa8f (patch)
tree3acadefc34a94f4395d52f79bdcb94a568db281c /src/tools/android/java/com/google/devtools/build/android/aapt2
parent5a7d2575d3527a35b8ac541ae09591b6a040f67b (diff)
Serialize and package xml attributes from resources xml tags in values folders for aapt2.
RELNOTES: none PiperOrigin-RevId: 181226483
Diffstat (limited to 'src/tools/android/java/com/google/devtools/build/android/aapt2')
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/aapt2/ResourceCompiler.java97
1 files changed, 90 insertions, 7 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/aapt2/ResourceCompiler.java b/src/tools/android/java/com/google/devtools/build/android/aapt2/ResourceCompiler.java
index e51192ce1e..50c5ff5b13 100644
--- a/src/tools/android/java/com/google/devtools/build/android/aapt2/ResourceCompiler.java
+++ b/src/tools/android/java/com/google/devtools/build/android/aapt2/ResourceCompiler.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.android.aapt2;
+import com.android.SdkConstants;
import com.android.builder.core.VariantType;
import com.android.repository.Revision;
import com.google.common.base.Preconditions;
@@ -22,6 +23,15 @@ import com.google.common.collect.ImmutableList.Builder;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.devtools.build.android.AaptCommandBuilder;
+import com.google.devtools.build.android.AndroidDataSerializer;
+import com.google.devtools.build.android.DataResourceXml;
+import com.google.devtools.build.android.FullyQualifiedName;
+import com.google.devtools.build.android.FullyQualifiedName.Factory;
+import com.google.devtools.build.android.FullyQualifiedName.VirtualType;
+import com.google.devtools.build.android.XmlResourceValues;
+import com.google.devtools.build.android.xml.Namespaces;
+import com.google.devtools.build.android.xml.ResourcesAttribute;
+import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
@@ -29,11 +39,17 @@ import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.logging.Logger;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
/** Invokes aapt2 to compile resources. */
public class ResourceCompiler {
@@ -58,7 +74,7 @@ public class ResourceCompiler {
private final CompilingVisitor compilingVisitor;
- private static class CompileTask implements Callable<Path> {
+ private static class CompileTask implements Callable<List<Path>> {
private final Path file;
private final Path compiledResourcesOut;
@@ -66,7 +82,10 @@ public class ResourceCompiler {
private final Revision buildToolsVersion;
private CompileTask(
- Path file, Path compiledResourcesOut, Path aapt2, Revision buildToolsVersion) {
+ Path file,
+ Path compiledResourcesOut,
+ Path aapt2,
+ Revision buildToolsVersion) {
this.file = file;
this.compiledResourcesOut = compiledResourcesOut;
this.aapt2 = aapt2;
@@ -74,7 +93,7 @@ public class ResourceCompiler {
}
@Override
- public Path call() throws Exception {
+ public List<Path> call() throws Exception {
logger.fine(
new AaptCommandBuilder(aapt2)
.forBuildToolsVersion(buildToolsVersion)
@@ -88,10 +107,34 @@ public class ResourceCompiler {
String type = file.getParent().getFileName().toString();
String filename = file.getFileName().toString();
+
+ List<Path> results = new ArrayList<>();
if (type.startsWith("values")) {
filename =
(filename.indexOf('.') != -1 ? filename.substring(0, filename.indexOf('.')) : filename)
+ ".arsc";
+
+ XMLEventReader xmlEventReader = null;
+ try {
+ // aapt2 compile strips out namespaces and attributes from the resources tag.
+ // Read them here separately and package them with the other flat files.
+ xmlEventReader =
+ XMLInputFactory.newInstance()
+ .createXMLEventReader(new FileInputStream(file.toString()));
+
+ StartElement rootElement = xmlEventReader.nextTag().asStartElement();
+ Iterator<Attribute> attributeIterator =
+ XmlResourceValues.iterateAttributesFrom(rootElement);
+
+ if (attributeIterator.hasNext()) {
+ results.add(
+ createAttributesProto(type, filename, attributeIterator));
+ }
+ } finally {
+ if (xmlEventReader != null) {
+ xmlEventReader.close();
+ }
+ }
}
final Path compiledResourcePath =
@@ -100,7 +143,47 @@ public class ResourceCompiler {
Files.exists(compiledResourcePath),
"%s does not exists after aapt2 ran.",
compiledResourcePath);
- return compiledResourcePath;
+ results.add(compiledResourcePath);
+ return results;
+ }
+
+ private Path createAttributesProto(
+ String type,
+ String filename,
+ Iterator<Attribute> attributeIterator)
+ throws IOException {
+
+ AndroidDataSerializer serializer = AndroidDataSerializer.create();
+ final Path resourcesAttributesPath =
+ compiledResourcesOut.resolve(type + "_" + filename + ".attributes");
+
+ while (attributeIterator.hasNext()) {
+ Attribute attribute = attributeIterator.next();
+ String namespaceUri = attribute.getName().getNamespaceURI();
+ String localPart = attribute.getName().getLocalPart();
+ String prefix = attribute.getName().getPrefix();
+ QName qName = new QName(namespaceUri, localPart, prefix);
+
+ Namespaces namespaces = Namespaces.from(qName);
+ String attributeName =
+ namespaceUri.isEmpty()
+ ? localPart
+ : prefix + ":" + localPart;
+
+ final String[] dirNameAndQualifiers = type.split(SdkConstants.RES_QUALIFIER_SEP);
+ Factory fqnFactory = Factory.fromDirectoryName(dirNameAndQualifiers);
+ FullyQualifiedName fqn =
+ fqnFactory.create(VirtualType.RESOURCES_ATTRIBUTE, qName.toString());
+ ResourcesAttribute resourceAttribute =
+ ResourcesAttribute.of(fqn, attributeName, attribute.getValue());
+ DataResourceXml resource =
+ DataResourceXml.createWithNamespaces(file, resourceAttribute, namespaces);
+
+ serializer.queueForSerialization(fqn, resource);
+ }
+
+ serializer.flushTo(resourcesAttributesPath);
+ return resourcesAttributesPath;
}
@Override
@@ -113,7 +196,7 @@ public class ResourceCompiler {
private final ListeningExecutorService executorService;
private final Path compiledResources;
- private final List<ListenableFuture<Path>> tasks = new ArrayList<>();
+ private final List<ListenableFuture<List<Path>>> tasks = new ArrayList<>();
private final Path aapt2;
private final Revision buildToolsVersion;
@@ -152,9 +235,9 @@ public class ResourceCompiler {
List<Path> getCompiledArtifacts() throws InterruptedException, ExecutionException {
Builder<Path> builder = ImmutableList.builder();
List<Throwable> compilationErrors = new ArrayList<>();
- for (ListenableFuture<Path> task : tasks) {
+ for (ListenableFuture<List<Path>> task : tasks) {
try {
- builder.add(task.get());
+ builder.addAll(task.get());
} catch (InterruptedException | ExecutionException e) {
compilationErrors.add(Optional.ofNullable(e.getCause()).orElse(e));
}