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    }