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.camel.builder.xml;
018    
019    import java.util.HashMap;
020    import java.util.Map;
021    
022    import javax.xml.namespace.QName;
023    import javax.xml.xpath.XPathVariableResolver;
024    
025    import org.apache.camel.Exchange;
026    import org.apache.camel.Message;
027    import org.apache.commons.logging.Log;
028    import org.apache.commons.logging.LogFactory;
029    
030    import static org.apache.camel.builder.xml.Namespaces.ENVIRONMENT_VARIABLES;
031    import static org.apache.camel.builder.xml.Namespaces.EXCHANGE_PROPERTY;
032    import static org.apache.camel.builder.xml.Namespaces.IN_NAMESPACE;
033    import static org.apache.camel.builder.xml.Namespaces.OUT_NAMESPACE;
034    import static org.apache.camel.builder.xml.Namespaces.SYSTEM_PROPERTIES_NAMESPACE;
035    
036    /**
037     * A variable resolver for XPath expressions which support properties on the
038     * messge, exchange as well as making system properties and environment
039     * properties available.
040     * 
041     * @version $Revision: 35332 $
042     */
043    public class MessageVariableResolver implements XPathVariableResolver {
044    
045        private static final transient Log LOG = LogFactory.getLog(MessageVariableResolver.class);
046    
047        private Exchange exchange;
048        private Map<String, Object> variables = new HashMap<String, Object>();
049    
050        public Exchange getExchange() {
051            return exchange;
052        }
053    
054        public void setExchange(Exchange exchange) {
055            this.exchange = exchange;
056        }
057    
058        public Object resolveVariable(QName name) {
059            String uri = name.getNamespaceURI();
060            String localPart = name.getLocalPart();
061            Object answer = null;
062    
063            Message in = exchange.getIn();
064            if (uri == null || uri.length() == 0) {
065                answer = variables.get(localPart);
066                if (answer == null) {
067                    Message message = in;
068                    if (message != null) {
069                        answer = message.getHeader(localPart);
070                    }
071                    if (answer == null) {
072                        answer = exchange.getProperty(localPart);
073                    }
074                }
075            } else if (uri.equals(SYSTEM_PROPERTIES_NAMESPACE)) {
076                try {
077                    answer = System.getProperty(localPart);
078                } catch (Exception e) {
079                    LOG
080                        .debug("Security exception evaluating system property: " + localPart + ". Reason: " + e,
081                               e);
082                }
083            } else if (uri.equals(ENVIRONMENT_VARIABLES)) {
084                answer = System.getenv().get(localPart);
085            } else if (uri.equals(EXCHANGE_PROPERTY)) {
086                answer = exchange.getProperty(localPart);
087            } else if (uri.equals(IN_NAMESPACE)) {
088                answer = in.getHeader(localPart);
089                if (answer == null && localPart.equals("body")) {
090                    answer = in.getBody();
091                }
092            } else if (uri.equals(OUT_NAMESPACE)) {
093                Message out = exchange.getOut(false);
094                if (out != null) {
095                    answer = out.getHeader(localPart);
096                    if (answer == null && localPart.equals("body")) {
097                        answer = out.getBody();
098                    }
099                }
100            }
101    
102            // TODO support exposing CamelContext properties/resources via XPath?
103            return answer;
104        }
105    
106        public void addVariable(String localPart, Object value) {
107            variables.put(localPart, value);
108        }
109    }