mirror of https://github.com/apache/activemq.git
fix for https://issues.apache.org/activemq/browse/AMQ-2179; xpath selectors and boolean expressions
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@758184 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
86ec0553c5
commit
42d91a3b79
|
@ -24,6 +24,7 @@ import javax.jms.JMSException;
|
|||
import javax.jms.TextMessage;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.xpath.XPath;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.traversal.NodeIterator;
|
||||
|
@ -32,6 +33,8 @@ import org.xml.sax.InputSource;
|
|||
import org.apache.activemq.command.Message;
|
||||
import org.apache.activemq.util.ByteArrayInputStream;
|
||||
import org.apache.xpath.CachedXPathAPI;
|
||||
import org.apache.xpath.objects.XObject;
|
||||
|
||||
|
||||
public class XalanXPathEvaluator implements XPathExpression.XPathEvaluator {
|
||||
|
||||
|
@ -63,10 +66,15 @@ public class XalanXPathEvaluator implements XPathExpression.XPathEvaluator {
|
|||
factory.setNamespaceAware(true);
|
||||
DocumentBuilder dbuilder = factory.newDocumentBuilder();
|
||||
Document doc = dbuilder.parse(inputSource);
|
||||
|
||||
|
||||
CachedXPathAPI cachedXPathAPI = new CachedXPathAPI();
|
||||
NodeIterator iterator = cachedXPathAPI.selectNodeIterator(doc, xpath);
|
||||
return iterator.nextNode() != null;
|
||||
XObject result = cachedXPathAPI.eval(doc, xpath);
|
||||
if (result.bool())
|
||||
return true;
|
||||
else {
|
||||
NodeIterator iterator = cachedXPathAPI.selectNodeIterator(doc, xpath);
|
||||
return (iterator.nextNode() != null);
|
||||
}
|
||||
|
||||
} catch (Throwable e) {
|
||||
return false;
|
||||
|
@ -82,12 +90,20 @@ public class XalanXPathEvaluator implements XPathExpression.XPathEvaluator {
|
|||
DocumentBuilder dbuilder = factory.newDocumentBuilder();
|
||||
Document doc = dbuilder.parse(inputSource);
|
||||
|
||||
// We should associated the cachedXPathAPI object with the message
|
||||
// being evaluated
|
||||
// since that should speedup subsequent xpath expressions.
|
||||
//An XPath expression could return a true or false value instead of a node.
|
||||
//eval() is a better way to determine the boolean value of the exp.
|
||||
//For compliance with legacy behavior where selecting an empty node returns true,
|
||||
//selectNodeIterator is attempted in case of a failure.
|
||||
|
||||
CachedXPathAPI cachedXPathAPI = new CachedXPathAPI();
|
||||
NodeIterator iterator = cachedXPathAPI.selectNodeIterator(doc, xpath);
|
||||
return iterator.nextNode() != null;
|
||||
XObject result = cachedXPathAPI.eval(doc, xpath);
|
||||
if (result.bool())
|
||||
return true;
|
||||
else {
|
||||
NodeIterator iterator = cachedXPathAPI.selectNodeIterator(doc, xpath);
|
||||
return (iterator.nextNode() != null);
|
||||
}
|
||||
|
||||
} catch (Throwable e) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -44,17 +44,42 @@ public class SelectorTest extends TestCase {
|
|||
ActiveMQTextMessage message = new ActiveMQTextMessage();
|
||||
|
||||
message.setJMSType("xml");
|
||||
message.setText("<root><a key='first'/><b key='second'/></root>");
|
||||
message.setText("<root><a key='first' num='1'/><b key='second' num='2'>b</b></root>");
|
||||
|
||||
assertSelector(message, "XPATH 'root/a'", true);
|
||||
assertSelector(message, "XPATH '//root/b'", true);
|
||||
assertSelector(message, "XPATH 'root/c'", false);
|
||||
|
||||
assertSelector(message, "XPATH '//root/b/text()=\"b\"'", true);
|
||||
assertSelector(message, "XPATH '//root/b=\"b\"'", true);
|
||||
assertSelector(message, "XPATH '//root/b=\"c\"'", false);
|
||||
assertSelector(message, "XPATH '//root/b!=\"c\"'", true);
|
||||
|
||||
assertSelector(message, "XPATH '//root/*[@key=''second'']'", true);
|
||||
assertSelector(message, "XPATH '//root/*[@key=''third'']'", false);
|
||||
|
||||
assertSelector(message, "XPATH '//root/a[@key=''first'']'", true);
|
||||
assertSelector(message, "XPATH '//root/a[@num=1]'", true);
|
||||
assertSelector(message, "XPATH '//root/a[@key=''second'']'", false);
|
||||
|
||||
assertSelector(message, "XPATH '/root/*[@key=''first'' or @key=''third'']'", true);
|
||||
assertSelector(message, "XPATH '//root/*[@key=''third'' or @key=''forth'']'", false);
|
||||
|
||||
assertSelector(message, "XPATH '/root/b=''b'' and /root/b[@key=''second'']'", true);
|
||||
assertSelector(message, "XPATH '/root/b=''b'' and /root/b[@key=''first'']'", false);
|
||||
|
||||
assertSelector(message, "XPATH 'not(//root/a)'", false);
|
||||
assertSelector(message, "XPATH 'not(//root/c)'", true);
|
||||
assertSelector(message, "XPATH '//root/a[not(@key=''first'')]'", false);
|
||||
assertSelector(message, "XPATH '//root/a[not(not(@key=''first''))]'", true);
|
||||
|
||||
assertSelector(message, "XPATH 'string(//root/b)'", true);
|
||||
assertSelector(message, "XPATH 'string(//root/a)'", false);
|
||||
|
||||
assertSelector(message, "XPATH 'sum(//@num) < 10'", true);
|
||||
assertSelector(message, "XPATH 'sum(//@num) > 10'", false);
|
||||
|
||||
assertSelector(message, "XPATH '//root/a[@num > 1]'", false);
|
||||
assertSelector(message, "XPATH '//root/b[@num > 1]'", true);
|
||||
|
||||
}
|
||||
|
||||
public void testJMSPropertySelectors() throws Exception {
|
||||
|
|
Loading…
Reference in New Issue