forked from phoedos/pmd
Use new ooxml lib
This commit is contained in:
@ -124,7 +124,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.oowekyala.ooxml</groupId>
|
||||
<artifactId>nice-xml-messages</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.internal.util.xml;
|
||||
|
||||
import net.sourceforge.pmd.util.log.MessageReporter;
|
||||
|
||||
import com.github.oowekyala.ooxml.messages.XmlException;
|
||||
import com.github.oowekyala.ooxml.messages.XmlMessageReporter;
|
||||
|
||||
/**
|
||||
* @author Clément Fournier
|
||||
*/
|
||||
public interface PmdXmlReporter extends XmlMessageReporter<MessageReporter> {
|
||||
|
||||
void addExceptionToThrowLater(XmlException e);
|
||||
|
||||
}
|
@ -14,8 +14,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import com.github.oowekyala.ooxml.messages.XmlErrorReporter;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
|
||||
/**
|
||||
@ -36,21 +35,21 @@ public class SchemaConstant {
|
||||
return e.hasAttribute(name) ? Boolean.parseBoolean(attr) : defaultValue;
|
||||
}
|
||||
|
||||
public @NonNull String getAttributeOrThrow(Element element, XmlErrorReporter err) {
|
||||
public @NonNull String getAttributeOrThrow(Element element, PmdXmlReporter err) {
|
||||
String attribute = element.getAttribute(name);
|
||||
if (!element.hasAttribute(name)) {
|
||||
throw err.error(element, XmlErrorMessages.ERR__MISSING_REQUIRED_ATTRIBUTE, name);
|
||||
throw err.at(element).error(XmlErrorMessages.ERR__MISSING_REQUIRED_ATTRIBUTE, name);
|
||||
}
|
||||
|
||||
return attribute;
|
||||
}
|
||||
|
||||
public @NonNull String getNonBlankAttributeOrThrow(Element element, XmlErrorReporter err) {
|
||||
public @NonNull String getNonBlankAttributeOrThrow(Element element, PmdXmlReporter err) {
|
||||
String attribute = element.getAttribute(name);
|
||||
if (!element.hasAttribute(name)) {
|
||||
throw err.error(element, XmlErrorMessages.ERR__MISSING_REQUIRED_ATTRIBUTE, name);
|
||||
throw err.at(element).error(XmlErrorMessages.ERR__MISSING_REQUIRED_ATTRIBUTE, name);
|
||||
} else if (StringUtils.isBlank(attribute)) {
|
||||
throw err.error(element, XmlErrorMessages.ERR__BLANK_REQUIRED_ATTRIBUTE, name);
|
||||
throw err.at(element).error(XmlErrorMessages.ERR__BLANK_REQUIRED_ATTRIBUTE, name);
|
||||
}
|
||||
return attribute;
|
||||
}
|
||||
@ -73,16 +72,16 @@ public class SchemaConstant {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Element> getElementChildrenNamedReportOthers(Element elt, XmlErrorReporter err) {
|
||||
public List<Element> getElementChildrenNamedReportOthers(Element elt, PmdXmlReporter err) {
|
||||
return XmlUtil.getElementChildrenNamedReportOthers(elt, setOf(name), err)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Element getSingleChildIn(Element elt, XmlErrorReporter err) {
|
||||
public Element getSingleChildIn(Element elt, PmdXmlReporter err) {
|
||||
return XmlUtil.getSingleChildIn(elt, true, err, setOf(name));
|
||||
}
|
||||
|
||||
public Element getOptChildIn(Element elt, XmlErrorReporter err) {
|
||||
public Element getOptChildIn(Element elt, PmdXmlReporter err) {
|
||||
return XmlUtil.getSingleChildIn(elt, false, err, setOf(name));
|
||||
}
|
||||
|
||||
@ -106,4 +105,7 @@ public class SchemaConstant {
|
||||
}
|
||||
|
||||
|
||||
public boolean isElementWithName(Node node) {
|
||||
return node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals(name);
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,15 @@ public final class SchemaConstants {
|
||||
public static final SchemaConstant DEPRECATED = new SchemaConstant("deprecated");
|
||||
|
||||
|
||||
// ruleset
|
||||
public static final SchemaConstant EXCLUDE_PATTERN = new SchemaConstant("exclude-pattern");
|
||||
public static final SchemaConstant INCLUDE_PATTERN = new SchemaConstant("include-pattern");
|
||||
public static final SchemaConstant RULE = new SchemaConstant("rule");
|
||||
|
||||
public static final SchemaConstant EXCLUDE = new SchemaConstant("exclude");
|
||||
public static final SchemaConstant PRIORITY = new SchemaConstant("priority");
|
||||
|
||||
|
||||
private SchemaConstants() {
|
||||
// utility class
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import org.w3c.dom.Node;
|
||||
import net.sourceforge.pmd.properties.xml.XmlMapper;
|
||||
|
||||
import com.github.oowekyala.ooxml.DomUtils;
|
||||
import com.github.oowekyala.ooxml.messages.XmlErrorReporter;
|
||||
|
||||
public final class XmlUtil {
|
||||
|
||||
@ -39,13 +38,13 @@ public final class XmlUtil {
|
||||
return getElementChildren(parent).filter(e -> names.contains(e.getTagName()));
|
||||
}
|
||||
|
||||
public static Stream<Element> getElementChildrenNamedReportOthers(Element parent, Set<String> names, XmlErrorReporter err) {
|
||||
public static Stream<Element> getElementChildrenNamedReportOthers(Element parent, Set<String> names, PmdXmlReporter err) {
|
||||
return getElementChildren(parent)
|
||||
.map(it -> {
|
||||
if (names.contains(it.getTagName())) {
|
||||
return it;
|
||||
} else {
|
||||
err.warn(it, IGNORED__UNEXPECTED_ELEMENT, it.getTagName(), formatPossibleNames(names));
|
||||
err.at(it).warn(IGNORED__UNEXPECTED_ELEMENT, it.getTagName(), formatPossibleNames(names));
|
||||
return null;
|
||||
}
|
||||
}).filter(Objects::nonNull);
|
||||
@ -55,10 +54,10 @@ public final class XmlUtil {
|
||||
return getElementChildren(parent).filter(e -> name.equals(e.getTagName()));
|
||||
}
|
||||
|
||||
public static <T> T expectElement(XmlErrorReporter err, Element elt, XmlMapper<T> syntax) {
|
||||
public static <T> T expectElement(PmdXmlReporter err, Element elt, XmlMapper<T> syntax) {
|
||||
|
||||
if (!syntax.getReadElementNames().contains(elt.getTagName())) {
|
||||
err.warn(elt, "Wrong name, expected " + formatPossibleNames(syntax.getReadElementNames()));
|
||||
err.at(elt).warn("Wrong name, expected " + formatPossibleNames(syntax.getReadElementNames()));
|
||||
} else {
|
||||
return syntax.fromXml(elt, err);
|
||||
}
|
||||
@ -67,28 +66,28 @@ public final class XmlUtil {
|
||||
}
|
||||
|
||||
|
||||
public static List<Element> getChildrenExpectSingleName(Element elt, String name, XmlErrorReporter err) {
|
||||
public static List<Element> getChildrenExpectSingleName(Element elt, String name, PmdXmlReporter err) {
|
||||
return XmlUtil.getElementChildren(elt).peek(it -> {
|
||||
if (!it.getTagName().equals(name)) {
|
||||
err.warn(it, IGNORED__UNEXPECTED_ELEMENT, it.getTagName(), name);
|
||||
err.at(it).warn(IGNORED__UNEXPECTED_ELEMENT, it.getTagName(), name);
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static Element getSingleChildIn(Element elt, boolean throwOnMissing, XmlErrorReporter err, Set<String> names) {
|
||||
public static Element getSingleChildIn(Element elt, boolean throwOnMissing, PmdXmlReporter err, Set<String> names) {
|
||||
List<Element> children = getElementChildrenNamed(elt, names).collect(Collectors.toList());
|
||||
if (children.size() == 1) {
|
||||
return children.get(0);
|
||||
} else if (children.isEmpty()) {
|
||||
if (throwOnMissing) {
|
||||
throw err.error(elt, ERR__MISSING_REQUIRED_ELEMENT, formatPossibleNames(names));
|
||||
throw err.at(elt).error(ERR__MISSING_REQUIRED_ELEMENT, formatPossibleNames(names));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
for (int i = 1; i < children.size(); i++) {
|
||||
Element child = children.get(i);
|
||||
err.warn(child, IGNORED__DUPLICATE_CHILD_ELEMENT, child.getTagName());
|
||||
err.at(child).warn(IGNORED__DUPLICATE_CHILD_ELEMENT, child.getTagName());
|
||||
}
|
||||
return children.get(0);
|
||||
}
|
||||
|
@ -10,19 +10,18 @@ import java.util.Set;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import net.sourceforge.pmd.internal.util.xml.PmdXmlReporter;
|
||||
import net.sourceforge.pmd.internal.util.xml.XmlErrorMessages;
|
||||
import net.sourceforge.pmd.properties.constraints.PropertyConstraint;
|
||||
import net.sourceforge.pmd.util.CollectionUtil;
|
||||
|
||||
import com.github.oowekyala.ooxml.messages.XmlErrorReporter;
|
||||
|
||||
/**
|
||||
* Decorates an XmlMapper with some {@link PropertyConstraint}s.
|
||||
* Those are checked when the value is parsed. This is used to
|
||||
* report errors on the most specific failing element.
|
||||
*
|
||||
* <p>Note that this is the only XmlMapper that *applies* constraints
|
||||
* in {@link #fromXml(Element, XmlErrorReporter)}. A {@link SeqSyntax}
|
||||
* in {@link #fromXml(Element, PmdXmlReporter)}. A {@link SeqSyntax}
|
||||
* or {@link OptionalSyntax} may return some constraints in {@link #getConstraints()}
|
||||
* that are derived from the constraints of the item, yet not check them
|
||||
* on elements (they will be applied on each element by the {@link XmlMapper}
|
||||
@ -40,13 +39,13 @@ class ConstraintDecorator<T> extends XmlMapper<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public T fromXml(Element element, XmlErrorReporter err) {
|
||||
public T fromXml(Element element, PmdXmlReporter err) {
|
||||
T t = xmlMapper.fromXml(element, err);
|
||||
|
||||
XmlSyntaxUtils.checkConstraintsThrow(
|
||||
t,
|
||||
constraints,
|
||||
s -> err.error(element, XmlErrorMessages.ERR__CONSTRAINT_NOT_SATISFIED, s)
|
||||
s -> err.at(element).error(XmlErrorMessages.ERR__CONSTRAINT_NOT_SATISFIED, s)
|
||||
);
|
||||
|
||||
return t;
|
||||
|
@ -15,13 +15,12 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import net.sourceforge.pmd.internal.util.xml.PmdXmlReporter;
|
||||
import net.sourceforge.pmd.internal.util.xml.XmlErrorMessages;
|
||||
import net.sourceforge.pmd.internal.util.xml.XmlUtil;
|
||||
import net.sourceforge.pmd.properties.constraints.PropertyConstraint;
|
||||
import net.sourceforge.pmd.util.CollectionUtil;
|
||||
|
||||
import com.github.oowekyala.ooxml.messages.XmlErrorReporter;
|
||||
|
||||
/**
|
||||
* A set of syntaxes for read and write. One special syntax is designated
|
||||
* as the one used to write elements, the others are used to read.
|
||||
@ -122,10 +121,10 @@ final class MapperSet<T> extends XmlMapper<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public T fromXml(Element element, XmlErrorReporter err) {
|
||||
public T fromXml(Element element, PmdXmlReporter err) {
|
||||
XmlMapper<T> syntax = readIndex.get(element.getTagName());
|
||||
if (syntax == null) {
|
||||
throw err.error(element, XmlErrorMessages.ERR__UNEXPECTED_ELEMENT, element.getTagName(), XmlUtil.formatPossibleNames(readIndex.keySet()));
|
||||
throw err.at(element).error(XmlErrorMessages.ERR__UNEXPECTED_ELEMENT, element.getTagName(), XmlUtil.formatPossibleNames(readIndex.keySet()));
|
||||
} else {
|
||||
return syntax.fromXml(element, err);
|
||||
}
|
||||
|
@ -13,11 +13,10 @@ import java.util.stream.Collectors;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import net.sourceforge.pmd.internal.util.xml.PmdXmlReporter;
|
||||
import net.sourceforge.pmd.properties.constraints.PropertyConstraint;
|
||||
import net.sourceforge.pmd.util.CollectionUtil;
|
||||
|
||||
import com.github.oowekyala.ooxml.messages.XmlErrorReporter;
|
||||
|
||||
/**
|
||||
* Serialize an optional value. If the value is itself an {@code Optional<S>},
|
||||
* then mentioning {@code </none>} will yield a toplevel empty optional. So
|
||||
@ -69,7 +68,7 @@ final class OptionalSyntax<T> extends XmlMapper<Optional<T>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<T> fromXml(Element element, XmlErrorReporter err) {
|
||||
public Optional<T> fromXml(Element element, PmdXmlReporter err) {
|
||||
if (EMPTY_NAME.equals(element.getTagName())) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
|
@ -12,13 +12,12 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import net.sourceforge.pmd.internal.util.xml.PmdXmlReporter;
|
||||
import net.sourceforge.pmd.internal.util.xml.XmlErrorMessages;
|
||||
import net.sourceforge.pmd.internal.util.xml.XmlUtil;
|
||||
import net.sourceforge.pmd.properties.constraints.PropertyConstraint;
|
||||
import net.sourceforge.pmd.properties.xml.XmlMapper.StableXmlMapper;
|
||||
|
||||
import com.github.oowekyala.ooxml.messages.XmlErrorReporter;
|
||||
|
||||
/**
|
||||
* Serialize to and from a simple string. Examples:
|
||||
*
|
||||
@ -47,8 +46,8 @@ final class SeqSyntax<T, C extends Iterable<T>> extends StableXmlMapper<C> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public C fromXml(Element element, XmlErrorReporter err) {
|
||||
RuntimeException aggregateEx = err.error(element, XmlErrorMessages.ERR__LIST_CONSTRAINT_NOT_SATISFIED);
|
||||
public C fromXml(Element element, PmdXmlReporter err) {
|
||||
RuntimeException aggregateEx = err.at(element).error(XmlErrorMessages.ERR__LIST_CONSTRAINT_NOT_SATISFIED);
|
||||
|
||||
C result = XmlUtil.getElementChildren(element)
|
||||
.map(child -> {
|
||||
|
@ -15,11 +15,10 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import net.sourceforge.pmd.internal.util.PredicateUtil;
|
||||
import net.sourceforge.pmd.internal.util.xml.PmdXmlReporter;
|
||||
import net.sourceforge.pmd.properties.constraints.PropertyConstraint;
|
||||
import net.sourceforge.pmd.properties.xml.XmlMapper.StableXmlMapper;
|
||||
|
||||
import com.github.oowekyala.ooxml.messages.XmlErrorReporter;
|
||||
|
||||
/**
|
||||
* Serialize to and from a simple string. Examples:
|
||||
*
|
||||
@ -77,11 +76,11 @@ class ValueSyntax<T> extends StableXmlMapper<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public T fromXml(Element element, XmlErrorReporter err) {
|
||||
public T fromXml(Element element, PmdXmlReporter err) {
|
||||
try {
|
||||
return fromString.apply(element.getTextContent());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw err.error(element, e);
|
||||
throw err.at(element).error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,12 +12,13 @@ import java.util.Set;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import net.sourceforge.pmd.internal.util.xml.PmdXmlReporter;
|
||||
import net.sourceforge.pmd.properties.PropertyFactory;
|
||||
import net.sourceforge.pmd.properties.constraints.PropertyConstraint;
|
||||
import net.sourceforge.pmd.util.log.MessageReporter;
|
||||
|
||||
import com.github.oowekyala.ooxml.messages.XmlErrorReporter;
|
||||
import com.github.oowekyala.ooxml.messages.XmlException;
|
||||
|
||||
|
||||
/**
|
||||
@ -35,11 +36,11 @@ public abstract class XmlMapper<T> {
|
||||
|
||||
/**
|
||||
* Extract the value from an XML element. If an error occurs, throws
|
||||
* an exception with {@link XmlErrorReporter#error(Node, Throwable)}
|
||||
* an {@link XmlException} with {@link MessageReporter#error(Throwable)}
|
||||
* on the most specific node (the type of exception is unspecified).
|
||||
* This will check property constraints if any.
|
||||
*/
|
||||
public abstract T fromXml(Element element, XmlErrorReporter err);
|
||||
public abstract T fromXml(Element element, PmdXmlReporter err);
|
||||
|
||||
|
||||
/** Write the value into the given XML element. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
@ -27,6 +27,7 @@ import net.sourceforge.pmd.Rule;
|
||||
import net.sourceforge.pmd.RulePriority;
|
||||
import net.sourceforge.pmd.RuleSetReference;
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
import net.sourceforge.pmd.internal.util.xml.PmdXmlReporter;
|
||||
import net.sourceforge.pmd.internal.util.xml.SchemaConstants;
|
||||
import net.sourceforge.pmd.internal.util.xml.XmlErrorMessages;
|
||||
import net.sourceforge.pmd.internal.util.xml.XmlUtil;
|
||||
@ -34,6 +35,7 @@ import net.sourceforge.pmd.lang.Language;
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
import net.sourceforge.pmd.lang.LanguageVersion;
|
||||
import net.sourceforge.pmd.lang.rule.RuleReference;
|
||||
import net.sourceforge.pmd.lang.rule.internal.CommonPropertyDescriptors;
|
||||
import net.sourceforge.pmd.properties.PropertyDescriptor;
|
||||
import net.sourceforge.pmd.properties.PropertyTypeId;
|
||||
import net.sourceforge.pmd.properties.PropertyTypeId.BuilderAndMapper;
|
||||
@ -42,7 +44,6 @@ import net.sourceforge.pmd.util.ResourceLoader;
|
||||
import net.sourceforge.pmd.util.StringUtil;
|
||||
|
||||
import com.github.oowekyala.ooxml.DomUtils;
|
||||
import com.github.oowekyala.ooxml.messages.XmlErrorReporter;
|
||||
import com.github.oowekyala.ooxml.messages.XmlException;
|
||||
|
||||
|
||||
@ -102,7 +103,7 @@ public class RuleFactory {
|
||||
*
|
||||
* @return A rule reference to the referenced rule
|
||||
*/
|
||||
public RuleReference decorateRule(Rule referencedRule, RuleSetReference ruleSetReference, Element ruleElement, XmlErrorReporter err) {
|
||||
public RuleReference decorateRule(Rule referencedRule, RuleSetReference ruleSetReference, Element ruleElement, PmdXmlReporter err) {
|
||||
RuleReference ruleReference = new RuleReference(referencedRule, ruleSetReference);
|
||||
|
||||
DomUtils.getAttributeOpt(ruleElement, DEPRECATED).map(Boolean::parseBoolean).ifPresent(ruleReference::setDeprecated);
|
||||
@ -125,8 +126,7 @@ public class RuleFactory {
|
||||
setPropertyValues(ruleReference, node, err);
|
||||
break;
|
||||
default:
|
||||
throw err.error(
|
||||
node,
|
||||
throw err.at(node).error(
|
||||
XmlErrorMessages.ERR__UNEXPECTED_ELEMENT_IN,
|
||||
"rule " + ruleReference.getName()
|
||||
);
|
||||
@ -148,14 +148,14 @@ public class RuleFactory {
|
||||
*
|
||||
* @throws IllegalArgumentException if the element doesn't describe a valid rule.
|
||||
*/
|
||||
public Rule buildRule(Element ruleElement, XmlErrorReporter err) {
|
||||
public Rule buildRule(Element ruleElement, PmdXmlReporter err) {
|
||||
|
||||
Rule rule;
|
||||
try {
|
||||
String clazz = getNonBlankAttribute(ruleElement, err, CLASS);
|
||||
rule = resourceLoader.loadRuleFromClassPath(clazz);
|
||||
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
|
||||
throw err.error(ruleElement.getAttributeNode(CLASS), e);
|
||||
throw err.at(ruleElement.getAttributeNode(CLASS)).error(e);
|
||||
}
|
||||
|
||||
rule.setName(getNonBlankAttribute(ruleElement, err, NAME));
|
||||
@ -191,45 +191,45 @@ public class RuleFactory {
|
||||
setPropertyValues(rule, node, err);
|
||||
break;
|
||||
default:
|
||||
throw err.error(node,
|
||||
XmlErrorMessages.ERR__UNEXPECTED_ELEMENT_IN,
|
||||
"rule " + ruleElement.getAttribute(NAME));
|
||||
throw err.at(node).error(
|
||||
XmlErrorMessages.ERR__UNEXPECTED_ELEMENT_IN,
|
||||
"rule " + ruleElement.getAttribute(NAME));
|
||||
}
|
||||
}
|
||||
|
||||
return rule;
|
||||
}
|
||||
|
||||
private void checkVersionsAreOrdered(Element ruleElement, XmlErrorReporter err, Rule rule) {
|
||||
private void checkVersionsAreOrdered(Element ruleElement, PmdXmlReporter err, Rule rule) {
|
||||
if (rule.getMinimumLanguageVersion() != null && rule.getMaximumLanguageVersion() != null
|
||||
&& rule.getMinimumLanguageVersion().compareTo(rule.getMaximumLanguageVersion()) > 0) {
|
||||
throw err.fatal(
|
||||
ruleElement.getAttributeNode(MINIMUM_LANGUAGE_VERSION),
|
||||
XmlErrorMessages.ERR__INVALID_VERSION_RANGE,
|
||||
rule.getMinimumLanguageVersion(),
|
||||
rule.getMaximumLanguageVersion()
|
||||
);
|
||||
throw err.at(ruleElement.getAttributeNode(MINIMUM_LANGUAGE_VERSION))
|
||||
.error(
|
||||
XmlErrorMessages.ERR__INVALID_VERSION_RANGE,
|
||||
rule.getMinimumLanguageVersion(),
|
||||
rule.getMaximumLanguageVersion()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private @NonNull RulePriority parsePriority(XmlErrorReporter err, Element node, String trim) {
|
||||
private @NonNull RulePriority parsePriority(PmdXmlReporter err, Element node, String trim) {
|
||||
try {
|
||||
int i = Integer.parseInt(trim.trim());
|
||||
RulePriority rp = RulePriority.valueOfNullable(i);
|
||||
if (rp == null) {
|
||||
err.warn(node, XmlErrorMessages.WARN__INVALID_PRIORITY_VALUE, i);
|
||||
err.at(node).warn(XmlErrorMessages.WARN__INVALID_PRIORITY_VALUE, i);
|
||||
return RulePriority.MEDIUM;
|
||||
} else {
|
||||
return rp;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
err.warn(node, XmlErrorMessages.WARN__INVALID_PRIORITY_VALUE, trim);
|
||||
err.at(node).warn(XmlErrorMessages.WARN__INVALID_PRIORITY_VALUE, trim);
|
||||
return RulePriority.MEDIUM;
|
||||
}
|
||||
}
|
||||
|
||||
private LanguageVersion getLanguageVersion(Element ruleElement, XmlErrorReporter err, Language language, String attrName) {
|
||||
private LanguageVersion getLanguageVersion(Element ruleElement, PmdXmlReporter err, Language language, String attrName) {
|
||||
if (ruleElement.hasAttribute(attrName)) {
|
||||
String attrValue = ruleElement.getAttribute(attrName);
|
||||
LanguageVersion version = language.getVersion(attrValue);
|
||||
@ -242,24 +242,24 @@ public class RuleFactory {
|
||||
String message = supportedVersions.isEmpty()
|
||||
? ERR__INVALID_LANG_VERSION_NO_NAMED_VERSION
|
||||
: ERR__INVALID_LANG_VERSION;
|
||||
throw err.fatal(
|
||||
ruleElement.getAttributeNode(attrName),
|
||||
message,
|
||||
attrValue,
|
||||
language.getTerseName(),
|
||||
supportedVersions
|
||||
);
|
||||
throw err.at(ruleElement.getAttributeNode(attrName))
|
||||
.error(
|
||||
message,
|
||||
attrValue,
|
||||
language.getTerseName(),
|
||||
supportedVersions
|
||||
);
|
||||
}
|
||||
return version;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setLanguage(Element ruleElement, XmlErrorReporter err, Rule rule) {
|
||||
private void setLanguage(Element ruleElement, PmdXmlReporter err, Rule rule) {
|
||||
String langId = getNonBlankAttribute(ruleElement, err, LANGUAGE);
|
||||
Language lang = LanguageRegistry.findLanguageByTerseName(langId);
|
||||
if (lang == null) {
|
||||
throw err.fatal(ruleElement.getAttributeNode(LANGUAGE), "Invalid language ''{0}'', possible values are {1}", langId, supportedLanguages());
|
||||
throw err.at(ruleElement.getAttributeNode(LANGUAGE)).error("Invalid language ''{0}'', possible values are {1}", langId, supportedLanguages());
|
||||
}
|
||||
rule.setLanguage(lang);
|
||||
}
|
||||
@ -268,14 +268,14 @@ public class RuleFactory {
|
||||
return LanguageRegistry.getLanguages().stream().map(Language::getTerseName).map(StringUtil::inSingleQuotes).collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
private @NonNull String getNonBlankAttribute(Element ruleElement, XmlErrorReporter err, String attrName) {
|
||||
private @NonNull String getNonBlankAttribute(Element ruleElement, PmdXmlReporter err, String attrName) {
|
||||
String clazz = ruleElement.getAttribute(attrName);
|
||||
if (StringUtils.isBlank(clazz)) {
|
||||
Attr attr = ruleElement.getAttributeNode(attrName);
|
||||
if (attr == null) {
|
||||
throw err.fatal(ruleElement, "Missing {0} attribute", attrName);
|
||||
throw err.at(ruleElement).error("Missing {0} attribute", attrName);
|
||||
} else {
|
||||
throw err.fatal(attr, "This attribute may not be blank");
|
||||
throw err.at(attr).error("This attribute may not be blank");
|
||||
}
|
||||
}
|
||||
return clazz;
|
||||
@ -285,11 +285,11 @@ public class RuleFactory {
|
||||
* Parses the properties node and adds property definitions to the builder. Doesn't care for value overriding, that
|
||||
* will be handled after the rule instantiation.
|
||||
*
|
||||
* @param rule Rule builder
|
||||
* @param rule Rule builder
|
||||
* @param propertiesNode Node to parse
|
||||
* @param err Error reporter
|
||||
*/
|
||||
private void parsePropertiesForDefinitions(Rule rule, Element propertiesNode, @NonNull XmlErrorReporter err) {
|
||||
private void parsePropertiesForDefinitions(Rule rule, Element propertiesNode, @NonNull PmdXmlReporter err) {
|
||||
for (Element child : SchemaConstants.PROPERTY_ELT.getElementChildrenNamedReportOthers(propertiesNode, err)) {
|
||||
if (isPropertyDefinition(child)) {
|
||||
rule.definePropertyDescriptor(parsePropertyDefinition(child, err));
|
||||
@ -303,21 +303,21 @@ public class RuleFactory {
|
||||
* @param rule The rule
|
||||
* @param propertiesElt The {@literal <properties>} element
|
||||
*/
|
||||
private void setPropertyValues(Rule rule, Element propertiesElt, XmlErrorReporter err) {
|
||||
private void setPropertyValues(Rule rule, Element propertiesElt, PmdXmlReporter err) {
|
||||
Set<String> overridden = new HashSet<>();
|
||||
|
||||
XmlException exception = null;
|
||||
for (Element element : SchemaConstants.PROPERTY_ELT.getElementChildrenNamedReportOthers(propertiesElt, err)) {
|
||||
String name = SchemaConstants.NAME.getAttributeOrThrow(element, err);
|
||||
if (!overridden.add(name)) {
|
||||
err.warn(element, IGNORED__DUPLICATE_PROPERTY_SETTER, name);
|
||||
err.at(element).warn(IGNORED__DUPLICATE_PROPERTY_SETTER, name);
|
||||
continue;
|
||||
}
|
||||
|
||||
PropertyDescriptor<?> desc = rule.getPropertyDescriptor(name);
|
||||
if (desc == null) {
|
||||
// todo just warn and ignore
|
||||
throw err.error(element, ERR__PROPERTY_DOES_NOT_EXIST, name, rule.getName());
|
||||
throw err.at(element).error(ERR__PROPERTY_DOES_NOT_EXIST, name, rule.getName());
|
||||
}
|
||||
try {
|
||||
setRulePropertyCapture(rule, desc, element, err);
|
||||
@ -334,7 +334,7 @@ public class RuleFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private <T> void setRulePropertyCapture(Rule rule, PropertyDescriptor<T> descriptor, Element propertyElt, XmlErrorReporter err) {
|
||||
private <T> void setRulePropertyCapture(Rule rule, PropertyDescriptor<T> descriptor, Element propertyElt, PmdXmlReporter err) {
|
||||
T value = parsePropertyValue(propertyElt, err, descriptor.xmlMapper());
|
||||
rule.setProperty(descriptor, value);
|
||||
}
|
||||
@ -358,24 +358,24 @@ public class RuleFactory {
|
||||
*
|
||||
* @return The property descriptor
|
||||
*/
|
||||
private static PropertyDescriptor<?> parsePropertyDefinition(Element propertyElement, XmlErrorReporter err) {
|
||||
private static PropertyDescriptor<?> parsePropertyDefinition(Element propertyElement, PmdXmlReporter err) {
|
||||
|
||||
String typeId = SchemaConstants.PROPERTY_TYPE.getAttributeOrThrow(propertyElement, err);
|
||||
|
||||
PropertyTypeId factory = PropertyTypeId.lookupMnemonic(typeId);
|
||||
if (factory == null) {
|
||||
throw err.fatal(
|
||||
PROPERTY_TYPE.getAttributeNode(propertyElement),
|
||||
"Unsupported property type ''{0}''",
|
||||
typeId
|
||||
);
|
||||
throw err.at(PROPERTY_TYPE.getAttributeNode(propertyElement))
|
||||
.error(
|
||||
"Unsupported property type ''{0}''",
|
||||
typeId
|
||||
);
|
||||
}
|
||||
|
||||
return propertyDefCapture(propertyElement, err, factory.getBuilderUtils());
|
||||
}
|
||||
|
||||
private static <T> PropertyDescriptor<T> propertyDefCapture(Element propertyElement,
|
||||
XmlErrorReporter err,
|
||||
PmdXmlReporter err,
|
||||
BuilderAndMapper<T> factory) {
|
||||
// TODO support constraints like numeric range
|
||||
|
||||
@ -391,11 +391,11 @@ public class RuleFactory {
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
// builder threw, rethrow with XML location
|
||||
throw err.error(propertyElement, e.getMessage());
|
||||
throw err.at(propertyElement).error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T parsePropertyValue(Element propertyElt, XmlErrorReporter err, XmlMapper<T> syntax) {
|
||||
private static <T> T parsePropertyValue(Element propertyElt, PmdXmlReporter err, XmlMapper<T> syntax) {
|
||||
@Nullable String defaultAttr = PROPERTY_VALUE.getAttributeOpt(propertyElt);
|
||||
if (defaultAttr != null) {
|
||||
Attr attrNode = PROPERTY_VALUE.getAttributeNode(propertyElt);
|
||||
@ -409,10 +409,10 @@ public class RuleFactory {
|
||||
try {
|
||||
return syntax.fromString(defaultAttr);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw err.error(attrNode, e);
|
||||
throw err.at(attrNode).error(e);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
throw err.error(attrNode,
|
||||
ERR__UNSUPPORTED_VALUE_ATTRIBUTE,
|
||||
throw err.at(attrNode)
|
||||
.error(ERR__UNSUPPORTED_VALUE_ATTRIBUTE,
|
||||
String.join("\nor\n", syntax.getExamples()));
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,9 @@
|
||||
package net.sourceforge.pmd.util.log;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.slf4j.event.Level;
|
||||
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
@ -26,9 +28,16 @@ public interface MessageReporter {
|
||||
|
||||
boolean isLoggable(Level level);
|
||||
|
||||
void log(Level level, String message, Object... formatArgs);
|
||||
default void log(Level level, String message, Object... formatArgs) {
|
||||
logEx(level, message, formatArgs, null);
|
||||
}
|
||||
|
||||
void logEx(Level level, String message, Object[] formatArgs, Throwable error);
|
||||
void logEx(Level level, @Nullable String message, Object[] formatArgs, @Nullable Throwable error);
|
||||
|
||||
default RuntimeException newException(Level level, @Nullable Throwable cause, String message, Object... formatArgs) {
|
||||
logEx(level, message, formatArgs, cause);
|
||||
return new RuntimeException(MessageFormat.format(message, formatArgs), cause);
|
||||
}
|
||||
|
||||
default void info(String message, Object... formatArgs) {
|
||||
log(Level.INFO, message, formatArgs);
|
||||
@ -46,8 +55,19 @@ public interface MessageReporter {
|
||||
logEx(Level.WARN, message, formatArgs, error);
|
||||
}
|
||||
|
||||
default void error(String message, Object... formatArgs) {
|
||||
default RuntimeException error(String message, Object... formatArgs) {
|
||||
log(Level.ERROR, message, formatArgs);
|
||||
return newException(Level.ERROR, null, message, formatArgs);
|
||||
}
|
||||
|
||||
default RuntimeException error(Throwable cause, String contextMessage, Object... formatArgs) {
|
||||
logEx(Level.ERROR, contextMessage, formatArgs, Objects.requireNonNull(cause));
|
||||
return newException(Level.ERROR, null, contextMessage, formatArgs);
|
||||
}
|
||||
|
||||
default RuntimeException error(Throwable error) {
|
||||
logEx(Level.ERROR, null, new Object[0], Objects.requireNonNull(error));
|
||||
return newException(Level.ERROR, error, error.getMessage());
|
||||
}
|
||||
|
||||
default void errorEx(String message, Throwable error) {
|
||||
|
@ -654,17 +654,17 @@ public class RuleSetFactoryTest {
|
||||
@Test
|
||||
public void testInvertedMinimumMaximumLanguageVersions() {
|
||||
assertCannotParse(INVERTED_MINIMUM_MAXIMUM_LANGUAGE_VERSIONS);
|
||||
verifyFoundAnErrorWithMessage(containing("versionRange"));
|
||||
verifyFoundAnErrorWithMessage(containing("version range"));
|
||||
}
|
||||
|
||||
private void verifyFoundAnErrorWithMessage(Predicate<String> messageTest) {
|
||||
Mockito.verify(mockReporter, Mockito.times(1))
|
||||
.log(Mockito.eq(Level.ERROR), Mockito.argThat(messageTest::test), Mockito.any());
|
||||
.logEx(Mockito.eq(Level.ERROR), Mockito.argThat(messageTest::test), Mockito.any(), Mockito.any());
|
||||
}
|
||||
|
||||
private void verifyFoundAWarningWithMessage(Predicate<String> messageTest) {
|
||||
Mockito.verify(mockReporter, Mockito.times(1))
|
||||
.log(Mockito.eq(Level.WARN), Mockito.argThat(messageTest::test), Mockito.any());
|
||||
.logEx(Mockito.eq(Level.WARN), Mockito.argThat(messageTest::test), Mockito.any(), Mockito.any());
|
||||
}
|
||||
|
||||
private static Predicate<String> containing(String part) {
|
||||
|
Reference in New Issue
Block a user