001 /**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements. See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 package org.apache.camel.builder.xpath;
019
020 import org.apache.camel.Exchange;
021 import org.apache.camel.Expression;
022 import org.apache.camel.Message;
023 import org.apache.camel.Predicate;
024 import org.apache.camel.util.ObjectHelper;
025 import org.xml.sax.InputSource;
026
027 import javax.xml.namespace.QName;
028 import javax.xml.xpath.XPathConstants;
029 import javax.xml.xpath.XPathExpression;
030 import javax.xml.xpath.XPathExpressionException;
031 import java.io.StringReader;
032
033 /**
034 * An {@link Expression} which uses XPath to perform the evaluation
035 *
036 * @version $Revision: 521180 $
037 */
038 public class ExchangeXPathExpression<E extends Exchange> implements Expression<E>, Predicate<E> {
039 private final XPathExpression expression;
040 private final MessageVariableResolver variableResolver;
041 private Class documentType;
042 private String text;
043 private QName resultType;
044
045 public ExchangeXPathExpression(XPathBuilder builder, XPathExpression expression, MessageVariableResolver variableResolver) {
046 this.expression = expression;
047 this.variableResolver = variableResolver;
048 this.documentType = builder.getDocumentType();
049 this.text = builder.getText();
050 this.resultType = builder.getResultType();
051 }
052
053 public boolean matches(E exchange) {
054 return ObjectHelper.toBoolean(evaluateAs(exchange, XPathConstants.BOOLEAN));
055 }
056
057 public Object evaluate(E exchange) {
058 return evaluateAs(exchange, resultType);
059 }
060
061 public Class getDocumentType() {
062 return documentType;
063 }
064
065 public String getText() {
066 return text;
067 }
068
069 public MessageVariableResolver getVariableResolver() {
070 return variableResolver;
071 }
072
073 /**
074 * Evaluates the expression as the given result type
075 */
076 protected synchronized Object evaluateAs(E exchange, QName resultType) {
077 variableResolver.setExchange(exchange);
078 try {
079 Object document = getDocument(exchange);
080 if (resultType != null) {
081 if (document instanceof InputSource) {
082 InputSource inputSource = (InputSource) document;
083 return expression.evaluate(inputSource, resultType);
084 }
085 else {
086 return expression.evaluate(document, resultType);
087 }
088 }
089 else {
090 if (document instanceof InputSource) {
091 InputSource inputSource = (InputSource) document;
092 return expression.evaluate(inputSource);
093 }
094 else {
095 return expression.evaluate(document);
096 }
097 }
098 }
099 catch (XPathExpressionException e) {
100 throw new InvalidXPathExpression(getText(), e);
101 }
102 }
103
104 /**
105 * Strategy method to extract the document from the exchange
106 */
107 protected Object getDocument(E exchange) {
108 Message in = exchange.getIn();
109 Class type = getDocumentType();
110 Object answer = null;
111 if (type != null) {
112 answer = in.getBody(type);
113 }
114 if (answer == null) {
115 answer = in.getBody();
116 }
117
118 // lets try coerce some common types into something JAXP can deal with
119 if (answer instanceof String) {
120 answer = new InputSource(new StringReader(answer.toString()));
121 }
122 return answer;
123 }
124 }
125