001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.drools.model;
018    
019    import javax.jbi.messaging.NormalizedMessage;
020    import javax.xml.namespace.NamespaceContext;
021    import javax.xml.transform.Source;
022    import javax.xml.transform.dom.DOMSource;
023    import javax.xml.xpath.XPath;
024    import javax.xml.xpath.XPathConstants;
025    import javax.xml.xpath.XPathExpressionException;
026    import javax.xml.xpath.XPathFactory;
027    
028    import org.w3c.dom.DOMException;
029    import org.w3c.dom.Element;
030    import org.w3c.dom.Node;
031    
032    import org.apache.servicemix.expression.JAXPBooleanXPathExpression;
033    import org.apache.servicemix.expression.JAXPStringXPathExpression;
034    import org.apache.servicemix.jbi.jaxp.SourceTransformer;
035    
036    public class Message {
037    
038        private static final SourceTransformer TRANFORMER = new SourceTransformer();
039        
040        private final NormalizedMessage message;
041        private final NamespaceContext namespaceContext;
042        
043        public Message(NormalizedMessage message, NamespaceContext namespaceContext) {
044            this.message = message;
045            // Make sure message is re-readable
046            this.namespaceContext = namespaceContext;
047            Source content = message.getContent();
048            if (content != null) {
049                try {
050                    content = new DOMSource(TRANFORMER.toDOMElement(content));
051                    message.setContent(content);
052                } catch (Exception e) {
053                    throw new RuntimeException(e);
054                }
055            }
056            
057        }
058        
059        public NormalizedMessage getInternalMessage() {
060            return this.message;
061        }
062        
063        public boolean xpath(String xpath) throws Exception {
064            JAXPBooleanXPathExpression expression = new JAXPBooleanXPathExpression(xpath);
065            if (this.namespaceContext != null) {
066                expression.setNamespaceContext(this.namespaceContext);
067            }
068            Boolean b = (Boolean) expression.evaluate(null, message);
069            return b.booleanValue();
070        }
071        
072        public String valueOf(String xpath) throws Exception {
073            JAXPStringXPathExpression expression = new JAXPStringXPathExpression(xpath);
074            if (this.namespaceContext != null) {
075                expression.setNamespaceContext(this.namespaceContext);
076            }
077            return (String)expression.evaluate(null, message);
078        }
079        
080        
081        public Object getProperty(String name) {
082            return message.getProperty(name);
083        }
084        
085        public void setProperty(String name, Object value) {
086            message.setProperty(name, value);
087        }
088        
089        public Element getContent() {
090            return (Element) ((DOMSource) message.getContent()).getNode();
091        }
092            
093        public Object getXPath(String path) throws XPathExpressionException {
094            Element msgXML = getContent();
095            if(msgXML!=null) {
096                XPath xpath = XPathFactory.newInstance().newXPath();
097                Node value = (Node) xpath.evaluate(path, getContent(), XPathConstants.NODE);
098                if(value == null || value.getNodeType() != Node.ATTRIBUTE_NODE) {
099                    throw new DOMException(DOMException.NOT_FOUND_ERR, "Attribute not found in message with XPath: " + path);
100                }
101                return value.getNodeValue();
102            } else {
103                return null;
104            }
105        }
106        
107        public void setXPath(String path, Object value) throws XPathExpressionException {
108            Element msgXML = getContent();
109            if(msgXML!=null) {
110                XPath xpath = XPathFactory.newInstance().newXPath();
111                Node node = (Node) xpath.evaluate(path, getContent(), XPathConstants.NODE);
112                if (node == null || node.getNodeType() != Node.ATTRIBUTE_NODE) {
113                    throw new DOMException(DOMException.NOT_FOUND_ERR, "Attribute not found in message with xpath: "+ path);
114                } else {
115                    node.setNodeValue(value.toString());
116                }
117            }        
118        }
119        
120    }