/** * shorten recursively all attributes that are package dependent of the passed nodes and all its * child nodes. * * @param packageName the manifest package name. * @param xmlElement the xml element to process recursively. */ private void extractFcqns(String packageName, XmlElement xmlElement) { for (XmlAttribute xmlAttribute : xmlElement.getAttributes()) { if (xmlAttribute.getModel() != null && xmlAttribute.getModel().isPackageDependent()) { String value = xmlAttribute.getValue(); if (value != null && value.startsWith(packageName) && value.charAt(packageName.length()) == '.') { xmlAttribute.getXml().setValue(value.substring(packageName.length())); } } } for (XmlElement child : xmlElement.getMergeableElements()) { extractFcqns(packageName, child); } }
private void visit( @NonNull ManifestMerger2.MergeType mergeType, @NonNull XmlElement xmlElement, @NonNull KeyBasedValueResolver<String> valueProvider, @NonNull MergingReport.Builder mergingReportBuilder) { for (XmlAttribute xmlAttribute : xmlElement.getAttributes()) { StringBuilder resultString = new StringBuilder(); String inputString = xmlAttribute.getValue(); Matcher matcher = PATTERN.matcher(inputString); if (matcher.matches()) { while (matcher.matches()) { String placeholderValue = valueProvider.getValue(matcher.group(2)); // whatever precedes the placeholder key is added back to the string. resultString.append(matcher.group(1)); if (placeholderValue == null) { // if this is a library, ignore the failure MergingReport.Record.Severity severity = mergeType == ManifestMerger2.MergeType.LIBRARY ? MergingReport.Record.Severity.INFO : MergingReport.Record.Severity.ERROR; xmlAttribute.addMessage( mergingReportBuilder, severity, String.format( "Attribute %1$s at %2$s requires a placeholder substitution" + " but no value for <%3$s> is provided.", xmlAttribute.getId(), xmlAttribute.printPosition(), matcher.group(2))); // we add back the placeholder key, since this is not an error for libraries resultString.append("${"); resultString.append(matcher.group(2)); resultString.append("}"); } else { // record the attribute set mergingReportBuilder .getActionRecorder() .recordAttributeAction( xmlAttribute, PositionImpl.UNKNOWN, Actions.ActionType.INJECTED, null /* attributeOperationType */); // substitute the placeholder key with its value. resultString.append(placeholderValue); } // the new input string is the tail of the previous match, as it may contain // more placeholders to substitute. inputString = matcher.group(3); // reset the pattern matching with that new string to test for more placeholders matcher = PATTERN.matcher(inputString); } // append the last remainder (without placeholders) in the result string. resultString.append(inputString); xmlAttribute.getXml().setValue(resultString.toString()); } } for (XmlElement childElement : xmlElement.getMergeableElements()) { visit(mergeType, childElement, valueProvider, mergingReportBuilder); } }