User: norbert
Date: 00/12/29 11:32:46
Modified: src/java/org/spydermq/selectors Operator.java Selector.java
jms.y
Log:
The Operators class seems complete, but needs more tests.
Thanks [EMAIL PROTECTED] for the LIKE operators.
Revision Changes Path
1.4 +407 -54 spyderMQ/src/java/org/spydermq/selectors/Operator.java
Index: Operator.java
===================================================================
RCS file:
/products/cvs/ejboss/spyderMQ/src/java/org/spydermq/selectors/Operator.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Operator.java 2000/12/06 00:58:27 1.3
+++ Operator.java 2000/12/29 19:32:45 1.4
@@ -6,12 +6,15 @@
*/
package org.spydermq.selectors;
+import java.util.HashSet;
+
/**
* An operator for the selector system
*
* @author Norbert Lataille ([EMAIL PROTECTED])
+ * @author [EMAIL PROTECTED]
*
- * @version $Revision: 1.3 $
+ * @version $Revision: 1.4 $
*/
public class Operator
{
@@ -22,34 +25,36 @@
Object arg1;
Object arg2;
+ Object arg3;
int class1;
int class2;
-
- public final static int EQUAL = 0; //String Long
+ int class3;
+
+ public final static int EQUAL = 0; //Done
public final static int NOT = 1; //Done
public final static int AND = 2; //Done
public final static int OR = 3; //Done
- public final static int GT = 4; //Long
- public final static int GE = 5; //Long
- public final static int LT = 6; //Long
- public final static int LE = 7; //Long
- public final static int DIFFERENT = 8; //String Long
- 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 GT = 4; //Done
+ public final static int GE = 5; //Done
+ public final static int LT = 6; //Done
+ public final static int LE = 7; //Done
+ public final static int DIFFERENT = 8; //Done
+ public final static int ADD = 9; //Done
+ public final static int SUB = 10;//Done
+ public final static int NEG = 11;//Done
+ public final static int MUL = 12;//Done
+ public final static int DIV = 13;//Done
+ public final static int BETWEEN = 14;//Done
+ public final static int NOT_BETWEEN = 15;//Done
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 IS_NULL = 20; //Done
+ public final static int IS_NOT_NULL = 21; //Done
+ public final static int IN = 22; //Done
+ public final static int NOT_IN = 23; //Done
public final static int STRING = 0;
public final static int DOUBLE = 1;
@@ -89,17 +94,14 @@
switch (class1) {
case STRING:
- computeArgument2();
- if (arg2==null) return Boolean.FALSE;
- if (class2!=STRING) throw new Exception("EQUAL: Bad
object type");
- return new Boolean(arg1.equals(arg2));
case LONG:
- computeArgument2();
- if (arg2==null) return Boolean.FALSE;
- if (class2!=LONG) throw new Exception("EQUAL: Bad
object type");
- return new Boolean(arg1.equals(arg2));
- default:
- throw new Exception("EQUAL: Bad object type");
+ case DOUBLE:
+ computeArgument2();
+ if (arg2==null) return Boolean.FALSE;
+ if (class2!=class1) throw new Exception("EQUAL: Bad object
type");
+ return new Boolean(arg1.equals(arg2));
+ default:
+ throw new Exception("EQUAL: Bad object type");
}
}
@@ -174,7 +176,12 @@
if (arg2==null) return Boolean.FALSE;
if (class2!=LONG) throw new Exception("GT: Bad object type");
return new Boolean(((Long)arg1).longValue() >
((Long)arg2).longValue());
- }
+ } else if (class1==DOUBLE) {
+ computeArgument2();
+ if (arg2==null) return Boolean.FALSE;
+ if (class2!=DOUBLE) throw new Exception("GT: Bad object type");
+ return new Boolean(((Double)arg1).doubleValue() >
((Double)arg2).doubleValue());
+ }
throw new Exception("GT: Bad object type");
}
@@ -182,7 +189,7 @@
//Operation 5
Object ge() throws Exception
{
- computeArgument1();
+ computeArgument1();
if (arg1==null) return Boolean.FALSE;
if (class1==LONG) {
@@ -190,7 +197,12 @@
if (arg2==null) return Boolean.FALSE;
if (class2!=LONG) throw new Exception("GE: Bad object type");
return new Boolean(((Long)arg1).longValue() >=
((Long)arg2).longValue());
- }
+ } else if (class1==DOUBLE) {
+ computeArgument2();
+ if (arg2==null) return Boolean.FALSE;
+ if (class2!=DOUBLE) throw new Exception("GE: Bad object type");
+ return new Boolean(((Double)arg1).doubleValue() >=
((Double)arg2).doubleValue());
+ }
throw new Exception("GE: Bad object type");
}
@@ -206,7 +218,12 @@
if (arg2==null) return Boolean.FALSE;
if (class2!=LONG) throw new Exception("LT: Bad object type");
return new Boolean(((Long)arg1).longValue() <
((Long)arg2).longValue());
- }
+ } else if (class1==DOUBLE) {
+ computeArgument2();
+ if (arg2==null) return Boolean.FALSE;
+ if (class2!=DOUBLE) throw new Exception("LT: Bad object type");
+ return new Boolean(((Double)arg1).doubleValue() <
((Double)arg2).doubleValue());
+ }
throw new Exception("LT: Bad object type");
}
@@ -222,7 +239,13 @@
if (arg2==null) return Boolean.FALSE;
if (class2!=LONG) throw new Exception("LE: Bad object type");
return new Boolean(((Long)arg1).longValue() <=
((Long)arg2).longValue());
- }
+ } else if (class1==DOUBLE) {
+ computeArgument2();
+ if (arg2==null) return Boolean.FALSE;
+ if (class2!=DOUBLE) throw new Exception("LE: Bad object type");
+ return new Boolean(((Double)arg1).doubleValue() <=
((Double)arg2).doubleValue());
+ }
+
throw new Exception("LE: Bad object type");
}
@@ -235,21 +258,306 @@
if (arg1==null) return Boolean.FALSE;
switch (class1) {
+ case DOUBLE:
case STRING:
- computeArgument2();
- if (arg2==null) return Boolean.FALSE;
- if (class2!=STRING) throw new Exception("DIFFERENT:
Bad object type");
- return new Boolean(!arg1.equals(arg2));
case LONG:
computeArgument2();
if (arg2==null) return Boolean.FALSE;
- if (class2!=LONG) throw new Exception("DIFFERENT: Bad
object type");
+ if (class2!=class1) throw new Exception("DIFFERENT:
Bad object type");
return new Boolean(!arg1.equals(arg2));
default:
throw new Exception("DIFFERENT: Bad object type");
}
}
+ //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(((Double)arg1).doubleValue()+((Double)arg2).doubleValue());
+ case LONG: return new
Double(((Double)arg1).doubleValue()+((Long)arg2).doubleValue());
+ default: throw new Exception("ADD: Bad object type");
+ }
+ case LONG:
+ switch (class2) {
+ case DOUBLE: return new
Double(((Long)arg1).doubleValue()+((Double)arg2).doubleValue());
+ case LONG: return new
Long(((Long)arg1).longValue()+((Long)arg2).longValue());
+ default: throw new Exception("ADD: Bad object type");
+ }
+ default:
+ throw new Exception("ADD: Bad object type");
+ }
+ }
+
+ //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(((Double)arg1).doubleValue()-((Double)arg2).doubleValue());
+ case LONG: return new
Double(((Double)arg1).doubleValue()-((Long)arg2).doubleValue());
+ default: throw new Exception("SUB: Bad object type");
+ }
+ case LONG:
+ switch (class2) {
+ case DOUBLE: return new
Double(((Long)arg1).doubleValue()-((Double)arg2).doubleValue());
+ case LONG: return new
Long(((Long)arg1).longValue()-((Long)arg2).longValue());
+ default: throw new Exception("SUB: Bad object type");
+ }
+ default:
+ throw new Exception("SUB: Bad object type");
+ }
+ }
+
+ //Operator 11
+ Object neg() throws Exception
+ {
+ computeArgument1();
+
+ if (arg1==null) return null;
+ switch (class1) {
+ case DOUBLE: return new Double(-((Double)arg1).doubleValue());
+ case LONG: return new Long(-((Long)arg1).longValue());
+ default:
+ throw new Exception("NEG: Bad object type");
+ }
+ }
+
+ //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(((Double)arg1).doubleValue()*((Double)arg2).doubleValue());
+ case LONG: return new
Double(((Double)arg1).doubleValue()*((Long)arg2).doubleValue());
+ default: throw new Exception("MUL: Bad object type");
+ }
+ case LONG:
+ switch (class2) {
+ case DOUBLE: return new
Double(((Long)arg1).doubleValue()*((Double)arg2).doubleValue());
+ case LONG: return new
Long(((Long)arg1).longValue()*((Long)arg2).longValue());
+ default: throw new Exception("MUL: Bad object type");
+ }
+ default:
+ throw new Exception("MUL: Bad object type");
+ }
+ }
+
+ //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(((Double)arg1).doubleValue()/((Double)arg2).doubleValue());
+ case LONG: return new
Double(((Double)arg1).doubleValue()/((Long)arg2).doubleValue());
+ default: throw new Exception("DIV: Bad object type");
+ }
+ case LONG:
+ switch (class2) {
+ case DOUBLE: return new
Double(((Long)arg1).doubleValue()/((Double)arg2).doubleValue());
+ case LONG: return new
Long(((Long)arg1).longValue()/((Long)arg2).longValue());
+ default: throw new Exception("DIV: Bad object type");
+ }
+ default:
+ throw new Exception("DIV: Bad object type");
+ }
+ }
+
+ //Operator 14
+ Object between() throws Exception
+ {
+ computeArgument1();
+ computeArgument2();
+ computeArgument3();
+
+ Object res=ge();
+ if (res==null) return null;
+ if ((Boolean)res==Boolean.FALSE) return res;
+
+ arg2=arg3;
+ class2=class3;
+ return le();
+ }
+
+
+ //Operator 15
+ Object not_between() throws Exception
+ {
+ computeArgument1();
+ computeArgument2();
+ computeArgument3();
+
+ Object res=lt();
+ if (res==null) return null;
+ if ((Boolean)res==Boolean.TRUE) return res;
+
+ arg2=arg3;
+ class2=class3;
+ return gt();
+ }
+
+ //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
+ */
+ Object like(boolean not, boolean use_escape) throws Exception
+ {
+ Character escapeChar = null;
+
+ computeArgument1();
+ if (arg1 == null) return null;
+ if (class1 != STRING) throw new Exception("LIKE: Bad object type");
+
+ computeArgument2();
+ if (arg2 == null) return null;
+ if (class2 != STRING) throw new Exception("LIKE: Bad object type");
+
+ if (use_escape) {
+ computeArgument3();
+ if (arg3 == null) return null;
+
+ if (class3 != STRING) throw new Exception("LIKE: Bad object
type");
+
+ StringBuffer escapeBuf = new StringBuffer ((String)arg3);
+ if (escapeBuf.length () != 1) {
+ throw new Exception ("LIKE ESCAPE: Bad escape
character");
+ }
+
+ escapeChar = new Character (escapeBuf.charAt(0));
+ }
+
+ StringBuffer patternBuf = new StringBuffer((String)arg2);
+ StringBuffer REpattern = new StringBuffer ("^");
+
+ for (int i = 0; i < patternBuf.length (); i++) {
+ boolean escaped = false;
+ char c = patternBuf.charAt (i);
+
+ if (use_escape && escapeChar != null && escapeChar.charValue
() == c) {
+ if (i + 1 < patternBuf.length ()) {
+ escaped = true;
+ i++;
+ c = patternBuf.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 ("\\" + c);
+ break;
+ default:
+ REpattern.append (c);
+ break;
+ }
+ }
+
+ REpattern.append ('$');
+
+ // Parse the regex
+ gnu.regexp.RE re = new gnu.regexp.RE (REpattern,
0,gnu.regexp.RESyntax.RE_SYNTAX_POSIX_MINIMAL_BASIC);
+
+ boolean result = re.isMatch (arg1);
+ if (not) {
+ result = !result;
+ }
+
+ return new Boolean (result);
+ }
+
+
+ //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;
+ }
+
+ //Operator 22
+ Object in() throws Exception
+ {
+ computeArgument1();
+
+ if (arg1==null) return null;
+ if (((HashSet)arg2).contains(arg1)) return Boolean.TRUE;
+ else return Boolean.FALSE;
+ }
+
+ //Operator 23
+ Object not_in() throws Exception
+ {
+ computeArgument1();
+
+ if (((HashSet)arg2).contains(arg1)) return Boolean.FALSE;
+ else return Boolean.TRUE;
+ }
+
+
void computeArgument1() throws Exception
{
Class className=oper1.getClass();
@@ -290,7 +598,7 @@
arg2=((Operator)oper2).apply();
} else arg2=oper2;
- if (arg1==null) {
+ if (arg2==null) {
class2=0;
return;
}
@@ -310,24 +618,69 @@
else throw new Exception("ARG2: Bad object type");
}
+ 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==Float.class) {
+ class3=DOUBLE;
+ arg3=new Double(((Float)arg3).doubleValue());
+ } else if (className==Boolean.class) class3=BOOLEAN;
+ else throw new Exception("ARG3: Bad object type");
+ }
+
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();
-
- }
+ 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");
+ throw new Exception("Unknown operation");
}
1.2 +9 -6 spyderMQ/src/java/org/spydermq/selectors/Selector.java
Index: Selector.java
===================================================================
RCS file:
/products/cvs/ejboss/spyderMQ/src/java/org/spydermq/selectors/Selector.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Selector.java 2000/05/31 18:10:19 1.1
+++ Selector.java 2000/12/29 19:32:45 1.2
@@ -17,13 +17,13 @@
*
* @author Norbert Lataille ([EMAIL PROTECTED])
*
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.2 $
*/
public class Selector
{
public HashMap identifiers; // HashMap of Identifiers
- public Object result;
+ public Object result;
public Selector(String sel) throws JMSException
{
@@ -38,7 +38,7 @@
throw exception;
}
- //Log.log(result.toString());
+ Log.notice(result.toString());
}
public boolean test(SpyMessage mes) throws JMSException
@@ -58,7 +58,9 @@
id.value=null;
} else {
Class type=find.getClass();
- if
(type.equals(Boolean.class)||type.equals(String.class)||type.equals(Double.class)||type.equals(Integer.class))
id.value=find;
+ if (type.equals(Boolean.class) ||
type.equals(String.class)
+ || type.equals(Double.class) ||
type.equals(Integer.class))
+ id.value=find;
else throw new Exception("Bad property type
!");
}
}
@@ -72,8 +74,9 @@
res=((Operator)result).apply();
} else res=result;
- if (res==null) throw new Exception("res==null");
- if (!(res.getClass().equals(Boolean.class))) throw new
Exception("Bad object type");
+ if (res==null) return false;
+ if (!(res.getClass().equals(Boolean.class)))
+ throw new Exception("Bad object type");
return ((Boolean)res).booleanValue();
1.2 +2 -0 spyderMQ/src/java/org/spydermq/selectors/jms.y
Index: jms.y
===================================================================
RCS file: /products/cvs/ejboss/spyderMQ/src/java/org/spydermq/selectors/jms.y,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- jms.y 2000/11/12 11:58:46 1.1
+++ jms.y 2000/12/29 19:32:45 1.2
@@ -1,3 +1,5 @@
+//NL: This file should be used with Byacc.
+
%{
package org.spydermq.selectors;