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 * message, exchange as well as making system properties and environment
039 * properties available.
040 * <p/>
041 * Implementations of this resolver must be thread safe
042 *
043 * @version $Revision: 824627 $
044 */
045 public class MessageVariableResolver implements XPathVariableResolver {
046 private static final transient Log LOG = LogFactory.getLog(MessageVariableResolver.class);
047
048 private Map<String, Object> variables = new HashMap<String, Object>();
049 private final ThreadLocal<Exchange> exchange;
050
051 public MessageVariableResolver(ThreadLocal<Exchange> exchange) {
052 this.exchange = exchange;
053 }
054
055 public Object resolveVariable(QName name) {
056 String uri = name.getNamespaceURI();
057 String localPart = name.getLocalPart();
058 Object answer = null;
059
060 Message in = exchange.get().getIn();
061 if (uri == null || uri.length() == 0) {
062 answer = variables.get(localPart);
063 if (answer == null) {
064 Message message = in;
065 if (message != null) {
066 answer = message.getHeader(localPart);
067 }
068 if (answer == null) {
069 answer = exchange.get().getProperty(localPart);
070 }
071 }
072 } else if (uri.equals(SYSTEM_PROPERTIES_NAMESPACE)) {
073 try {
074 answer = System.getProperty(localPart);
075 } catch (Exception e) {
076 LOG.debug("Security exception evaluating system property: " + localPart + ". Reason: " + e, e);
077 }
078 } else if (uri.equals(ENVIRONMENT_VARIABLES)) {
079 answer = System.getenv().get(localPart);
080 } else if (uri.equals(EXCHANGE_PROPERTY)) {
081 answer = exchange.get().getProperty(localPart);
082 } else if (uri.equals(IN_NAMESPACE)) {
083 answer = in.getHeader(localPart);
084 if (answer == null && localPart.equals("body")) {
085 answer = in.getBody();
086 }
087 } else if (uri.equals(OUT_NAMESPACE)) {
088 if (exchange.get().hasOut()) {
089 Message out = exchange.get().getOut();
090 answer = out.getHeader(localPart);
091 if (answer == null && localPart.equals("body")) {
092 answer = out.getBody();
093 }
094 }
095 }
096
097 // If we can't find an answer we must return void.
098 // We can't return null then the xpath engine will throw a NullPointerException
099 if (answer == null) {
100 return Void.class;
101 } else {
102 return answer;
103 }
104 }
105
106 public void addVariable(String localPart, Object value) {
107 variables.put(localPart, value);
108 }
109 }