Source code: org/activemq/filter/XPathExpression.java
1 /**
2 * Copyright 2005 Hiram Chirino
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 **/
17 package org.activemq.filter;
18
19 import java.lang.reflect.Constructor;
20 import java.lang.reflect.InvocationTargetException;
21
22 import javax.jms.JMSException;
23 import javax.jms.Message;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 /**
29 * Used to evaluate an XPath Expression in a JMS selector.
30 */
31 public final class XPathExpression implements BooleanExpression {
32
33 private static final Log log = LogFactory.getLog(XPathExpression.class);
34 private static final String EVALUATOR_SYSTEM_PROPERTY = "org.activemq.XPathEvaluatorClassName";
35 private static final String DEFAULT_EVALUATOR_CLASS_NAME=XalanXPathEvaluator.class.getName();
36
37 private static final Constructor EVALUATOR_CONSTRUCTOR;
38
39 static {
40 String cn = System.getProperty(EVALUATOR_SYSTEM_PROPERTY, DEFAULT_EVALUATOR_CLASS_NAME);
41 Constructor m = null;
42 try {
43 try {
44 m = getXPathEvaluatorConstructor(cn);
45 } catch (Throwable e) {
46 log.warn("Invalid "+XPathEvaluator.class.getName()+" implementation: "+cn+", reason: "+e,e);
47 cn = DEFAULT_EVALUATOR_CLASS_NAME;
48 try {
49 m = getXPathEvaluatorConstructor(cn);
50 } catch (Throwable e2) {
51 log.error("Default XPath evaluator could not be loaded",e);
52 }
53 }
54 } finally {
55 EVALUATOR_CONSTRUCTOR = m;
56 }
57 }
58
59 private static Constructor getXPathEvaluatorConstructor(String cn) throws ClassNotFoundException, SecurityException, NoSuchMethodException {
60 Class c = XPathExpression.class.getClassLoader().loadClass(cn);
61 if( !XPathEvaluator.class.isAssignableFrom(c) ) {
62 throw new ClassCastException(""+c+" is not an instance of "+XPathEvaluator.class);
63 }
64 return c.getConstructor(new Class[]{String.class});
65 }
66
67 private final String xpath;
68 private final XPathEvaluator evaluator;
69
70 static public interface XPathEvaluator {
71 public boolean evaluate(Message message) throws JMSException;
72 }
73
74 XPathExpression(String xpath) {
75 this.xpath = xpath;
76 this.evaluator = createEvaluator(xpath);
77 }
78
79 private XPathEvaluator createEvaluator(String xpath2) {
80 try {
81 return (XPathEvaluator)EVALUATOR_CONSTRUCTOR.newInstance(new Object[]{xpath});
82 } catch (InvocationTargetException e) {
83 Throwable cause = e.getCause();
84 if( cause instanceof RuntimeException ) {
85 throw (RuntimeException)cause;
86 }
87 throw new RuntimeException("Invalid XPath Expression: "+xpath+" reason: "+e.getMessage(), e);
88 } catch (Throwable e) {
89 throw new RuntimeException("Invalid XPath Expression: "+xpath+" reason: "+e.getMessage(), e);
90 }
91 }
92
93 public Object evaluate(Message message) throws JMSException {
94 return evaluator.evaluate(message) ? Boolean.TRUE : Boolean.FALSE;
95 }
96
97 public String toString() {
98 return "XPATH "+ConstantExpression.encodeString(xpath);
99 }
100 }