KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > query > SearchFilter


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

17
18 import java.util.Enumeration JavaDoc;
19 import java.util.Hashtable JavaDoc;
20 import java.util.Vector JavaDoc;
21
22 /**
23  * Class to build selection criteria for searches
24  * Search Filter Class (Abstract)
25  * This class builds a search filter tree, specifing how names and
26  * values are to be compared when searching a database.
27  * It just builds internal structures, and needs to be extended
28  * to return a search filter string or other object that can be
29  * used by the database to perform the actual search.
30  */

31 public abstract class SearchFilter
32 {
33     // Define the operators
34
// Binary operators have bit 8 set
35
// Logical operators have bit 9 set
36
public static final int AND = 0x200; // Logical operator
37
public static final int OR = 0x201; // Logical operator
38
public static final int NOT = 0x2; // Unary operator
39
public static final int IN = 0x3;
40     public static final int NOT_IN = 0x4;
41     public static final int LIKE = 0x109; // Binary operator
42
public static final int EQUAL = 0x10A; // Binary operator
43
public static final int NOT_EQUAL = 0x10B; // Binary operator
44
public static final int LESS_THAN = 0x10C; // Binary operator
45
public static final int GREATER_THAN = 0x10D; // Binary operator
46
public static final int GREATER_EQUAL = 0x10E; // Binary operator
47
public static final int LESS_EQUAL = 0x10F; // Binary operator
48
// Define a mask for the binary and logical operators
49
// private static final int BINARY_OPER_MASK = 0x100;
50
// private static final int LOGICAL_OPER_MASK = 0x200;
51
protected static final int BINARY_OPER_MASK = 0x100;
52     protected static final int LOGICAL_OPER_MASK = 0x200;
53     // Define the current search filter
54
protected SearchBase m_filter = null;
55
56     /**
57      * Create an empty search filter.
58      *
59      */

60     // -----------------------------------------------------------
61
public SearchFilter()
62     {
63     }
64
65     /**
66      * Change the search filter to one that specifies an element to
67      * match or not match one of a list of values.
68      * The old search filter is deleted.
69      *
70      * @param ElementName is the name of the element to be matched
71      * @param values is a vector of possible matches
72      * @param oper is the IN or NOT_IN operator to indicate how to matche
73      */

74     public void matchList(String JavaDoc ElementName, Vector JavaDoc values, int oper)
75     {
76         // Delete the old search filter
77
m_filter = null;
78         // If not NOT_IN, assume IN
79
// (Since ints are passed by value, it is OK to change it)
80
if (oper != NOT_IN)
81         {
82             oper = IN;
83             // Convert the vector of match strings to an array of strings
84
}
85         String JavaDoc[] value_string_array = new String JavaDoc[values.size()];
86         values.copyInto(value_string_array);
87         // Create a leaf node for this list and store it as the filter
88
m_filter = new SearchBaseLeaf(ElementName, oper, value_string_array);
89     }
90
91     /**
92      * Change the search filter to one that specifies an element to not
93      * match one of a list of values.
94      * The old search filter is deleted.
95      *
96      * @param ElementName is the name of the element to be matched
97      * @param values is an array of possible matches
98      * @param oper is the IN or NOT_IN operator to indicate how to matche
99      */

100     public void matchList(String JavaDoc ElementName, String JavaDoc[] values, int oper)
101     {
102         // Delete the old search filter
103
m_filter = null;
104         // If not NOT_IN, assume IN
105
// (Since ints are passed by value, it is OK to change it)
106
if (oper != NOT_IN)
107         {
108             oper = IN;
109             // Create a leaf node for this list and store it as the filter
110
}
111         m_filter = new SearchBaseLeaf(ElementName, oper, values);
112     }
113
114     /**
115      * Change the search filter to one that specifies an element to not
116      * match one of a list of integer values.
117      * The old search filter is deleted.
118      *
119      * @param ElementName is the name of the element to be matched
120      * @param values is an array of possible integer matches
121      * @param oper is the IN or NOT_IN operator to indicate how to matche
122      */

123     public void matchList(String JavaDoc ElementName, int[] values, int oper)
124     {
125         // Delete the old search filter
126
m_filter = null;
127         // If not NOT_IN, assume IN
128
// (Since ints are passed by value, it is OK to change it)
129
if (oper != NOT_IN)
130         {
131             oper = IN;
132             // Create a leaf node for this list and store it as the filter
133
}
134         m_filter = new SearchBaseLeafInt(ElementName, oper, values);
135     }
136
137     /**
138      * Change the search filter to one that specifies an element to not
139      * match one single value.
140      * The old search filter is deleted.
141      *
142      * @param ElementName is the name of the element to be matched
143      * @param value is the value to not be matched
144      * @param oper is the IN or NOT_IN operator to indicate how to matche
145      */

146     public void matchValue(String JavaDoc ElementName, String JavaDoc value, int oper)
147     {
148         // Delete the old search filter
149
m_filter = null;
150         // If not NOT_IN, assume IN
151
// (Since ints are passed by value, it is OK to change it)
152
if (oper != NOT_IN)
153         {
154             oper = IN;
155             // Create a String array in which to hold the one name,
156
// and put that name in the array
157
}
158         String JavaDoc[] ValueArray = new String JavaDoc[1];
159         ValueArray[0] = value;
160         // Create a leaf node for this list and store it as the filter
161
m_filter = new SearchBaseLeaf(ElementName, oper, ValueArray);
162     }
163
164     /**
165      * -----------------------------------------------------------
166      * @param ElementName
167      * @param value
168      * @param oper
169      */

170     public void matchValue(String JavaDoc ElementName, int value, int oper)
171     {
172         // Delete the old search filter
173
m_filter = null;
174         // If not NOT_IN, assume IN
175
// (Since ints are passed by value, it is OK to change it)
176
if (oper != NOT_IN)
177         {
178             oper = IN;
179             // Create a leaf node for this list and store it as the filter
180
}
181         m_filter = new SearchBaseLeafInt(ElementName, oper, new int[]
182         {
183             value
184         });
185     }
186
187     /**
188      * Change the search filter to one that compares an element name to a value.
189      * The old search filter is deleted.
190      *
191      * @param ElementName is the name of the element to be tested
192      * @param value is the value to be compared against
193      * @param oper is the binary comparison operator to be used
194      * @exception DBException
195      */

196     public void compareFilter(String JavaDoc ElementName, String JavaDoc value, int oper) throws DBException
197     {
198         // Delete the old search filter
199
m_filter = null;
200         // If this is not a binary operator, throw an exception
201
if ((oper & BINARY_OPER_MASK) == 0)
202         {
203             throw new DBException();
204             // Create a SearchBaseLeafComparison node and store it as the filter
205
}
206         m_filter = new SearchBaseLeafComparison(ElementName, oper, value);
207     }
208
209     /**
210      * Change the search filter to one that specifies a set of elements and their values
211      * that must match, and the operator to use to combine the elements.
212      * Each key is compared for an equal match to the value, and all
213      * comparisons are combined by the specified logical operator (OR or AND).
214      * The old search filter is deleted.
215      *
216      * @param elements is a hashtable holding key-value pairs
217      * @param combine_op is the logical operator to be used to combine the comparisons
218      * @param compare_op is the binary operator to be used for the comparisons
219      * @exception DBException
220      */

221     public void matchSet(Hashtable JavaDoc elements, int combine_op, int compare_op) throws DBException
222     {
223         // Delete the old search filter
224
m_filter = null;
225         // If combine_op is not a logical operator, throw an exception
226
if ((combine_op & LOGICAL_OPER_MASK) == 0)
227         {
228             throw new DBException();
229             // If compare_op is not a binary operator, throw an exception
230
}
231         if ((compare_op & BINARY_OPER_MASK) == 0)
232         {
233             throw new DBException();
234             // Create a vector that will hold the comparison nodes for all elements in the hashtable
235
}
236         Vector JavaDoc compareVector = new Vector JavaDoc();
237         // For each of the elements in the hashtable, create a comparison node for the match
238
for (Enumeration JavaDoc e = elements.keys(); e.hasMoreElements();)
239         {
240             // Get the element name from the enumerator
241
// and its value
242
String JavaDoc elementName = (String JavaDoc) e.nextElement();
243             String JavaDoc elementValue = (String JavaDoc) elements.get(elementName);
244             // Create a comparison node for this list and store it as the filter
245
SearchBaseLeafComparison comparenode = new SearchBaseLeafComparison(elementName,
246                     compare_op, elementValue);
247             // Add this leaf node to the vector
248
compareVector.addElement(comparenode);
249         }
250         // Now return a node that holds this set of leaf nodes
251
m_filter = new SearchBaseNode(combine_op, compareVector);
252     }
253
254     /**
255      * Change the search filter to one that specifies a set of elements and their values
256      * that must match, and the operator to use to combine the elements.
257      * Each element name is compared for an equal match to the value, and all
258      * comparisons are combined by the specified logical operator (OR or AND).
259      * The old search filter is deleted.
260      *
261      * @param ElementNames is an array of names of elements to be tested
262      * @param ElementValues is an array of values for the corresponding element
263      * @param op is the logical operator to be used to combine the comparisons
264      * @exception DBException
265      */

266     public void matchSet(String JavaDoc[] ElementNames, String JavaDoc[] ElementValues, int op) throws DBException
267     {
268         // Delete the old search filter
269
m_filter = null;
270         // If this is not a logical operator, throw an exception
271
if ((op & LOGICAL_OPER_MASK) == 0)
272         {
273             throw new DBException();
274             // Create a vector that will hold the leaf nodes for all elements in the hashtable
275
}
276         Vector JavaDoc leafVector = new Vector JavaDoc();
277         // For each of the elements in the array, create a leaf node for the match
278
int numnames = ElementNames.length;
279         for (int i = 0; i < numnames; i++)
280         {
281             // Create a leaf node for this list and store it as the filter
282
SearchBaseLeaf leafnode = new SearchBaseLeaf(ElementNames[i], IN, ElementValues[i]);
283             // Add this leaf node to the vector
284
leafVector.addElement(leafnode);
285         }
286         // Now return a node that holds this set of leaf nodes
287
m_filter = new SearchBaseNode(op, leafVector);
288     }
289
290     /**
291      * Combine other search filters with this one, using the specific operator.
292      *
293      * @param new_filters is a vector of SearchFilter classes to be combined
294      * @param op is the logical operator to be used to combine the filters
295      * @exception DBException
296      */

297     public void combine(Vector JavaDoc new_filters, int op) throws DBException
298     {
299         // If this is not a logical operator, throw an exception
300
if ((op & LOGICAL_OPER_MASK) == 0)
301         {
302             throw new DBException();
303             // Create a new vector consisting of just the filters
304
// from the SearchFilter classes in new_filters
305
}
306         Vector JavaDoc filters = new Vector JavaDoc();
307         // Now add in all the nodes of the new filters
308
for (Enumeration JavaDoc e = new_filters.elements(); e.hasMoreElements();)
309         {
310             // Get the search filter from the vector
311
SearchFilter f = (SearchFilter) e.nextElement();
312             filters.addElement(f.getFilter());
313         }
314         // Create a node for this list and return it
315
m_filter = new SearchBaseNode(op, m_filter, filters);
316     }
317
318     /**
319      * Combine one other search filters with this one, using the specific operator.
320      *
321      * @param new_filter is the SearchFilter class to be combined
322      * @param op is the logical operator to be used to combine the filters
323      * @exception DBException
324      */

325     public void combine(SearchFilter new_filter, int op) throws DBException
326     {
327         // If this is not a logical operator, throw an exception
328
if ((op & LOGICAL_OPER_MASK) == 0)
329         {
330             throw new DBException();
331             // Create a new vector consisting of just the filters
332
// from the SearchFilter classes in new_filters
333
}
334         Vector JavaDoc filters = new Vector JavaDoc();
335         filters.addElement(new_filter.getFilter());
336         // Create a node for this list and return it
337
m_filter = new SearchBaseNode(op, m_filter, filters);
338     }
339
340     /**
341      * Static method to convert a binary operator into a string.
342      *
343      * @param oper is the binary comparison operator to be converted
344      */

345     protected static String JavaDoc ConvertBinaryOperator(int oper)
346     {
347         // Convert the operator into the proper string
348
String JavaDoc oper_string;
349         switch (oper)
350         {
351             default:
352             case EQUAL:
353                 oper_string = "=";
354                 break;
355             case LIKE:
356                 oper_string = "LIKE";
357                 break;
358             case NOT_EQUAL:
359                 oper_string = "!=";
360                 break;
361             case LESS_THAN:
362                 oper_string = "<";
363                 break;
364             case GREATER_THAN:
365                 oper_string = ">";
366                 break;
367             case GREATER_EQUAL:
368                 oper_string = ">=";
369                 break;
370             case LESS_EQUAL:
371                 oper_string = "<=";
372                 break;
373         }
374         return oper_string;
375     }
376
377     /**
378      * Get the actual filter out of the class.
379      * This is only needed when combining filters together
380      * and one instantiation has to get the filter from another.
381      * However, I do not know how to protect it from outside use.
382      * @return
383      *
384      */

385     protected SearchBase getFilter()
386     {
387         return m_filter;
388     }
389
390     /**
391      * Converts this search filter into a search string for use by a database.
392      *
393      */

394
395     /**
396      * -----------------------------------------------------------
397      * @return
398      */

399     public abstract String JavaDoc toString();
400
401     /**
402      * SearchBase is the base node class for the parse tree
403      * This class holds the binary operator
404      *
405      */

406     // ===============================================================
407
protected class SearchBase
408     {
409         // Define the operator to be used for this group
410
public int oper;
411
412         /**
413          * Constructor.
414          * This is protected so only the subclasses can instantiate it
415          *
416          */

417         // ------------------------------------------------------------
418
protected SearchBase()
419         {
420         }
421
422     }
423
424     /**
425      * SearchBaseLeafComparison holds a leaf of the search tree
426      * This class holds an element name, a binary operator, and a value to be compared
427      */

428     // ===============================================================
429
protected class SearchBaseLeafComparison extends SearchBase
430     {
431         // Define the element name
432
public String JavaDoc elementName;
433         // Only operators allowed are binary operators
434
// Define the comparison value
435
public String JavaDoc value;
436
437         /**
438          * Constructor.
439          *
440          * @param ElementName is the name of the element to be tested
441          * @param oper is the binary operator to be used for the comparison
442          * @param value is the value to be used for the comparison
443          */

444         SearchBaseLeafComparison(String JavaDoc ElementName, int oper, String JavaDoc value)
445         {
446             this.elementName = ElementName;
447             this.oper = oper;
448             this.value = value;
449         }
450
451     }
452
453     /**
454      * SearchBaseLeaf holds a leaf of the search tree
455      * This class holds an element name, and a vector of possible matches.
456      * It searches for an element of the given name that matches at least
457      * one of the strings in the array (IN), or does not match any (NOT_IN)
458      *
459      */

460     // ===============================================================
461
protected class SearchBaseLeaf extends SearchBase
462     {
463         // Define the element name
464
public String JavaDoc elementName;
465         // Only operators allowed are IN and NOT_IN
466
// Define the vector of possible matches
467
public String JavaDoc[] matches;
468
469         /**
470          * Constructor.
471          *
472          * @param ElementName is the name of the element to be tested
473          * @param oper is the operator (IN or NOT_IN) to be used for the comparison
474          * @param matches is an array of String values to be matched
475          */

476         SearchBaseLeaf(String JavaDoc ElementName, int oper, String JavaDoc[] matches)
477         {
478             this.elementName = ElementName;
479             this.oper = oper;
480             this.matches = matches;
481         }
482
483         /**
484          * Constructor for only one value.
485          *
486          * @param ElementName is the name of the element to be tested
487          * @param oper is the operator (IN or NOT_IN) to be used for the comparison
488          * @param match is a string value to be matched
489          */

490         SearchBaseLeaf(String JavaDoc ElementName, int oper, String JavaDoc match)
491         {
492             this.elementName = ElementName;
493             this.oper = oper;
494             this.matches = new String JavaDoc[1];
495             this.matches[0] = match;
496         }
497
498     }
499
500     /**
501      * SearchBaseLeafInt holds a leaf of the search tree with integers
502      * This class holds an element name, and a vector of possible matches.
503      * It searches for an element of the given name that matches at least
504      * one of the integers in the array (IN), or does not match any (NOT_IN)
505      */

506     // ===============================================================
507
protected class SearchBaseLeafInt extends SearchBase
508     {
509         // Define the element name
510
public String JavaDoc elementName;
511         // Only operators allowed are IN and NOT_IN
512
// Define the vector of possible matches
513
public int[] matches;
514
515         /**
516          * Constructor.
517          *
518          * @param ElementName is the name of the element to be tested
519          * @param oper is the operator (IN or NOT_IN) to be used for the comparison
520          * @param matches is an array of integer values to be matched
521          */

522         SearchBaseLeafInt(String JavaDoc ElementName, int oper, int[] matches)
523         {
524             this.elementName = ElementName;
525             this.oper = oper;
526             this.matches = matches;
527         }
528
529         /**
530          * Constructor for only one value.
531          *
532          * @param ElementName is the name of the element to be tested
533          * @param oper is the operator (IN or NOT_IN) to be used for the comparison
534          * @param match is an int value to be matched
535          */

536         SearchBaseLeafInt(String JavaDoc ElementName, int oper, int match)
537         {
538             this.elementName = ElementName;
539             this.oper = oper;
540             this.matches = new int[1];
541             this.matches[0] = match;
542         }
543
544     }
545
546     /**
547      * Define the class to represent a node of the search tree
548      * This class holds an operator and a vector other nodes.
549      */

550     // ===============================================================
551
protected class SearchBaseNode extends SearchBase
552     {
553         // Define the vector of other nodes
554
public Vector JavaDoc nodes;
555
556         /**
557          * Constructor.
558          * Store a list of filters and an operator for combining them.
559          *
560          * @param oper is the operator (IN or NOT_IN) to be used for the comparison
561          * @param new_filters is a vector of filters to be combined
562          */

563         SearchBaseNode(int oper, Vector JavaDoc new_filters)
564         {
565             this.oper = oper;
566             this.nodes = new_filters;
567         }
568
569         /**
570          * Constructor for a specific filter and a vector of new ones.
571          * Store a list of filters and an operator for combining them.
572          *
573          * @param oper is the operator (IN or NOT_IN) to be used for the comparison
574          * @param filter is the first filter to be combined
575          * @param new_filters is a vector of filters to be combined
576          */

577         SearchBaseNode(int oper, Object JavaDoc filter, Vector JavaDoc new_filters)
578         {
579             // Store the operator
580
this.oper = oper;
581             // Create a vector and add in the first filter as the initial node (if present)
582
nodes = new Vector JavaDoc();
583             if (filter != null)
584             {
585                 nodes.addElement(filter);
586                 // Now add in all the nodes of the new filters
587
}
588             for (Enumeration JavaDoc e = new_filters.elements(); e.hasMoreElements();)
589             {
590                 nodes.addElement(e.nextElement());
591             }
592         }
593
594     }
595 }
596
Popular Tags