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:
Bosanac Dejan 2009-03-25 09:12:52 +00:00
parent 86ec0553c5
commit 42d91a3b79
2 changed files with 52 additions and 11 deletions

View File

@ -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;
}

View File

@ -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 {