diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/AstAttributeNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/AstAttributeNode.java index 6fd0b8469a..6195e129c9 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/AstAttributeNode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/AstAttributeNode.java @@ -6,13 +6,14 @@ package net.sourceforge.pmd.lang.rule.xpath.internal; import java.util.Collections; import java.util.List; +import java.util.function.Predicate; import net.sourceforge.pmd.lang.rule.xpath.Attribute; import net.sf.saxon.om.AtomicSequence; import net.sf.saxon.om.NodeInfo; -import net.sf.saxon.pattern.NodeTest; import net.sf.saxon.tree.iter.AxisIterator; +import net.sf.saxon.tree.iter.EmptyIterator; import net.sf.saxon.tree.util.FastStringBuffer; import net.sf.saxon.tree.util.Navigator; import net.sf.saxon.tree.wrapper.SiblingCountingNode; @@ -50,30 +51,22 @@ class AstAttributeNode extends BaseNodeInfo implements SiblingCountingNode { return siblingPosition; } - @Override - protected AxisIterator iterateAttributes(NodeTest nodeTest) { - return null; - } - @Override - protected AxisIterator iterateChildren(NodeTest nodeTest) { - return null; + protected AxisIterator iterateAttributes(Predicate<? super NodeInfo> nodeTest) { + return EmptyIterator.ofNodes(); } - @Override - protected AxisIterator iterateSiblings(NodeTest nodeTest, boolean forwards) { - return null; + protected AxisIterator iterateChildren(Predicate<? super NodeInfo> nodeTest) { + return EmptyIterator.ofNodes(); } - @Override - protected AxisIterator iterateDescendants(NodeTest nodeTest, boolean includeSelf) { - return null; + protected AxisIterator iterateSiblings(Predicate<? super NodeInfo> nodeTest, boolean forwards) { + return EmptyIterator.ofNodes(); } - @Override public AtomicSequence atomize() { if (value == null) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/AstDocumentNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/AstDocumentNode.java index 72bf990f27..b13587fe99 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/AstDocumentNode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/AstDocumentNode.java @@ -6,16 +6,15 @@ package net.sourceforge.pmd.lang.rule.xpath.internal; import java.util.Collections; import java.util.List; +import java.util.function.Predicate; import org.apache.commons.lang3.mutable.MutableInt; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.RootNode; -import net.sourceforge.pmd.lang.rule.xpath.internal.AstElementNode.DescendantIter; import net.sf.saxon.Configuration; import net.sf.saxon.om.NodeInfo; -import net.sf.saxon.pattern.NodeTest; import net.sf.saxon.tree.iter.AxisIterator; import net.sf.saxon.tree.iter.EmptyIterator; import net.sf.saxon.tree.util.FastStringBuffer; @@ -48,23 +47,18 @@ class AstDocumentNode extends BaseNodeInfo { } @Override - protected AxisIterator iterateAttributes(NodeTest nodeTest) { - return EmptyIterator.OfNodes.THE_INSTANCE; + protected AxisIterator iterateAttributes(Predicate<? super NodeInfo> nodeTest) { + return EmptyIterator.ofNodes(); } @Override - protected AxisIterator iterateChildren(NodeTest nodeTest) { + protected AxisIterator iterateChildren(Predicate<? super NodeInfo> nodeTest) { return filter(nodeTest, iterateList(children)); } @Override - protected AxisIterator iterateSiblings(NodeTest nodeTest, boolean forwards) { - return EmptyIterator.OfNodes.THE_INSTANCE; - } - - @Override - protected AxisIterator iterateDescendants(NodeTest nodeTest, boolean includeSelf) { - return filter(nodeTest, new DescendantIter(this, includeSelf)); + protected AxisIterator iterateSiblings(Predicate<? super NodeInfo> nodeTest, boolean forwards) { + return EmptyIterator.ofNodes(); } @Override diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/AstElementNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/AstElementNode.java index 45719895b5..b5debaa918 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/AstElementNode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/AstElementNode.java @@ -4,13 +4,13 @@ package net.sourceforge.pmd.lang.rule.xpath.internal; -import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Deque; +import java.util.EnumSet; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.function.Predicate; import org.apache.commons.lang3.mutable.MutableInt; import org.checkerframework.checker.nullness.qual.Nullable; @@ -23,11 +23,9 @@ import net.sourceforge.pmd.util.CollectionUtil; import net.sf.saxon.Configuration; import net.sf.saxon.om.NodeInfo; import net.sf.saxon.pattern.NameTest; -import net.sf.saxon.pattern.NodeTest; import net.sf.saxon.tree.iter.AxisIterator; import net.sf.saxon.tree.iter.EmptyIterator; import net.sf.saxon.tree.iter.LookaheadIterator; -import net.sf.saxon.tree.iter.ReverseListIterator; import net.sf.saxon.tree.iter.SingleNodeIterator; import net.sf.saxon.tree.util.FastStringBuffer; import net.sf.saxon.tree.util.Navigator; @@ -120,38 +118,31 @@ public final class AstElementNode extends BaseNodeInfo implements SiblingCountin } @Override - protected AxisIterator iterateAttributes(NodeTest nodeTest) { - if (nodeTest instanceof NameTest) { - String local = ((NameTest) nodeTest).getLocalPart(); + protected AxisIterator iterateAttributes(Predicate<? super NodeInfo> predicate) { + if (predicate instanceof NameTest) { + String local = ((NameTest) predicate).getLocalPart(); return SingleNodeIterator.makeIterator(getAttributes().get(local)); } - return filter(nodeTest, new IteratorAdapter(getAttributes().values().iterator())); + return filter(predicate, new IteratorAdapter(getAttributes().values().iterator())); } - @Override - protected AxisIterator iterateChildren(NodeTest nodeTest) { + protected AxisIterator iterateChildren(Predicate<? super NodeInfo> nodeTest) { return filter(nodeTest, iterateList(children)); } - @Override // this excludes self - protected AxisIterator iterateSiblings(NodeTest nodeTest, boolean forwards) { + protected AxisIterator iterateSiblings(Predicate<? super NodeInfo> nodeTest, boolean forwards) { if (parent == null) { - return EmptyIterator.OfNodes.THE_INSTANCE; + return EmptyIterator.ofNodes(); } List<? extends NodeInfo> siblingsList = forwards ? CollectionUtil.drop(parent.getChildren(), wrappedNode.getIndexInParent() + 1) : CollectionUtil.take(parent.getChildren(), wrappedNode.getIndexInParent()); - @SuppressWarnings("PMD.CloseResource") - AxisIterator iter = - forwards ? iterateList(siblingsList) - : new RevListAxisIterator(siblingsList); - - return filter(nodeTest, iter); + return filter(nodeTest, iterateList(siblingsList, forwards)); } @@ -162,11 +153,6 @@ public final class AstElementNode extends BaseNodeInfo implements SiblingCountin return attributeWrapper == null ? null : attributeWrapper.getStringValue(); } - @Override - protected AxisIterator iterateDescendants(NodeTest nodeTest, boolean includeSelf) { - return filter(nodeTest, new DescendantIter(this, includeSelf)); - } - @Override public int getLineNumber() { @@ -214,59 +200,11 @@ public final class AstElementNode extends BaseNodeInfo implements SiblingCountin return "Wrapper[" + getLocalPart() + "]@" + hashCode(); } - static class DescendantIter implements AxisIterator, LookaheadIterator<NodeInfo> { - private final Deque<BaseNodeInfo> todo; - DescendantIter(BaseNodeInfo start, boolean includeSelf) { - todo = new ArrayDeque<>(); - if (includeSelf) { - todo.addLast(start); - } else { - todo.addAll(start.getChildren()); - } - } - - @Override - public boolean hasNext() { - return !todo.isEmpty(); - } - - @Override - public NodeInfo next() { - if (todo.isEmpty()) { - return null; - } - BaseNodeInfo first = todo.removeFirst(); - todo.addAll(first.getChildren()); - return first; - } - - @Override - public void close() { - todo.clear(); - } - - @Override - public int getProperties() { - return LOOKAHEAD; - } - } - - private static class RevListAxisIterator extends ReverseListIterator<NodeInfo> implements AxisIterator { - - RevListAxisIterator(List<? extends NodeInfo> list) { - super((List<NodeInfo>) list); - } - - @Override - public NodeInfo next() { - return super.next(); - } - } - - private static class IteratorAdapter implements AxisIterator, LookaheadIterator<NodeInfo> { + private static class IteratorAdapter implements AxisIterator, LookaheadIterator { + private static final EnumSet<Property> PROPERTIES = EnumSet.of(Property.LOOKAHEAD); private final Iterator<? extends NodeInfo> it; IteratorAdapter(Iterator<? extends NodeInfo> it) { @@ -290,8 +228,8 @@ public final class AstElementNode extends BaseNodeInfo implements SiblingCountin @Override - public int getProperties() { - return LOOKAHEAD; + public EnumSet<Property> getProperties() { + return PROPERTIES; } } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/BaseNodeInfo.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/BaseNodeInfo.java index 37a36033fb..0f8d7672e3 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/BaseNodeInfo.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/BaseNodeInfo.java @@ -6,13 +6,14 @@ package net.sourceforge.pmd.lang.rule.xpath.internal; import java.util.List; +import java.util.function.Predicate; import net.sf.saxon.om.NamePool; import net.sf.saxon.om.NodeInfo; import net.sf.saxon.pattern.AnyNodeTest; -import net.sf.saxon.pattern.NodeTest; import net.sf.saxon.tree.iter.AxisIterator; import net.sf.saxon.tree.iter.ListIterator; +import net.sf.saxon.tree.iter.ReverseListIterator; import net.sf.saxon.tree.util.Navigator.AxisFilter; import net.sf.saxon.tree.wrapper.AbstractNodeWrapper; import net.sf.saxon.tree.wrapper.SiblingCountingNode; @@ -77,12 +78,24 @@ abstract class BaseNodeInfo extends AbstractNodeWrapper implements SiblingCounti return nodeKind; } - protected static AxisIterator filter(NodeTest nodeTest, AxisIterator iter) { - return nodeTest != null && nodeTest != AnyNodeTest.getInstance() ? new AxisFilter(iter, nodeTest) : iter; + protected static AxisIterator filter(Predicate<? super NodeInfo> nodeTest, AxisIterator iter) { + return nodeTest == null || (nodeTest instanceof AnyNodeTest) ? new AxisFilter(iter, nodeTest) : iter; } static AxisIterator iterateList(List<? extends NodeInfo> nodes) { - return new ListIterator.OfNodes((List) nodes); + return iterateList(nodes, true); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + static AxisIterator iterateList(List<? extends NodeInfo> nodes, boolean forwards) { + return forwards ? new ListIterator.OfNodes((List) nodes) + : new RevListAxisIterator((List) nodes); + } + + private static class RevListAxisIterator extends ReverseListIterator<NodeInfo> implements AxisIterator { + RevListAxisIterator(List<NodeInfo> list) { + super(list); + } } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonXPathRuleQuery.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonXPathRuleQuery.java index 39c014865b..f4ee66325f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonXPathRuleQuery.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/xpath/internal/SaxonXPathRuleQuery.java @@ -118,8 +118,8 @@ public class SaxonXPathRuleQuery { List<Expression> expressions = getExpressionsForLocalNameOrDefault(node.getXPathNodeName()); for (Expression expression : expressions) { @SuppressWarnings("PMD.CloseResource") - SequenceIterator<?> iterator = expression.iterate(xpathDynamicContext.getXPathContextObject()); - Item<?> current = iterator.next(); + SequenceIterator iterator = expression.iterate(xpathDynamicContext.getXPathContextObject()); + Item current = iterator.next(); while (current != null) { if (current instanceof AstElementNode) { results.add(((AstElementNode) current).getUnderlyingNode()); @@ -190,9 +190,11 @@ public class SaxonXPathRuleQuery { return; } try { - final XPathEvaluator xpathEvaluator = new XPathEvaluator(); - this.configuration = xpathEvaluator.getConfiguration(); - StaticContextWithProperties staticCtx = new StaticContextWithProperties(configuration); + this.configuration = Configuration.newConfiguration(); + this.configuration.setNamePool(getNamePool()); + + + StaticContextWithProperties staticCtx = new StaticContextWithProperties(this.configuration); staticCtx.declareNamespace("fn", NamespaceConstant.FN); for (final PropertyDescriptor<?> propertyDescriptor : properties.keySet()) { @@ -202,15 +204,15 @@ public class SaxonXPathRuleQuery { } } - xpathEvaluator.setStaticContext(staticCtx); - configuration.setNamePool(getNamePool()); - for (ExtensionFunctionDefinition fun : xPathHandler.getRegisteredExtensionFunctions()) { StructuredQName qname = fun.getFunctionQName(); staticCtx.declareNamespace(qname.getPrefix(), qname.getURI()); - configuration.registerExtensionFunction(fun); + this.configuration.registerExtensionFunction(fun); } + final XPathEvaluator xpathEvaluator = new XPathEvaluator(configuration); + xpathEvaluator.setStaticContext(staticCtx); + xpathExpression = xpathEvaluator.createExpression(xpathExpr); analyzeXPathForRuleChain(xpathEvaluator); } catch (final XPathException e) { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/internal/ElementNodeTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/internal/ElementNodeTest.java index d429109e29..37d7f2d0dd 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/internal/ElementNodeTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/internal/ElementNodeTest.java @@ -12,7 +12,6 @@ import net.sourceforge.pmd.lang.ast.DummyNode; import net.sourceforge.pmd.lang.ast.DummyRoot; import net.sf.saxon.Configuration; -import net.sf.saxon.sxpath.XPathEvaluator; import net.sf.saxon.type.Type; public class ElementNodeTest { @@ -31,7 +30,7 @@ public class ElementNodeTest { root.addChild(c1, 1); - Configuration configuration = new XPathEvaluator().getStaticContext().getConfiguration(); + Configuration configuration = Configuration.newConfiguration(); AstTreeInfo treeInfo = new AstTreeInfo(root, configuration); Assert.assertSame(root, treeInfo.getRootNode().getUnderlyingNode()); diff --git a/pom.xml b/pom.xml index f892e0934a..7069730ae4 100644 --- a/pom.xml +++ b/pom.xml @@ -632,7 +632,7 @@ <dependency> <groupId>net.sf.saxon</groupId> <artifactId>Saxon-HE</artifactId> - <version>9.9.1-6</version> + <version>10.1</version> </dependency> <dependency> <groupId>org.mozilla</groupId>