[jboss-cvs] JBoss Messaging SVN: r3591 - in trunk/src/main/org/jboss/messaging/core/impl: filter and 1 other directory.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Fri Jan 18 08:38:40 EST 2008
Author: timfox
Date: 2008-01-18 08:38:40 -0500 (Fri, 18 Jan 2008)
New Revision: 3591
Added:
trunk/src/main/org/jboss/messaging/core/impl/filter/
trunk/src/main/org/jboss/messaging/core/impl/filter/FilterImpl.java
trunk/src/main/org/jboss/messaging/core/impl/filter/FilterParser.jj
trunk/src/main/org/jboss/messaging/core/impl/filter/Identifier.java
trunk/src/main/org/jboss/messaging/core/impl/filter/Operator.java
trunk/src/main/org/jboss/messaging/core/impl/filter/RegExp.java
Log:
Added filter files
Added: trunk/src/main/org/jboss/messaging/core/impl/filter/FilterImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/filter/FilterImpl.java (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/filter/FilterImpl.java 2008-01-18 13:38:40 UTC (rev 3591)
@@ -0,0 +1,153 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.impl.filter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.Filter;
+import org.jboss.messaging.core.Message;
+
+/**
+* This class implements a JBoss Messaging filter
+*
+* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+*
+* Derived from JBoss MQ version by
+*
+* @author <a href="mailto:Norbert.Lataille at m4x.org">Norbert Lataille</a>
+* @author <a href="mailto:jplindfo at helsinki.fi">Juha Lindfors</a>
+* @author <a href="mailto:jason at planet57.com">Jason Dillon</a>
+* @author <a href="mailto:Scott.Stark at jboss.org">Scott Stark</a>
+*
+* @version $Revision: 3569 $
+*
+* $Id: Selector.java 3569 2008-01-15 21:14:04Z timfox $
+*/
+public class FilterImpl implements Filter
+{
+ private static final Logger log = Logger.getLogger(FilterImpl.class);
+
+ private String filterString;
+
+ private Map<String, Identifier> identifiers = new HashMap<String, Identifier>();
+
+ private Operator operator;
+
+ private FilterParser parser = new FilterParser();
+
+ public FilterImpl(String filterString) throws Exception
+ {
+ this.filterString = filterString;
+
+ try
+ {
+ operator = (Operator)parser.parse(filterString, identifiers);
+ }
+ catch (Throwable e)
+ {
+ throw new IllegalArgumentException("Invalid filter: " + filterString);
+ }
+ }
+
+ // Filter implementation ---------------------------------------------------------------------
+
+ public String getFilterString()
+ {
+ return filterString;
+ }
+
+ public boolean match(Message message)
+ {
+ try
+ {
+ // Set the identifiers values
+
+ for (Identifier id : identifiers.values())
+ {
+ Object val = null;
+
+ if (id.name.startsWith("JBM"))
+ {
+ //Look it up as header fields
+
+ val = getHeaderFieldValue(message, id.name);
+ }
+
+ if (val == null)
+ {
+ //First look it up in the headers
+
+ val = message.getHeader(id.name);
+ }
+
+ if (val != null)
+ {
+ id.value = val;
+ }
+ }
+
+ // Compute the result of this operator
+
+ boolean res = (Boolean)operator.apply();
+
+ return res;
+ }
+ catch (Exception e)
+ {
+ log.warn("Invalid filter string: " + filterString, e);
+
+ return false;
+ }
+ }
+
+ // Private --------------------------------------------------------------------------
+
+ private Object getHeaderFieldValue(Message msg, String fieldName)
+ {
+ if ("JBMMessageID".equals(fieldName))
+ {
+ return msg.getMessageID();
+ }
+ else if ("JBMPriority".equals(fieldName))
+ {
+ return new Integer(msg.getPriority());
+ }
+ else if ("JBMTimestamp".equals(fieldName))
+ {
+ return msg.getTimestamp();
+ }
+ else if ("JBMDurable".equals(fieldName))
+ {
+ return msg.isDurable() ? "DURABLE" : "NON_DURABLE";
+ }
+ else if ("JBMExpiration".equals(fieldName))
+ {
+ return msg.getExpiration();
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
Added: trunk/src/main/org/jboss/messaging/core/impl/filter/FilterParser.jj
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/filter/FilterParser.jj (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/filter/FilterParser.jj 2008-01-18 13:38:40 UTC (rev 3591)
@@ -0,0 +1,641 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+options {
+ LOOKAHEAD=1;
+/*
+ DEBUG_PARSER=true;
+ DEBUG_LOOKAHEAD=true;
+ DEBUG_TOKEN_MANAGER=true;
+*/
+}
+
+PARSER_BEGIN(FilterParser)
+
+package org.jboss.messaging.core.impl.filter;
+
+import java.io.StringReader;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A JavaCC 2.0 grammar for JBoss Messaging filters
+ *
+ * @author Scott.Stark at jboss.org
+ * @author adrian at jboss.org
+ * @version $Revision: 2681 $
+ */
+public class FilterParser
+{
+ private static final String LOFFER_L = "l";
+ private static final String UPPER_L = "L";
+ private static final String OX = "0X";
+ private static final String Ox = "0x";
+ private static final String ZERRO = "0";
+
+ private Map identifierMap;
+
+ public FilterParser()
+ {
+ // keep the parser from feaking out, init using one of
+ // the JavaCC generated constructor
+ this(new StringReader(""));
+ }
+
+ public Object parse(String selector, Map identifierMap)
+ throws ParseException
+ {
+ return parse(selector, identifierMap, false);
+ }
+
+ public Object parse(String selector, Map identifierMap, boolean trace)
+ throws ParseException
+ {
+ StringReader sr = new StringReader(selector);
+ ReInit(sr);
+
+ // This will have no effect unless the debugging options are true
+ if (trace)
+ {
+ this.enable_tracing();
+ }
+ else
+ {
+ this.disable_tracing();
+ }
+
+ this.identifierMap = identifierMap;
+ return this.expression();
+ }
+
+ /**
+ * Strip off the leading and trailing (quote) chars from the given string
+ * and return it.
+ */
+ private String stripQuotes(String image)
+ {
+ StringBuffer result = new StringBuffer(image.length()-2);
+ int i = 1;
+ boolean escaped = false;
+ while (i < image.length() - 1)
+ {
+ if (escaped)
+ {
+ if (image.charAt(i) == '\'')
+ result.append('\'');
+ else
+ throw new RuntimeException("Invalid uses of quotes: " + image);
+ escaped = false;
+ }
+ else if (image.charAt(i) == '\'')
+ escaped = true;
+ else
+ result.append(image.charAt(i));
+ ++i;
+ }
+ return result.toString();
+ }
+
+ public static Object doParse(String selector, Map identifierMap)
+ throws ParseException
+ {
+ return doParse(selector, identifierMap, false);
+ }
+
+ public static Object doParse(String selector, Map identifierMap, boolean trace)
+ throws ParseException
+ {
+ FilterParser parser = new FilterParser();
+ return parser.parse(selector, identifierMap, trace);
+ }
+}
+
+PARSER_END(FilterParser)
+
+/* IGNORE WHITESPACE */
+
+SKIP :
+{
+ " "
+ | "\r"
+ | "\t"
+ | "\f"
+ | "\n"
+}
+
+
+/* RESERVED WORDS AND LITERALS */
+
+TOKEN [IGNORE_CASE]:
+{
+ < TRUE: "TRUE" >
+ | < FALSE: "FALSE" >
+ | < NULL: "NULL" >
+ | < AND: "AND" >
+ | < NOT: "NOT" >
+ | < OR: "OR" >
+ | < BETWEEN: "BETWEEN" >
+ | < LIKE: "LIKE" >
+ | < IN: "IN" >
+ | < IS: "IS" >
+ | < ESCAPE: "ESCAPE" >
+ | < LPAREN: "(" >
+ | < RPAREN: ")" >
+ | < SEMICOLON: ";" >
+ | < COMMA: "," >
+
+}
+
+/* OPERATORS */
+
+TOKEN :
+{
+ < MULT: "*" >
+ | < DIV: "/" >
+ | < MINUS: "-" >
+ | < PLUS: "+" >
+ | < GT: ">" >
+ | < GE: ">=" >
+ | < LT: "<" >
+ | < LE: "<=" >
+ | < NE: "<>" >
+ | < EQ: "=" >
+
+}
+
+/* Literals */
+
+<DEFAULT> TOKEN : /* Numeric Literal */
+{
+ < INTEGER_LITERAL:
+ "-9223372036854775808"
+ | "-9223372036854775808l"
+ | "-9223372036854775808L"
+ | <DECIMAL_LITERAL> (["l","L"])?
+ | <HEX_LITERAL> (["l","L"])?
+ | <OCTAL_LITERAL> (["l","L"])?
+ >
+|
+ < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
+|
+ < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
+|
+ < #OCTAL_LITERAL: "0" (["0"-"7"])* >
+|
+ < FLOATING_POINT_LITERAL:
+ (["+","-"])? (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])?
+ | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])?
+ | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])?
+ | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]
+ >
+|
+ < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
+}
+
+
+TOKEN :
+{
+ < STRING:
+ "'"
+ ( (~["'","\n","\r"])
+ | ("''")
+ )*
+ "'"
+ >
+}
+
+/* Function names */
+
+TOKEN :
+{
+ < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
+ |
+ < #LETTER: [ "_","$", "a"-"z", "A"-"Z" ] >
+ |
+ < #DIGIT: ["0" - "9"] >
+}
+
+/** Start of the grammar */
+
+Object expression() :
+{
+ Object exp1 = null;
+}
+{
+ exp1=selectorExpression()<EOF>
+ {
+ return exp1;
+ }
+}
+
+Object selectorExpression() :
+{
+ Object exp1 = null;
+ Object exp2 = null;
+}
+{
+ exp1=selectorTerm()
+ (
+ <OR> exp2=selectorTerm()
+ {
+ exp1 = new Operator(Operator.OR, exp1, exp2);
+ }
+ )*
+ {
+ return exp1;
+ }
+}
+
+Object selectorTerm() :
+{
+ Object exp1 = null;
+ Object exp2 = null;
+}
+{
+ exp1=selectorFactor()
+ (
+ <AND> exp2=selectorFactor()
+ {
+ exp1 = new Operator(Operator.AND, exp1, exp2);
+ }
+ )*
+ {
+ return exp1;
+ }
+}
+
+Object selectorFactor() :
+{
+ Object exp1 = null;
+}
+{
+ exp1=conditionalExpression()
+ {
+ return exp1;
+ }
+ | <NOT> exp1=conditionalExpression()
+ {
+ exp1 = new Operator(Operator.NOT, exp1);
+ }
+ {
+ return exp1;
+ }
+}
+
+Object conditionalExpression() :
+{
+ Object exp1 = null;
+}
+{
+ LOOKAHEAD(3)
+ <LPAREN> exp1=selectorExpression() <RPAREN>
+ {
+ return exp1;
+ }
+ |
+ exp1 = comparisonExpression()
+ {
+ return exp1;
+ }
+}
+
+Object comparisonExpression() :
+{
+ int op = -1;
+ Set set = null;
+ Object exp1 = null;
+ Object exp2 = null;
+ Object exp3 = null;
+ Object id = null;
+ Token not = null;
+}
+{
+ LOOKAHEAD(2147483647)
+ exp1=identifier() <IS> [ not=<NOT> ] <NULL>
+ {
+ int opCode = not == null ? Operator.IS_NULL : Operator.IS_NOT_NULL;
+ return new Operator(opCode, exp1);
+ }
+ |
+ LOOKAHEAD(2147483647)
+ id=identifier() [ not=<NOT> ] <IN> <LPAREN> { set = new HashSet(); } stringList(set) <RPAREN>
+ {
+ if (not == null)
+ return new Operator(Operator.IN, id, set);
+ else
+ return new Operator(Operator.NOT_IN, id, set);
+ return exp1;
+ }
+ |
+ LOOKAHEAD(2147483647)
+ id=identifier() [ not=<NOT> ] <LIKE> exp1=patternExpression(id)
+ {
+ if (not != null)
+ exp1 = new Operator(Operator.NOT, exp1);
+ return exp1;
+ }
+ |
+ LOOKAHEAD(2147483647)
+ exp1=stringExpression()
+ (
+ <EQ>{ op = Operator.EQUAL;}
+ | <NE>{ op = Operator.DIFFERENT;}
+ ) exp2=stringExpression()
+ {
+ return new Operator(op, exp1, exp2);
+ }
+ |
+ LOOKAHEAD(2147483647)
+ exp1=booleanExpression()
+ (
+ <EQ>{ op = Operator.EQUAL;}
+ | <NE>{ op = Operator.DIFFERENT;}
+ ) exp2=booleanExpression()
+ {
+ return new Operator(op, exp1, exp2);
+ }
+ |
+ LOOKAHEAD(2147483647)
+ exp1=arithExpression()
+ (
+ <EQ>{ op = Operator.EQUAL;}
+ | <NE>{ op = Operator.DIFFERENT;}
+ | <GT>{ op = Operator.GT;}
+ | <GE>{ op = Operator.GE;}
+ | <LT>{ op = Operator.LT;}
+ | <LE>{ op = Operator.LE;}
+ ) exp2=arithExpression()
+ {
+ return new Operator(op, exp1, exp2);
+ }
+ |
+ LOOKAHEAD(2147483647)
+ exp1=arithExpression() [ not=<NOT> ] <BETWEEN> exp2=arithExpression() <AND> exp3=arithExpression()
+ {
+ exp1 = new Operator(Operator.BETWEEN, exp1, exp2, exp3);
+ if (not != null)
+ exp1 = new Operator(Operator.NOT, exp1);
+ return exp1;
+ }
+ | exp1=booleanExpression()
+ {
+ return exp1;
+ }
+}
+
+void stringList(Set set) :
+{
+}
+{
+ stringToken(set) ( <COMMA> stringToken(set))*
+}
+
+void stringToken(Set set) :
+{
+ Token t = null;
+}
+{
+ [ t=<STRING> ]
+ {
+ if (t != null)
+ set.add(stripQuotes(t.image));
+ }
+}
+
+Object patternExpression(Object exp1) :
+{
+ Object exp2 = null;
+ Token esc = null;
+ Object escChar = null;
+}
+{
+ exp2=stringLiteral() [ esc=<ESCAPE> escChar=stringLiteral() ]
+ {
+ Operator op = null;
+ if (esc == null)
+ op = new Operator(Operator.LIKE, exp1, exp2);
+ else
+ op = new Operator(Operator.LIKE_ESCAPE, exp1, exp2, escChar);
+ return op;
+ }
+}
+
+Object arithExpression() :
+{
+ Object exp1 = null;
+ Object exp2 = null;
+}
+{
+ exp1=arithTerm()
+ (
+ <PLUS> exp2=arithTerm()
+ {
+ exp1 = new Operator(Operator.ADD, exp1, exp2);
+ }
+ | <MINUS> exp2=arithTerm()
+ {
+ exp1 = new Operator(Operator.SUB, exp1, exp2);
+ }
+ )*
+ {
+ return exp1;
+ }
+}
+
+Object arithTerm() :
+{
+ Object exp1 = null;
+ Object exp2 = null;
+}
+{
+ exp1=arithFactor()
+ (
+ <MULT> exp2=arithFactor()
+ {
+ exp1 = new Operator(Operator.MUL, exp1, exp2);
+ }
+ | <DIV> exp2=arithFactor()
+ {
+ exp1 = new Operator(Operator.DIV, exp1, exp2);
+ }
+ )*
+ {
+ return exp1;
+ }
+}
+
+Object arithFactor() :
+{
+ Object exp1 = null;
+ boolean negate = false;
+}
+{
+ [<PLUS>|<MINUS>{ negate = true; }] exp1=numericExpression()
+ {
+ if (negate)
+ exp1 = new Operator(Operator.NEG, exp1);
+ return exp1;
+ }
+}
+
+Object booleanExpression() :
+{
+ Object exp1 = null;
+}
+{
+ (
+ exp1=identifier()
+ | exp1=booleanLiteral()
+ )
+ {
+ return exp1;
+ }
+}
+
+Object booleanLiteral() :
+{
+ boolean isTrue = true;
+}
+{
+ (<TRUE>|<FALSE>{ isTrue = false; })
+ {
+ if (isTrue)
+ return Boolean.TRUE;
+ else
+ return Boolean.FALSE;
+ }
+}
+
+Object stringExpression() :
+{
+ Object exp1 = null;
+}
+{
+ (
+ exp1=identifier()
+ | exp1=stringLiteral()
+ )
+ {
+ return exp1;
+ }
+}
+
+Object stringLiteral() :
+{
+ Token string = null;
+}
+{
+ string=<STRING>
+ {
+ return stripQuotes(string.image);
+ }
+}
+
+Object numericExpression() :
+{
+ Object exp1 = null;
+}
+{
+ (
+ exp1 = numericLiteral()
+ | (<LPAREN> exp1=arithExpression() <RPAREN>)
+ | exp1 = identifier()
+ )
+ {
+ return exp1;
+ }
+}
+Object numericLiteral() :
+{
+ Token literal = null;
+}
+{
+ literal=<FLOATING_POINT_LITERAL>
+ {
+ return new Double(literal.image);
+ }
+ |
+ literal=<INTEGER_LITERAL>
+ {
+ String number = literal.image;
+
+ // long suffix
+ if (number.endsWith(LOFFER_L) || number.endsWith(UPPER_L))
+ {
+ // chop off the suffix
+ return new Long(number.substring(0, number.length() - 1));
+ }
+
+ // hex
+ if (number.startsWith(OX) || number.startsWith(Ox))
+ {
+ // handle literals from 0x8000000000000000L to 0xffffffffffffffffL:
+ // remove sign bit, parse as positive, then calculate the negative
+ // value with the sign bit
+ if(number.length() == 18)
+ {
+ byte first = Byte.decode(number.substring(0, 3)).byteValue();
+ if (first >= 8)
+ {
+ number = Ox + (first - 8) + number.substring(3);
+ return new Long(Long.decode(number).longValue() - Long.MAX_VALUE - 1);
+ }
+ }
+ }
+ else if (number.startsWith(ZERRO))
+ {
+ // octal
+ // handle literals
+ // from 01000000000000000000000L to 01777777777777777777777L
+ // remove sign bit, parse as positive, then calculate the
+ // negative value with the sign bit
+ if (number.length() == 23)
+ {
+ if (number.charAt(1) == '1')
+ {
+ number = ZERRO + number.substring(2);
+ return new Long(Long.decode(number).longValue() - Long.MAX_VALUE - 1);
+ }
+ }
+ }
+ return Long.decode(number);
+ }
+}
+
+Object identifier() :
+{
+ Token id = null;
+}
+{
+ id=<IDENTIFIER>
+ {
+ Identifier identifier = (Identifier) identifierMap.get(id.image);
+ if (identifier == null)
+ {
+ identifier = new Identifier(id.image);
+ identifierMap.put(id.image, identifier);
+ }
+ return identifier;
+ }
+}
Added: trunk/src/main/org/jboss/messaging/core/impl/filter/Identifier.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/filter/Identifier.java (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/filter/Identifier.java 2008-01-18 13:38:40 UTC (rev 3591)
@@ -0,0 +1,79 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.impl.filter;
+
+/**
+ * This is a JMS identifier
+ *
+ * @author Norbert Lataille (Norbert.Lataille at m4x.org)
+ * @author Scott.Stark at jboss.org
+ * @version $Revision: 2681 $
+ */
+public class Identifier
+{
+ String name;
+ Object value;
+ private int hash;
+
+ public Identifier( String name )
+ {
+ this.name = name;
+ hash = name.hashCode();
+ value = null;
+ }
+
+ public String toString()
+ {
+ return "Identifier@" + name;
+ }
+
+ public boolean equals( Object obj )
+ {
+ if ( obj.getClass() != Identifier.class )
+ {
+ return false;
+ }
+ if ( obj.hashCode() != hash )
+ {
+ return false;
+ }
+ return ( ( Identifier )obj ).name.equals( name );
+ }
+
+ public int hashCode()
+ {
+ return hash;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+ public Object getValue()
+ {
+ return value;
+ }
+ public void setValue(Object value)
+ {
+ this.value = value;
+ }
+}
Added: trunk/src/main/org/jboss/messaging/core/impl/filter/Operator.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/filter/Operator.java (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/filter/Operator.java 2008-01-18 13:38:40 UTC (rev 3591)
@@ -0,0 +1,1086 @@
+package org.jboss.messaging.core.impl.filter;
+
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+import java.util.HashSet;
+
+import org.jboss.util.Primitives;
+
+/**
+* An operator for JBM filters
+*
+* @author Norbert Lataille (Norbert.Lataille at m4x.org)
+* @author droy at boostmyscore.com
+* @author Scott.Stark at jboss.org
+* @author adrian at jboss.com
+* @version $Revision: 2681 $
+*/
+public class Operator
+{
+ int operation;
+ Object oper1;
+ Object oper2;
+ Object oper3;
+
+ Object arg1;
+ Object arg2;
+ Object arg3;
+
+ int class1;
+ int class2;
+ int class3;
+
+ // info about the regular expression
+ // if this is a LIKE operator
+ // (perhaps this should be a subclass)
+ RegExp re = null;
+
+ public final static int EQUAL = 0;
+ public final static int NOT = 1;
+ public final static int AND = 2;
+ public final static int OR = 3;
+ public final static int GT = 4;
+ public final static int GE = 5;
+ public final static int LT = 6;
+ public final static int LE = 7;
+ public final static int DIFFERENT = 8;
+ public final static int ADD = 9;
+ public final static int SUB = 10;
+ public final static int NEG = 11;
+ public final static int MUL = 12;
+ public final static int DIV = 13;
+ public final static int BETWEEN = 14;
+ public final static int NOT_BETWEEN = 15;
+ public final static int LIKE = 16;
+ public final static int NOT_LIKE = 17;
+ public final static int LIKE_ESCAPE = 18;
+ public final static int NOT_LIKE_ESCAPE = 19;
+ public final static int IS_NULL = 20;
+ public final static int IS_NOT_NULL = 21;
+ public final static int IN = 22;
+ public final static int NOT_IN = 23;
+
+ public final static int STRING = 0;
+ public final static int DOUBLE = 1;
+ //DOUBLE FLOAT
+ public final static int LONG = 2;
+ //LONG BYTE SHORT INTEGER
+ public final static int BOOLEAN = 3;
+
+ public Operator(int operation, Object oper1, Object oper2, Object oper3)
+ {
+ this.operation = operation;
+ this.oper1 = oper1;
+ this.oper2 = oper2;
+ this.oper3 = oper3;
+ }
+
+ public Operator(int operation, Object oper1, Object oper2)
+ {
+ this.operation = operation;
+ this.oper1 = oper1;
+ this.oper2 = oper2;
+ this.oper3 = null;
+ }
+
+ public Operator(int operation, Object oper1)
+ {
+ this.operation = operation;
+ this.oper1 = oper1;
+ this.oper2 = null;
+ this.oper3 = null;
+ }
+
+ //--- Print functions ---
+
+ public String toString()
+ {
+ return print("");
+ }
+
+ public String print(String level)
+ {
+ String st = level + operation + ":" + operationString(operation) + "(\n";
+
+ String nextLevel = level + " ";
+
+ if (oper1 == null)
+ st += nextLevel + "null\n";
+ else if (oper1 instanceof Operator)
+ st += ((Operator) oper1).print( nextLevel );
+ else
+ st += nextLevel + oper1.toString() + "\n";
+
+ if (oper2 != null)
+ {
+ if (oper2 instanceof Operator)
+ st += ((Operator) oper2).print(nextLevel);
+ else
+ st += nextLevel + oper2.toString() + "\n";
+ }
+
+ if (oper3 != null)
+ {
+ if (oper3 instanceof Operator)
+ st += ((Operator) oper3).print(nextLevel);
+ else
+ st += nextLevel + oper3.toString() + "\n";
+ }
+
+ st += level + ")\n";
+
+ return st;
+ }
+
+
+ //Operator 20
+ Object is_null() throws Exception
+ {
+ computeArgument1();
+ if (arg1 == null)
+ return Boolean.TRUE;
+ else
+ return Boolean.FALSE;
+ }
+
+ //Operator 21
+ Object is_not_null() throws Exception
+ {
+ computeArgument1();
+ if (arg1 != null)
+ return Boolean.TRUE;
+ else
+ return Boolean.FALSE;
+ }
+
+ //Operation 0
+ Object equal() throws Exception
+ {
+ computeArgument1();
+ if (arg1 == null)
+ return Boolean.FALSE;
+
+ switch (class1)
+ {
+ case LONG:
+ computeArgument1();
+ if (arg1 == null)
+ return null;
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 == LONG)
+ return Primitives.valueOf(((Number) arg1).longValue() == ((Number) arg2).longValue());
+ if (class2 == DOUBLE)
+ return Primitives.valueOf(((Number) arg1).longValue() == ((Number) arg2).doubleValue());
+ return Boolean.FALSE;
+ case DOUBLE:
+ computeArgument1();
+ if (arg1 == null)
+ return null;
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 == LONG)
+ return Primitives.valueOf(((Number) arg1).doubleValue() == ((Number) arg2).longValue());
+ if (class2 == DOUBLE)
+ return Primitives.valueOf(((Number) arg1).doubleValue() == ((Number) arg2).doubleValue());
+ return Boolean.FALSE;
+ case STRING:
+ case BOOLEAN:
+ computeArgument2();
+ if (arg2 == null)
+ return Boolean.FALSE;
+ if (class2 != class1)
+ throwBadObjectException(class1, class2);
+ return Primitives.valueOf(arg1.equals(arg2));
+ default:
+ throwBadObjectException(class1);
+ return null;
+ }
+
+ }
+
+ //Operation 1
+ Object not() throws Exception
+ {
+ computeArgument1();
+ if (arg1 == null)
+ return null;
+ if (class1 != BOOLEAN)
+ throwBadObjectException(class1);
+ if (((Boolean)arg1).booleanValue())
+ return Boolean.FALSE;
+ else
+ return Boolean.TRUE;
+ }
+
+ //Operation 2
+ Object and() throws Exception
+ {
+ computeArgument1();
+ if (arg1 == null)
+ {
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 != BOOLEAN)
+ throwBadObjectException(class2);
+ if (((Boolean) arg2).booleanValue() == false )
+ return Boolean.FALSE;
+ return null;
+ }
+
+ if (class1 == BOOLEAN)
+ {
+ if (((Boolean) arg1).booleanValue() == false)
+ return Boolean.FALSE;
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 != BOOLEAN)
+ throwBadObjectException(class2);
+ return arg2;
+ }
+
+ throwBadObjectException(class1);
+ return null;
+ }
+
+ /**
+ * Operation 3
+ *
+ * | OR | T | F | U
+ * +------+-------+-------+--------
+ * | T | T | T | T
+ * | F | T | F | U
+ * | U | T | U | U
+ * +------+-------+-------+-------
+ */
+ Object or() throws Exception
+ {
+ short falseCounter=0;
+
+ computeArgument1();
+ if (arg1 != null)
+ {
+ if (class1 != BOOLEAN)
+ throwBadObjectException(class1);
+ if (((Boolean) arg1).booleanValue())
+ return Boolean.TRUE;
+ else
+ falseCounter++;
+ }
+
+ computeArgument2();
+ if (arg2 != null)
+ {
+ if (class2 != BOOLEAN)
+ throwBadObjectException(class2);
+ if (((Boolean)arg2).booleanValue())
+ return Boolean.TRUE;
+ else
+ falseCounter++;
+ }
+
+ if (falseCounter == 2)
+ return Boolean.FALSE;
+
+ return null;
+ }
+
+ //Operation 4
+ Object gt() throws Exception
+ {
+ computeArgument1();
+ if (arg1 == null)
+ return null;
+
+ if (class1 == LONG)
+ {
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 == LONG)
+ return Primitives.valueOf(((Number) arg1).longValue() > ((Number) arg2).longValue());
+ if (class2 == DOUBLE)
+ return Primitives.valueOf(((Number) arg1).longValue() > ((Number) arg2).doubleValue());
+ }
+ else if ( class1 == DOUBLE )
+ {
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 == LONG)
+ return Primitives.valueOf(((Number) arg1).doubleValue() > ((Number) arg2).longValue());
+ if (class2 == DOUBLE)
+ return Primitives.valueOf(((Number) arg1).doubleValue() > ((Number) arg2).doubleValue());
+ return Boolean.FALSE;
+ }
+ return Boolean.FALSE;
+ }
+
+ //Operation 5
+ Object ge() throws Exception
+ {
+ computeArgument1();
+ if (arg1 == null)
+ return null;
+
+ if (class1 == LONG)
+ {
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 == LONG)
+ return Primitives.valueOf(((Number) arg1).longValue() >= ((Number) arg2).longValue());
+ if (class2 == DOUBLE)
+ return Primitives.valueOf(((Number) arg1).longValue() >= ((Number) arg2).doubleValue());
+ }
+ else if ( class1 == DOUBLE )
+ {
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 == LONG)
+ return Primitives.valueOf(((Number) arg1).longValue() >= ((Number) arg2).longValue());
+ if (class2 == DOUBLE)
+ return Primitives.valueOf(((Number) arg1).doubleValue() >= ((Number) arg2).doubleValue());
+ return Boolean.FALSE;
+ }
+ return Boolean.FALSE;
+ }
+
+ //Operation 6
+ Object lt() throws Exception
+ {
+ computeArgument1();
+ if (arg1 == null)
+ return null;
+
+ if (class1 == LONG)
+ {
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 == LONG)
+ return Primitives.valueOf(((Number) arg1).longValue() < ((Number) arg2).longValue());
+ if (class2 == DOUBLE)
+ return Primitives.valueOf(((Number) arg1).longValue() < ((Number) arg2).doubleValue());
+ }
+ else if (class1 == DOUBLE)
+ {
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 == LONG)
+ return Primitives.valueOf(((Number) arg1).doubleValue() < ((Number) arg2).longValue());
+ if (class2 == DOUBLE)
+ return Primitives.valueOf(((Number) arg1).doubleValue() < ((Number) arg2).doubleValue());
+ }
+
+ return Boolean.FALSE;
+ }
+
+ //Operation 7
+ Object le() throws Exception
+ {
+ computeArgument1();
+ if (arg1 == null)
+ return null;
+
+ if (class1 == LONG)
+ {
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 == LONG)
+ return Primitives.valueOf(((Number) arg1).longValue() <= ((Number) arg2).longValue());
+ if (class2 == DOUBLE)
+ return Primitives.valueOf(((Number) arg1).longValue() <= ((Number) arg2).doubleValue());
+ }
+ else if (class1 == DOUBLE)
+ {
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 == LONG)
+ return Primitives.valueOf(((Number) arg1).doubleValue() <= ((Number) arg2).longValue());
+ if (class2 == DOUBLE)
+ return Primitives.valueOf(((Number) arg1).doubleValue() <= ((Number) arg2).doubleValue());
+ }
+ return Boolean.FALSE;
+ }
+
+ //Operation 8
+ Object different() throws Exception
+ {
+ computeArgument1();
+ if ( arg1 == null )
+ return Boolean.FALSE;
+
+ switch (class1)
+ {
+ case LONG:
+ computeArgument1();
+ if (arg1 == null)
+ return null;
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 == LONG)
+ return Primitives.valueOf(((Number) arg1).longValue() != ((Number) arg2).longValue());
+ if (class2 == DOUBLE)
+ return Primitives.valueOf(((Number) arg1).longValue() != ((Number) arg2).doubleValue());
+ return Boolean.FALSE;
+ case DOUBLE:
+ computeArgument1();
+ if (arg1 == null)
+ return null;
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 == LONG)
+ return Primitives.valueOf(((Number) arg1).doubleValue() != ((Number) arg2).longValue());
+ if (class2 == DOUBLE)
+ return Primitives.valueOf(((Number) arg1).doubleValue() != ((Number) arg2).doubleValue());
+ return Boolean.FALSE;
+ case STRING:
+ case BOOLEAN:
+ computeArgument2();
+ if (arg2 == null)
+ return Boolean.FALSE;
+ if (class2 != class1)
+ throwBadObjectException(class1, class2);
+ return Primitives.valueOf(arg1.equals(arg2) == false);
+ default:
+ throwBadObjectException(class1);
+ }
+ return null;
+ }
+
+ //Operator 9
+ Object add() throws Exception
+ {
+ computeArgument1();
+ computeArgument2();
+
+ if (arg1 == null || arg2 == null)
+ return null;
+ switch (class1)
+ {
+ case DOUBLE:
+ switch (class2)
+ {
+ case DOUBLE:
+ return new Double(((Number) arg1).doubleValue() + ((Number) arg2).doubleValue());
+ case LONG:
+ return new Double(((Number) arg1).doubleValue() + ((Number) arg2).doubleValue());
+ default:
+ throwBadObjectException(class2);
+ }
+ case LONG:
+ switch (class2)
+ {
+ case DOUBLE:
+ return new Double(((Number) arg1).doubleValue() + ((Number) arg2).doubleValue());
+ case LONG:
+ return new Long(((Number) arg1).longValue() + ((Number) arg2).longValue());
+ default:
+ throwBadObjectException(class2);
+ }
+ default:
+ throwBadObjectException(class1);
+ }
+ return null;
+ }
+
+ //Operator 10
+ Object sub() throws Exception
+ {
+ computeArgument1();
+ computeArgument2();
+
+ if (arg1 == null || arg2 == null)
+ return null;
+ switch (class1)
+ {
+ case DOUBLE:
+ switch (class2)
+ {
+ case DOUBLE:
+ return new Double(((Number) arg1).doubleValue() - ((Number) arg2).doubleValue());
+ case LONG:
+ return new Double(((Number) arg1).doubleValue() - ((Number) arg2).doubleValue());
+ default:
+ throwBadObjectException(class2);
+ }
+ case LONG:
+ switch (class2)
+ {
+ case DOUBLE:
+ return new Double(((Number) arg1).doubleValue() - ((Number) arg2).doubleValue());
+ case LONG:
+ return new Long(((Number) arg1).longValue() - ((Number) arg2).longValue());
+ default:
+ throwBadObjectException(class2);
+ }
+ default:
+ throwBadObjectException(class1);
+ }
+ return null;
+ }
+
+ //Operator 11
+ Object neg() throws Exception
+ {
+ computeArgument1();
+ if (arg1 == null)
+ return null;
+ switch (class1)
+ {
+ case DOUBLE:
+ return new Double(-((Number) arg1).doubleValue());
+ case LONG:
+ return new Long(-((Number)arg1).longValue());
+ default:
+ throwBadObjectException(class1);
+ }
+ return null;
+ }
+
+ //Operator 12
+ Object mul() throws Exception
+ {
+ computeArgument1();
+ computeArgument2();
+ if (arg1 == null || arg2 == null)
+ return null;
+ switch (class1)
+ {
+ case DOUBLE:
+ switch (class2)
+ {
+ case DOUBLE:
+ return new Double(((Number) arg1).doubleValue() * ((Number) arg2).doubleValue());
+ case LONG:
+ return new Double(((Number) arg1).doubleValue() * ((Number) arg2).doubleValue());
+ default:
+ throwBadObjectException(class2);
+ }
+ case LONG:
+ switch (class2)
+ {
+ case DOUBLE:
+ return new Double(((Number) arg1).doubleValue() * ((Number) arg2).doubleValue());
+ case LONG:
+ return new Long(((Number) arg1).longValue() * ((Number) arg2).longValue());
+ default:
+ throwBadObjectException(class2);
+ }
+ default:
+ throwBadObjectException(class1);
+ }
+ return null;
+ }
+
+ //Operator 13
+ Object div() throws Exception
+ {
+ //Can throw Divide by zero exception...
+ computeArgument1();
+ computeArgument2();
+ if (arg1 == null || arg2 == null)
+ return null;
+ switch (class1)
+ {
+ case DOUBLE:
+ switch (class2)
+ {
+ case DOUBLE:
+ return new Double(((Number) arg1).doubleValue() / ((Number) arg2).doubleValue());
+ case LONG:
+ return new Double(((Number) arg1).doubleValue() / ((Number) arg2).doubleValue());
+ default:
+ throwBadObjectException(class2);
+ }
+ case LONG:
+ switch (class2)
+ {
+ case DOUBLE:
+ return new Double(((Number) arg1).doubleValue() / ((Number) arg2).doubleValue());
+ case LONG:
+ return new Long(((Number) arg1).longValue() / ((Number) arg2).longValue());
+ default:
+ throwBadObjectException(class2);
+ }
+ default:
+ throwBadObjectException(class1);
+ }
+ return null;
+ }
+
+ //Operator 14
+ Object between() throws Exception
+ {
+ Object res = ge();
+ if (res == null)
+ return null;
+ if (((Boolean) res).booleanValue() == false)
+ return res;
+
+ Object oper4 = oper2;
+ oper2 = oper3;
+ res = le();
+ oper2 = oper4;
+ return res;
+ }
+
+ //Operator 15
+ Object not_between() throws Exception
+ {
+ Object res = lt();
+ if (res == null)
+ return null;
+ if (((Boolean) res).booleanValue())
+ return res;
+
+ Object oper4 = oper2;
+ oper2 = oper3;
+ res = gt();
+ oper2 = oper4;
+ return res;
+ }
+
+ //Operation 16,17,18,19
+ /**
+ * Handle LIKE, NOT LIKE, LIKE ESCAPE, and NOT LIKE ESCAPE operators.
+ *
+ * @param not true if this is a NOT LIKE construct, false if this
+ * is a LIKE construct.
+ * @param use_escape true if this is a LIKE ESCAPE construct, false if
+ * there is no ESCAPE clause
+ * @return Description of the Returned Value
+ * @exception Exception Description of Exception
+ */
+ Object like(boolean not, boolean use_escape) throws Exception
+ {
+ Character escapeChar = null;
+
+ computeArgument1();
+ if (arg1 == null)
+ return null;
+ if (class1 != STRING)
+ throwBadObjectException(class1);
+
+ computeArgument2();
+ if (arg2 == null)
+ return null;
+ if (class2 != STRING)
+ throwBadObjectException(class2);
+
+ if (use_escape)
+ {
+ computeArgument3();
+ if (arg3 == null)
+ return null;
+
+ if (class3 != STRING)
+ throwBadObjectException(class3);
+
+ StringBuffer escapeBuf = new StringBuffer((String) arg3);
+ if (escapeBuf.length() != 1)
+ throw new Exception("LIKE ESCAPE: Bad escape character " + escapeBuf.toString());
+
+ escapeChar = new Character(escapeBuf.charAt(0));
+ }
+
+ if (re == null)
+ // the first time through we prepare the regular expression
+ re = new RegExp ((String) arg2, escapeChar);
+
+ boolean result = re.isMatch (arg1);
+ if (not)
+ result = !result;
+
+ if (result == true)
+ return Boolean.TRUE;
+ else
+ return Boolean.FALSE;
+ }
+
+ //Operator 22
+ Object in() throws Exception
+ {
+ computeArgument1();
+ if (arg1 == null)
+ return null;
+ if (((HashSet) oper2).contains(arg1))
+ return Boolean.TRUE;
+ else
+ return Boolean.FALSE;
+ }
+
+ //Operator 23
+ Object not_in() throws Exception
+ {
+ computeArgument1();
+ if (arg1 == null)
+ return null;
+ if (class1 != STRING)
+ throwBadObjectException(class1);
+ if (((HashSet) oper2).contains(arg1))
+ return Boolean.FALSE;
+ else
+ return Boolean.TRUE;
+ }
+
+
+ void computeArgument1() throws Exception
+ {
+ Class className = oper1.getClass();
+
+ if (className == Identifier.class)
+ arg1 = ((Identifier) oper1).value;
+ else if (className == Operator.class)
+ arg1 = ((Operator) oper1).apply();
+ else
+ arg1 = oper1;
+
+ if (arg1 == null)
+ {
+ class1 = 0;
+ return;
+ }
+
+ className = arg1.getClass();
+
+ if (className == String.class)
+ class1 = STRING;
+ else if (className == Double.class)
+ class1 = DOUBLE;
+ else if (className == Long.class)
+ class1 = LONG;
+ else if (className == Integer.class)
+ {
+ class1 = LONG;
+ arg1 = new Long(((Integer) arg1).longValue());
+ }
+ else if (className == Short.class)
+ {
+ class1 = LONG;
+ arg1 = new Long(((Short) arg1).longValue());
+ }
+ else if (className == Byte.class)
+ {
+ class1 = LONG;
+ arg1 = new Long(((Byte) arg1).longValue());
+ }
+ else if (className == Float.class)
+ {
+ class1 = DOUBLE;
+ arg1 = new Double(((Float) arg1).doubleValue());
+ }
+ else if (className == Boolean.class)
+ class1 = BOOLEAN;
+ else
+ throwBadObjectException(className);
+ }
+
+ void computeArgument2() throws Exception
+ {
+ Class className = oper2.getClass();
+
+ if (className == Identifier.class)
+ arg2 = ((Identifier) oper2).value;
+ else if (className == Operator.class)
+ arg2 = ((Operator) oper2).apply();
+ else
+ arg2 = oper2;
+
+ if (arg2 == null)
+ {
+ class2 = 0;
+ return;
+ }
+
+ className = arg2.getClass();
+
+ if (className == String.class)
+ class2 = STRING;
+ else if (className == Double.class)
+ class2 = DOUBLE;
+ else if (className == Long.class)
+ class2 = LONG;
+ else if (className == Integer.class)
+ {
+ class2 = LONG;
+ arg2 = new Long(((Integer) arg2).longValue());
+ }
+ else if (className == Short.class)
+ {
+ class2 = LONG;
+ arg2 = new Long(((Short) arg2).longValue());
+ }
+ else if (className == Byte.class)
+ {
+ class2 = LONG;
+ arg2 = new Long(((Byte) arg2).longValue());
+ }
+ else if (className == Float.class)
+ {
+ class2 = DOUBLE;
+ arg2 = new Double(((Float) arg2).doubleValue());
+ }
+ else if (className == Boolean.class)
+ class2 = BOOLEAN;
+ else
+ throwBadObjectException(className);
+ }
+
+ void computeArgument3() throws Exception
+ {
+ Class className = oper3.getClass();
+
+ if (className == Identifier.class)
+ arg3 = ((Identifier) oper3).value;
+ else if (className == Operator.class)
+ arg3 = ((Operator ) oper3).apply();
+ else
+ arg3 = oper3;
+
+ if (arg3 == null)
+ {
+ class3 = 0;
+ return;
+ }
+
+ className = arg3.getClass();
+
+ if (className == String.class)
+ class3 = STRING;
+ else if (className == Double.class)
+ class3 = DOUBLE;
+ else if (className == Long.class)
+ class3 = LONG;
+ else if (className == Integer.class)
+ {
+ class3 = LONG;
+ arg3 = new Long(((Integer) arg3).longValue());
+ }
+ else if (className == Short.class)
+ {
+ class3 = LONG;
+ arg3 = new Long(((Short) arg3).longValue());
+ }
+ else if (className == Byte.class)
+ {
+ class3 = LONG;
+ arg3 = new Long(((Byte) arg3).longValue());
+ }
+ else if (className == Float.class)
+ {
+ class3 = DOUBLE;
+ arg3 = new Double(((Float) arg3).doubleValue());
+ }
+ else if (className == Boolean.class)
+ class3 = BOOLEAN;
+ else
+ throwBadObjectException(className);
+ }
+
+ public Object apply() throws Exception
+ {
+ switch (operation)
+ {
+ case EQUAL:
+ return equal();
+ case NOT:
+ return not();
+ case AND:
+ return and();
+ case OR:
+ return or();
+ case GT:
+ return gt();
+ case GE:
+ return ge();
+ case LT:
+ return lt();
+ case LE:
+ return le();
+ case DIFFERENT:
+ return different();
+ case ADD:
+ return add();
+ case SUB:
+ return sub();
+ case NEG:
+ return neg();
+ case MUL:
+ return mul();
+ case DIV:
+ return div();
+ case BETWEEN:
+ return between();
+ case NOT_BETWEEN:
+ return not_between();
+ case LIKE:
+ return like(false, false);
+ case NOT_LIKE:
+ return like(true, false);
+ case LIKE_ESCAPE:
+ return like(false, true);
+ case NOT_LIKE_ESCAPE:
+ return like(true, true);
+ case IS_NULL:
+ return is_null();
+ case IS_NOT_NULL:
+ return is_not_null();
+ case IN:
+ return in();
+ case NOT_IN:
+ return not_in();
+ }
+
+ throw new Exception("Unknown operation: " + toString());
+ }
+
+ public void throwBadObjectException(Class class1) throws Exception
+ {
+ throw new Exception("Bad Object: '" + class1.getName() + "' for operation: " + toString());
+ }
+
+ public void throwBadObjectException(int class1) throws Exception
+ {
+ throw new Exception("Bad Object: '" + getClassName(class1) + "' for operation: " + toString());
+ }
+
+ public void throwBadObjectException(int class1, int class2) throws Exception
+ {
+ throw new Exception("Bad Object: expected '" + getClassName(class1) + "' got '" + getClassName(class2) + "' for operation: " + toString());
+ }
+
+ static String getClassName(int class1)
+ {
+ String str = "Unknown";
+ switch (class1)
+ {
+ case STRING:
+ str = "String";
+ break;
+ case LONG:
+ str = "Long";
+ break;
+ case DOUBLE:
+ str = "Double";
+ break;
+ case BOOLEAN:
+ str = "Boolean";
+ break;
+ }
+ return str;
+ }
+
+ static String operationString(int operation)
+ {
+ String str = "Unknown";
+ switch( operation )
+ {
+ case EQUAL:
+ str = "EQUAL";
+ break;
+ case NOT:
+ str = "NOT";
+ break;
+ case AND:
+ str = "AND";
+ break;
+ case OR:
+ str = "OR";
+ break;
+ case GT:
+ str = "GT";
+ break;
+ case GE:
+ str = "GE";
+ break;
+ case LT:
+ str = "LT";
+ break;
+ case LE:
+ str = "LE";
+ break;
+ case DIFFERENT:
+ str = "DIFFERENT";
+ break;
+ case ADD:
+ str = "ADD";
+ break;
+ case SUB:
+ str = "SUB";
+ break;
+ case NEG:
+ str = "NEG";
+ break;
+ case MUL:
+ str = "MUL";
+ break;
+ case DIV:
+ str = "DIV";
+ break;
+ case BETWEEN:
+ str = "BETWEEN";
+ break;
+ case NOT_BETWEEN:
+ str = "NOT_BETWEEN";
+ break;
+ case LIKE:
+ str = "LIKE";
+ break;
+ case NOT_LIKE:
+ str = "NOT_LIKE";
+ break;
+ case LIKE_ESCAPE:
+ str = "LIKE_ESCAPE";
+ break;
+ case NOT_LIKE_ESCAPE:
+ str = "NOT_LIKE_ESCAPE";
+ break;
+ case IS_NULL:
+ str = "IS_NULL";
+ break;
+ case IS_NOT_NULL:
+ str = "IS_NOT_NULL";
+ break;
+ case IN:
+ str = "IN";
+ break;
+ case NOT_IN:
+ str = "NOT_IN";
+ break;
+ }
+ return str;
+ }
+}
+
Added: trunk/src/main/org/jboss/messaging/core/impl/filter/RegExp.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/filter/RegExp.java (rev 0)
+++ trunk/src/main/org/jboss/messaging/core/impl/filter/RegExp.java 2008-01-18 13:38:40 UTC (rev 3591)
@@ -0,0 +1,127 @@
+package org.jboss.messaging.core.impl.filter;
+
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+
+import java.util.regex.Pattern;
+
+/**
+ * Regular expressions to support the selector LIKE operator.
+ *
+ * @version <tt>$Revision: 2681 $</tt>
+ *
+ * @author Norbert Lataille (Norbert.Lataille at m4x.org)
+ * @author droy at boostmyscore.com
+ * @author Scott.Stark at jboss.org
+ * @author Loren Rosen
+ *
+ * $Id: RegExp.java 2681 2007-05-15 00:09:10Z timfox $
+ */
+public class RegExp
+{
+ protected Pattern re;
+
+ public RegExp (String pattern, Character escapeChar)
+ throws Exception
+ {
+ String pat = adjustPattern(pattern, escapeChar);
+ re = Pattern.compile(pat);
+ }
+
+ public boolean isMatch (Object target)
+ {
+ String str = target != null ? target.toString() : "";
+ return re.matcher(str).matches();
+ }
+
+ protected String adjustPattern (String pattern, Character escapeChar)
+ throws Exception
+ {
+ int patternLen = pattern.length();
+ StringBuffer REpattern = new StringBuffer(patternLen + 10);
+ boolean useEscape = (escapeChar != null);
+ char escape = Character.UNASSIGNED;
+ if (useEscape) {
+ escape = escapeChar.charValue();
+ }
+
+ REpattern.append ('^');
+
+ for ( int i = 0; i < patternLen; i++ ) {
+ boolean escaped = false;
+ char c = pattern.charAt( i );
+
+ if ( useEscape && escape == c ) {
+ i++;
+ if ( i < patternLen ) {
+ escaped = true;
+ c = pattern.charAt( i );
+ } else {
+ throw new Exception( "LIKE ESCAPE: Bad use of escape character" );
+ }
+ }
+
+ // Match characters, or escape ones special to the underlying
+ // regex engine
+ switch ( c ) {
+ case '_':
+ if ( escaped ) {
+ REpattern.append( c );
+ } else {
+ REpattern.append( '.' );
+ }
+ break;
+ case '%':
+ if ( escaped ) {
+ REpattern.append( c );
+ } else {
+ REpattern.append( ".*" );
+ }
+ break;
+ case '*':
+ case '.':
+ case '\\':
+ case '^':
+ case '$':
+ case '[':
+ case ']':
+ case '(':
+ case ')':
+ case '+':
+ case '?':
+ case '{':
+ case '}':
+ case '|':
+ REpattern.append( "\\");
+ REpattern.append ( c );
+ break;
+ default:
+ REpattern.append( c );
+ break;
+ }
+ }
+
+ REpattern.append( '$' );
+ return REpattern.toString();
+ }
+}
+
More information about the jboss-cvs-commits
mailing list