KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > xpath > expr > BooleanExpr


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.xpath.expr;
30
31 import com.caucho.xpath.Expr;
32 import com.caucho.xpath.ExprEnvironment;
33 import com.caucho.xpath.XPathException;
34 import com.caucho.xpath.pattern.NodeIterator;
35
36 import org.w3c.dom.Element JavaDoc;
37 import org.w3c.dom.Node JavaDoc;
38 import org.w3c.dom.NodeList JavaDoc;
39
40 import java.util.ArrayList JavaDoc;
41 import java.util.Iterator JavaDoc;
42
43 public class BooleanExpr extends Expr {
44   private int _code;
45   private Expr _left;
46   private Expr _right;
47   private boolean _value;
48   private ArrayList JavaDoc _args;
49
50   public BooleanExpr(int code, Expr left, Expr right)
51   {
52     _code = code;
53     _left = left;
54     _right = right;
55
56     if (code == Expr.EQ) {
57       if (_left.isNodeSet() || _right.isNodeSet())
58     _code = Expr.EQ;
59       else if (_left.isBoolean() || _right.isBoolean())
60     _code = Expr.BOOLEAN_EQ;
61       else if (left.isNumber() || right.isNumber())
62     _code = Expr.NUMBER_EQ;
63       else if (left.isString() && right.isString())
64     _code = Expr.STRING_EQ;
65       else
66     _code = Expr.EQ;
67     }
68     else if (code == Expr.NEQ) {
69       if (left.isNodeSet() || right.isNodeSet())
70     _code = Expr.NEQ;
71       else if (left.isBoolean() || right.isBoolean())
72     _code = Expr.BOOLEAN_NEQ;
73       else if (left.isNumber() || right.isNumber())
74     _code = Expr.NUMBER_NEQ;
75       else if (left.isString() && right.isString())
76     _code = Expr.STRING_NEQ;
77       else
78     _code = Expr.NEQ;
79     }
80     else if (code == Expr.LT) {
81       if (left.isNodeSet() || right.isNodeSet())
82     _code = Expr.LT;
83       else if (left.isNumber() || right.isNumber())
84     _code = Expr.NUMBER_LT;
85       else
86     _code = Expr.LT;
87     }
88     else if (code == Expr.LE) {
89       if (left.isNodeSet() || right.isNodeSet())
90     _code = Expr.LE;
91       else if (left.isNumber() || right.isNumber())
92     _code = Expr.NUMBER_LE;
93       else
94     _code = Expr.LE;
95     }
96     else if (code == Expr.GT) {
97       if (left.isNodeSet() || right.isNodeSet())
98     _code = Expr.GT;
99       else if (left.isNumber() || right.isNumber())
100     _code = Expr.NUMBER_GT;
101       else
102     _code = Expr.GT;
103     }
104     else if (code == Expr.GE) {
105       if (left.isNodeSet() || right.isNodeSet())
106     _code = Expr.GE;
107       else if (left.isNumber() || right.isNumber())
108     _code = Expr.NUMBER_GE;
109       else
110     _code = Expr.GE;
111     }
112   }
113
114   public BooleanExpr(int code, Expr expr)
115   {
116     _code = code;
117     _left = expr;
118   }
119
120   public BooleanExpr(boolean value)
121   {
122     _code = CONST;
123     _value = value;
124   }
125
126   public BooleanExpr(int code, ArrayList JavaDoc args)
127   {
128     _code = code;
129     _args = args;
130
131     if (args.size() > 0)
132       _left = (Expr) args.get(0);
133     if (args.size() > 1)
134       _right = (Expr) args.get(1);
135   }
136
137   public boolean isBoolean() { return true; }
138
139   /**
140    * Evaluates the expression as a boolean.
141    *
142    * @param node current node
143    * @param env the environment
144    *
145    * @return the boolean representation
146    */

147   public boolean evalBoolean(Node JavaDoc node, ExprEnvironment env)
148     throws XPathException
149   {
150     switch (_code) {
151     case CONST:
152       return _value;
153
154     case BOOLEAN_EQ:
155       return (_left.evalBoolean(node, env) == _right.evalBoolean(node, env));
156
157     case NUMBER_EQ:
158       return (_left.evalNumber(node, env) == _right.evalNumber(node, env));
159
160     case STRING_EQ:
161       String JavaDoc lstr = _left.evalString(node, env);
162       String JavaDoc rstr = _right.evalString(node, env);
163       return lstr.equals(rstr);
164
165     case EQ:
166       Object JavaDoc lobj = _left.evalObject(node, env);
167       Object JavaDoc robj = _right.evalObject(node, env);
168
169       if (lobj == robj)
170     return true;
171
172       return cmp(P_EQ, lobj, robj);
173
174     case BOOLEAN_NEQ:
175       return (_left.evalBoolean(node, env) != _right.evalBoolean(node, env));
176
177     case NUMBER_NEQ:
178       return (_left.evalNumber(node, env) != _right.evalNumber(node, env));
179
180     case STRING_NEQ:
181       lstr = _left.evalString(node, env);
182       rstr = _right.evalString(node, env);
183       return ! lstr.equals(rstr);
184
185     case NEQ:
186       lobj = _left.evalObject(node, env);
187       robj = _right.evalObject(node, env);
188
189       if (lobj == robj)
190     return false;
191
192       return cmp(P_NEQ, lobj, robj);
193
194     case LT:
195       return cmp(P_LT,
196          _left.evalObject(node, env),
197          _right.evalObject(node, env));
198
199     case LE:
200       return cmp(P_LE,
201          _left.evalObject(node, env),
202          _right.evalObject(node, env));
203
204     case GT:
205       return cmp(P_GT,
206          _left.evalObject(node, env),
207          _right.evalObject(node, env));
208
209     case GE:
210       return cmp(P_GE,
211          _left.evalObject(node, env),
212          _right.evalObject(node, env));
213       
214     case NUMBER_LT:
215       return (_left.evalNumber(node, env) < _right.evalNumber(node, env));
216
217     case NUMBER_LE:
218       return (_left.evalNumber(node, env) <= _right.evalNumber(node, env));
219
220     case NUMBER_GT:
221       return (_left.evalNumber(node, env) > _right.evalNumber(node, env));
222
223     case NUMBER_GE:
224       return (_left.evalNumber(node, env) >= _right.evalNumber(node, env));
225
226     case OR:
227       return (_left.evalBoolean(node, env) || _right.evalBoolean(node, env));
228
229     case AND:
230       return (_left.evalBoolean(node, env) && _right.evalBoolean(node, env));
231
232     case TRUE:
233       return true;
234
235     case FALSE:
236       return false;
237
238     case NOT:
239       return ! _left.evalBoolean(node, env);
240
241     case BOOLEAN:
242       return _left.evalBoolean(node, env);
243
244     case STARTS_WITH:
245       lstr = _left.evalString(node, env);
246       rstr = _right.evalString(node, env);
247       return lstr.startsWith(rstr);
248
249     case CONTAINS:
250       lstr = _left.evalString(node, env);
251       rstr = _right.evalString(node, env);
252       return lstr.indexOf(rstr) >= 0;
253
254     case LANG:
255       lstr = _left.evalString(node, env);
256       for (; node != null; node = node.getParentNode()) {
257     if (! (node instanceof Element JavaDoc))
258       continue;
259     String JavaDoc lang = ((Element JavaDoc) node).getAttribute("xml:lang");
260     if (lang != null && lang.equals(lstr))
261       return true;
262       }
263       return false;
264
265     case FUNCTION_AVAILABLE:
266       return false;
267
268     default:
269       throw new RuntimeException JavaDoc("unknown code: " + _code);
270     }
271   }
272
273   private boolean cmp(Predicate test, Object JavaDoc lobj, Object JavaDoc robj)
274     throws XPathException
275   {
276     if (lobj instanceof NodeList JavaDoc) {
277       NodeList JavaDoc list = (NodeList JavaDoc) lobj;
278
279       int length = list.getLength();
280       for (int i = 0; i < length; i++) {
281     if (cmp(test, list.item(i), robj))
282       return true;
283       }
284       
285       return false;
286     }
287     else if (lobj instanceof ArrayList JavaDoc) {
288       ArrayList JavaDoc list = (ArrayList JavaDoc) lobj;
289
290       for (int i = 0; i < list.size(); i++) {
291     if (cmp(test, list.get(i), robj))
292       return true;
293       }
294       
295       return false;
296     }
297     else if (lobj instanceof Iterator) {
298       Iterator iter = (Iterator) lobj;
299       
300       while (iter.hasNext()) {
301     if (cmp(test, iter.next(), robj))
302       return true;
303       }
304       
305       return false;
306     }
307
308     if (robj instanceof NodeList JavaDoc) {
309       NodeList JavaDoc list = (NodeList JavaDoc) robj;
310
311       int length = list.getLength();
312       for (int i = 0; i < length; i++) {
313     if (cmp(test, lobj, list.item(i)))
314       return true;
315       }
316       
317       return false;
318     }
319     else if (robj instanceof ArrayList JavaDoc) {
320       ArrayList JavaDoc list = (ArrayList JavaDoc) robj;
321
322       for (int i = 0; i < list.size(); i++) {
323     if (cmp(test, lobj, list.get(i)))
324       return true;
325       }
326       
327       return false;
328     }
329     else if (robj instanceof NodeIterator) {
330       Iterator iter = null;
331
332       iter = (Iterator) ((NodeIterator) robj).clone();
333
334       while (iter.hasNext()) {
335     if (cmp(test, lobj, iter.next()))
336       return true;
337       }
338       return false;
339     }
340
341     return test.test(lobj, robj);
342   }
343
344   /**
345    * Evaluates the expression as a number.
346    *
347    * @param node current node
348    * @param env the environment
349    *
350    * @return the numeric representation
351    */

352   public double evalNumber(Node JavaDoc node, ExprEnvironment env)
353     throws XPathException
354   {
355     if (evalBoolean(node, env))
356       return 1.0;
357     else
358       return 0.0;
359   }
360
361   /**
362    * Evaluates the expression as a string.
363    *
364    * @param node current node
365    * @param env the environment
366    *
367    * @return the string representation
368    */

369   public String JavaDoc evalString(Node JavaDoc node, ExprEnvironment env)
370     throws XPathException
371   {
372     if (evalBoolean(node, env))
373       return "true";
374     else
375       return "false";
376   }
377
378   /**
379    * Evaluates the expression as a object.
380    *
381    * @param node current node
382    * @param env the environment
383    *
384    * @return the object representation
385    */

386   public Object JavaDoc evalObject(Node JavaDoc node, ExprEnvironment env)
387     throws XPathException
388   {
389     return new Boolean JavaDoc(evalBoolean(node, env));
390   }
391
392   public String JavaDoc toString()
393   {
394     switch (_code) {
395     case CONST:
396       return String.valueOf(_value);
397       
398     case BOOLEAN_EQ:
399     case NUMBER_EQ:
400     case STRING_EQ:
401     case EQ:
402       return "(" + _left.toString() + " = " + _right.toString() + ")";
403       
404     case BOOLEAN_NEQ:
405     case NUMBER_NEQ:
406     case STRING_NEQ:
407     case NEQ:
408       return "(" + _left.toString() + " != " + _right.toString() + ")";
409       
410     case LT:
411     case NUMBER_LT:
412       return "(" + _left.toString() + " < " + _right.toString() + ")";
413       
414     case LE:
415     case NUMBER_LE:
416       return "(" + _left.toString() + " <= " + _right.toString() + ")";
417       
418     case GT:
419     case NUMBER_GT:
420       return "(" + _left.toString() + " > " + _right.toString() + ")";
421       
422     case GE:
423     case NUMBER_GE:
424       return "(" + _left.toString() + " >= " + _right.toString() + ")";
425
426     case OR:
427       return "(" + _left.toString() + " or " + _right.toString() + ")";
428       
429     case AND:
430       return "(" + _left.toString() + " and " + _right.toString() + ")";
431
432     case TRUE:
433       return "true()";
434       
435     case FALSE:
436       return "false()";
437
438     case NOT:
439       return "not(" + _left.toString() + ")";
440       
441     case BOOLEAN:
442       return "boolean(" + _left.toString() + ")";
443
444     case STARTS_WITH:
445       return "starts-with(" + _left + ", " + _right + ")";
446
447     case CONTAINS:
448       return "contains(" + _left + ", " + _right + ")";
449
450     case LANG:
451       return "lang(" + _left + ")";
452
453     case FUNCTION_AVAILABLE:
454       return "function-available(" + _left + ")";
455
456     default: return super.toString();
457     }
458   }
459
460   abstract static class Predicate {
461     abstract public boolean test(Object JavaDoc l, Object JavaDoc r)
462       throws XPathException;
463   }
464
465   final static Predicate P_EQ = new Predicate() {
466       public boolean test(Object JavaDoc lobj, Object JavaDoc robj)
467     throws XPathException
468       {
469     if (lobj instanceof Boolean JavaDoc || robj instanceof Boolean JavaDoc)
470       return toBoolean(lobj) == toBoolean(robj);
471     else if (lobj instanceof Double JavaDoc || robj instanceof Double JavaDoc)
472       return toDouble(lobj) == toDouble(robj);
473     else
474       return BooleanExpr.toString(lobj).equals(BooleanExpr.toString(robj));
475       }
476     };
477
478   final static Predicate P_NEQ = new Predicate() {
479       public boolean test(Object JavaDoc lobj, Object JavaDoc robj)
480     throws XPathException
481       {
482     if (lobj instanceof Boolean JavaDoc || robj instanceof Boolean JavaDoc)
483       return toBoolean(lobj) != toBoolean(robj);
484     else if (lobj instanceof Double JavaDoc || robj instanceof Double JavaDoc)
485       return toDouble(lobj) != toDouble(robj);
486     else
487       return ! BooleanExpr.toString(lobj).equals(BooleanExpr.toString(robj));
488       }
489     };
490
491   final static Predicate P_LT = new Predicate() {
492       public boolean test(Object JavaDoc lobj, Object JavaDoc robj)
493     throws XPathException
494       {
495     return toDouble(lobj) < toDouble(robj);
496       }
497     };
498
499   final static Predicate P_LE = new Predicate() {
500       public boolean test(Object JavaDoc lobj, Object JavaDoc robj)
501     throws XPathException
502       {
503     return toDouble(lobj) <= toDouble(robj);
504       }
505     };
506
507   final static Predicate P_GT = new Predicate() {
508       public boolean test(Object JavaDoc lobj, Object JavaDoc robj)
509     throws XPathException
510       {
511     return toDouble(lobj) > toDouble(robj);
512       }
513     };
514
515   final static Predicate P_GE = new Predicate() {
516       public boolean test(Object JavaDoc lobj, Object JavaDoc robj)
517     throws XPathException
518       {
519     return toDouble(lobj) >= toDouble(robj);
520       }
521     };
522 }
523
Popular Tags