Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: gov/lanl/Database/SearchFilter.java


1   /*--- formatted by Jindent 2.1, (www.c-lab.de/~jindent) ---*/
2   
3   // Search Filter Class (Abstract)
4   // 
5   // This class builds a search filter tree, specifing how names and
6   // values are to be compared when searching a database.
7   // It just builds internal structures, and needs to be extended
8   // to return a search filter string or other object that can be
9   // used by the database to perform the actual search.
10  
11  /**
12   * ***********************************
13   * This program was prepared by the Regents of the University of California at
14   * Los Alamos National Laboratory (the University) under Contract No.
15   * W-7405-ENG-36 with the U.S. Department of Energy (DOE).  The University has
16   * certain rights in the program pursuant to the contract and the program
17   * should not be copied or distributed outside your organization.  All rights
18   * in the program are reserved by the DOE and the University.  Neither the
19   * U.S. Government nor the University makes any warranty, express or implied,
20   * or assumes any liability or responsibility for the use of this software.
21   * **********************************
22   */
23  package gov.lanl.Database;
24  
25  import java.util.*;
26  
27  /**
28   * Class to build selection criteria for searches
29   */
30  
31  // ===============================================================
32  public abstract class SearchFilter {
33  
34    // Define the operators
35    // Binary operators have bit 8 set
36    // Logical operators have bit 9 set
37    public static final int AND = 0x200;        // Logical operator
38    public static final int OR = 0x201;          // Logical operator
39    public static final int NOT = 0x2;          // Unary operator
40    public static final int IN = 0x3;
41    public static final int NOT_IN = 0x4;
42    public static final int LIKE = 0x109;        // Binary operator
43    public static final int EQUAL = 0x10A;        // Binary operator
44    public static final int NOT_EQUAL = 0x10B;      // Binary operator
45    public static final int LESS_THAN = 0x10C;      // Binary operator
46    public static final int GREATER_THAN = 0x10D;    // Binary operator
47    public static final int GREATER_EQUAL = 0x10E;    // Binary operator
48    public static final int LESS_EQUAL = 0x10F;      // Binary operator
49  
50    // Define a mask for the binary and logical operators
51    // private static final int          BINARY_OPER_MASK = 0x100;
52    // private static final int          LOGICAL_OPER_MASK = 0x200;
53    protected static final int BINARY_OPER_MASK = 0x100;
54    protected static final int LOGICAL_OPER_MASK = 0x200;
55  
56    // Define the current search filter
57    protected SearchBase filter = null;
58  
59    /**
60     * Create an empty search filter.
61     * 
62     */
63  
64    // -----------------------------------------------------------
65    public SearchFilter() {}
66  
67    /**
68     * Change the search filter to one that specifies an element to
69     * match or not match one of a list of values.
70     * The old search filter is deleted.
71     * 
72     * @param ElementName is the name of the element to be matched
73     * @param values is a vector of possible matches
74     * @param oper is the IN or NOT_IN operator to indicate how to matche
75     */
76    public void matchList(String ElementName, Vector values, int oper) {
77  
78      // Delete the old search filter
79      filter = null;
80  
81      // If not NOT_IN, assume IN
82      // (Since ints are passed by value, it is OK to change it)
83      if (oper != NOT_IN) {
84        oper = IN;
85  
86        // Convert the vector of match strings to an array of strings
87      } 
88  
89      String[] value_string_array = new String[values.size()];
90  
91      values.copyInto(value_string_array);
92  
93      // Create a leaf node for this list and store it as the filter
94      filter = new SearchBaseLeaf(ElementName, oper, value_string_array);
95    } 
96  
97    /**
98     * Change the search filter to one that specifies an element to not
99     * match one of a list of values.
100    * The old search filter is deleted.
101    * 
102    * @param ElementName is the name of the element to be matched
103    * @param values is an array of possible matches
104    * @param oper is the IN or NOT_IN operator to indicate how to matche
105    */
106   public void matchList(String ElementName, String[] values, int oper) {
107 
108     // Delete the old search filter
109     filter = null;
110 
111     // If not NOT_IN, assume IN
112     // (Since ints are passed by value, it is OK to change it)
113     if (oper != NOT_IN) {
114       oper = IN;
115 
116       // Create a leaf node for this list and store it as the filter
117     } 
118 
119     filter = new SearchBaseLeaf(ElementName, oper, values);
120   } 
121 
122   /**
123    * Change the search filter to one that specifies an element to not
124    * match one of a list of integer values.
125    * The old search filter is deleted.
126    * 
127    * @param ElementName is the name of the element to be matched
128    * @param values is an array of possible integer matches
129    * @param oper is the IN or NOT_IN operator to indicate how to matche
130    */
131   public void matchList(String ElementName, int[] values, int oper) {
132 
133     // Delete the old search filter
134     filter = null;
135 
136     // If not NOT_IN, assume IN
137     // (Since ints are passed by value, it is OK to change it)
138     if (oper != NOT_IN) {
139       oper = IN;
140 
141       // Create a leaf node for this list and store it as the filter
142     } 
143 
144     filter = new SearchBaseLeafInt(ElementName, oper, values);
145   } 
146 
147   /**
148    * Change the search filter to one that specifies an element to not
149    * match one single value.
150    * The old search filter is deleted.
151    * 
152    * @param ElementName is the name of the element to be matched
153    * @param value is the value to not be matched
154    * @param oper is the IN or NOT_IN operator to indicate how to matche
155    */
156   public void matchValue(String ElementName, String value, int oper) {
157 
158     // Delete the old search filter
159     filter = null;
160 
161     // If not NOT_IN, assume IN
162     // (Since ints are passed by value, it is OK to change it)
163     if (oper != NOT_IN) {
164       oper = IN;
165 
166       // Create a String array in which to hold the one name,
167       // and put that name in the array
168     } 
169 
170     String[] ValueArray = new String[1];
171 
172     ValueArray[0] = value;
173 
174     // Create a leaf node for this list and store it as the filter
175     filter = new SearchBaseLeaf(ElementName, oper, ValueArray);
176   } 
177 
178   /**
179    * -----------------------------------------------------------
180    * @param ElementName
181    * @param value
182    * @param oper
183    */
184   public void matchValue(String ElementName, int value, int oper) {
185 
186     // Delete the old search filter
187     filter = null;
188 
189     // If not NOT_IN, assume IN
190     // (Since ints are passed by value, it is OK to change it)
191     if (oper != NOT_IN) {
192       oper = IN;
193 
194       // Create a leaf node for this list and store it as the filter
195     } 
196 
197     filter = new SearchBaseLeafInt(ElementName, oper, new int[] {
198       value
199     });
200   } 
201 
202   /**
203    * Change the search filter to one that compares an element name to a value.
204    * The old search filter is deleted.
205    * 
206    * @param ElementName is the name of the element to be tested
207    * @param value is the value to be compared against
208    * @param oper is the binary comparison operator to be used
209    * @exception gov.lanl.Database.DBException
210    */
211   public void compareFilter(String ElementName, String value, 
212                 int oper) throws DBException {
213 
214     // Delete the old search filter
215     filter = null;
216 
217     // If this is not a binary operator, throw an exception
218     if ((oper & BINARY_OPER_MASK) == 0) {
219       throw new DBException();
220 
221       // Create a SearchBaseLeafComparison node and store it as the filter
222     } 
223 
224     filter = new SearchBaseLeafComparison(ElementName, oper, value);
225   } 
226 
227   /**
228    * Change the search filter to one that specifies a set of elements and their values
229    * that must match, and the operator to use to combine the elements.
230    * Each key is compared for an equal match to the value, and all
231    * comparisons are combined by the specified logical operator (OR or AND).
232    * The old search filter is deleted.
233    * 
234    * @param elements is a hashtable holding key-value pairs
235    * @param combine_op is the logical operator to be used to combine the comparisons
236    * @param compare_op is the binary operator to be used for the comparisons
237    * @exception gov.lanl.Database.DBException
238    */
239   public void matchSet(Hashtable elements, int combine_op, 
240              int compare_op) throws DBException {
241 
242     // Delete the old search filter
243     filter = null;
244 
245     // If combine_op is not a logical operator, throw an exception
246     if ((combine_op & LOGICAL_OPER_MASK) == 0) {
247       throw new DBException();
248 
249       // If compare_op is not a binary operator, throw an exception
250     } 
251 
252     if ((compare_op & BINARY_OPER_MASK) == 0) {
253       throw new DBException();
254 
255       // Create a vector that will hold the comparison nodes for all elements in the hashtable
256     } 
257 
258     Vector compareVector = new Vector();
259 
260     // For each of the elements in the hashtable, create a comparison node for the match
261     for (Enumeration e = elements.keys(); e.hasMoreElements(); ) {
262 
263       // Get the element name from the enumerator
264       // and its value
265       String elementName = (String) e.nextElement();
266       String elementValue = (String) elements.get(elementName);
267 
268       // Create a comparison node for this list and store it as the filter
269       SearchBaseLeafComparison comparenode = 
270         new SearchBaseLeafComparison(elementName, compare_op, elementValue);
271 
272       // Add this leaf node to the vector
273       compareVector.addElement(comparenode);
274     } 
275 
276     // Now return a node that holds this set of leaf nodes
277     filter = new SearchBaseNode(combine_op, compareVector);
278   } 
279 
280   /**
281    * Change the search filter to one that specifies a set of elements and their values
282    * that must match, and the operator to use to combine the elements.
283    * Each element name is compared for an equal match to the value, and all
284    * comparisons are combined by the specified logical operator (OR or AND).
285    * The old search filter is deleted.
286    * 
287    * @param ElementNames is an array of names of elements to be tested
288    * @param ElementValues is an array of values for the corresponding element
289    * @param oper is the logical operator to be used to combine the comparisons
290    * @exception gov.lanl.Database.DBException
291    */
292   public void matchSet(String[] ElementNames, String[] ElementValues, 
293              int op) throws DBException {
294 
295     // Delete the old search filter
296     filter = null;
297 
298     // If this is not a logical operator, throw an exception
299     if ((op & LOGICAL_OPER_MASK) == 0) {
300       throw new DBException();
301 
302       // Create a vector that will hold the leaf nodes for all elements in the hashtable
303     } 
304 
305     Vector leafVector = new Vector();
306 
307     // For each of the elements in the array, create a leaf node for the match
308     int numnames = ElementNames.length;
309 
310     for (int i = 0; i < numnames; i++) {
311 
312       // Create a leaf node for this list and store it as the filter
313       SearchBaseLeaf leafnode = new SearchBaseLeaf(ElementNames[i], IN, 
314           ElementValues[i]);
315 
316       // Add this leaf node to the vector
317       leafVector.addElement(leafnode);
318     } 
319 
320     // Now return a node that holds this set of leaf nodes
321     filter = new SearchBaseNode(op, leafVector);
322   } 
323 
324   /**
325    * Combine other search filters with this one, using the specific operator.
326    * 
327    * @param new_filters is a vector of SearchFilter classes to be combined
328    * @param op is the logical operator to be used to combine the filters
329    * @exception gov.lanl.Database.DBException
330    */
331   public void combine(Vector new_filters, int op) throws DBException {
332 
333     // If this is not a logical operator, throw an exception
334     if ((op & LOGICAL_OPER_MASK) == 0) {
335       throw new DBException();
336 
337       // Create a new vector consisting of just the filters
338       // from the SearchFilter classes in new_filters
339     } 
340 
341     Vector filters = new Vector();
342 
343     // Now add in all the nodes of the new filters
344     for (Enumeration e = new_filters.elements(); e.hasMoreElements(); ) {
345 
346       // Get the search filter from the vector
347       SearchFilter f = (SearchFilter) e.nextElement();
348 
349       filters.addElement(f.getFilter());
350     } 
351 
352     // Create a node for this list and return it
353     filter = new SearchBaseNode(op, filter, filters);
354   } 
355 
356   /**
357    * Combine one other search filters with this one, using the specific operator.
358    * 
359    * @param new_filter is the SearchFilter class to be combined
360    * @param op is the logical operator to be used to combine the filters
361    * @exception gov.lanl.Database.DBException
362    */
363   public void combine(SearchFilter new_filter, int op) throws DBException {
364 
365     // If this is not a logical operator, throw an exception
366     if ((op & LOGICAL_OPER_MASK) == 0) {
367       throw new DBException();
368 
369       // Create a new vector consisting of just the filters
370       // from the SearchFilter classes in new_filters
371     } 
372 
373     Vector filters = new Vector();
374 
375     filters.addElement(new_filter.getFilter());
376 
377     // Create a node for this list and return it
378     filter = new SearchBaseNode(op, filter, filters);
379   } 
380 
381   /**
382    * Static method to convert a binary operator into a string.
383    * 
384    * @param oper is the binary comparison operator to be converted
385    * @return
386    */
387   protected static String ConvertBinaryOperator(int oper) {
388 
389     // Convert the operator into the proper string
390     String oper_string;
391 
392     switch (oper) {
393 
394     default:
395 
396     case EQUAL:
397       oper_string = "=";
398 
399       break;
400 
401     case LIKE:
402       oper_string = "LIKE";
403 
404       break;
405 
406     case NOT_EQUAL:
407       oper_string = "!=";
408 
409       break;
410 
411     case LESS_THAN:
412       oper_string = "<";
413 
414       break;
415 
416     case GREATER_THAN:
417       oper_string = ">";
418 
419       break;
420 
421     case GREATER_EQUAL:
422       oper_string = ">=";
423 
424       break;
425 
426     case LESS_EQUAL:
427       oper_string = "<=";
428 
429       break;
430     }
431 
432     return oper_string;
433   } 
434 
435   /**
436    * Get the actual filter out of the class.
437    * This is only needed when combining filters together
438    * and one instantiation has to get the filter from another.
439    * However, I do not know how to protect it from outside use.
440    * @return
441    * 
442    */
443   protected SearchBase getFilter() {
444     return filter;
445   } 
446 
447   /**
448    * Converts this search filter into a search string for use by a database.
449    * 
450    */
451 
452   /**
453    * -----------------------------------------------------------
454    * @return
455    */
456   public abstract String toString();
457 
458   /**
459    * SearchBase is the base node class for the parse tree
460    * This class holds the binary operator
461    * 
462    */
463 
464   // ===============================================================
465   protected class SearchBase {
466 
467     // Define the operator to be used for this group
468     public int oper;
469 
470     /**
471      * Constructor.
472      * This is protected so only the subclasses can instantiate it
473      * 
474      */
475 
476     // ------------------------------------------------------------
477     protected SearchBase() {}
478 
479   }
480 
481   /**
482    * SearchBaseLeafComparison holds a leaf of the search tree
483    * This class holds an element name, a binary operator, and a value to be compared
484    */
485 
486   // ===============================================================
487   protected class SearchBaseLeafComparison extends SearchBase {
488 
489     // Define the element name
490     public String elementName;
491 
492     // Only operators allowed are binary operators
493     // Define the comparison value
494     public String value;
495 
496     /**
497      * Constructor.
498      * 
499      * @param ElementName is the name of the element to be tested
500      * @param oper is the binary operator to be used for the comparison
501      * @param value is the value to be used for the comparison
502      */
503     SearchBaseLeafComparison(String ElementName, int oper, String value) {
504       this.elementName = ElementName;
505       this.oper = oper;
506       this.value = value;
507     }
508 
509   }
510 
511   /**
512    * SearchBaseLeaf holds a leaf of the search tree
513    * This class holds an element name, and a vector of possible matches.
514    * It searches for an element of the given name that matches at least
515    * one of the strings in the array (IN), or does not match any (NOT_IN)
516    * 
517    */
518 
519   // ===============================================================
520   protected class SearchBaseLeaf extends SearchBase {
521 
522     // Define the element name
523     public String elementName;
524 
525     // Only operators allowed are IN and NOT_IN
526     // Define the vector of possible matches
527     public String[] matches;
528 
529     /**
530      * Constructor.
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 matches is an array of String values to be matched
535      */
536     SearchBaseLeaf(String ElementName, int oper, String[] matches) {
537       this.elementName = ElementName;
538       this.oper = oper;
539       this.matches = matches;
540     }
541 
542     /**
543      * Constructor for only one value.
544      * 
545      * @param ElementName is the name of the element to be tested
546      * @param oper is the operator (IN or NOT_IN) to be used for the comparison
547      * @param match is a string value to be matched
548      */
549     SearchBaseLeaf(String ElementName, int oper, String match) {
550       this.elementName = ElementName;
551       this.oper = oper;
552       this.matches = new String[1];
553       this.matches[0] = match;
554     }
555 
556   }
557 
558   /**
559    * SearchBaseLeafInt holds a leaf of the search tree with integers
560    * This class holds an element name, and a vector of possible matches.
561    * It searches for an element of the given name that matches at least
562    * one of the integers in the array (IN), or does not match any (NOT_IN)
563    */
564 
565   // ===============================================================
566   protected class SearchBaseLeafInt extends SearchBase {
567 
568     // Define the element name
569     public String elementName;
570 
571     // Only operators allowed are IN and NOT_IN
572     // Define the vector of possible matches
573     public int[] matches;
574 
575     /**
576      * Constructor.
577      * 
578      * @param ElementName is the name of the element to be tested
579      * @param oper is the operator (IN or NOT_IN) to be used for the comparison
580      * @param matches is an array of integer values to be matched
581      */
582     SearchBaseLeafInt(String ElementName, int oper, int[] matches) {
583       this.elementName = ElementName;
584       this.oper = oper;
585       this.matches = matches;
586     }
587 
588     /**
589      * Constructor for only one value.
590      * 
591      * @param ElementName is the name of the element to be tested
592      * @param oper is the operator (IN or NOT_IN) to be used for the comparison
593      * @param match is an int value to be matched
594      */
595     SearchBaseLeafInt(String ElementName, int oper, int match) {
596       this.elementName = ElementName;
597       this.oper = oper;
598       this.matches = new int[1];
599       this.matches[0] = match;
600     }
601 
602   }
603 
604   /**
605    * Define the class to represent a node of the search tree
606    * This class holds an operator and a vector other nodes.
607    */
608 
609   // ===============================================================
610   protected class SearchBaseNode extends SearchBase {
611 
612     // Define the vector of other nodes
613     public Vector nodes;
614 
615     /**
616      * Constructor.
617      * Store a list of filters and an operator for combining them.
618      * 
619      * @param oper is the operator (IN or NOT_IN) to be used for the comparison
620      * @param new_filters is a vector of filters to be combined
621      */
622     SearchBaseNode(int oper, Vector new_filters) {
623       this.oper = oper;
624       this.nodes = new_filters;
625     }
626 
627     /**
628      * Constructor for a specific filter and a vector of new ones.
629      * Store a list of filters and an operator for combining them.
630      * 
631      * @param oper is the operator (IN or NOT_IN) to be used for the comparison
632      * @param filter is the first filter to be combined
633      * @param new_filters is a vector of filters to be combined
634      */
635     SearchBaseNode(int oper, Object filter, Vector new_filters) {
636 
637       // Store the operator
638       this.oper = oper;
639 
640       // Create a vector and add in the first filter as the initial node (if present)
641       nodes = new Vector();
642 
643       if (filter != null) {
644         nodes.addElement(filter);
645 
646         // Now add in all the nodes of the new filters
647       } 
648 
649       for (Enumeration e = new_filters.elements(); e.hasMoreElements(); ) {
650         nodes.addElement(e.nextElement());
651       } 
652     }
653 
654   }
655 
656 }
657 
658 
659 
660 /*--- formatting done in "OpenEMed Convention" style on 10-22-2001 ---*/
661