You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ch...@apache.org on 2009/06/01 06:05:38 UTC
svn commit: r780558 [2/3] - in /activemq/sandbox/activemq-flow: ./
activemq-all/ activemq-all/.settings/ activemq-all/eclipse-classes/
activemq-all/target/ activemq-broker/
activemq-broker/src/main/java/org/apache/activemq/broker/
activemq-broker/src/m...
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/grammar/SelectorParser.jj
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/grammar/SelectorParser.jj?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/grammar/SelectorParser.jj (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/grammar/SelectorParser.jj Mon Jun 1 04:05:34 2009
@@ -0,0 +1,609 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ----------------------------------------------------------------------------
+// OPTIONS
+// ----------------------------------------------------------------------------
+options {
+ STATIC = false;
+ UNICODE_INPUT = true;
+
+ // some performance optimizations
+ OPTIMIZE_TOKEN_MANAGER = true;
+ ERROR_REPORTING = false;
+}
+
+// ----------------------------------------------------------------------------
+// PARSER
+// ----------------------------------------------------------------------------
+
+PARSER_BEGIN(SelectorParser)
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.activemq.selector;
+
+import java.io.*;
+import java.util.*;
+
+import org.apache.activemq.filter.*;
+import org.apache.activemq.util.LRUCache;
+
+/**
+ * JMS Selector Parser generated by JavaCC
+ *
+ * Do not edit this .java file directly - it is autogenerated from SelectorParser.jj
+ */
+public class SelectorParser {
+
+ private static final LRUCache cache = new LRUCache(100);
+
+ public static BooleanExpression parse(String sql) throws FilterException {
+ Object result = cache.get(sql);
+ if (result instanceof FilterException) {
+ throw (FilterException) result;
+ } else if (result instanceof BooleanExpression) {
+ return (BooleanExpression) result;
+ } else {
+ try {
+ BooleanExpression e = new SelectorParser(sql).parse();
+ cache.put(sql, e);
+ return e;
+ } catch (FilterException t) {
+ cache.put(sql, t);
+ throw t;
+ }
+ }
+ }
+
+ public static void clearCache() {
+ cache.clear();
+ }
+
+ private String sql;
+
+ protected SelectorParser(String sql) {
+ this(new StringReader(sql));
+ this.sql = sql;
+ }
+
+ protected BooleanExpression parse() throws FilterException {
+ try {
+ return this.JmsSelector();
+ }
+ catch (Throwable e) {
+ throw new FilterException(sql, e);
+ }
+ }
+
+ private BooleanExpression asBooleanExpression(Expression value) throws ParseException {
+ if (value instanceof BooleanExpression) {
+ return (BooleanExpression) value;
+ }
+ if (value instanceof PropertyExpression) {
+ return UnaryExpression.createBooleanCast( value );
+ }
+ throw new ParseException("Expression will not result in a boolean value: " + value);
+ }
+
+
+}
+
+PARSER_END(SelectorParser)
+
+// ----------------------------------------------------------------------------
+// Tokens
+// ----------------------------------------------------------------------------
+
+/* White Space */
+SPECIAL_TOKEN :
+{
+ " " | "\t" | "\n" | "\r" | "\f"
+}
+
+/* Comments */
+SKIP:
+{
+ <LINE_COMMENT: "--" (~["\n","\r"])* ("\n"|"\r"|"\r\n") >
+}
+
+SKIP:
+{
+ <BLOCK_COMMENT: "/*" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* "*"))* "/">
+}
+
+/* Reserved Words */
+TOKEN [IGNORE_CASE] :
+{
+ < NOT : "NOT">
+ | < AND : "AND">
+ | < OR : "OR">
+ | < BETWEEN : "BETWEEN">
+ | < LIKE : "LIKE">
+ | < ESCAPE : "ESCAPE">
+ | < IN : "IN">
+ | < IS : "IS">
+ | < TRUE : "TRUE" >
+ | < FALSE : "FALSE" >
+ | < NULL : "NULL" >
+ | < XPATH : "XPATH" >
+ | < XQUERY : "XQUERY" >
+}
+
+/* Literals */
+TOKEN [IGNORE_CASE] :
+{
+
+ < DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* (["l","L"])? >
+ | < HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
+ | < OCTAL_LITERAL: "0" (["0"-"7"])* >
+ | < FLOATING_POINT_LITERAL:
+ (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? // matches: 5.5 or 5. or 5.5E10 or 5.E10
+ | "." (["0"-"9"])+ (<EXPONENT>)? // matches: .5 or .5E10
+ | (["0"-"9"])+ <EXPONENT> // matches: 5E10
+ >
+ | < #EXPONENT: "E" (["+","-"])? (["0"-"9"])+ >
+ | < STRING_LITERAL: "'" ( ("''") | ~["'"] )* "'" >
+}
+
+TOKEN [IGNORE_CASE] :
+{
+ < ID : ["a"-"z", "_", "$"] (["a"-"z","0"-"9","_", "$"])* >
+}
+
+// ----------------------------------------------------------------------------
+// Grammer
+// ----------------------------------------------------------------------------
+BooleanExpression JmsSelector() :
+{
+ Expression left=null;
+}
+{
+ (
+ left = orExpression()
+ )
+ {
+ return asBooleanExpression(left);
+ }
+
+}
+
+Expression orExpression() :
+{
+ Expression left;
+ Expression right;
+}
+{
+ (
+ left = andExpression()
+ (
+ <OR> right = andExpression()
+ {
+ left = LogicExpression.createOR(asBooleanExpression(left), asBooleanExpression(right));
+ }
+ )*
+ )
+ {
+ return left;
+ }
+
+}
+
+
+Expression andExpression() :
+{
+ Expression left;
+ Expression right;
+}
+{
+ (
+ left = equalityExpression()
+ (
+ <AND> right = equalityExpression()
+ {
+ left = LogicExpression.createAND(asBooleanExpression(left), asBooleanExpression(right));
+ }
+ )*
+ )
+ {
+ return left;
+ }
+}
+
+Expression equalityExpression() :
+{
+ Expression left;
+ Expression right;
+}
+{
+ (
+ left = comparisonExpression()
+ (
+
+ "=" right = comparisonExpression()
+ {
+ left = ComparisonExpression.createEqual(left, right);
+ }
+ |
+ "<>" right = comparisonExpression()
+ {
+ left = ComparisonExpression.createNotEqual(left, right);
+ }
+ |
+ LOOKAHEAD(2)
+ <IS> <NULL>
+ {
+ left = ComparisonExpression.createIsNull(left);
+ }
+ |
+ <IS> <NOT> <NULL>
+ {
+ left = ComparisonExpression.createIsNotNull(left);
+ }
+ )*
+ )
+ {
+ return left;
+ }
+}
+
+Expression comparisonExpression() :
+{
+ Expression left;
+ Expression right;
+ Expression low;
+ Expression high;
+ String t, u;
+ boolean not;
+ ArrayList list;
+}
+{
+ (
+ left = addExpression()
+ (
+
+ ">" right = addExpression()
+ {
+ left = ComparisonExpression.createGreaterThan(left, right);
+ }
+ |
+ ">=" right = addExpression()
+ {
+ left = ComparisonExpression.createGreaterThanEqual(left, right);
+ }
+ |
+ "<" right = addExpression()
+ {
+ left = ComparisonExpression.createLessThan(left, right);
+ }
+ |
+ "<=" right = addExpression()
+ {
+ left = ComparisonExpression.createLessThanEqual(left, right);
+ }
+ |
+ {
+ u=null;
+ }
+ <LIKE> t = stringLitteral()
+ [ <ESCAPE> u = stringLitteral() ]
+ {
+ left = ComparisonExpression.createLike(left, t, u);
+ }
+ |
+ LOOKAHEAD(2)
+ {
+ u=null;
+ }
+ <NOT> <LIKE> t = stringLitteral() [ <ESCAPE> u = stringLitteral() ]
+ {
+ left = ComparisonExpression.createNotLike(left, t, u);
+ }
+ |
+ <BETWEEN> low = addExpression() <AND> high = addExpression()
+ {
+ left = ComparisonExpression.createBetween(left, low, high);
+ }
+ |
+ LOOKAHEAD(2)
+ <NOT> <BETWEEN> low = addExpression() <AND> high = addExpression()
+ {
+ left = ComparisonExpression.createNotBetween(left, low, high);
+ }
+ |
+ <IN>
+ "("
+ t = stringLitteral()
+ {
+ list = new ArrayList();
+ list.add( t );
+ }
+ (
+ ","
+ t = stringLitteral()
+ {
+ list.add( t );
+ }
+
+ )*
+ ")"
+ {
+ left = ComparisonExpression.createInFilter(left, list);
+ }
+ |
+ LOOKAHEAD(2)
+ <NOT> <IN>
+ "("
+ t = stringLitteral()
+ {
+ list = new ArrayList();
+ list.add( t );
+ }
+ (
+ ","
+ t = stringLitteral()
+ {
+ list.add( t );
+ }
+
+ )*
+ ")"
+ {
+ left = ComparisonExpression.createNotInFilter(left, list);
+ }
+
+ )*
+ )
+ {
+ return left;
+ }
+}
+
+Expression addExpression() :
+{
+ Expression left;
+ Expression right;
+}
+{
+ left = multExpr()
+ (
+ LOOKAHEAD( ("+"|"-") multExpr())
+ (
+ "+" right = multExpr()
+ {
+ left = ArithmeticExpression.createPlus(left, right);
+ }
+ |
+ "-" right = multExpr()
+ {
+ left = ArithmeticExpression.createMinus(left, right);
+ }
+ )
+
+ )*
+ {
+ return left;
+ }
+}
+
+Expression multExpr() :
+{
+ Expression left;
+ Expression right;
+}
+{
+ left = unaryExpr()
+ (
+ "*" right = unaryExpr()
+ {
+ left = ArithmeticExpression.createMultiply(left, right);
+ }
+ |
+ "/" right = unaryExpr()
+ {
+ left = ArithmeticExpression.createDivide(left, right);
+ }
+ |
+ "%" right = unaryExpr()
+ {
+ left = ArithmeticExpression.createMod(left, right);
+ }
+
+ )*
+ {
+ return left;
+ }
+}
+
+
+Expression unaryExpr() :
+{
+ String s=null;
+ Expression left=null;
+}
+{
+ (
+ LOOKAHEAD( "+" unaryExpr() )
+ "+" left=unaryExpr()
+ |
+ "-" left=unaryExpr()
+ {
+ left = UnaryExpression.createNegate(left);
+ }
+ |
+ <NOT> left=unaryExpr()
+ {
+ left = UnaryExpression.createNOT( asBooleanExpression(left) );
+ }
+ |
+ <XPATH> s=stringLitteral()
+ {
+ left = UnaryExpression.createXPath( s );
+ }
+ |
+ <XQUERY> s=stringLitteral()
+ {
+ left = UnaryExpression.createXQuery( s );
+ }
+ |
+ left = primaryExpr()
+ )
+ {
+ return left;
+ }
+
+}
+
+Expression primaryExpr() :
+{
+ Expression left=null;
+}
+{
+ (
+ left = literal()
+ |
+ left = variable()
+ |
+ "(" left = orExpression() ")"
+ )
+ {
+ return left;
+ }
+}
+
+
+
+ConstantExpression literal() :
+{
+ Token t;
+ String s;
+ ConstantExpression left=null;
+}
+{
+ (
+ (
+ s = stringLitteral()
+ {
+ left = new ConstantExpression(s);
+ }
+ )
+ |
+ (
+ t = <DECIMAL_LITERAL>
+ {
+ left = ConstantExpression.createFromDecimal(t.image);
+ }
+ )
+ |
+ (
+ t = <HEX_LITERAL>
+ {
+ left = ConstantExpression.createFromHex(t.image);
+ }
+ )
+ |
+ (
+ t = <OCTAL_LITERAL>
+ {
+ left = ConstantExpression.createFromOctal(t.image);
+ }
+ )
+ |
+ (
+ t = <FLOATING_POINT_LITERAL>
+ {
+ left = ConstantExpression.createFloat(t.image);
+ }
+ )
+ |
+ (
+ <TRUE>
+ {
+ left = ConstantExpression.TRUE;
+ }
+ )
+ |
+ (
+ <FALSE>
+ {
+ left = ConstantExpression.FALSE;
+ }
+ )
+ |
+ (
+ <NULL>
+ {
+ left = ConstantExpression.NULL;
+ }
+ )
+ )
+ {
+ return left;
+ }
+}
+
+String stringLitteral() :
+{
+ Token t;
+ StringBuffer rc = new StringBuffer();
+ boolean first=true;
+}
+{
+ t = <STRING_LITERAL>
+ {
+ // Decode the sting value.
+ String image = t.image;
+ for( int i=1; i < image.length()-1; i++ ) {
+ char c = image.charAt(i);
+ if( c == '\'' )
+ i++;
+ rc.append(c);
+ }
+ return rc.toString();
+ }
+}
+
+PropertyExpression variable() :
+{
+ Token t;
+ PropertyExpression left=null;
+}
+{
+ (
+ t = <ID>
+ {
+ left = new PropertyExpression(t.image);
+ }
+ )
+ {
+ return left;
+ }
+}
Propchange: activemq/sandbox/activemq-flow/activemq-selector/src/main/grammar/SelectorParser.jj
------------------------------------------------------------------------------
svn:executable = *
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ArithmeticExpression.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ArithmeticExpression.java?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ArithmeticExpression.java (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ArithmeticExpression.java Mon Jun 1 04:05:34 2009
@@ -0,0 +1,203 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.filter;
+
+
+/**
+ * An expression which performs an operation on two expression values
+ *
+ * @version $Revision: 1.2 $
+ */
+public abstract class ArithmeticExpression extends BinaryExpression {
+
+ protected static final int INTEGER = 1;
+ protected static final int LONG = 2;
+ protected static final int DOUBLE = 3;
+
+ /**
+ * @param left
+ * @param right
+ */
+ public ArithmeticExpression(Expression left, Expression right) {
+ super(left, right);
+ }
+
+ public static Expression createPlus(Expression left, Expression right) {
+ return new ArithmeticExpression(left, right) {
+ protected Object evaluate(Object lvalue, Object rvalue) {
+ if (lvalue instanceof String) {
+ String text = (String)lvalue;
+ String answer = text + rvalue;
+ return answer;
+ } else if (lvalue instanceof Number) {
+ return plus((Number)lvalue, asNumber(rvalue));
+ }
+ throw new RuntimeException("Cannot call plus operation on: " + lvalue + " and: " + rvalue);
+ }
+
+ public String getExpressionSymbol() {
+ return "+";
+ }
+ };
+ }
+
+ public static Expression createMinus(Expression left, Expression right) {
+ return new ArithmeticExpression(left, right) {
+ protected Object evaluate(Object lvalue, Object rvalue) {
+ if (lvalue instanceof Number) {
+ return minus((Number)lvalue, asNumber(rvalue));
+ }
+ throw new RuntimeException("Cannot call minus operation on: " + lvalue + " and: " + rvalue);
+ }
+
+ public String getExpressionSymbol() {
+ return "-";
+ }
+ };
+ }
+
+ public static Expression createMultiply(Expression left, Expression right) {
+ return new ArithmeticExpression(left, right) {
+
+ protected Object evaluate(Object lvalue, Object rvalue) {
+ if (lvalue instanceof Number) {
+ return multiply((Number)lvalue, asNumber(rvalue));
+ }
+ throw new RuntimeException("Cannot call multiply operation on: " + lvalue + " and: " + rvalue);
+ }
+
+ public String getExpressionSymbol() {
+ return "*";
+ }
+ };
+ }
+
+ public static Expression createDivide(Expression left, Expression right) {
+ return new ArithmeticExpression(left, right) {
+
+ protected Object evaluate(Object lvalue, Object rvalue) {
+ if (lvalue instanceof Number) {
+ return divide((Number)lvalue, asNumber(rvalue));
+ }
+ throw new RuntimeException("Cannot call divide operation on: " + lvalue + " and: " + rvalue);
+ }
+
+ public String getExpressionSymbol() {
+ return "/";
+ }
+ };
+ }
+
+ public static Expression createMod(Expression left, Expression right) {
+ return new ArithmeticExpression(left, right) {
+
+ protected Object evaluate(Object lvalue, Object rvalue) {
+ if (lvalue instanceof Number) {
+ return mod((Number)lvalue, asNumber(rvalue));
+ }
+ throw new RuntimeException("Cannot call mod operation on: " + lvalue + " and: " + rvalue);
+ }
+
+ public String getExpressionSymbol() {
+ return "%";
+ }
+ };
+ }
+
+ protected Number plus(Number left, Number right) {
+ switch (numberType(left, right)) {
+ case INTEGER:
+ return new Integer(left.intValue() + right.intValue());
+ case LONG:
+ return new Long(left.longValue() + right.longValue());
+ default:
+ return new Double(left.doubleValue() + right.doubleValue());
+ }
+ }
+
+ protected Number minus(Number left, Number right) {
+ switch (numberType(left, right)) {
+ case INTEGER:
+ return new Integer(left.intValue() - right.intValue());
+ case LONG:
+ return new Long(left.longValue() - right.longValue());
+ default:
+ return new Double(left.doubleValue() - right.doubleValue());
+ }
+ }
+
+ protected Number multiply(Number left, Number right) {
+ switch (numberType(left, right)) {
+ case INTEGER:
+ return new Integer(left.intValue() * right.intValue());
+ case LONG:
+ return new Long(left.longValue() * right.longValue());
+ default:
+ return new Double(left.doubleValue() * right.doubleValue());
+ }
+ }
+
+ protected Number divide(Number left, Number right) {
+ return new Double(left.doubleValue() / right.doubleValue());
+ }
+
+ protected Number mod(Number left, Number right) {
+ return new Double(left.doubleValue() % right.doubleValue());
+ }
+
+ private int numberType(Number left, Number right) {
+ if (isDouble(left) || isDouble(right)) {
+ return DOUBLE;
+ } else if (left instanceof Long || right instanceof Long) {
+ return LONG;
+ } else {
+ return INTEGER;
+ }
+ }
+
+ private boolean isDouble(Number n) {
+ return n instanceof Float || n instanceof Double;
+ }
+
+ protected Number asNumber(Object value) {
+ if (value instanceof Number) {
+ return (Number)value;
+ } else {
+ throw new RuntimeException("Cannot convert value: " + value + " into a number");
+ }
+ }
+
+ public Object evaluate(MessageEvaluationContext message) throws FilterException {
+ Object lvalue = left.evaluate(message);
+ if (lvalue == null) {
+ return null;
+ }
+ Object rvalue = right.evaluate(message);
+ if (rvalue == null) {
+ return null;
+ }
+ return evaluate(lvalue, rvalue);
+ }
+
+ /**
+ * @param lvalue
+ * @param rvalue
+ * @return
+ */
+ protected abstract Object evaluate(Object lvalue, Object rvalue);
+
+}
Propchange: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ArithmeticExpression.java
------------------------------------------------------------------------------
svn:executable = *
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/BinaryExpression.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/BinaryExpression.java?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/BinaryExpression.java (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/BinaryExpression.java Mon Jun 1 04:05:34 2009
@@ -0,0 +1,96 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.filter;
+
+
+
+/**
+ * An expression which performs an operation on two expression values.
+ *
+ * @version $Revision: 1.2 $
+ */
+public abstract class BinaryExpression implements Expression {
+ protected Expression left;
+ protected Expression right;
+
+ public BinaryExpression(Expression left, Expression right) {
+ this.left = left;
+ this.right = right;
+ }
+
+ public Expression getLeft() {
+ return left;
+ }
+
+ public Expression getRight() {
+ return right;
+ }
+
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return "(" + left.toString() + " " + getExpressionSymbol() + " " + right.toString() + ")";
+ }
+
+ /**
+ * TODO: more efficient hashCode()
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ /**
+ * TODO: more efficient hashCode()
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object o) {
+
+ if (o == null || !this.getClass().equals(o.getClass())) {
+ return false;
+ }
+ return toString().equals(o.toString());
+
+ }
+
+ /**
+ * Returns the symbol that represents this binary expression. For example, addition is
+ * represented by "+"
+ *
+ * @return
+ */
+ public abstract String getExpressionSymbol();
+
+ /**
+ * @param expression
+ */
+ public void setRight(Expression expression) {
+ right = expression;
+ }
+
+ /**
+ * @param expression
+ */
+ public void setLeft(Expression expression) {
+ left = expression;
+ }
+
+}
Propchange: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/BinaryExpression.java
------------------------------------------------------------------------------
svn:executable = *
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/BooleanExpression.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/BooleanExpression.java?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/BooleanExpression.java (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/BooleanExpression.java Mon Jun 1 04:05:34 2009
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.filter;
+
+
+
+/**
+ * A BooleanExpression is an expression that always
+ * produces a Boolean result.
+ *
+ * @version $Revision: 1.2 $
+ */
+public interface BooleanExpression extends Expression {
+
+ /**
+ * @param message
+ * @return true if the expression evaluates to Boolean.TRUE.
+ * @throws FilterException
+ */
+ boolean matches(MessageEvaluationContext message) throws FilterException;
+
+}
Propchange: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/BooleanExpression.java
------------------------------------------------------------------------------
svn:executable = *
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ComparisonExpression.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ComparisonExpression.java?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ComparisonExpression.java (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ComparisonExpression.java Mon Jun 1 04:05:34 2009
@@ -0,0 +1,433 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.filter;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+
+/**
+ * A filter performing a comparison of two objects
+ *
+ * @version $Revision: 1.2 $
+ */
+public abstract class ComparisonExpression extends BinaryExpression implements BooleanExpression {
+
+ private static final Set<Character> REGEXP_CONTROL_CHARS = new HashSet<Character>();
+
+ /**
+ * @param left
+ * @param right
+ */
+ public ComparisonExpression(Expression left, Expression right) {
+ super(left, right);
+ }
+
+ public static BooleanExpression createBetween(Expression value, Expression left, Expression right) {
+ return LogicExpression.createAND(createGreaterThanEqual(value, left), createLessThanEqual(value, right));
+ }
+
+ public static BooleanExpression createNotBetween(Expression value, Expression left, Expression right) {
+ return LogicExpression.createOR(createLessThan(value, left), createGreaterThan(value, right));
+ }
+
+ static {
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('.'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('\\'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('['));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf(']'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('^'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('$'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('?'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('*'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('+'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('{'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('}'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('|'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('('));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf(')'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf(':'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('&'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('<'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('>'));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('='));
+ REGEXP_CONTROL_CHARS.add(Character.valueOf('!'));
+ }
+
+ static class LikeExpression extends UnaryExpression implements BooleanExpression {
+
+ Pattern likePattern;
+
+ /**
+ * @param left
+ */
+ public LikeExpression(Expression right, String like, int escape) {
+ super(right);
+
+ StringBuffer regexp = new StringBuffer(like.length() * 2);
+ regexp.append("\\A"); // The beginning of the input
+ for (int i = 0; i < like.length(); i++) {
+ char c = like.charAt(i);
+ if (escape == (0xFFFF & c)) {
+ i++;
+ if (i >= like.length()) {
+ // nothing left to escape...
+ break;
+ }
+
+ char t = like.charAt(i);
+ regexp.append("\\x");
+ regexp.append(Integer.toHexString(0xFFFF & t));
+ } else if (c == '%') {
+ regexp.append(".*?"); // Do a non-greedy match
+ } else if (c == '_') {
+ regexp.append("."); // match one
+ } else if (REGEXP_CONTROL_CHARS.contains(new Character(c))) {
+ regexp.append("\\x");
+ regexp.append(Integer.toHexString(0xFFFF & c));
+ } else {
+ regexp.append(c);
+ }
+ }
+ regexp.append("\\z"); // The end of the input
+
+ likePattern = Pattern.compile(regexp.toString(), Pattern.DOTALL);
+ }
+
+ /**
+ * @see org.apache.activemq.filter.UnaryExpression#getExpressionSymbol()
+ */
+ public String getExpressionSymbol() {
+ return "LIKE";
+ }
+
+ /**
+ * @see org.apache.activemq.filter.Expression#evaluate(MessageEvaluationContext)
+ */
+ public Object evaluate(MessageEvaluationContext message) throws FilterException {
+
+ Object rv = this.getRight().evaluate(message);
+
+ if (rv == null) {
+ return null;
+ }
+
+ if (!(rv instanceof String)) {
+ return Boolean.FALSE;
+ // throw new RuntimeException("LIKE can only operate on String
+ // identifiers. LIKE attemped on: '" + rv.getClass());
+ }
+
+ return likePattern.matcher((String)rv).matches() ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ public boolean matches(MessageEvaluationContext message) throws FilterException {
+ Object object = evaluate(message);
+ return object != null && object == Boolean.TRUE;
+ }
+ }
+
+ public static BooleanExpression createLike(Expression left, String right, String escape) {
+ if (escape != null && escape.length() != 1) {
+ throw new RuntimeException("The ESCAPE string litteral is invalid. It can only be one character. Litteral used: " + escape);
+ }
+ int c = -1;
+ if (escape != null) {
+ c = 0xFFFF & escape.charAt(0);
+ }
+
+ return new LikeExpression(left, right, c);
+ }
+
+ public static BooleanExpression createNotLike(Expression left, String right, String escape) {
+ return UnaryExpression.createNOT(createLike(left, right, escape));
+ }
+
+ public static BooleanExpression createInFilter(Expression left, List elements) {
+
+ if (!(left instanceof PropertyExpression)) {
+ throw new RuntimeException("Expected a property for In expression, got: " + left);
+ }
+ return UnaryExpression.createInExpression((PropertyExpression)left, elements, false);
+
+ }
+
+ public static BooleanExpression createNotInFilter(Expression left, List elements) {
+
+ if (!(left instanceof PropertyExpression)) {
+ throw new RuntimeException("Expected a property for In expression, got: " + left);
+ }
+ return UnaryExpression.createInExpression((PropertyExpression)left, elements, true);
+
+ }
+
+ public static BooleanExpression createIsNull(Expression left) {
+ return doCreateEqual(left, ConstantExpression.NULL);
+ }
+
+ public static BooleanExpression createIsNotNull(Expression left) {
+ return UnaryExpression.createNOT(doCreateEqual(left, ConstantExpression.NULL));
+ }
+
+ public static BooleanExpression createNotEqual(Expression left, Expression right) {
+ return UnaryExpression.createNOT(createEqual(left, right));
+ }
+
+ public static BooleanExpression createEqual(Expression left, Expression right) {
+ checkEqualOperand(left);
+ checkEqualOperand(right);
+ checkEqualOperandCompatability(left, right);
+ return doCreateEqual(left, right);
+ }
+
+ private static BooleanExpression doCreateEqual(Expression left, Expression right) {
+ return new ComparisonExpression(left, right) {
+
+ public Object evaluate(MessageEvaluationContext message) throws FilterException {
+ Object lv = left.evaluate(message);
+ Object rv = right.evaluate(message);
+
+ // Iff one of the values is null
+ if (lv == null ^ rv == null) {
+ return Boolean.FALSE;
+ }
+ if (lv == rv || lv.equals(rv)) {
+ return Boolean.TRUE;
+ }
+ if (lv instanceof Comparable && rv instanceof Comparable) {
+ return compare((Comparable)lv, (Comparable)rv);
+ }
+ return Boolean.FALSE;
+ }
+
+ protected boolean asBoolean(int answer) {
+ return answer == 0;
+ }
+
+ public String getExpressionSymbol() {
+ return "=";
+ }
+ };
+ }
+
+ public static BooleanExpression createGreaterThan(final Expression left, final Expression right) {
+ checkLessThanOperand(left);
+ checkLessThanOperand(right);
+ return new ComparisonExpression(left, right) {
+ protected boolean asBoolean(int answer) {
+ return answer > 0;
+ }
+
+ public String getExpressionSymbol() {
+ return ">";
+ }
+ };
+ }
+
+ public static BooleanExpression createGreaterThanEqual(final Expression left, final Expression right) {
+ checkLessThanOperand(left);
+ checkLessThanOperand(right);
+ return new ComparisonExpression(left, right) {
+ protected boolean asBoolean(int answer) {
+ return answer >= 0;
+ }
+
+ public String getExpressionSymbol() {
+ return ">=";
+ }
+ };
+ }
+
+ public static BooleanExpression createLessThan(final Expression left, final Expression right) {
+ checkLessThanOperand(left);
+ checkLessThanOperand(right);
+ return new ComparisonExpression(left, right) {
+
+ protected boolean asBoolean(int answer) {
+ return answer < 0;
+ }
+
+ public String getExpressionSymbol() {
+ return "<";
+ }
+
+ };
+ }
+
+ public static BooleanExpression createLessThanEqual(final Expression left, final Expression right) {
+ checkLessThanOperand(left);
+ checkLessThanOperand(right);
+ return new ComparisonExpression(left, right) {
+
+ protected boolean asBoolean(int answer) {
+ return answer <= 0;
+ }
+
+ public String getExpressionSymbol() {
+ return "<=";
+ }
+ };
+ }
+
+ /**
+ * Only Numeric expressions can be used in >, >=, < or <= expressions.s
+ *
+ * @param expr
+ */
+ public static void checkLessThanOperand(Expression expr) {
+ if (expr instanceof ConstantExpression) {
+ Object value = ((ConstantExpression)expr).getValue();
+ if (value instanceof Number) {
+ return;
+ }
+
+ // Else it's boolean or a String..
+ throw new RuntimeException("Value '" + expr + "' cannot be compared.");
+ }
+ if (expr instanceof BooleanExpression) {
+ throw new RuntimeException("Value '" + expr + "' cannot be compared.");
+ }
+ }
+
+ /**
+ * Validates that the expression can be used in == or <> expression. Cannot
+ * not be NULL TRUE or FALSE litterals.
+ *
+ * @param expr
+ */
+ public static void checkEqualOperand(Expression expr) {
+ if (expr instanceof ConstantExpression) {
+ Object value = ((ConstantExpression)expr).getValue();
+ if (value == null) {
+ throw new RuntimeException("'" + expr + "' cannot be compared.");
+ }
+ }
+ }
+
+ /**
+ * @param left
+ * @param right
+ */
+ private static void checkEqualOperandCompatability(Expression left, Expression right) {
+ if (left instanceof ConstantExpression && right instanceof ConstantExpression) {
+ if (left instanceof BooleanExpression && !(right instanceof BooleanExpression)) {
+ throw new RuntimeException("'" + left + "' cannot be compared with '" + right + "'");
+ }
+ }
+ }
+
+ public Object evaluate(MessageEvaluationContext message) throws FilterException {
+ Comparable<Comparable> lv = (Comparable)left.evaluate(message);
+ if (lv == null) {
+ return null;
+ }
+ Comparable rv = (Comparable)right.evaluate(message);
+ if (rv == null) {
+ return null;
+ }
+ return compare(lv, rv);
+ }
+
+ protected Boolean compare(Comparable lv, Comparable rv) {
+ Class<? extends Comparable> lc = lv.getClass();
+ Class<? extends Comparable> rc = rv.getClass();
+ // If the the objects are not of the same type,
+ // try to convert up to allow the comparison.
+ if (lc != rc) {
+ if (lc == Byte.class) {
+ if (rc == Short.class) {
+ lv = Short.valueOf(((Number)lv).shortValue());
+ } else if (rc == Integer.class) {
+ lv = Integer.valueOf(((Number)lv).intValue());
+ } else if (rc == Long.class) {
+ lv = Long.valueOf(((Number)lv).longValue());
+ } else if (rc == Float.class) {
+ lv = new Float(((Number)lv).floatValue());
+ } else if (rc == Double.class) {
+ lv = new Double(((Number)lv).doubleValue());
+ } else {
+ return Boolean.FALSE;
+ }
+ } else if (lc == Short.class) {
+ if (rc == Integer.class) {
+ lv = Integer.valueOf(((Number)lv).intValue());
+ } else if (rc == Long.class) {
+ lv = Long.valueOf(((Number)lv).longValue());
+ } else if (rc == Float.class) {
+ lv = new Float(((Number)lv).floatValue());
+ } else if (rc == Double.class) {
+ lv = new Double(((Number)lv).doubleValue());
+ } else {
+ return Boolean.FALSE;
+ }
+ } else if (lc == Integer.class) {
+ if (rc == Long.class) {
+ lv = Long.valueOf(((Number)lv).longValue());
+ } else if (rc == Float.class) {
+ lv = new Float(((Number)lv).floatValue());
+ } else if (rc == Double.class) {
+ lv = new Double(((Number)lv).doubleValue());
+ } else {
+ return Boolean.FALSE;
+ }
+ } else if (lc == Long.class) {
+ if (rc == Integer.class) {
+ rv = Long.valueOf(((Number)rv).longValue());
+ } else if (rc == Float.class) {
+ lv = new Float(((Number)lv).floatValue());
+ } else if (rc == Double.class) {
+ lv = new Double(((Number)lv).doubleValue());
+ } else {
+ return Boolean.FALSE;
+ }
+ } else if (lc == Float.class) {
+ if (rc == Integer.class) {
+ rv = new Float(((Number)rv).floatValue());
+ } else if (rc == Long.class) {
+ rv = new Float(((Number)rv).floatValue());
+ } else if (rc == Double.class) {
+ lv = new Double(((Number)lv).doubleValue());
+ } else {
+ return Boolean.FALSE;
+ }
+ } else if (lc == Double.class) {
+ if (rc == Integer.class) {
+ rv = new Double(((Number)rv).doubleValue());
+ } else if (rc == Long.class) {
+ rv = new Double(((Number)rv).doubleValue());
+ } else if (rc == Float.class) {
+ rv = new Float(((Number)rv).doubleValue());
+ } else {
+ return Boolean.FALSE;
+ }
+ } else {
+ return Boolean.FALSE;
+ }
+ }
+ return asBoolean(lv.compareTo(rv)) ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ protected abstract boolean asBoolean(int answer);
+
+ public boolean matches(MessageEvaluationContext message) throws FilterException {
+ Object object = evaluate(message);
+ return object != null && object == Boolean.TRUE;
+ }
+
+}
Propchange: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ComparisonExpression.java
------------------------------------------------------------------------------
svn:executable = *
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ConstantExpression.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ConstantExpression.java?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ConstantExpression.java (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ConstantExpression.java Mon Jun 1 04:05:34 2009
@@ -0,0 +1,163 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.filter;
+
+import java.math.BigDecimal;
+
+
+/**
+ * Represents a constant expression
+ *
+ * @version $Revision: 1.2 $
+ */
+public class ConstantExpression implements Expression {
+
+ static class BooleanConstantExpression extends ConstantExpression implements BooleanExpression {
+ public BooleanConstantExpression(Object value) {
+ super(value);
+ }
+
+ public boolean matches(MessageEvaluationContext message) throws FilterException {
+ Object object = evaluate(message);
+ return object != null && object == Boolean.TRUE;
+ }
+ }
+
+ public static final BooleanConstantExpression NULL = new BooleanConstantExpression(null);
+ public static final BooleanConstantExpression TRUE = new BooleanConstantExpression(Boolean.TRUE);
+ public static final BooleanConstantExpression FALSE = new BooleanConstantExpression(Boolean.FALSE);
+
+ private Object value;
+
+ public ConstantExpression(Object value) {
+ this.value = value;
+ }
+
+ public static ConstantExpression createFromDecimal(String text) {
+
+ // Strip off the 'l' or 'L' if needed.
+ if (text.endsWith("l") || text.endsWith("L")) {
+ text = text.substring(0, text.length() - 1);
+ }
+
+ Number value;
+ try {
+ value = new Long(text);
+ } catch (NumberFormatException e) {
+ // The number may be too big to fit in a long.
+ value = new BigDecimal(text);
+ }
+
+ long l = value.longValue();
+ if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE) {
+ value = Integer.valueOf(value.intValue());
+ }
+ return new ConstantExpression(value);
+ }
+
+ public static ConstantExpression createFromHex(String text) {
+ Number value = Long.valueOf(Long.parseLong(text.substring(2), 16));
+ long l = value.longValue();
+ if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE) {
+ value = Integer.valueOf(value.intValue());
+ }
+ return new ConstantExpression(value);
+ }
+
+ public static ConstantExpression createFromOctal(String text) {
+ Number value = Long.valueOf(Long.parseLong(text, 8));
+ long l = value.longValue();
+ if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE) {
+ value = Integer.valueOf(value.intValue());
+ }
+ return new ConstantExpression(value);
+ }
+
+ public static ConstantExpression createFloat(String text) {
+ Number value = new Double(text);
+ return new ConstantExpression(value);
+ }
+
+ public Object evaluate(MessageEvaluationContext message) throws FilterException {
+ return value;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ if (value == null) {
+ return "NULL";
+ }
+ if (value instanceof Boolean) {
+ return ((Boolean)value).booleanValue() ? "TRUE" : "FALSE";
+ }
+ if (value instanceof String) {
+ return encodeString((String)value);
+ }
+ return value.toString();
+ }
+
+ /**
+ * TODO: more efficient hashCode()
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ /**
+ * TODO: more efficient hashCode()
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object o) {
+
+ if (o == null || !this.getClass().equals(o.getClass())) {
+ return false;
+ }
+ return toString().equals(o.toString());
+
+ }
+
+ /**
+ * Encodes the value of string so that it looks like it would look like when
+ * it was provided in a selector.
+ *
+ * @param string
+ * @return
+ */
+ public static String encodeString(String s) {
+ StringBuffer b = new StringBuffer();
+ b.append('\'');
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == '\'') {
+ b.append(c);
+ }
+ b.append(c);
+ }
+ b.append('\'');
+ return b.toString();
+ }
+
+}
Propchange: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/ConstantExpression.java
------------------------------------------------------------------------------
svn:executable = *
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/Expression.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/Expression.java?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/Expression.java (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/Expression.java Mon Jun 1 04:05:34 2009
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.activemq.filter;
+
+
+
+/**
+ * Represents an expression
+ *
+ * @version $Revision: 1.2 $
+ */
+public interface Expression {
+
+ /**
+ * @return the value of this expression
+ */
+ Object evaluate(MessageEvaluationContext message) throws FilterException;
+
+}
Propchange: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/Expression.java
------------------------------------------------------------------------------
svn:executable = *
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/FilterException.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/FilterException.java?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/FilterException.java (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/FilterException.java Mon Jun 1 04:05:34 2009
@@ -0,0 +1,23 @@
+package org.apache.activemq.filter;
+
+public class FilterException extends Exception {
+
+ private static final long serialVersionUID = -6892363158919485507L;
+
+ public FilterException() {
+ super();
+ }
+
+ public FilterException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public FilterException(String message) {
+ super(message);
+ }
+
+ public FilterException(Throwable cause) {
+ super(cause);
+ }
+
+}
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/LogicExpression.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/LogicExpression.java?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/LogicExpression.java (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/LogicExpression.java Mon Jun 1 04:05:34 2009
@@ -0,0 +1,88 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.filter;
+
+
+/**
+ * A filter performing a comparison of two objects
+ *
+ * @version $Revision: 1.2 $
+ */
+public abstract class LogicExpression extends BinaryExpression implements BooleanExpression {
+
+ /**
+ * @param left
+ * @param right
+ */
+ public LogicExpression(BooleanExpression left, BooleanExpression right) {
+ super(left, right);
+ }
+
+ public static BooleanExpression createOR(BooleanExpression lvalue, BooleanExpression rvalue) {
+ return new LogicExpression(lvalue, rvalue) {
+
+ public Object evaluate(MessageEvaluationContext message) throws FilterException {
+
+ Boolean lv = (Boolean)left.evaluate(message);
+ // Can we do an OR shortcut??
+ if (lv != null && lv.booleanValue()) {
+ return Boolean.TRUE;
+ }
+
+ Boolean rv = (Boolean)right.evaluate(message);
+ return rv == null ? null : rv;
+ }
+
+ public String getExpressionSymbol() {
+ return "OR";
+ }
+ };
+ }
+
+ public static BooleanExpression createAND(BooleanExpression lvalue, BooleanExpression rvalue) {
+ return new LogicExpression(lvalue, rvalue) {
+
+ public Object evaluate(MessageEvaluationContext message) throws FilterException {
+
+ Boolean lv = (Boolean)left.evaluate(message);
+
+ // Can we do an AND shortcut??
+ if (lv == null) {
+ return null;
+ }
+ if (!lv.booleanValue()) {
+ return Boolean.FALSE;
+ }
+
+ Boolean rv = (Boolean)right.evaluate(message);
+ return rv == null ? null : rv;
+ }
+
+ public String getExpressionSymbol() {
+ return "AND";
+ }
+ };
+ }
+
+ public abstract Object evaluate(MessageEvaluationContext message) throws FilterException;
+
+ public boolean matches(MessageEvaluationContext message) throws FilterException {
+ Object object = evaluate(message);
+ return object != null && object == Boolean.TRUE;
+ }
+
+}
Propchange: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/LogicExpression.java
------------------------------------------------------------------------------
svn:executable = *
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/MessageEvaluationContext.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/MessageEvaluationContext.java?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/MessageEvaluationContext.java (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/MessageEvaluationContext.java Mon Jun 1 04:05:34 2009
@@ -0,0 +1,123 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.filter;
+
+
+
+/**
+ * MessageEvaluationContext is used to cache selection results. A message
+ * usually has multiple selectors applied against it. Some selector have a high
+ * cost of evaluating against the message. Those selectors may whish to cache
+ * evaluation results associated with the message in the
+ * MessageEvaluationContext.
+ *
+ * @version $Revision: 1.4 $
+ */
+public interface MessageEvaluationContext {
+
+ /**
+ * This method is used by message filters which do content based routing (Like the XPath
+ * based selectors).
+ *
+ * @param <T>
+ * @param type
+ * @return
+ * @throws FilterException
+ */
+ <T> T getBodyAs(Class<T> type) throws FilterException;
+
+ /**
+ * Creates an expression which extracts the named property from a message.
+ * @param name
+ * @return
+ */
+ Expression getPropertyExpression(String name);
+
+ /**
+ * Stubbed in here to get stuff compiling but I think this can go away. Used by the NoLocal filter.
+ * @return
+ */
+ @Deprecated
+ Object getLocalConnectionId();
+
+ /**
+ * @return the destination that the message is on
+ */
+ <T> T getDestination();
+
+ void setDestination(Object destination);
+
+// protected MessageReference messageReference;
+// protected boolean loaded;
+// protected boolean dropped;
+// protected Message message;
+// protected ActiveMQDestination destination;
+//
+// public MessageEvaluationContext() {
+// }
+//
+// public boolean isDropped() throws IOException {
+// getMessage();
+// return dropped;
+// }
+//
+// public Message getMessage() throws IOException {
+// if (!dropped && !loaded) {
+// loaded = true;
+// messageReference.incrementReferenceCount();
+// message = messageReference.getMessage();
+// if (message == null) {
+// messageReference.decrementReferenceCount();
+// dropped = true;
+// loaded = false;
+// }
+// }
+// return message;
+// }
+//
+// public void setMessageReference(MessageReference messageReference) {
+// if (this.messageReference != messageReference) {
+// clearMessageCache();
+// }
+// this.messageReference = messageReference;
+// }
+//
+// public void clear() {
+// clearMessageCache();
+// destination = null;
+// }
+//
+// public ActiveMQDestination getDestination() {
+// return destination;
+// }
+//
+// public void setDestination(ActiveMQDestination destination) {
+// this.destination = destination;
+// }
+//
+// /**
+// * A strategy hook to allow per-message caches to be cleared
+// */
+// protected void clearMessageCache() {
+// if (loaded) {
+// messageReference.decrementReferenceCount();
+// }
+// message = null;
+// dropped = false;
+// loaded = false;
+// }
+}
Propchange: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/MessageEvaluationContext.java
------------------------------------------------------------------------------
svn:executable = *
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/PropertyExpression.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/PropertyExpression.java?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/PropertyExpression.java (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/PropertyExpression.java Mon Jun 1 04:05:34 2009
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.activemq.filter;
+
+
+/**
+ * Represents a property expression
+ *
+ * @version $Revision: 1.5 $
+ */
+public class PropertyExpression implements Expression {
+
+ private final String name;
+ private Expression expression;
+
+ public PropertyExpression(String name) {
+ this.name = name;
+ }
+
+ public Object evaluate(MessageEvaluationContext message) throws FilterException {
+ if (expression == null) {
+ expression = message.getPropertyExpression(name);
+ }
+ return expression.evaluate(message);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object o) {
+ if (o == null || !this.getClass().equals(o.getClass())) {
+ return false;
+ }
+ return name.equals(((PropertyExpression)o).name);
+
+ }
+
+}
Propchange: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/PropertyExpression.java
------------------------------------------------------------------------------
svn:executable = *
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/UnaryExpression.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/UnaryExpression.java?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/UnaryExpression.java (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/UnaryExpression.java Mon Jun 1 04:05:34 2009
@@ -0,0 +1,256 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.filter;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+
+/**
+ * An expression which performs an operation on two expression values
+ *
+ * @version $Revision: 1.3 $
+ */
+public abstract class UnaryExpression implements Expression {
+
+ private static final BigDecimal BD_LONG_MIN_VALUE = BigDecimal.valueOf(Long.MIN_VALUE);
+ protected Expression right;
+
+ public UnaryExpression(Expression left) {
+ this.right = left;
+ }
+
+ public static Expression createNegate(Expression left) {
+ return new UnaryExpression(left) {
+ public Object evaluate(MessageEvaluationContext message) throws FilterException {
+ Object rvalue = right.evaluate(message);
+ if (rvalue == null) {
+ return null;
+ }
+ if (rvalue instanceof Number) {
+ return negate((Number)rvalue);
+ }
+ return null;
+ }
+
+ public String getExpressionSymbol() {
+ return "-";
+ }
+ };
+ }
+
+ public static BooleanExpression createInExpression(PropertyExpression right, List<Object> elements, final boolean not) {
+
+ // Use a HashSet if there are many elements.
+ Collection<Object> t;
+ if (elements.size() == 0) {
+ t = null;
+ } else if (elements.size() < 5) {
+ t = elements;
+ } else {
+ t = new HashSet<Object>(elements);
+ }
+ final Collection<Object> inList = t;
+
+ return new BooleanUnaryExpression(right) {
+ public Object evaluate(MessageEvaluationContext message) throws FilterException {
+
+ Object rvalue = right.evaluate(message);
+ if (rvalue == null) {
+ return null;
+ }
+ if (rvalue.getClass() != String.class) {
+ return null;
+ }
+
+ if ((inList != null && inList.contains(rvalue)) ^ not) {
+ return Boolean.TRUE;
+ } else {
+ return Boolean.FALSE;
+ }
+
+ }
+
+ public String toString() {
+ StringBuffer answer = new StringBuffer();
+ answer.append(right);
+ answer.append(" ");
+ answer.append(getExpressionSymbol());
+ answer.append(" ( ");
+
+ int count = 0;
+ for (Iterator<Object> i = inList.iterator(); i.hasNext();) {
+ Object o = (Object)i.next();
+ if (count != 0) {
+ answer.append(", ");
+ }
+ answer.append(o);
+ count++;
+ }
+
+ answer.append(" )");
+ return answer.toString();
+ }
+
+ public String getExpressionSymbol() {
+ if (not) {
+ return "NOT IN";
+ } else {
+ return "IN";
+ }
+ }
+ };
+ }
+
+ abstract static class BooleanUnaryExpression extends UnaryExpression implements BooleanExpression {
+ public BooleanUnaryExpression(Expression left) {
+ super(left);
+ }
+
+ public boolean matches(MessageEvaluationContext message) throws FilterException {
+ Object object = evaluate(message);
+ return object != null && object == Boolean.TRUE;
+ }
+ };
+
+ public static BooleanExpression createNOT(BooleanExpression left) {
+ return new BooleanUnaryExpression(left) {
+ public Object evaluate(MessageEvaluationContext message) throws FilterException {
+ Boolean lvalue = (Boolean)right.evaluate(message);
+ if (lvalue == null) {
+ return null;
+ }
+ return lvalue.booleanValue() ? Boolean.FALSE : Boolean.TRUE;
+ }
+
+ public String getExpressionSymbol() {
+ return "NOT";
+ }
+ };
+ }
+
+ public static BooleanExpression createXPath(final String xpath) {
+ return new XPathExpression(xpath);
+ }
+
+ public static BooleanExpression createXQuery(final String xpath) {
+ return new XQueryExpression(xpath);
+ }
+
+ public static BooleanExpression createBooleanCast(Expression left) {
+ return new BooleanUnaryExpression(left) {
+ public Object evaluate(MessageEvaluationContext message) throws FilterException {
+ Object rvalue = right.evaluate(message);
+ if (rvalue == null) {
+ return null;
+ }
+ if (!rvalue.getClass().equals(Boolean.class)) {
+ return Boolean.FALSE;
+ }
+ return ((Boolean)rvalue).booleanValue() ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ public String toString() {
+ return right.toString();
+ }
+
+ public String getExpressionSymbol() {
+ return "";
+ }
+ };
+ }
+
+ private static Number negate(Number left) {
+ Class clazz = left.getClass();
+ if (clazz == Integer.class) {
+ return new Integer(-left.intValue());
+ } else if (clazz == Long.class) {
+ return new Long(-left.longValue());
+ } else if (clazz == Float.class) {
+ return new Float(-left.floatValue());
+ } else if (clazz == Double.class) {
+ return new Double(-left.doubleValue());
+ } else if (clazz == BigDecimal.class) {
+ // We ussually get a big deciamal when we have Long.MIN_VALUE
+ // constant in the
+ // Selector. Long.MIN_VALUE is too big to store in a Long as a
+ // positive so we store it
+ // as a Big decimal. But it gets Negated right away.. to here we try
+ // to covert it back
+ // to a Long.
+ BigDecimal bd = (BigDecimal)left;
+ bd = bd.negate();
+
+ if (BD_LONG_MIN_VALUE.compareTo(bd) == 0) {
+ return Long.valueOf(Long.MIN_VALUE);
+ }
+ return bd;
+ } else {
+ throw new RuntimeException("Don't know how to negate: " + left);
+ }
+ }
+
+ public Expression getRight() {
+ return right;
+ }
+
+ public void setRight(Expression expression) {
+ right = expression;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return "(" + getExpressionSymbol() + " " + right.toString() + ")";
+ }
+
+ /**
+ * TODO: more efficient hashCode()
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ /**
+ * TODO: more efficient hashCode()
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object o) {
+
+ if (o == null || !this.getClass().equals(o.getClass())) {
+ return false;
+ }
+ return toString().equals(o.toString());
+
+ }
+
+ /**
+ * Returns the symbol that represents this binary expression. For example,
+ * addition is represented by "+"
+ *
+ * @return
+ */
+ public abstract String getExpressionSymbol();
+
+}
Propchange: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/UnaryExpression.java
------------------------------------------------------------------------------
svn:executable = *
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XPathExpression.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XPathExpression.java?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XPathExpression.java (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XPathExpression.java Mon Jun 1 04:05:34 2009
@@ -0,0 +1,109 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.filter;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * Used to evaluate an XPath Expression in a JMS selector.
+ */
+public final class XPathExpression implements BooleanExpression {
+
+ private static final Log LOG = LogFactory.getLog(XPathExpression.class);
+ private static final String EVALUATOR_SYSTEM_PROPERTY = "org.apache.activemq.XPathEvaluatorClassName";
+ private static final String DEFAULT_EVALUATOR_CLASS_NAME = XalanXPathEvaluator.class.getName();
+
+ private static final Constructor EVALUATOR_CONSTRUCTOR;
+
+ static {
+ String cn = System.getProperty(EVALUATOR_SYSTEM_PROPERTY, DEFAULT_EVALUATOR_CLASS_NAME);
+ Constructor m = null;
+ try {
+ try {
+ m = getXPathEvaluatorConstructor(cn);
+ } catch (Throwable e) {
+ LOG.warn("Invalid " + XPathEvaluator.class.getName() + " implementation: " + cn + ", reason: " + e, e);
+ cn = DEFAULT_EVALUATOR_CLASS_NAME;
+ try {
+ m = getXPathEvaluatorConstructor(cn);
+ } catch (Throwable e2) {
+ LOG.error("Default XPath evaluator could not be loaded", e);
+ }
+ }
+ } finally {
+ EVALUATOR_CONSTRUCTOR = m;
+ }
+ }
+
+ private final String xpath;
+ private final XPathEvaluator evaluator;
+
+ public static interface XPathEvaluator {
+ boolean evaluate(MessageEvaluationContext message) throws FilterException;
+ }
+
+ XPathExpression(String xpath) {
+ this.xpath = xpath;
+ this.evaluator = createEvaluator(xpath);
+ }
+
+ private static Constructor getXPathEvaluatorConstructor(String cn) throws ClassNotFoundException, SecurityException, NoSuchMethodException {
+ Class c = XPathExpression.class.getClassLoader().loadClass(cn);
+ if (!XPathEvaluator.class.isAssignableFrom(c)) {
+ throw new ClassCastException("" + c + " is not an instance of " + XPathEvaluator.class);
+ }
+ return c.getConstructor(new Class[] {String.class});
+ }
+
+ private XPathEvaluator createEvaluator(String xpath2) {
+ try {
+ return (XPathEvaluator)EVALUATOR_CONSTRUCTOR.newInstance(new Object[] {xpath});
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof RuntimeException) {
+ throw (RuntimeException)cause;
+ }
+ throw new RuntimeException("Invalid XPath Expression: " + xpath + " reason: " + e.getMessage(), e);
+ } catch (Throwable e) {
+ throw new RuntimeException("Invalid XPath Expression: " + xpath + " reason: " + e.getMessage(), e);
+ }
+ }
+
+ public Object evaluate(MessageEvaluationContext message) throws FilterException {
+ return evaluator.evaluate(message) ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ public String toString() {
+ return "XPATH " + ConstantExpression.encodeString(xpath);
+ }
+
+ /**
+ * @param message
+ * @return true if the expression evaluates to Boolean.TRUE.
+ * @throws FilterException
+ */
+ public boolean matches(MessageEvaluationContext message) throws FilterException {
+ Object object = evaluate(message);
+ return object != null && object == Boolean.TRUE;
+ }
+
+}
Propchange: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XPathExpression.java
------------------------------------------------------------------------------
svn:executable = *
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XQueryExpression.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XQueryExpression.java?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XQueryExpression.java (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XQueryExpression.java Mon Jun 1 04:05:34 2009
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.filter;
+
+
+/**
+ * Used to evaluate an XQuery Expression in a JMS selector.
+ */
+public final class XQueryExpression implements BooleanExpression {
+ private final String xpath;
+
+ XQueryExpression(String xpath) {
+ super();
+ this.xpath = xpath;
+ }
+
+ public Object evaluate(MessageEvaluationContext message) throws FilterException {
+ return Boolean.FALSE;
+ }
+
+ public String toString() {
+ return "XQUERY " + ConstantExpression.encodeString(xpath);
+ }
+
+ /**
+ * @param message
+ * @return true if the expression evaluates to Boolean.TRUE.
+ * @throws FilterException
+ */
+ public boolean matches(MessageEvaluationContext message) throws FilterException {
+ Object object = evaluate(message);
+ return object != null && object == Boolean.TRUE;
+ }
+
+}
Propchange: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XQueryExpression.java
------------------------------------------------------------------------------
svn:executable = *
Added: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XalanXPathEvaluator.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XalanXPathEvaluator.java?rev=780558&view=auto
==============================================================================
--- activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XalanXPathEvaluator.java (added)
+++ activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XalanXPathEvaluator.java Mon Jun 1 04:05:34 2009
@@ -0,0 +1,106 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.activemq.filter;
+
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.activemq.protobuf.Buffer;
+import org.apache.activemq.protobuf.BufferInputStream;
+import org.apache.xpath.CachedXPathAPI;
+import org.apache.xpath.objects.XObject;
+import org.w3c.dom.Document;
+import org.w3c.dom.traversal.NodeIterator;
+import org.xml.sax.InputSource;
+
+
+public class XalanXPathEvaluator implements XPathExpression.XPathEvaluator {
+
+ private final String xpath;
+
+ public XalanXPathEvaluator(String xpath) {
+ this.xpath = xpath;
+ }
+
+ public boolean evaluate(MessageEvaluationContext m) throws FilterException {
+ String stringBody = m.getBodyAs(String.class);
+ if (stringBody!=null) {
+ return evaluate(stringBody);
+ }
+
+ Buffer bufferBody = m.getBodyAs(Buffer.class);
+ if (bufferBody!=null) {
+ return evaluate(bufferBody);
+ }
+ return false;
+ }
+
+ private boolean evaluate(Buffer data) {
+ try {
+
+ InputSource inputSource = new InputSource(new BufferInputStream(data));
+
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ DocumentBuilder dbuilder = factory.newDocumentBuilder();
+ Document doc = dbuilder.parse(inputSource);
+
+ CachedXPathAPI cachedXPathAPI = new CachedXPathAPI();
+ XObject result = cachedXPathAPI.eval(doc, xpath);
+ if (result.bool())
+ return true;
+ else {
+ NodeIterator iterator = cachedXPathAPI.selectNodeIterator(doc, xpath);
+ return (iterator.nextNode() != null);
+ }
+
+ } catch (Throwable e) {
+ return false;
+ }
+ }
+
+ private boolean evaluate(String text) {
+ try {
+ InputSource inputSource = new InputSource(new StringReader(text));
+
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ DocumentBuilder dbuilder = factory.newDocumentBuilder();
+ Document doc = dbuilder.parse(inputSource);
+
+ //An XPath expression could return a true or false value instead of a node.
+ //eval() is a better way to determine the boolean value of the exp.
+ //For compliance with legacy behavior where selecting an empty node returns true,
+ //selectNodeIterator is attempted in case of a failure.
+
+ CachedXPathAPI cachedXPathAPI = new CachedXPathAPI();
+ XObject result = cachedXPathAPI.eval(doc, xpath);
+ if (result.bool())
+ return true;
+ else {
+ NodeIterator iterator = cachedXPathAPI.selectNodeIterator(doc, xpath);
+ return (iterator.nextNode() != null);
+ }
+
+ } catch (Throwable e) {
+ return false;
+ }
+ }
+}
Propchange: activemq/sandbox/activemq-flow/activemq-selector/src/main/java/org/apache/activemq/filter/XalanXPathEvaluator.java
------------------------------------------------------------------------------
svn:executable = *