use of com.android.tools.build.bundletool.model.utils.xmlproto.XmlProtoElementBuilder in project bundletool by google.
the class FusingAndroidManifestMerger method mergeElements.
/**
* Merges element with the same name and type from different manifests. {@code elements} list in
* this method contains data from feature modules first and element from the base module is the
* last one in the list.
*
* <p>If element is presented in more than one feature module elements are sorted by name of
* feature module. Example: if service with name 'myService' is defined in base module and
* features 'a' and 'b', {@code elements} list will contain its declaration in the following
* order: 'a' feature, 'b' feature, base.
*/
private XmlProtoElement mergeElements(ApplicationElementId elementId, List<XmlProtoElement> elements) {
// we just take the first element from the list.
if (mode.equals(Mode.REPLACE) || elements.size() == 1) {
return elements.get(0);
}
// Remove source data from nested elements as this data is meaningless for functionality and
// just contains information about line/column where element appeared in the original xml.
List<XmlProtoElement> elementsNoSource = elements.stream().map(element -> element.toBuilder().removeSourceDataRecursive().build()).collect(toImmutableList());
// For intent filters we gather all distinct filters defined in all modules.
Set<XmlProtoElement> intentFilters = elementsNoSource.stream().flatMap(element -> element.getChildrenElements(AndroidManifest.INTENT_FILTER_ELEMENT_NAME)).collect(toImmutableSet());
// For meta-data we group them by name and take one per each name.
ImmutableMap<String, XmlProtoElement> metadataByName = elementsNoSource.stream().flatMap(element -> element.getChildrenElements(AndroidManifest.META_DATA_ELEMENT_NAME)).filter(meta -> meta.getAndroidAttribute(AndroidManifest.NAME_RESOURCE_ID).isPresent()).collect(toImmutableMap(meta -> meta.getAndroidAttribute(AndroidManifest.NAME_RESOURCE_ID).get().getValueAsString(), Function.identity(), (a, b) -> {
// different modules throw conflict exception.
if (!a.equals(b)) {
throw CommandExecutionException.builder().withInternalMessage("Multiple meta-data entries with the same name are found inside" + " %s:%s: %s, %s", elementId.getType(), elementId.getName(), a, b).build();
}
return a;
}));
// Take element declaration from feature module and add all intent filters and meta data to it.
XmlProtoElementBuilder builder = elementsNoSource.get(0).toBuilder();
builder.removeChildrenElementsIf(child -> {
if (!child.isElement()) {
return false;
}
XmlProtoElementBuilder childElement = child.getElement();
String tag = childElement.getName();
Optional<String> name = childElement.getAndroidAttribute(AndroidManifest.NAME_RESOURCE_ID).map(XmlProtoAttributeBuilder::getValueAsString);
return tag.equals(AndroidManifest.INTENT_FILTER_ELEMENT_NAME) || (tag.equals(AndroidManifest.META_DATA_ELEMENT_NAME) && name.map(metadataByName::containsKey).orElse(false));
});
intentFilters.forEach(e -> builder.addChildElement(e.toBuilder()));
metadataByName.values().forEach(e -> builder.addChildElement(e.toBuilder()));
return builder.build();
}
use of com.android.tools.build.bundletool.model.utils.xmlproto.XmlProtoElementBuilder in project bundletool by google.
the class SplitsProtoXmlBuilder method build.
public XmlNode build() {
XmlProtoElementBuilder splitsXml = XmlProtoElementBuilder.create("splits");
for (String moduleName : splitsByModuleAndLanguage.rowKeySet()) {
XmlProtoElementBuilder languageXml = XmlProtoElementBuilder.create("language");
splitsByModuleAndLanguage.row(moduleName).forEach((language, splitId) -> languageXml.addChildElement(createEntry(language, splitId)));
splitsXml.addChildElement(XmlProtoElementBuilder.create("module").addAttribute(XmlProtoAttributeBuilder.create("name").setValueAsString(moduleName)).addChildElement(languageXml));
}
return XmlProtoNode.createElementNode(splitsXml.build()).getProto();
}
use of com.android.tools.build.bundletool.model.utils.xmlproto.XmlProtoElementBuilder in project bundletool by google.
the class LocaleConfigXmlInjector method createLocalesXmlNode.
public static XmlNode createLocalesXmlNode(ImmutableList<ModuleSplit> splits) {
// Get all locales from the base module splits
ImmutableSet<String> allLocales = getLocalesFromBaseModuleSplits(splits);
XmlProtoElementBuilder localesConfigXml = XmlProtoElementBuilder.create(LOCALE_CONFIG_ELEMENT);
allLocales.stream().filter(locale -> !locale.isEmpty()).forEach(locale -> localesConfigXml.addChildElement(createAttributes(locale)));
return XmlProtoNode.createElementNode(localesConfigXml.build()).getProto();
}
use of com.android.tools.build.bundletool.model.utils.xmlproto.XmlProtoElementBuilder in project bundletool by google.
the class Activity method asXmlProtoElement.
@Memoized
public XmlProtoElement asXmlProtoElement() {
XmlProtoElementBuilder elementBuilder = XmlProtoElementBuilder.create(ACTIVITY_ELEMENT_NAME);
setNameAttribute(elementBuilder);
setThemeAttribute(elementBuilder);
setExportedAttribute(elementBuilder);
setExcludeFromRecentsAttribute(elementBuilder);
setStateNotNeeded(elementBuilder);
setIntentFilterElement(elementBuilder);
return elementBuilder.build();
}
use of com.android.tools.build.bundletool.model.utils.xmlproto.XmlProtoElementBuilder in project bundletool by google.
the class SplitsProtoXmlBuilderTest method buildOneModule.
@Test
public void buildOneModule() {
SplitsProtoXmlBuilder splitsProtoXmlBuilder = new SplitsProtoXmlBuilder();
splitsProtoXmlBuilder.addLanguageMapping(BundleModuleName.create("module"), /* language = */
"en", /* splitId = */
"module.config.en");
XmlNode rootNode = splitsProtoXmlBuilder.build();
// Answer:
// <splits>
// <module name="module">
// <language>
// <entry key="en" split="module.config.en">
// </language>
// </module>
// </splits>
XmlProtoElementBuilder actual = XmlProtoElementBuilder.create("splits").addChildElement(XmlProtoElementBuilder.create("module").addAttribute(createAttribute("name", "module")).addChildElement(XmlProtoElementBuilder.create("language").addChildElement(XmlProtoElementBuilder.create("entry").addAttribute(createAttribute("key", "en")).addAttribute(createAttribute("split", "module.config.en")))));
assertThat(rootNode).isEqualTo(getProto(actual));
}
Aggregations