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