aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/android/java/com/google/devtools/build/android/xml
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2017-11-15 11:55:15 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2017-11-15 11:57:13 -0800
commit7925d5b265249466bff385602e94509a05de6870 (patch)
tree9543038c23171dd93261a792a6f0571591e3cb09 /src/tools/android/java/com/google/devtools/build/android/xml
parent1e0b7cb49b5d22f72d9e32018d15972a9f28878c (diff)
Create merge action and data deserializer for aapt2 compiled resources.
RELNOTES: None PiperOrigin-RevId: 175858467
Diffstat (limited to 'src/tools/android/java/com/google/devtools/build/android/xml')
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/xml/ArrayXmlResourceValue.java27
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/xml/AttrXmlResourceValue.java64
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/xml/PluralXmlResourceValue.java27
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/xml/SimpleXmlResourceValue.java61
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/xml/StyleXmlResourceValue.java39
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/xml/StyleableXmlResourceValue.java19
6 files changed, 236 insertions, 1 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/xml/ArrayXmlResourceValue.java b/src/tools/android/java/com/google/devtools/build/android/xml/ArrayXmlResourceValue.java
index e3f5571c7d..fb74fd2208 100644
--- a/src/tools/android/java/com/google/devtools/build/android/xml/ArrayXmlResourceValue.java
+++ b/src/tools/android/java/com/google/devtools/build/android/xml/ArrayXmlResourceValue.java
@@ -13,6 +13,10 @@
// limitations under the License.
package com.google.devtools.build.android.xml;
+import com.android.aapt.Resources.Array;
+import com.android.aapt.Resources.Array.Element;
+import com.android.aapt.Resources.Item;
+import com.android.aapt.Resources.Value;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
@@ -117,6 +121,29 @@ public class ArrayXmlResourceValue implements XmlResourceValue {
ImmutableMap.copyOf(proto.getAttribute()));
}
+ public static XmlResourceValue from(Value proto) {
+ Array array = proto.getCompoundValue().getArray();
+ List<String> items = new ArrayList<>();
+
+ for (Element entry : array.getElementList()) {
+ Item item = entry.getItem();
+
+ if (item.hasPrim()) {
+ String stringValue = "#" + Integer.toHexString(item.getPrim().getData());
+ items.add(stringValue);
+ } else if (item.hasRef()) {
+ items.add("@" + item.getRef().getName());
+ } else if (item.hasStr()) {
+ items.add(item.getStr().getValue());
+ }
+ }
+
+ return of(
+ ArrayType.ARRAY,
+ items,
+ ImmutableMap.of());
+ }
+
@Override
public void write(
FullyQualifiedName key, DataSource source, AndroidDataWritingVisitor mergedDataWriter) {
diff --git a/src/tools/android/java/com/google/devtools/build/android/xml/AttrXmlResourceValue.java b/src/tools/android/java/com/google/devtools/build/android/xml/AttrXmlResourceValue.java
index 661e5ddf98..f2645ac0a3 100644
--- a/src/tools/android/java/com/google/devtools/build/android/xml/AttrXmlResourceValue.java
+++ b/src/tools/android/java/com/google/devtools/build/android/xml/AttrXmlResourceValue.java
@@ -16,6 +16,9 @@ package com.google.devtools.build.android.xml;
import static com.google.common.base.Predicates.equalTo;
import static com.google.common.base.Predicates.not;
+import com.android.aapt.Resources.Attribute;
+import com.android.aapt.Resources.Attribute.Symbol;
+import com.android.aapt.Resources.Value;
import com.android.resources.ResourceType;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
@@ -39,6 +42,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
@@ -195,6 +199,66 @@ public class AttrXmlResourceValue implements XmlResourceValue {
return of(formats.build());
}
+ public static XmlResourceValue from(Value proto) throws InvalidProtocolBufferException {
+ Builder<String, ResourceXmlAttrValue> formats =
+ ImmutableMap.builder();
+
+ Attribute attribute = proto.getCompoundValue().getAttr();
+ int formatFlags = attribute.getFormatFlags();
+
+ if (formatFlags != 0xFFFF) {
+ //These flags are defined in AOSP in ResourceTypes.h:ResTable_map
+ if ((formatFlags & 1 << 0) != 0) {
+ formats.put("reference", ReferenceResourceXmlAttrValue.of());
+ }
+ if ((formatFlags & 1 << 1) != 0) {
+ formats.put("string", StringResourceXmlAttrValue.of());
+ }
+ if ((formatFlags & 1 << 2) != 0) {
+ formats.put("integer", IntegerResourceXmlAttrValue.of());
+ }
+ if ((formatFlags & 1 << 3) != 0) {
+ formats.put("boolean", BooleanResourceXmlAttrValue.of());
+ }
+ if ((formatFlags & 1 << 4) != 0) {
+ formats.put("color", ColorResourceXmlAttrValue.of());
+ }
+ if ((formatFlags & 1 << 5) != 0) {
+ formats.put("float", FloatResourceXmlAttrValue.of());
+ }
+ if ((formatFlags & 1 << 6) != 0) {
+ formats.put("dimension", DimensionResourceXmlAttrValue.of());
+ }
+ if ((formatFlags & 1 << 7) != 0) {
+ formats.put("fraction", FractionResourceXmlAttrValue.of());
+ }
+ if ((formatFlags & 1 << 16) != 0) {
+ Map<String, String> enums = new HashMap<>();
+
+ for (Symbol attrSymbol : attribute.getSymbolList()) {
+ String name = attrSymbol.getName().getName().replaceFirst("id/", "");
+ enums.put(name, Integer.toString(attrSymbol.getValue()));
+ }
+
+ formats.put("enum", EnumResourceXmlAttrValue.of(enums));
+ }
+ if ((formatFlags & 1 << 17) != 0) {
+ Map<String, String> flags = new HashMap<>();
+ for (Symbol attrSymbol : attribute.getSymbolList()) {
+ String name = attrSymbol.getName().getName().replaceFirst("id/", "");
+ flags.put(name, Integer.toString(attrSymbol.getValue()));
+ }
+
+ formats.put("flags", FlagResourceXmlAttrValue.of(flags));
+ }
+ if ((formatFlags & 0xFFFCFF00) != 0) {
+ throw new InvalidProtocolBufferException(
+ "Unexpected format flags: " + formatFlags);
+ }
+ }
+ return of(formats.build());
+ }
+
/**
* Creates a new {@link AttrXmlResourceValue}. Returns null if there are no formats.
*/
diff --git a/src/tools/android/java/com/google/devtools/build/android/xml/PluralXmlResourceValue.java b/src/tools/android/java/com/google/devtools/build/android/xml/PluralXmlResourceValue.java
index 1ff1578eab..6e1fba18c7 100644
--- a/src/tools/android/java/com/google/devtools/build/android/xml/PluralXmlResourceValue.java
+++ b/src/tools/android/java/com/google/devtools/build/android/xml/PluralXmlResourceValue.java
@@ -13,6 +13,8 @@
// limitations under the License.
package com.google.devtools.build.android.xml;
+import com.android.aapt.Resources.Plural;
+import com.android.aapt.Resources.Value;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.android.AndroidDataWritingVisitor;
@@ -27,6 +29,8 @@ import com.google.devtools.build.android.proto.SerializeFormat.DataValueXml.XmlT
import com.google.protobuf.CodedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import javax.annotation.concurrent.Immutable;
@@ -131,6 +135,29 @@ public class PluralXmlResourceValue implements XmlResourceValue {
ImmutableMap.copyOf(proto.getMappedStringValue()));
}
+ public static XmlResourceValue from(Value proto) {
+ Plural plural = proto.getCompoundValue().getPlural();
+
+ Map<String, String> items = new HashMap<>();
+
+ for (Plural.Entry entry : plural.getEntryList()) {
+ String name = entry.getArity().toString().toLowerCase();
+ String value =
+ entry
+ .getItem()
+ .getStr()
+ .toString()
+ .replace("value: \"", "")
+ .replace("\"", "")
+ .replace('\n', ' ');
+ items.put(name, value);
+ }
+
+ return createWithAttributesAndValues(
+ ImmutableMap.of(),
+ ImmutableMap.copyOf(items));
+ }
+
@Override
public int serializeTo(int sourceId, Namespaces namespaces, OutputStream output)
throws IOException {
diff --git a/src/tools/android/java/com/google/devtools/build/android/xml/SimpleXmlResourceValue.java b/src/tools/android/java/com/google/devtools/build/android/xml/SimpleXmlResourceValue.java
index 923c163ad3..4006d4d7a4 100644
--- a/src/tools/android/java/com/google/devtools/build/android/xml/SimpleXmlResourceValue.java
+++ b/src/tools/android/java/com/google/devtools/build/android/xml/SimpleXmlResourceValue.java
@@ -13,6 +13,10 @@
// limitations under the License.
package com.google.devtools.build.android.xml;
+import com.android.aapt.Resources.Item;
+import com.android.aapt.Resources.StyledString;
+import com.android.aapt.Resources.StyledString.Span;
+import com.android.aapt.Resources.Value;
import com.android.resources.ResourceType;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableMap;
@@ -54,6 +58,8 @@ public class SimpleXmlResourceValue implements XmlResourceValue {
static final QName TAG_FRACTION = QName.valueOf("fraction");
static final QName TAG_INTEGER = QName.valueOf("integer");
static final QName TAG_ITEM = QName.valueOf("item");
+ static final QName TAG_LAYOUT = QName.valueOf("layout");
+ static final QName TAG_MIPMAP = QName.valueOf("mipmap");
static final QName TAG_PUBLIC = QName.valueOf("public");
static final QName TAG_STRING = QName.valueOf("string");
@@ -108,6 +114,20 @@ public class SimpleXmlResourceValue implements XmlResourceValue {
return true;
}
},
+ LAYOUT(TAG_LAYOUT) {
+ @Override
+ public boolean validate(String value) {
+ // TODO(corysmith): Validate the item type.
+ return true;
+ }
+ },
+ MIPMAP(TAG_MIPMAP) {
+ @Override
+ public boolean validate(String value) {
+ // TODO(corysmith): Validate the item type.
+ return true;
+ }
+ },
PUBLIC(TAG_PUBLIC) {
@Override
public boolean validate(String value) {
@@ -121,7 +141,7 @@ public class SimpleXmlResourceValue implements XmlResourceValue {
return true;
}
};
- private QName tagName;
+ private final QName tagName;
Type(QName tagName) {
this.tagName = tagName;
@@ -211,6 +231,45 @@ public class SimpleXmlResourceValue implements XmlResourceValue {
proto.hasValue() ? proto.getValue() : null);
}
+ public static XmlResourceValue from(Value proto, ResourceType resourceType) {
+ Item item = proto.getItem();
+ String stringValue = null;
+
+ if (item.hasStr()) {
+ stringValue = item.getStr().toString();
+ } else if (item.hasRef()) {
+ stringValue = "@" + item.getRef().getName();
+ } else if (item.hasStyledStr()) {
+ StyledString styledString = item.getStyledStr();
+ StringBuilder stringBuilder = new StringBuilder(styledString.getValue());
+
+ for (Span span : styledString.getSpanList()) {
+ stringBuilder.append(
+ String.format(";%s,%d,%d", span.getTag(), span.getFirstChar(), span.getLastChar()));
+ }
+ stringValue = stringBuilder.toString();
+ } else if ((resourceType == ResourceType.COLOR
+ || resourceType == ResourceType.DRAWABLE) && item.hasPrim()) {
+ stringValue =
+ String.format("#%1$8s", Integer.toHexString(item.getPrim().getData())).replace(' ', '0');
+ } else if (resourceType == ResourceType.INTEGER && item.hasPrim()){
+ stringValue = Integer.toString(item.getPrim().getData());
+ } else if (resourceType == ResourceType.BOOL && item.hasPrim()) {
+ stringValue = item.getPrim().getData() == 0 ? "false" : "true";
+ } else if (resourceType == ResourceType.FRACTION
+ || resourceType == ResourceType.DIMEN) {
+ stringValue = Integer.toString(item.getPrim().getData());
+ } else {
+ throw new IllegalArgumentException(
+ String.format("'%s' is not a valid resource type.", resourceType));
+ }
+
+ return of(
+ Type.valueOf(resourceType.toString().toUpperCase()),
+ ImmutableMap.of(),
+ stringValue);
+ }
+
@Override
public void writeResourceToClass(FullyQualifiedName key, AndroidResourceSymbolSink sink) {
sink.acceptSimpleResource(key.type(), key.name());
diff --git a/src/tools/android/java/com/google/devtools/build/android/xml/StyleXmlResourceValue.java b/src/tools/android/java/com/google/devtools/build/android/xml/StyleXmlResourceValue.java
index ccf52b6480..55c3d00fdd 100644
--- a/src/tools/android/java/com/google/devtools/build/android/xml/StyleXmlResourceValue.java
+++ b/src/tools/android/java/com/google/devtools/build/android/xml/StyleXmlResourceValue.java
@@ -13,6 +13,8 @@
// limitations under the License.
package com.google.devtools.build.android.xml;
+import com.android.aapt.Resources.Style;
+import com.android.aapt.Resources.Value;
import com.google.common.base.Function;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableMap;
@@ -27,6 +29,7 @@ import com.google.devtools.build.android.proto.SerializeFormat;
import com.google.devtools.build.android.proto.SerializeFormat.DataValueXml.XmlType;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
@@ -77,6 +80,42 @@ public class StyleXmlResourceValue implements XmlResourceValue {
this.values = values;
}
+ public static XmlResourceValue from(Value proto) {
+ Style style = proto.getCompoundValue().getStyle();
+ String parent = "";
+
+ if (style.hasParent()) {
+ parent = proto.getCompoundValue().getStyle().getParent().getName();
+ }
+
+ Map<String, String> items = itemMapFromProto(style);
+
+ return of(parent, items);
+ }
+
+ private static Map<String, String> itemMapFromProto(Style style) {
+ Map<String, String> result = new HashMap<>();
+
+ for (Style.Entry styleEntry : style.getEntryList()) {
+ String itemName = styleEntry.getKey().getName().replace("attr/", "");
+ String itemValue;
+
+ if (styleEntry.getItem().hasRawStr()) {
+ itemValue = styleEntry.getItem().getRawStr().getValue();
+ } else if (styleEntry.getItem().hasRef()) {
+ itemValue = "@" + styleEntry.getItem().getRef().getName();
+ if (itemValue.equals("@")) {
+ itemValue = "@null";
+ }
+ } else {
+ throw new IllegalArgumentException("Could not parse item value from Style resource.");
+ }
+ result.put(itemName, itemValue);
+ }
+
+ return result;
+ }
+
@Override
public void write(
FullyQualifiedName key, DataSource source, AndroidDataWritingVisitor mergedDataWriter) {
diff --git a/src/tools/android/java/com/google/devtools/build/android/xml/StyleableXmlResourceValue.java b/src/tools/android/java/com/google/devtools/build/android/xml/StyleableXmlResourceValue.java
index 8e55e089d3..c9661690cf 100644
--- a/src/tools/android/java/com/google/devtools/build/android/xml/StyleableXmlResourceValue.java
+++ b/src/tools/android/java/com/google/devtools/build/android/xml/StyleableXmlResourceValue.java
@@ -13,6 +13,8 @@
// limitations under the License.
package com.google.devtools.build.android.xml;
+import com.android.aapt.Resources.Styleable;
+import com.android.aapt.Resources.Value;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.MoreObjects;
@@ -31,6 +33,7 @@ import com.google.devtools.build.android.proto.SerializeFormat.DataValueXml.XmlT
import java.io.IOException;
import java.io.OutputStream;
import java.util.AbstractMap.SimpleEntry;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
@@ -161,6 +164,22 @@ public class StyleableXmlResourceValue implements XmlResourceValue {
Iterables.transform(proto.getReferencesList(), DATA_KEY_TO_FULLY_QUALIFIED_NAME)));
}
+ public static XmlResourceValue from(
+ Value proto, Map<String, Entry<FullyQualifiedName, Boolean>> fullyQualifiedNames) {
+ Map<FullyQualifiedName, Boolean> attributes = new HashMap<>();
+
+ Styleable styleable = proto.getCompoundValue().getStyleable();
+ for (Styleable.Entry entry : styleable.getEntryList()) {
+ String attrName = entry.getAttr().getName();
+
+ Entry<FullyQualifiedName, Boolean> fqnEntry = fullyQualifiedNames.get(attrName);
+ attributes.put(fqnEntry.getKey(), fqnEntry.getValue());
+ fqnEntry.setValue(false);
+ }
+
+ return of(ImmutableMap.copyOf(attributes));
+ }
+
@Override
public int hashCode() {
return attrs.hashCode();