[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