diff options
author | Googler <noreply@google.com> | 2016-06-13 18:32:27 +0000 |
---|---|---|
committer | Yue Gan <yueg@google.com> | 2016-06-14 08:15:01 +0000 |
commit | 2692f9bd968f04c6358cbee4026c5d3110dba832 (patch) | |
tree | c8731966b731e8ccb09670eb61cdd90ff06325a9 /src | |
parent | 956b01e9afeda73b08c3db3c1be47b5832e82a7e (diff) |
Rollback of commit 5160d196e62bf6f8fa56b32746a01b182729c5c8.
*** Reason for rollback ***
Rolling forward with fixed proto call to getMappedStringValue.
*** Original change description ***
Automated [] rollback of commit 4f854d47888d011354357e965fd3c7bf1d74b95f.
*** Reason for rollback ***
Breakage: http://ci.bazel.io/view/Bazel%20bootstrap%20and%20maintenance/job/Bazel/601/
*** Original change description ***
Xml processing fixes:
* Support for <item name="foo" type="id">7x0000</item>
* Adds <eat-comment/> after source attributions to ensure they are not sent to the final binary
* Store attributes for arrays to the string translatable=false case
--
MOS_MIGRATED_REVID=124748547
Diffstat (limited to 'src')
6 files changed, 164 insertions, 64 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/DataResourceXml.java b/src/tools/android/java/com/google/devtools/build/android/DataResourceXml.java index a29c589743..dfc0496476 100644 --- a/src/tools/android/java/com/google/devtools/build/android/DataResourceXml.java +++ b/src/tools/android/java/com/google/devtools/build/android/DataResourceXml.java @@ -151,7 +151,7 @@ public class DataResourceXml implements DataResource { throws XMLStreamException { // Handle ids first, as they are a special kind of item. if (resourceType == ID) { - return XmlResourceValues.parseId(); + return XmlResourceValues.parseId(eventReader, start); } // Handle item stubs. if (XmlResourceValues.isItem(start)) { diff --git a/src/tools/android/java/com/google/devtools/build/android/XmlResourceValues.java b/src/tools/android/java/com/google/devtools/build/android/XmlResourceValues.java index 9267e97d93..306931d809 100644 --- a/src/tools/android/java/com/google/devtools/build/android/XmlResourceValues.java +++ b/src/tools/android/java/com/google/devtools/build/android/XmlResourceValues.java @@ -158,13 +158,34 @@ public class XmlResourceValues { return value; } - static XmlResourceValue parseId() { - return IdXmlResourceValue.of(); + static XmlResourceValue parseId(XMLEventReader eventReader, StartElement start) + throws XMLStreamException { + if (XmlResourceValues.isEndTag(eventReader.peek(), start.getName())) { + return IdXmlResourceValue.of(); + } else { + return IdXmlResourceValue.of(readContentsAsString(eventReader, start.getName())); + } } static XmlResourceValue parseSimple( XMLEventReader eventReader, ResourceType resourceType, StartElement start) throws XMLStreamException { + String contents; + // Check that the element is unary. If it is, the contents is null + if (isEndTag(eventReader.peek(), start.getName())) { + contents = null; + } else { + contents = readContentsAsString(eventReader, start.getName()); + } + return SimpleXmlResourceValue.of( + start.getName().equals(TAG_ITEM) + ? SimpleXmlResourceValue.Type.ITEM + : SimpleXmlResourceValue.Type.from(resourceType), + ImmutableMap.copyOf(parseTagAttributes(start)), + contents); + } + + public static Map<String, String> parseTagAttributes(StartElement start) { // Using a map to deduplicate xmlns declarations on the attributes. Map<String, String> attributeMap = new LinkedHashMap<>(); Iterator<Attribute> attributes = iterateAttributesFrom(start); @@ -190,19 +211,7 @@ public class XmlResourceValues { attributeMap.put(attribute.getName().getLocalPart(), value); } } - String contents; - // Check and see if the element is unary. If it is, the contents is null - if (isEndTag(eventReader.peek(), start.getName())) { - contents = null; - } else { - contents = readContentsAsString(eventReader, start.getName()); - } - return SimpleXmlResourceValue.of( - start.getName().equals(TAG_ITEM) - ? SimpleXmlResourceValue.Type.ITEM - : SimpleXmlResourceValue.Type.from(resourceType), - ImmutableMap.copyOf(attributeMap), - contents); + return attributeMap; } // TODO(corysmith): Replace this with real escaping system, preferably a performant high level xml 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 0a07a5daad..42d9d76150 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 @@ -18,6 +18,7 @@ import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.devtools.build.android.AndroidDataWritingVisitor; import com.google.devtools.build.android.FullyQualifiedName; import com.google.devtools.build.android.XmlResourceValue; @@ -30,6 +31,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map.Entry; import java.util.Objects; import javax.annotation.Nullable; @@ -94,8 +96,19 @@ public class ArrayXmlResourceValue implements XmlResourceValue { String.format("%s not found in %s", tagQName, Arrays.toString(values()))); } - String openTag(FullyQualifiedName key) { - return String.format("<%s name='%s'>", tagName.getLocalPart(), key.name()); + String openTag(FullyQualifiedName key, ImmutableMap<String, String> attributes) { + StringBuilder xmlString = new StringBuilder("<"); + xmlString.append(tagName.getLocalPart()); + xmlString.append(" name='").append(key.name()).append("'"); + for (Entry<String, String> entry : attributes.entrySet()) { + xmlString + .append(" ") + .append(entry.getKey()) + .append("=\"") + .append(entry.getValue()) + .append("\""); + } + return xmlString.append(">").toString(); } String closeTag() { @@ -105,10 +118,13 @@ public class ArrayXmlResourceValue implements XmlResourceValue { private final ImmutableList<String> values; private final ArrayType arrayType; + private final ImmutableMap<String, String> attributes; - private ArrayXmlResourceValue(ArrayType arrayType, ImmutableList<String> values) { + private ArrayXmlResourceValue( + ArrayType arrayType, ImmutableList<String> values, ImmutableMap<String, String> attributes) { this.arrayType = arrayType; this.values = values; + this.attributes = attributes; } @VisibleForTesting @@ -117,11 +133,20 @@ public class ArrayXmlResourceValue implements XmlResourceValue { } public static XmlResourceValue of(ArrayType arrayType, List<String> values) { - return new ArrayXmlResourceValue(arrayType, ImmutableList.copyOf(values)); + return of(arrayType, values, ImmutableMap.<String, String>of()); + } + + public static XmlResourceValue of( + ArrayType arrayType, List<String> values, ImmutableMap<String, String> attributes) { + return new ArrayXmlResourceValue(arrayType, ImmutableList.copyOf(values), attributes); } + @SuppressWarnings("deprecation") public static XmlResourceValue from(SerializeFormat.DataValueXml proto) { - return of(ArrayType.valueOf(proto.getValueType()), proto.getListValueList()); + return of( + ArrayType.valueOf(proto.getValueType()), + proto.getListValueList(), + ImmutableMap.copyOf(proto.getMappedStringValue())); } @Override @@ -130,7 +155,8 @@ public class ArrayXmlResourceValue implements XmlResourceValue { mergedDataWriter.writeToValuesXml( key, FluentIterable.from( - ImmutableList.of(String.format("<!-- %s -->", source), arrayType.openTag(key))) + ImmutableList.of( + String.format("<!-- %s -->", source), arrayType.openTag(key, attributes))) .append(FluentIterable.from(values).transform(ITEM_TO_XML)) .append(arrayType.closeTag())); } @@ -144,12 +170,13 @@ public class ArrayXmlResourceValue implements XmlResourceValue { SerializeFormat.DataValueXml.newBuilder() .addAllListValue(values) .setType(SerializeFormat.DataValueXml.XmlType.ARRAY) + .putAllMappedStringValue(attributes) .setValueType(arrayType.toString()))); } @Override public int hashCode() { - return Objects.hash(arrayType, values); + return Objects.hash(arrayType, values, attributes); } @Override @@ -158,7 +185,9 @@ public class ArrayXmlResourceValue implements XmlResourceValue { return false; } ArrayXmlResourceValue other = (ArrayXmlResourceValue) obj; - return Objects.equals(arrayType, other.arrayType) && Objects.equals(values, other.values); + return Objects.equals(arrayType, other.arrayType) + && Objects.equals(values, other.values) + && Objects.equals(attributes, other.attributes); } @Override @@ -166,6 +195,7 @@ public class ArrayXmlResourceValue implements XmlResourceValue { return MoreObjects.toStringHelper(getClass()) .add("arrayType", arrayType) .add("values", values) + .add("attributes", attributes) .toString(); } @@ -185,13 +215,16 @@ public class ArrayXmlResourceValue implements XmlResourceValue { throw new XMLStreamException( String.format("Expected start element %s", element), element.getLocation()); } - String contents = XmlResourceValues.readContentsAsString(eventReader, - element.asStartElement().getName()); + String contents = + XmlResourceValues.readContentsAsString(eventReader, element.asStartElement().getName()); values.add(contents != null ? contents : ""); } } try { - return of(ArrayType.fromTagName(start), values); + return of( + ArrayType.fromTagName(start), + values, + ImmutableMap.copyOf(XmlResourceValues.parseTagAttributes(start))); } catch (IllegalArgumentException e) { throw new XMLStreamException(e.getMessage(), start.getLocation()); } 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 07b8855f4b..ce9641b7ac 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 @@ -289,21 +289,36 @@ public class AttrXmlResourceValue implements XmlResourceValue { @Override public void write( FullyQualifiedName key, Path source, AndroidDataWritingVisitor mergedDataWriter) { + ImmutableList<String> formatKeys = Ordering.natural().immutableSortedCopy(formats.keySet()); - FluentIterable<String> iterable = - FluentIterable.from( - ImmutableList.of( - String.format("<!-- %s -->", source), - formatKeys.isEmpty() - ? String.format("<attr name='%s'>", key.name()) - : String.format( - "<attr name='%s' format='%s'>", - key.name(), - Joiner.on('|').join(formatKeys)))); - for (String formatKey : formatKeys) { - iterable = formats.get(formatKey).appendTo(iterable); - } - mergedDataWriter.writeToValuesXml(key, iterable.append("</attr>")); + if (formatKeys.isEmpty()) { + mergedDataWriter.writeToValuesXml( + key, + ImmutableList.of( + String.format("<!-- %s -->", source), + String.format("<attr name='%s'/>", key.name()))); + } else if (formats.containsKey(FLAGS) || formats.containsKey(ENUM)) { + FluentIterable<String> iterable = + FluentIterable.from( + ImmutableList.of( + String.format("<!-- %s -->", source), + formatKeys.isEmpty() + ? String.format("<attr name='%s'>", key.name()) + : String.format( + "<attr format='%s' name='%s' >", + Joiner.on('|').join(formatKeys), key.name()))); + for (String formatKey : formatKeys) { + iterable = formats.get(formatKey).appendTo(iterable); + } + mergedDataWriter.writeToValuesXml(key, iterable.append("</attr>")); + } else { + mergedDataWriter.writeToValuesXml( + key, + ImmutableList.of( + String.format("<!-- %s -->", source), + String.format( + "<attr format='%s' name='%s'/>", Joiner.on('|').join(formatKeys), key.name()))); + } } @Override diff --git a/src/tools/android/java/com/google/devtools/build/android/xml/IdXmlResourceValue.java b/src/tools/android/java/com/google/devtools/build/android/xml/IdXmlResourceValue.java index 65e31619ee..0b0b476fcc 100644 --- a/src/tools/android/java/com/google/devtools/build/android/xml/IdXmlResourceValue.java +++ b/src/tools/android/java/com/google/devtools/build/android/xml/IdXmlResourceValue.java @@ -20,13 +20,16 @@ import com.google.devtools.build.android.FullyQualifiedName; import com.google.devtools.build.android.XmlResourceValue; import com.google.devtools.build.android.XmlResourceValues; import com.google.devtools.build.android.proto.SerializeFormat; +import com.google.devtools.build.android.proto.SerializeFormat.DataValueXml.Builder; import com.google.devtools.build.android.proto.SerializeFormat.DataValueXml.XmlType; import com.google.protobuf.CodedOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Path; +import java.util.Objects; +import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; /** @@ -42,43 +45,87 @@ import javax.annotation.concurrent.Immutable; @Immutable public class IdXmlResourceValue implements XmlResourceValue { - static final IdXmlResourceValue SINGLETON = new IdXmlResourceValue(); + static final IdXmlResourceValue SINGLETON = new IdXmlResourceValue(null); + private String value; public static XmlResourceValue of() { return SINGLETON; } + + public static XmlResourceValue of(@Nullable String value) { + if (value == null) { + return of(); + } + return new IdXmlResourceValue(value); + } + + private IdXmlResourceValue(String value) { + this.value = value; + } @Override public void write( FullyQualifiedName key, Path source, AndroidDataWritingVisitor mergedDataWriter) { - mergedDataWriter.writeToValuesXml( - key, - ImmutableList.of( - String.format("<!-- %s -->", source), - String.format("<item type='id' name='%s'/>", key.name()))); + String sourceString = String.format("<!-- %s -->", source); + if (value == null) { + mergedDataWriter.writeToValuesXml( + key, + ImmutableList.of(sourceString, String.format("<item type='id' name='%s'/>", key.name()))); + } else { + mergedDataWriter.writeToValuesXml( + key, + ImmutableList.of( + sourceString, + String.format("<item type='id' name='%s'>%s</item>", key.name(), value))); + } } @Override public int serializeTo(Path source, OutputStream output) throws IOException { - SerializeFormat.DataValue value = - XmlResourceValues.newSerializableDataValueBuilder(source) - .setXmlValue(SerializeFormat.DataValueXml.newBuilder().setType(XmlType.ID)) - .build(); - value.writeDelimitedTo(output); - return CodedOutputStream.computeUInt32SizeNoTag(value.getSerializedSize()) - + value.getSerializedSize(); + Builder xmlValue = SerializeFormat.DataValueXml.newBuilder().setType(XmlType.ID); + if (value != null) { + xmlValue.setValue(value); + } + SerializeFormat.DataValue dataValue = + XmlResourceValues.newSerializableDataValueBuilder(source).setXmlValue(xmlValue).build(); + dataValue.writeDelimitedTo(output); + return CodedOutputStream.computeUInt32SizeNoTag(dataValue.getSerializedSize()) + + dataValue.getSerializedSize(); + } + + @Override + public int hashCode() { + return value != null ? value.hashCode() : super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof IdXmlResourceValue)) { + return false; + } + IdXmlResourceValue other = (IdXmlResourceValue) obj; + return Objects.equals(value, other.value); } @Override public String toString() { - return MoreObjects.toStringHelper(getClass()).toString(); + return MoreObjects.toStringHelper(getClass()).add("value", value).toString(); } @Override - public XmlResourceValue combineWith(XmlResourceValue value) { - if (value != SINGLETON) { - throw new IllegalArgumentException(value + "is not combinable with " + this); + public XmlResourceValue combineWith(XmlResourceValue resourceValue) { + if (equals(resourceValue)) { + return this; + } + if (resourceValue instanceof IdXmlResourceValue) { + IdXmlResourceValue otherId = (IdXmlResourceValue) resourceValue; + if (value == null && otherId.value != null) { + return otherId; + } + if (value != null && otherId.value == null) { + return this; + } } - return this; + throw new IllegalArgumentException(resourceValue + "is not combinable with " + this); } } 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 9169401c21..218dd3cb86 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 @@ -175,11 +175,6 @@ public class SimpleXmlResourceValue implements XmlResourceValue { return withAttributes(Type.ITEM, ImmutableMap.of("type", resourceType.getName())); } - @Deprecated - public static XmlResourceValue of(Type valueType, @Nullable String value) { - return of(valueType, ImmutableMap.<String, String>of(), value); - } - public static XmlResourceValue of( Type valueType, ImmutableMap<String, String> attributes, @Nullable String value) { return new SimpleXmlResourceValue(valueType, attributes, value); @@ -223,6 +218,7 @@ public class SimpleXmlResourceValue implements XmlResourceValue { key, ImmutableList.of(String.format("<!-- %s -->", source), xmlString.toString())); } + @SuppressWarnings("deprecation") public static XmlResourceValue from(SerializeFormat.DataValueXml proto) { return of( Type.valueOf(proto.getValueType()), |