1 18 package org.apache.activemq.filter; 19 20 import java.util.HashSet ; 21 import java.util.List ; 22 import java.util.regex.Pattern ; 23 24 import javax.jms.JMSException ; 25 26 31 public abstract class ComparisonExpression extends BinaryExpression implements BooleanExpression { 32 33 public static BooleanExpression createBetween(Expression value, Expression left, Expression right) { 34 return LogicExpression.createAND(createGreaterThanEqual(value, left), createLessThanEqual(value, right)); 35 } 36 37 public static BooleanExpression createNotBetween(Expression value, Expression left, Expression right) { 38 return LogicExpression.createOR(createLessThan(value, left), createGreaterThan(value, right)); 39 } 40 41 static final private HashSet REGEXP_CONTROL_CHARS = new HashSet (); 42 43 static { 44 REGEXP_CONTROL_CHARS.add(new Character ('.')); 45 REGEXP_CONTROL_CHARS.add(new Character ('\\')); 46 REGEXP_CONTROL_CHARS.add(new Character ('[')); 47 REGEXP_CONTROL_CHARS.add(new Character (']')); 48 REGEXP_CONTROL_CHARS.add(new Character ('^')); 49 REGEXP_CONTROL_CHARS.add(new Character ('$')); 50 REGEXP_CONTROL_CHARS.add(new Character ('?')); 51 REGEXP_CONTROL_CHARS.add(new Character ('*')); 52 REGEXP_CONTROL_CHARS.add(new Character ('+')); 53 REGEXP_CONTROL_CHARS.add(new Character ('{')); 54 REGEXP_CONTROL_CHARS.add(new Character ('}')); 55 REGEXP_CONTROL_CHARS.add(new Character ('|')); 56 REGEXP_CONTROL_CHARS.add(new Character ('(')); 57 REGEXP_CONTROL_CHARS.add(new Character (')')); 58 REGEXP_CONTROL_CHARS.add(new Character (':')); 59 REGEXP_CONTROL_CHARS.add(new Character ('&')); 60 REGEXP_CONTROL_CHARS.add(new Character ('<')); 61 REGEXP_CONTROL_CHARS.add(new Character ('>')); 62 REGEXP_CONTROL_CHARS.add(new Character ('=')); 63 REGEXP_CONTROL_CHARS.add(new Character ('!')); 64 } 65 66 static class LikeExpression extends UnaryExpression implements BooleanExpression { 67 68 Pattern likePattern; 69 70 73 public LikeExpression(Expression right, String like, int escape) { 74 super(right); 75 76 StringBuffer regexp = new StringBuffer (like.length() * 2); 77 regexp.append("\\A"); for (int i = 0; i < like.length(); i++) { 79 char c = like.charAt(i); 80 if (escape == (0xFFFF & c)) { 81 i++; 82 if (i >= like.length()) { 83 break; 85 } 86 87 char t = like.charAt(i); 88 regexp.append("\\x"); 89 regexp.append(Integer.toHexString(0xFFFF & t)); 90 } 91 else if (c == '%') { 92 regexp.append(".*?"); } 94 else if (c == '_') { 95 regexp.append("."); } 97 else if (REGEXP_CONTROL_CHARS.contains(new Character (c))) { 98 regexp.append("\\x"); 99 regexp.append(Integer.toHexString(0xFFFF & c)); 100 } 101 else { 102 regexp.append(c); 103 } 104 } 105 regexp.append("\\z"); 107 likePattern = Pattern.compile(regexp.toString(), Pattern.DOTALL); 108 } 109 110 113 public String getExpressionSymbol() { 114 return "LIKE"; 115 } 116 117 120 public Object evaluate(MessageEvaluationContext message) throws JMSException { 121 122 Object rv = this.getRight().evaluate(message); 123 124 if (rv == null) { 125 return null; 126 } 127 128 if (!(rv instanceof String )) { 129 return Boolean.FALSE; 130 } 132 133 return likePattern.matcher((String ) rv).matches() ? Boolean.TRUE : Boolean.FALSE; 134 } 135 136 public boolean matches(MessageEvaluationContext message) throws JMSException { 137 Object object = evaluate(message); 138 return object!=null && object==Boolean.TRUE; 139 } 140 } 141 142 public static BooleanExpression createLike(Expression left, String right, String escape) { 143 if (escape != null && escape.length() != 1) { 144 throw new RuntimeException ("The ESCAPE string litteral is invalid. It can only be one character. Litteral used: " + escape); 145 } 146 int c = -1; 147 if (escape != null) { 148 c = 0xFFFF & escape.charAt(0); 149 } 150 151 return new LikeExpression(left, right, c); 152 } 153 154 public static BooleanExpression createNotLike(Expression left, String right, String escape) { 155 return UnaryExpression.createNOT(createLike(left, right, escape)); 156 } 157 158 public static BooleanExpression createInFilter(Expression left, List elements) { 159 160 if( !(left instanceof PropertyExpression) ) 161 throw new RuntimeException ("Expected a property for In expression, got: "+left); 162 return UnaryExpression.createInExpression((PropertyExpression)left, elements, false); 163 164 } 165 166 public static BooleanExpression createNotInFilter(Expression left, List elements) { 167 168 if( !(left instanceof PropertyExpression) ) 169 throw new RuntimeException ("Expected a property for In expression, got: "+left); 170 return UnaryExpression.createInExpression((PropertyExpression)left, elements, true); 171 172 } 173 174 public static BooleanExpression createIsNull(Expression left) { 175 return doCreateEqual(left, ConstantExpression.NULL); 176 } 177 178 public static BooleanExpression createIsNotNull(Expression left) { 179 return UnaryExpression.createNOT(doCreateEqual(left, ConstantExpression.NULL)); 180 } 181 182 public static BooleanExpression createNotEqual(Expression left, Expression right) { 183 return UnaryExpression.createNOT(createEqual(left, right)); 184 } 185 186 public static BooleanExpression createEqual(Expression left, Expression right) { 187 checkEqualOperand(left); 188 checkEqualOperand(right); 189 checkEqualOperandCompatability(left, right); 190 return doCreateEqual(left, right); 191 } 192 193 private static BooleanExpression doCreateEqual(Expression left, Expression right) { 194 return new ComparisonExpression(left, right) { 195 196 public Object evaluate(MessageEvaluationContext message) throws JMSException { 197 Object lv = left.evaluate(message); 198 Object rv = right.evaluate(message); 199 200 if (lv == null ^ rv == null) { 202 return Boolean.FALSE; 203 } 204 if (lv == rv || lv.equals(rv)) { 205 return Boolean.TRUE; 206 } 207 if( lv instanceof Comparable && rv instanceof Comparable ) { 208 return compare((Comparable )lv, (Comparable )rv); 209 } 210 return Boolean.FALSE; 211 } 212 213 protected boolean asBoolean(int answer) { 214 return answer == 0; 215 } 216 217 public String getExpressionSymbol() { 218 return "="; 219 } 220 }; 221 } 222 223 public static BooleanExpression createGreaterThan(final Expression left, final Expression right) { 224 checkLessThanOperand(left); 225 checkLessThanOperand(right); 226 return new ComparisonExpression(left, right) { 227 protected boolean asBoolean(int answer) { 228 return answer > 0; 229 } 230 231 public String getExpressionSymbol() { 232 return ">"; 233 } 234 }; 235 } 236 237 public static BooleanExpression createGreaterThanEqual(final Expression left, final Expression right) { 238 checkLessThanOperand(left); 239 checkLessThanOperand(right); 240 return new ComparisonExpression(left, right) { 241 protected boolean asBoolean(int answer) { 242 return answer >= 0; 243 } 244 245 public String getExpressionSymbol() { 246 return ">="; 247 } 248 }; 249 } 250 251 public static BooleanExpression createLessThan(final Expression left, final Expression right) { 252 checkLessThanOperand(left); 253 checkLessThanOperand(right); 254 return new ComparisonExpression(left, right) { 255 256 protected boolean asBoolean(int answer) { 257 return answer < 0; 258 } 259 260 public String getExpressionSymbol() { 261 return "<"; 262 } 263 264 }; 265 } 266 267 public static BooleanExpression createLessThanEqual(final Expression left, final Expression right) { 268 checkLessThanOperand(left); 269 checkLessThanOperand(right); 270 return new ComparisonExpression(left, right) { 271 272 protected boolean asBoolean(int answer) { 273 return answer <= 0; 274 } 275 276 public String getExpressionSymbol() { 277 return "<="; 278 } 279 }; 280 } 281 282 287 public static void checkLessThanOperand(Expression expr ) { 288 if( expr instanceof ConstantExpression ) { 289 Object value = ((ConstantExpression)expr).getValue(); 290 if( value instanceof Number ) 291 return; 292 293 throw new RuntimeException ("Value '"+expr+"' cannot be compared."); 295 } 296 if( expr instanceof BooleanExpression ) { 297 throw new RuntimeException ("Value '"+expr+"' cannot be compared."); 298 } 299 } 300 301 307 public static void checkEqualOperand(Expression expr ) { 308 if( expr instanceof ConstantExpression ) { 309 Object value = ((ConstantExpression)expr).getValue(); 310 if( value == null ) 311 throw new RuntimeException ("'"+expr+"' cannot be compared."); 312 } 313 } 314 315 320 private static void checkEqualOperandCompatability(Expression left, Expression right) { 321 if( left instanceof ConstantExpression && right instanceof ConstantExpression ) { 322 if( left instanceof BooleanExpression && !(right instanceof BooleanExpression) ) 323 throw new RuntimeException ("'"+left+"' cannot be compared with '"+right+"'"); 324 } 325 } 326 327 328 329 333 public ComparisonExpression(Expression left, Expression right) { 334 super(left, right); 335 } 336 337 public Object evaluate(MessageEvaluationContext message) throws JMSException { 338 Comparable lv = (Comparable ) left.evaluate(message); 339 if (lv == null) { 340 return null; 341 } 342 Comparable rv = (Comparable ) right.evaluate(message); 343 if (rv == null) { 344 return null; 345 } 346 return compare(lv, rv); 347 } 348 349 protected Boolean compare(Comparable lv, Comparable rv) { 350 Class lc = lv.getClass(); 351 Class rc = rv.getClass(); 352 if (lc != rc) { 355 if (lc == Byte .class) { 356 if (rc == Short .class) { 357 lv = new Short (((Number ) lv).shortValue()); 358 } 359 else if (rc == Integer .class) { 360 lv = new Integer (((Number ) lv).intValue()); 361 } 362 else if (rc == Long .class) { 363 lv = new Long (((Number ) lv).longValue()); 364 } 365 else if (rc == Float .class) { 366 lv = new Float (((Number ) lv).floatValue()); 367 } 368 else if (rc == Double .class) { 369 lv = new Double (((Number ) lv).doubleValue()); 370 } 371 else { 372 return Boolean.FALSE; 373 } 374 } else if (lc == Short .class) { 375 if (rc == Integer .class) { 376 lv = new Integer (((Number ) lv).intValue()); 377 } 378 else if (rc == Long .class) { 379 lv = new Long (((Number ) lv).longValue()); 380 } 381 else if (rc == Float .class) { 382 lv = new Float (((Number ) lv).floatValue()); 383 } 384 else if (rc == Double .class) { 385 lv = new Double (((Number ) lv).doubleValue()); 386 } 387 else { 388 return Boolean.FALSE; 389 } 390 } else if (lc == Integer .class) { 391 if (rc == Long .class) { 392 lv = new Long (((Number ) lv).longValue()); 393 } 394 else if (rc == Float .class) { 395 lv = new Float (((Number ) lv).floatValue()); 396 } 397 else if (rc == Double .class) { 398 lv = new Double (((Number ) lv).doubleValue()); 399 } 400 else { 401 return Boolean.FALSE; 402 } 403 } 404 else if (lc == Long .class) { 405 if (rc == Integer .class) { 406 rv = new Long (((Number ) rv).longValue()); 407 } 408 else if (rc == Float .class) { 409 lv = new Float (((Number ) lv).floatValue()); 410 } 411 else if (rc == Double .class) { 412 lv = new Double (((Number ) lv).doubleValue()); 413 } 414 else { 415 return Boolean.FALSE; 416 } 417 } 418 else if (lc == Float .class) { 419 if (rc == Integer .class) { 420 rv = new Float (((Number ) rv).floatValue()); 421 } 422 else if (rc == Long .class) { 423 rv = new Float (((Number ) rv).floatValue()); 424 } 425 else if (rc == Double .class) { 426 lv = new Double (((Number ) lv).doubleValue()); 427 } 428 else { 429 return Boolean.FALSE; 430 } 431 } 432 else if (lc == Double .class) { 433 if (rc == Integer .class) { 434 rv = new Double (((Number ) rv).doubleValue()); 435 } 436 else if (rc == Long .class) { 437 rv = new Double (((Number ) rv).doubleValue()); 438 } 439 else if (rc == Float .class) { 440 rv = new Float (((Number ) rv).doubleValue()); 441 } 442 else { 443 return Boolean.FALSE; 444 } 445 } 446 else 447 return Boolean.FALSE; 448 } 449 return asBoolean(lv.compareTo(rv)) ? Boolean.TRUE : Boolean.FALSE; 450 } 451 452 protected abstract boolean asBoolean(int answer); 453 454 public boolean matches(MessageEvaluationContext message) throws JMSException { 455 Object object = evaluate(message); 456 return object!=null && object==Boolean.TRUE; 457 } 458 459 } 460 | Popular Tags |