001 package org.activemq.filter;
002
003 import java.io.ByteArrayInputStream;
004 import java.io.StringReader;
005
006 import javax.jms.BytesMessage;
007 import javax.jms.JMSException;
008 import javax.jms.Message;
009 import javax.jms.TextMessage;
010 import javax.xml.parsers.DocumentBuilder;
011 import javax.xml.parsers.DocumentBuilderFactory;
012
013 import org.apache.xpath.CachedXPathAPI;
014 import org.w3c.dom.Document;
015 import org.w3c.dom.traversal.NodeIterator;
016 import org.xml.sax.InputSource;
017
018 public class XalanXPathEvaluator implements XPathExpression.XPathEvaluator {
019
020 private final String xpath;
021
022 public XalanXPathEvaluator(String xpath) {
023 this.xpath = xpath;
024 }
025
026 public boolean evaluate(Message message) throws JMSException {
027 if( message instanceof TextMessage ) {
028 String text = ((TextMessage)message).getText();
029 return evaluate(text);
030 } else if ( message instanceof BytesMessage ) {
031 BytesMessage bm = (BytesMessage) message;
032 byte data[] = new byte[(int) bm.getBodyLength()];
033 bm.readBytes(data);
034 return evaluate(data);
035 }
036 return false;
037 }
038
039 private boolean evaluate(byte[] data) {
040 try {
041
042 InputSource inputSource = new InputSource(new ByteArrayInputStream(data));
043
044 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
045 factory.setNamespaceAware(true);
046 DocumentBuilder dbuilder = factory.newDocumentBuilder();
047 Document doc = dbuilder.parse(inputSource);
048
049 CachedXPathAPI cachedXPathAPI = new CachedXPathAPI();
050 NodeIterator iterator = cachedXPathAPI.selectNodeIterator(doc,xpath);
051 return iterator.nextNode()!=null;
052
053 } catch (Throwable e) {
054 return false;
055 }
056 }
057
058 private boolean evaluate(String text) {
059 try {
060 InputSource inputSource = new InputSource(new StringReader(text));
061
062 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
063 factory.setNamespaceAware(true);
064 DocumentBuilder dbuilder = factory.newDocumentBuilder();
065 Document doc = dbuilder.parse(inputSource);
066
067 // We should associated the cachedXPathAPI object with the message being evaluated
068 // since that should speedup subsequent xpath expressions.
069 CachedXPathAPI cachedXPathAPI = new CachedXPathAPI();
070 NodeIterator iterator = cachedXPathAPI.selectNodeIterator(doc,xpath);
071 return iterator.nextNode()!=null;
072 } catch (Throwable e) {
073 return false;
074 }
075 }
076 }