KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > josql > expressions > InExpression


1 /*
2  * Copyright 2004-2005 Gary Bentley
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may
5  * not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */

15 package org.josql.expressions;
16
17 import java.util.List JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.Collection JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Iterator JavaDoc;
23
24 import org.josql.Query;
25 import org.josql.QueryExecutionException;
26 import org.josql.QueryParseException;
27
28 import org.josql.internal.Utilities;
29
30 /**
31  * This class represents in [ NOT ] IN [ LIKE ] [ ALL ] expression.
32  * If any of the values listed are Maps or Collections then they are iterated over to see if a match
33  * is found. For Maps only the key values are checked. If you pass a list then it is iterated over
34  * using a <code>for</code> construct rather than an Iterator since it's much faster.
35  * <p>
36  * Note: due to the way that the expression is designed it is POSSIBLE to have a binary expression
37  * in the in list, however at this time that is not supported since it can lead to an ambiguous result,
38  * for example: <code>true IN (true, false)</code> has no sensible meaning.
39  * <p>
40  * Last Modified By: $Author: barrygently $<br />
41  * Last Modified On: $Date: 2005/04/28 05:48:59 $<br />
42  * Current Revision: $Revision: 1.3 $<br />
43  */

44 public class InExpression extends BinaryExpression
45 {
46
47     private List JavaDoc items = new ArrayList JavaDoc ();
48     private boolean not = false;
49     private boolean doLike = false;
50     private boolean all = false;
51     private Map JavaDoc lPats = null;
52     private boolean ignoreCase = false;
53
54     /**
55      * Initialise the IN expression. Init the LHS and then all of the values in the brackets.
56      *
57      * @param q The Query object.
58      * @throws QueryParseException If something goes wrong with the init.
59      */

60     public void init (Query q)
61                   throws QueryParseException
62     {
63
64     this.left.init (q);
65
66     int s = this.items.size ();
67
68     for (int i = 0; i < s; i++)
69     {
70
71         Expression exp = (Expression) this.items.get (i);
72
73         exp.init (q);
74
75     }
76
77     }
78
79     public void setIgnoreCase (boolean v)
80     {
81
82     this.ignoreCase = v;
83
84     }
85
86     public boolean isIgnoreCase ()
87     {
88
89     return this.ignoreCase;
90
91     }
92
93     public boolean isAll ()
94     {
95
96     return this.all;
97
98     }
99
100     public void setAll (boolean v)
101     {
102
103     this.all = v;
104
105     }
106
107     public boolean isDoLike ()
108     {
109
110     return this.doLike;
111
112     }
113
114     public void setDoLike (boolean d)
115     {
116
117     this.doLike = d;
118
119     }
120
121     public void setItems (List JavaDoc items)
122     {
123
124     this.items = items;
125
126     }
127
128     public List JavaDoc getItems ()
129     {
130
131     return this.items;
132
133     }
134
135     public void addItem (Expression e)
136     {
137
138     this.items.add (e);
139
140     }
141
142     public boolean isNot ()
143     {
144
145     return this.not;
146
147     }
148
149     public void setNot (boolean v)
150     {
151
152     this.not = v;
153
154     }
155
156     /**
157      * Return whether this expression evaulates to <code>true</code>. If any of the values on RHS are Maps (keys
158      * only) or Collections then they are iterated over and checked against the LHS.
159      *
160      * @param o The current object to perform the expression on.
161      * @param q The Query object.
162      * @return <code>true</code> if the LHS is "equal" (as determined by: {@link Utilities#isEquals(Object,Object)})
163      * to any of the values in the brackets. If this is a NOT expression then the result is negated.
164      * @throws QueryExecutionException If the expression cannot be evaluated.
165      */

166     public boolean isTrue (Object JavaDoc o,
167                Query q)
168                        throws QueryExecutionException
169     {
170
171     // Get the LHS.
172
Object JavaDoc l = this.left.getValue (o,
173                        q);
174
175     String JavaDoc v = null;
176     String JavaDoc wc = String.valueOf (q.getWildcardCharacter ());
177
178     if (this.doLike)
179     {
180
181         if (l != null)
182         {
183
184         v = l.toString ();
185
186         if (this.ignoreCase)
187         {
188
189             v = v.toLowerCase ();
190
191         }
192
193         }
194
195     }
196
197     int count = 0;
198
199     // Cycle over our items.
200
int s = this.items.size ();
201
202     for (int i = 0; i < s; i++)
203     {
204
205         Expression exp = (Expression) this.items.get (i);
206
207         // Evaluate it.
208
Object JavaDoc eo = exp.getValue (o,
209                       q);
210
211         boolean eq = false;
212         boolean proc = false;
213
214         if (eo instanceof Collection JavaDoc)
215         {
216
217         Collection JavaDoc col = (Collection JavaDoc) eo;
218
219         eq = this.compareCollection (l,
220                          col,
221                          v,
222                          wc);
223         proc = true;
224
225         }
226
227         if (eo instanceof Map JavaDoc)
228         {
229
230         eq = this.compareMap (l,
231                       (Map JavaDoc) eo,
232                       v,
233                       wc);
234         proc = true;
235
236         }
237
238         if (!proc)
239         {
240
241         // See if the objects are equivalent.
242
eq = this.compareItem (l,
243                        eo,
244                        v,
245                        wc);
246
247         }
248
249         if (eq)
250         {
251
252         count++;
253
254         if (this.not)
255         {
256
257             return false;
258
259         }
260
261         if (!this.all)
262         {
263
264             return true;
265
266         }
267
268         }
269
270     }
271
272     if ((this.all)
273         &&
274         (!this.not)
275         &&
276         (count == s)
277        )
278     {
279
280         return true;
281
282     }
283
284     if ((this.all)
285         &&
286         (this.not)
287         &&
288         (count == 0)
289        )
290     {
291
292         return true;
293
294     }
295
296     if (this.not)
297     {
298
299         return true;
300
301     }
302
303     return false;
304
305     }
306
307     private boolean compareCollection (Object JavaDoc o,
308                        Collection JavaDoc c,
309                        String JavaDoc v,
310                        String JavaDoc wc)
311     {
312
313     if (c instanceof List JavaDoc)
314     {
315
316         return this.compareList (o,
317                      (List JavaDoc) c,
318                      v,
319                      wc);
320
321     }
322
323     Iterator JavaDoc i = c.iterator ();
324
325     int count = 0;
326
327     while (i.hasNext ())
328     {
329
330         Object JavaDoc n = i.next ();
331
332         if (this.compareItem (o,
333                   n,
334                   v,
335                   wc))
336         {
337
338         count++;
339
340         if (!this.all)
341         {
342
343             return true;
344
345         }
346
347         }
348
349     }
350
351     if ((this.all)
352         &&
353         (!this.not)
354         &&
355         (count == c.size ())
356        )
357     {
358
359         return true;
360
361     }
362
363     if ((this.all)
364         &&
365         (this.not)
366         &&
367         (count == 0)
368        )
369     {
370
371         return true;
372
373     }
374
375     return false;
376
377     }
378
379     private boolean compareList (Object JavaDoc o,
380                  List JavaDoc l,
381                  String JavaDoc v,
382                  String JavaDoc wc)
383     {
384
385     int s = l.size ();
386
387     int count = 0;
388
389     for (int i = 0; i < s; i++)
390     {
391
392         Object JavaDoc n = l.get (i);
393
394         if (this.compareItem (o,
395                   n,
396                   v,
397                   wc))
398         {
399
400         count++;
401
402         if (!this.all)
403         {
404
405             return true;
406
407         }
408
409         }
410
411     }
412
413     if ((this.all)
414         &&
415         (!this.not)
416         &&
417         (count == s)
418        )
419     {
420
421         return true;
422
423     }
424
425     if ((this.all)
426         &&
427         (this.not)
428         &&
429         (count == 0)
430        )
431     {
432
433         return true;
434
435     }
436
437     return false;
438
439     }
440
441     private boolean compareItem (Object JavaDoc o,
442                  Object JavaDoc n,
443                  String JavaDoc v,
444                  String JavaDoc wc)
445     {
446
447     boolean eq = true;
448
449     if (this.doLike)
450     {
451
452         if ((v == null)
453         &&
454         (n == null)
455            )
456         {
457
458         return true;
459
460         }
461
462         if (n == null)
463         {
464
465         return false;
466
467         }
468
469         String JavaDoc vn = n.toString ();
470
471         if (this.ignoreCase)
472         {
473
474         vn = vn.toLowerCase ();
475
476         }
477
478         List JavaDoc pat = Utilities.getLikePattern (vn,
479                          wc);
480
481         eq = Utilities.matchLikePattern (pat,
482                          v);
483
484     } else {
485
486         if (this.ignoreCase)
487         {
488
489         if ((o == null)
490             &&
491             (n == null)
492            )
493         {
494
495             return true;
496
497         }
498
499         if (n == null)
500         {
501
502             return false;
503
504         }
505
506         return o.toString ().equalsIgnoreCase (n.toString ());
507
508         }
509
510         eq = Utilities.isEquals (o,
511                      n);
512
513     }
514
515     return eq;
516
517     }
518
519     private boolean compareMap (Object JavaDoc o,
520                 Map JavaDoc m,
521                 String JavaDoc v,
522                 String JavaDoc wc)
523     {
524
525     Iterator JavaDoc i = m.keySet ().iterator ();
526
527     int count = 0;
528     
529     while (i.hasNext ())
530     {
531
532         Object JavaDoc n = i.next ();
533
534         if (this.compareItem (o,
535                   n,
536                   v,
537                   wc))
538         {
539
540         count++;
541
542         if (!this.all)
543         {
544
545             return true;
546
547         }
548
549         }
550
551     }
552
553     if ((this.all)
554         &&
555         (!this.not)
556         &&
557         (count == m.size ())
558        )
559     {
560
561         return true;
562
563     }
564
565     if ((this.all)
566         &&
567         (this.not)
568         &&
569         (count == 0)
570        )
571     {
572
573         return true;
574
575     }
576
577     return false;
578
579     }
580
581     /**
582      * Return a string representation of this expression.
583      * In the form: {@link Expression#toString() Expression} [ NOT ] [$]IN [ LIKE ] [ ALL ]
584      * ( {@link Expression#toString() Expression} [ , {@link Expression#toString() Expression}* ] )
585      *
586      * @return A string representation of this expression.
587      */

588     public String JavaDoc toString ()
589     {
590
591     StringBuffer JavaDoc buf = new StringBuffer JavaDoc (this.left.toString ());
592
593     buf.append (" ");
594
595     if (this.isNot ())
596     {
597
598         buf.append ("NOT ");
599
600     }
601
602     if (this.ignoreCase)
603     {
604
605         buf.append ("$");
606
607     }
608
609     buf.append ("IN ");
610
611     if (this.doLike)
612     {
613
614         buf.append ("LIKE ");
615
616     }
617
618     if (this.all)
619     {
620
621         buf.append ("ALL ");
622
623     }
624
625     buf.append ("(");
626
627     for (int i = 0; i < this.items.size (); i++)
628     {
629
630         buf.append (this.items.get (i));
631
632         if (i < (this.items.size () - 1))
633         {
634
635         buf.append (",");
636
637         }
638
639     }
640
641     buf.append (")");
642
643     if (this.isBracketed ())
644     {
645
646         buf.insert (0,
647             "(");
648         buf.append (")");
649
650     }
651
652     return buf.toString ();
653
654     }
655
656 }
657
Popular Tags