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

Quick Search    Search Deep

Source code: ojb/broker/query/SearchFilter.java


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