001 package org.apache.ojb.broker.query;
002
003 /* Copyright 2002-2005 The Apache Software Foundation
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 import java.util.Enumeration;
019 import java.util.Hashtable;
020 import java.util.Vector;
021
022 /**
023 * OJB Search Filter Class for ObJectRelationalBridge O/R mapping tool
024 *
025 * This class builds a search filter tree, specifing how names and
026 * values are to be compared when searching a database.
027 * This extends SearchFilter and implements the Convert method
028 * that produces the search filter string for the SQL database
029 *
030 * @author David Forslund
031 * @author koenig
032 * @version $Revision: 1.1 $ $Date: 2007-08-24 22:17:36 $
033 */
034 public class OJBSearchFilter extends SearchFilter
035 {
036 Criteria criteria = new Criteria();
037
038 /**
039 * Constructors are not needed, as the base class has a default constructor.
040 *
041 */
042
043 /**
044 * Change the search filter to one that specifies an element to
045 * match or not match one of a list of values.
046 * The old search filter is deleted.
047 *
048 * @param elementName is the name of the element to be matched
049 * @param values is a vector of possible matches
050 * @param oper is the IN or NOT_IN operator to indicate how to matche
051 */
052 public void matchList(String elementName, Vector values, int oper)
053 {
054
055 // Delete the old search criteria
056 criteria = new Criteria();
057
058 if (oper != NOT_IN)
059 {
060 for (int i = 0; i < values.size(); i++)
061 {
062 Criteria tempCrit = new Criteria();
063
064 tempCrit.addEqualTo(elementName, values.elementAt(i));
065 criteria.addOrCriteria(tempCrit);
066 }
067 }
068 else
069 {
070 for (int i = 0; i < values.size(); i++)
071 {
072 criteria.addNotEqualTo(elementName, values.elementAt(i));
073 }
074 }
075 }
076
077 /**
078 * Change the search filter to one that specifies an element to not
079 * match one of a list of values.
080 * The old search filter is deleted.
081 *
082 * @param elementName is the name of the element to be matched
083 * @param values is an array of possible matches
084 * @param oper is the IN or NOT_IN operator to indicate how to matche
085 */
086 public void matchList(String elementName, String[] values, int oper)
087 {
088
089 // see also matchList(String elementName, Vector values, int oper)
090 // Delete the old search criteria
091 criteria = new Criteria();
092
093 if (oper != NOT_IN)
094 {
095 for (int i = 0; i < values.length; i++)
096 {
097 Criteria tempCrit = new Criteria();
098
099 tempCrit.addEqualTo(elementName, values[i]);
100 criteria.addOrCriteria(tempCrit);
101 }
102 }
103 else
104 {
105 for (int i = 0; i < values.length; i++)
106 {
107 criteria.addNotEqualTo(elementName, values[i]);
108 }
109 }
110 }
111
112 /**
113 * Change the search filter to one that specifies an element to not
114 * match one of a list of integer values.
115 * The old search filter is deleted.
116 *
117 * @param elementName is the name of the element to be matched
118 * @param values is an array of possible integer matches
119 * @param oper is the IN or NOT_IN operator to indicate how to matche
120 */
121 public void matchList(String elementName, int[] values, int oper)
122 {
123
124 // see also matchList(String elementName, Vector values, int oper)
125 // Delete the old search criteria
126 criteria = new Criteria();
127
128 if (oper != NOT_IN)
129 {
130 for (int i = 0; i < values.length; i++)
131 {
132 Criteria tempCrit = new Criteria();
133
134 tempCrit.addEqualTo(elementName, new Integer(values[i]));
135 criteria.addOrCriteria(tempCrit);
136 }
137 }
138 else
139 {
140 for (int i = 0; i < values.length; i++)
141 {
142 criteria.addNotEqualTo(elementName, new Integer(values[i]));
143 }
144 }
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
159 // Delete the old search criteria
160 criteria = new Criteria();
161
162 if (oper != NOT_IN)
163 {
164 criteria.addEqualTo(elementName, value);
165 }
166 else
167 {
168 criteria.addNotEqualTo(elementName, value);
169 }
170 }
171
172 /**
173 * -----------------------------------------------------------
174 * @param elementName
175 * @param value
176 * @param oper
177 */
178 public void matchValue(String elementName, int value, int oper)
179 {
180
181 // Delete the old search criteria
182 criteria = new Criteria();
183
184 if (oper != NOT_IN)
185 {
186 criteria.addEqualTo(elementName, new Integer(value));
187 }
188 else
189 {
190 criteria.addNotEqualTo(elementName, new Integer(value));
191 }
192 }
193
194 /**
195 * Change the search filter to one that compares an element name to a value.
196 * The old search filter is deleted.
197 *
198 * @param elementName is the name of the element to be tested
199 * @param value is the value to be compared against
200 * @param oper is the binary comparison operator to be used
201 * @exception DBException
202 */
203 public void compareFilter(String elementName, String value,
204 int oper) throws DBException
205 {
206
207 // Delete the old search criteria
208 criteria = new Criteria();
209
210 // If this is not a binary operator, throw an exception
211 if ((oper & BINARY_OPER_MASK) == 0)
212 {
213 throw new DBException();
214 }
215
216 switch (oper)
217 {
218
219 case LIKE:
220 {
221 criteria.addLike(elementName, value);
222
223 break;
224 }
225
226 case EQUAL:
227 {
228 criteria.addEqualTo(elementName, value);
229
230 break;
231 }
232
233 case NOT_EQUAL:
234 {
235 criteria.addNotEqualTo(elementName, value);
236
237 break;
238 }
239
240 case LESS_THAN:
241 {
242 criteria.addLessThan(elementName, value);
243
244 break;
245 }
246
247 case GREATER_THAN:
248 {
249 criteria.addGreaterThan(elementName, value);
250
251 break;
252 }
253
254 case GREATER_EQUAL:
255 {
256 criteria.addGreaterOrEqualThan(elementName, value);
257
258 break;
259 }
260
261 case LESS_EQUAL:
262 {
263 criteria.addLessOrEqualThan(elementName, value);
264
265 break;
266 }
267
268 default:
269 {
270 throw new DBException("Unsupported binary operation in OJBSearchFilter!");
271 }
272 }
273 }
274
275 /**
276 * Change the search filter to one that specifies a set of elements and their values
277 * that must match, and the operator to use to combine the elements.
278 * Each key is compared for an equal match to the value, and all
279 * comparisons are combined by the specified logical operator (OR or AND).
280 * The old search filter is deleted.
281 *
282 * @param elements is a hashtable holding key-value pairs
283 * @param combine_op is the logical operator to be used to combine the comparisons
284 * @param compare_op is the binary operator to be used for the comparisons
285 * @exception DBException
286 */
287 public void matchSet(Hashtable elements, int combine_op,
288 int compare_op) throws DBException
289 {
290
291 // Delete the old search criteria
292 criteria = new Criteria();
293
294 // If compare_op is not a binary operator, throw an exception
295 if ((compare_op & BINARY_OPER_MASK) == 0)
296 {
297 throw new DBException();
298 }
299
300 if (combine_op == AND)
301 {
302 // combine all value pairs by an AND
303
304 // For each of the elements in the hashtable, create a comparison node for the match
305 for (Enumeration e = elements.keys(); e.hasMoreElements();)
306 {
307
308 // Get the element name from the enumerator
309 // and its value
310 String elementName = (String) e.nextElement();
311 String elementValue = (String) elements.get(elementName);
312
313 switch (compare_op)
314 {
315
316 case LIKE:
317 {
318 criteria.addLike(elementName, elementValue);
319
320 break;
321 }
322
323 case EQUAL:
324 {
325 criteria.addEqualTo(elementName, elementValue);
326
327 break;
328 }
329
330 case NOT_EQUAL:
331 {
332 criteria.addNotEqualTo(elementName, elementValue);
333
334 break;
335 }
336
337 case LESS_THAN:
338 {
339 criteria.addLessThan(elementName, elementValue);
340
341 break;
342 }
343
344 case GREATER_THAN:
345 {
346 criteria.addGreaterThan(elementName, elementValue);
347
348 break;
349 }
350
351 case GREATER_EQUAL:
352 {
353 criteria.addGreaterOrEqualThan(elementName, elementValue);
354
355 break;
356 }
357
358 case LESS_EQUAL:
359 {
360 criteria.addLessOrEqualThan(elementName, elementValue);
361
362 break;
363 }
364
365 default:
366 {
367 throw new DBException("Unsupported binary operation in OJBSearchFilter!");
368 }
369 } // end of switch
370 } // end of for
371 }
372 else if (combine_op == OR)
373 {
374 // combine all value pairs by an OR
375 // For each of the elements in the hashtable, create a comparison node for the match
376 for (Enumeration e = elements.keys(); e.hasMoreElements();)
377 {
378
379 // Get the element name from the enumerator
380 // and its value
381 String elementName = (String) e.nextElement();
382 String elementValue = (String) elements.get(elementName);
383
384 switch (compare_op)
385 {
386
387 case LIKE:
388 {
389 Criteria tempCrit = new Criteria();
390
391 tempCrit.addLike(elementName, elementValue);
392 criteria.addOrCriteria(tempCrit);
393
394 break;
395 }
396
397 case EQUAL:
398 {
399 Criteria tempCrit = new Criteria();
400
401 tempCrit.addEqualTo(elementName, elementValue);
402 criteria.addOrCriteria(tempCrit);
403
404 break;
405 }
406
407 case NOT_EQUAL:
408 {
409 Criteria tempCrit = new Criteria();
410
411 tempCrit.addNotEqualTo(elementName, elementValue);
412 criteria.addOrCriteria(tempCrit);
413
414 break;
415 }
416
417 case LESS_THAN:
418 {
419 Criteria tempCrit = new Criteria();
420
421 tempCrit.addLessThan(elementName, elementValue);
422 criteria.addOrCriteria(tempCrit);
423
424 break;
425 }
426
427 case GREATER_THAN:
428 {
429 Criteria tempCrit = new Criteria();
430
431 tempCrit.addGreaterThan(elementName, elementValue);
432 criteria.addOrCriteria(tempCrit);
433
434 break;
435 }
436
437 case GREATER_EQUAL:
438 {
439 Criteria tempCrit = new Criteria();
440
441 tempCrit.addGreaterOrEqualThan(elementName, elementValue);
442 criteria.addOrCriteria(tempCrit);
443
444 break;
445 }
446
447 case LESS_EQUAL:
448 {
449 Criteria tempCrit = new Criteria();
450
451 tempCrit.addLessOrEqualThan(elementName, elementValue);
452 criteria.addOrCriteria(tempCrit);
453
454 break;
455 }
456
457 default:
458 {
459 throw new DBException("Unsupported binary operation in OJBSearchFilter!");
460 }
461 } // end of switch
462 } // end of for
463
464 }
465 else
466 {
467
468 // combine_op is not a logical operator, throw an exception
469 throw new DBException();
470 }
471 }
472
473 /**
474 * Change the search filter to one that specifies a set of elements and their values
475 * that must match, and the operator to use to combine the elements.
476 * Each element name is compared for an equal match to the value, and all
477 * comparisons are combined by the specified logical operator (OR or AND).
478 * The old search filter is deleted.
479 *
480 * @param elementNames is an array of names of elements to be tested
481 * @param elementValues is an array of values for the corresponding element
482 * @param op is the logical operator to be used to combine the comparisons
483 * @exception DBException
484 */
485 public void matchSet(String[] elementNames, String[] elementValues,
486 int op) throws DBException
487 {
488
489 // Delete the old search criteria
490 criteria = new Criteria();
491
492 if (op == OR)
493 {
494 // For each of the elements in the array, create a leaf node for the match
495 for (int i = 0; i < elementNames.length; i++)
496 {
497 Criteria tempCrit = new Criteria();
498
499 tempCrit.addEqualTo(elementNames[i], elementValues[i]);
500 criteria.addOrCriteria(tempCrit);
501 }
502 }
503 else if (op == AND)
504 {
505 for (int i = 0; i < elementNames.length; i++)
506 {
507 criteria.addEqualTo(elementNames[i], elementValues[i]);
508 }
509 }
510 else
511 {
512 throw new DBException();
513 }
514 }
515
516 /**
517 * Combine other search filters with this one, using the specific operator.
518 *
519 * @param new_filters is a vector of SearchFilter classes to be combined
520 * @param op is the logical operator to be used to combine the filters
521 * @exception DBException
522 */
523 public void combine(Vector new_filters, int op) throws DBException
524 {
525 for (Enumeration elems = new_filters.elements(); elems.hasMoreElements();)
526 {
527 SearchFilter filter = (SearchFilter) elems.nextElement();
528
529 combine(filter, op);
530 }
531 }
532
533 /**
534 * Combine one other search filters with this one, using the specific operator.
535 *
536 * @param new_filter is the SearchFilter class to be combined
537 * @param op is the logical operator to be used to combine the filters
538 * @exception DBException
539 */
540 public void combine(SearchFilter new_filter, int op) throws DBException
541 {
542
543 // cast down to OJBSearchFilter
544 OJBSearchFilter ojbFilter = (OJBSearchFilter) new_filter;
545
546 switch (op)
547 {
548
549 case OR:
550 {
551 criteria.addOrCriteria(ojbFilter.getCriteria());
552 break;
553 }
554
555 case AND:
556 {
557 criteria.addAndCriteria(ojbFilter.getCriteria());
558 break;
559 }
560
561 default:
562 {
563 throw new DBException();
564 }
565 }
566 }
567
568 /**
569 * Converts this search filter into a search string
570 * Note:
571 * ObJectRelationalBridge can't parse a SQL string yet, the functionality
572 * is therefor not implemented!
573 */
574
575 /**
576 * -----------------------------------------------------------
577 * @return
578 */
579 public String toString()
580 {
581
582 // return "";
583 return criteria.toString();
584 }
585
586 /**
587 * Returns the search critera
588 *
589 */
590
591 /**
592 * -----------------------------------------------------------
593 * @return
594 */
595 protected Criteria getCriteria()
596 {
597
598 // return the search criteria
599 return criteria;
600 }
601
602 }