@Override public boolean validates(@NonNull MergingReport.Builder mergingReport, @NonNull XmlAttribute attribute, @NonNull String value) { Matcher matcher = PATTERN.matcher(value); boolean valid = matcher.matches() && matcher.group(1).length() <= 8; if (!valid) { attribute.addMessage(mergingReport, MergingReport.Record.Severity.ERROR, String.format( "Attribute %1$s at %2$s is not a valid hexadecimal 32 bit value," + " found %3$s", attribute.getId(), attribute.printPosition(), value )); } return valid; } }
@Override public boolean validates(@NonNull MergingReport.Builder mergingReport, @NonNull XmlAttribute attribute, @NonNull String value) { boolean matches = TRUE_PATTERN.matcher(value).matches() || FALSE_PATTERN.matcher(value).matches(); if (!matches) { attribute.addMessage(mergingReport, MergingReport.Record.Severity.ERROR, String.format( "Attribute %1$s at %2$s has an illegal value=(%3$s), " + "expected 'true' or 'false'", attribute.getId(), attribute.printPosition(), value ) ); } return matches; } }
@Override public boolean validates(@NonNull MergingReport.Builder mergingReport, @NonNull XmlAttribute attribute, @NonNull String value) { try { return Integer.parseInt(value) > 0; } catch (NumberFormatException e) { attribute.addMessage(mergingReport, MergingReport.Record.Severity.ERROR, String.format( "Attribute %1$s at %2$s must be an integer, found %3$s", attribute.getId(), attribute.printPosition(), value) ); return false; } } }
private static Optional<String> checkAttributes( @NonNull XmlElement expected, @NonNull XmlElement actual) { for (XmlAttribute expectedAttr : expected.getAttributes()) { XmlAttribute.NodeName attributeName = expectedAttr.getName(); if (attributeName.isInNamespace(SdkConstants.TOOLS_URI)) { continue; } Optional<XmlAttribute> actualAttr = actual.getAttribute(attributeName); if (actualAttr.isPresent()) { if (!expectedAttr.getValue().equals(actualAttr.get().getValue())) { return Optional.of( String.format("Attribute %1$s do not match: %2$s versus %3$s at %4$s", expectedAttr.getId(), expectedAttr.getValue(), actualAttr.get().getValue(), actual.printPosition())); } } else { return Optional.of(String.format("Attribute %1$s not found at %2$s", expectedAttr.getId(), actual.printPosition())); } } return Optional.absent(); }
@Override public boolean validates(@NonNull MergingReport.Builder mergingReport, @NonNull XmlAttribute attribute, @NonNull String value) { for (String multiValue : multiValues) { if (multiValue.equals(value)) { return true; } } attribute.addMessage(mergingReport, MergingReport.Record.Severity.ERROR, String.format( "Invalid value for attribute %1$s at %2$s, value=(%3$s), " + "acceptable values are (%4$s)", attribute.getId(), attribute.printPosition(), value, allValues ) ); return false; } }
"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)
@Override public boolean validates(@NonNull MergingReport.Builder mergingReport, @NonNull XmlAttribute attribute, @NonNull String value) { boolean valid = super.validates(mergingReport, attribute, value); if (valid) { try { Long decodedValue = Long.decode(value); valid = decodedValue >= mMinimumValue && decodedValue < 0xFFFFFFFFL; } catch(NumberFormatException e) { valid = false; } if (!valid) { attribute.addMessage(mergingReport, MergingReport.Record.Severity.ERROR, String.format( "Attribute %1$s at %2$s is not a valid hexadecimal value," + " minimum is 0x%3$08X, maximum is 0x%4$08X, found %5$s", attribute.getId(), attribute.printPosition(), mMinimumValue, Integer.MAX_VALUE, value )); } return valid; } return false; } }
private void addIllegalImplicitOverrideMessage( @NonNull MergingReport.Builder mergingReport, @NonNull AttributeModel attributeModel, @NonNull XmlElement implicitNode) { String error = String.format("Attribute %1$s value=(%2$s) at %3$s" + " cannot override implicit default value=(%4$s) at %5$s", getId(), getValue(), printPosition(), attributeModel.getDefaultValue(), implicitNode.printPosition()); addMessage(mergingReport, MergingReport.Record.Severity.ERROR, error); }
private static void addToElement( @NonNull ManifestSystemProperty manifestSystemProperty, @NonNull ActionRecorder actionRecorder, String value, @NonNull XmlElement to) { to.getXml().setAttribute(manifestSystemProperty.toCamelCase(), value); XmlAttribute xmlAttribute = new XmlAttribute(to, to.getXml().getAttributeNode(manifestSystemProperty.toCamelCase()), null); actionRecorder.recordAttributeAction(xmlAttribute, new Actions.AttributeRecord( Actions.ActionType.INJECTED, new SourceFilePosition(to.getSourceFile(), SourcePosition.UNKNOWN), xmlAttribute.getId(), null, /* reason */ null /* attributeOperationType */)); }
+ "\tis also present at %4$s value=(%5$s).\n" + "\tAttributes of <%6$s> elements are not merged.", higherPriority.getId(), higherPriority.getValue(), attributeRecord != null + "\tSuggestion: add 'tools:replace=\"%6$s\"' to <%7$s> element " + "at %8$s to override.", higherPriority.getId(), higherPriority.getValue(), attributeRecord != null
private static void addToElementInAndroidNS( @NonNull ManifestSystemProperty manifestSystemProperty, @NonNull ActionRecorder actionRecorder, String value, @NonNull XmlElement to) { String toolsPrefix = getAndroidPrefix(to.getXml()); to.getXml().setAttributeNS(SdkConstants.ANDROID_URI, toolsPrefix + XmlUtils.NS_SEPARATOR + manifestSystemProperty.toCamelCase(), value); Attr attr = to.getXml().getAttributeNodeNS(SdkConstants.ANDROID_URI, manifestSystemProperty.toCamelCase()); XmlAttribute xmlAttribute = new XmlAttribute(to, attr, null); actionRecorder.recordAttributeAction(xmlAttribute, new Actions.AttributeRecord( Actions.ActionType.INJECTED, new SourceFilePosition(to.getSourceFile(), SourcePosition.UNKNOWN), xmlAttribute.getId(), null, /* reason */ null /* attributeOperationType */ ) ); }