diff options
author | Googler <noreply@google.com> | 2016-06-29 15:49:52 +0000 |
---|---|---|
committer | Dmitry Lomov <dslomov@google.com> | 2016-06-30 11:40:54 +0000 |
commit | af2ea37ceab2300a6d40afe65c1e333dfbaa0a11 (patch) | |
tree | ebecae8914404203e3944f03f9b6a5b31bb11c3f /src/tools/android/java/com/google/devtools/build/android/AndroidDataWritingVisitor.java | |
parent | 368cc56fb2baa3e21be4acdd2410a4ce8245de93 (diff) |
Creates a fluent api that moves the xml generation into the data writer.
The new "define" method replaces the now deprecated writeToValuesXml method. This provides three benefits:
* An agnostic writing interface to the XmlResourceValue classes, easing the replacement of them with a proper xml writer.
* A delayed write which allows the StyleableXmlResourceValue to claim AttrXmlResourceValue definitions before writing.
* Centralized method of source attribution, enabling a less verbose way to indicate multiple values came from a single xml source file.
An example of the new interface writing the StyleXmlResourceValue:
ValuesResourceDefinition definition = mergedDataWriter
.define(key)
.derivedFrom(source)
.startTag("style")
.named(key)
.optional()
.attribute("parent")
.setTo(parent)
.closeTag();
for (Entry<String, String> entry : values.entrySet()) {
definition = definition
.startItemTag()
.named(entry.getKey())
.close()
.addCharactersOf(entry.getValue())
.endTag();
}
definition.endTag().save();
--
MOS_MIGRATED_REVID=126196028
Diffstat (limited to 'src/tools/android/java/com/google/devtools/build/android/AndroidDataWritingVisitor.java')
-rw-r--r-- | src/tools/android/java/com/google/devtools/build/android/AndroidDataWritingVisitor.java | 116 |
1 files changed, 112 insertions, 4 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidDataWritingVisitor.java b/src/tools/android/java/com/google/devtools/build/android/AndroidDataWritingVisitor.java index ce9b85394d..2aa469dc8a 100644 --- a/src/tools/android/java/com/google/devtools/build/android/AndroidDataWritingVisitor.java +++ b/src/tools/android/java/com/google/devtools/build/android/AndroidDataWritingVisitor.java @@ -15,13 +15,16 @@ package com.google.devtools.build.android; import com.android.ide.common.res2.MergingException; +import java.io.Flushable; import java.io.IOException; import java.nio.file.Path; +import java.util.Map.Entry; -/** - * An interface for visiting android data for writing. - */ -public interface AndroidDataWritingVisitor { +import javax.annotation.CheckReturnValue; +import javax.xml.namespace.QName; + +/** An interface for visiting android data for writing. */ +public interface AndroidDataWritingVisitor extends Flushable { /** * Copies the AndroidManifest to the destination directory. */ @@ -54,5 +57,110 @@ public interface AndroidDataWritingVisitor { * @param xmlFragment the xml fragment as an Iterable<String> which allows lazy generation. */ // TODO(corysmith): Change this to pass in a xml writer. Safer all around. + @Deprecated void writeToValuesXml(FullyQualifiedName key, Iterable<String> xmlFragment); + + /** + * Provides a fluent interface to generate an xml resource for the values directory. + * + * <p>Example usage: + * <code> + * writer.define(key) + * .derivedFrom(source) + * .startTag(tagName) + * .named(key) + * .closeTag() + * .write(stringValue) + * .endTag() + * .save(); + * </code> + */ + // Check return value will ensure that the value is finished being written. + @CheckReturnValue + ValueResourceDefinitionMetadata define(FullyQualifiedName fqn); + + /** Represents the xml values resource meta data. */ + @CheckReturnValue + interface ValueResourceDefinitionMetadata { + ValuesResourceDefinition derivedFrom(Path source); + } + + /** Fluent interface to define the xml value for a {@link FullyQualifiedName}. */ + @CheckReturnValue + interface ValuesResourceDefinition { + /** Starts an xml tag with a prefix and localName. */ + StartTag startTag(String prefix, String localName); + + /** Starts an xml tag with a localName. */ + StartTag startTag(String localName); + + /** Starts an xml tag with a QName. */ + StartTag startTag(QName name); + + /** Starts an xml tag with the name "item" */ + StartTag startItemTag(); + + /** + * Takes another values xml resource and writes it as a child tag here. + * + * <p>This allows xml elements from other {@link XmlResourceValue} to be moved in the stream. + * Currently, this is only necessary for {@link StyleableXmlResourceValue} which can have {@link + * AttrXmlResourceValue} defined as child elements (yet, they are merged and treated as + * independent resources.) + * + * @param fqn The {@link FullyQualifiedName} of the {@link XmlResourceValue} to be adopted. This + * resource doesn't have to be defined for the adopt invocation, but it must exist when + * {@link AndroidDataWritingVisitor#flush()} is called. + * @return The current definition. + */ + ValuesResourceDefinition adopt(FullyQualifiedName fqn); + + /** Adds a string as xml characters to the definition. */ + ValuesResourceDefinition addCharactersOf(String characters); + + /** Ends the last {@link StartTag}. */ + ValuesResourceDefinition endTag(); + + /** Saves and validates the xml resource definition. */ + void save(); + } + + /** Represents the start of opening tag of a resource xml. */ + @CheckReturnValue + interface StartTag { + /** Adds name="{@link FullyQualifiedName}#name()" attribute. */ + StartTag named(FullyQualifiedName key); + /** Adds "name" attribute to the {@link StartTag}. */ + StartTag named(String key); + /** Adds all the {@link Entry} as key="value" to the {@link StartTag}. */ + StartTag addAttributesFrom(Iterable<Entry<String, String>> entries); + /** Starts an attribute of prefix:name. */ + Attribute attribute(String prefix, String name); + /** Starts an attribute of name. */ + Attribute attribute(String string); + /** Indicates the next attribute will only be written if the value is not null. */ + Optional optional(); + /** Closes the {@link StartTag} as ">" */ + ValuesResourceDefinition closeTag(); + /** Closes the {@link StartTag} as "/>", indicating it is a unary xml element. */ + ValuesResourceDefinition closeUnaryTag(); + } + + /** Adjective for an optional attribute. */ + @CheckReturnValue + interface Optional { + /** Starts an attribute of prefix:name. */ + Attribute attribute(String prefix, String name); + /** Starts an attribute of name. */ + Attribute attribute(String string); + } + + /** Represents an xml attribute of a start tag. */ + @CheckReturnValue + interface Attribute { + /** Sets the attribute value. */ + StartTag setTo(String value); + /** Sets the attributes values to {@linkplain FullyQualifiedName#name()}. */ + StartTag setTo(FullyQualifiedName fqn); + } } |