1 package org.apache.torque.util;
2
3 /* ====================================================================
4 * The Apache Software License, Version 1.1
5 *
6 * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
7 * reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. The end-user documentation included with the redistribution,
22 * if any, must include the following acknowledgment:
23 * "This product includes software developed by the
24 * Apache Software Foundation (http://www.apache.org/)."
25 * Alternately, this acknowledgment may appear in the software itself,
26 * if and wherever such third-party acknowledgments normally appear.
27 *
28 * 4. The names "Apache" and "Apache Software Foundation" and
29 * "Apache Turbine" must not be used to endorse or promote products
30 * derived from this software without prior written permission. For
31 * written permission, please contact apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache",
34 * "Apache Turbine", nor may "Apache" appear in their name, without
35 * prior written permission of the Apache Software Foundation.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This software consists of voluntary contributions made by many
52 * individuals on behalf of the Apache Software Foundation. For more
53 * information on the Apache Software Foundation, please see
54 * <http://www.apache.org/>.
55 */
56
57 import java.io.Serializable;
58 import java.lang.reflect.Array;
59 import java.math.BigDecimal;
60 import java.util.ArrayList;
61 import java.util.Arrays;
62 import java.util.GregorianCalendar;
63 import java.util.HashMap;
64 import java.util.Hashtable;
65 import java.util.Iterator;
66 import java.util.List;
67 import java.util.Map;
68
69 import org.apache.commons.lang.StringUtils;
70
71 import org.apache.commons.logging.Log;
72 import org.apache.commons.logging.LogFactory;
73
74 import org.apache.torque.Torque;
75 import org.apache.torque.adapter.DB;
76 import org.apache.torque.om.DateKey;
77 import org.apache.torque.om.ObjectKey;
78
79 /***
80 * This is a utility class that is used for retrieving different types
81 * of values from a hashtable based on a simple name string. This
82 * class is meant to minimize the amount of casting that needs to be
83 * done when working with Hashtables.
84 *
85 * NOTE: other methods will be added as needed and as time permits.
86 *
87 * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
88 * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
89 * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
90 * @author <a href="mailto:eric@dobbse.net">Eric Dobbs</a>
91 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
92 * @author <a href="mailto:sam@neurogrid.com">Sam Joseph</a>
93 * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
94 * @version $Id: Criteria.java,v 1.42 2003/06/24 09:47:30 mpoeschl Exp $
95 */
96 public class Criteria extends Hashtable
97 {
98
99 /*** Comparison type. */
100 public static final SqlEnum EQUAL = SqlEnum.EQUAL;
101
102 /*** Comparison type. */
103 public static final SqlEnum NOT_EQUAL = SqlEnum.NOT_EQUAL;
104
105 /*** Comparison type. */
106 public static final SqlEnum ALT_NOT_EQUAL = SqlEnum.ALT_NOT_EQUAL;
107
108 /*** Comparison type. */
109 public static final SqlEnum GREATER_THAN = SqlEnum.GREATER_THAN;
110
111 /*** Comparison type. */
112 public static final SqlEnum LESS_THAN = SqlEnum.LESS_THAN;
113
114 /*** Comparison type. */
115 public static final SqlEnum GREATER_EQUAL = SqlEnum.GREATER_EQUAL;
116
117 /*** Comparison type. */
118 public static final SqlEnum LESS_EQUAL = SqlEnum.LESS_EQUAL;
119
120 /*** Comparison type. */
121 public static final SqlEnum LIKE = SqlEnum.LIKE;
122
123 /*** Comparison type. */
124 public static final SqlEnum NOT_LIKE = SqlEnum.NOT_LIKE;
125
126 /*** Comparison type. */
127 public static final SqlEnum CUSTOM = SqlEnum.CUSTOM;
128
129 /*** Comparison type. */
130 public static final SqlEnum DISTINCT = SqlEnum.DISTINCT;
131
132 /*** Comparison type. */
133 public static final SqlEnum IN = SqlEnum.IN;
134
135 /*** Comparison type. */
136 public static final SqlEnum NOT_IN = SqlEnum.NOT_IN;
137
138 /*** Comparison type. */
139 public static final SqlEnum ALL = SqlEnum.ALL;
140
141 /*** Comparison type. */
142 public static final SqlEnum JOIN = SqlEnum.JOIN;
143
144 /*** "Order by" qualifier - ascending */
145 private static final SqlEnum ASC = SqlEnum.ASC;
146
147 /*** "Order by" qualifier - descending */
148 private static final SqlEnum DESC = SqlEnum.DESC;
149
150 /*** "IS NULL" null comparison */
151 public static final SqlEnum ISNULL = SqlEnum.ISNULL;
152
153 /*** "IS NOT NULL" null comparison */
154 public static final SqlEnum ISNOTNULL = SqlEnum.ISNOTNULL;
155
156 /*** "CURRENT_DATE" ANSI SQL function */
157 public static final SqlEnum CURRENT_DATE = SqlEnum.CURRENT_DATE;
158
159 /*** "CURRENT_TIME" ANSI SQL function */
160 public static final SqlEnum CURRENT_TIME = SqlEnum.CURRENT_TIME;
161
162 private static final int DEFAULT_CAPACITY = 10;
163
164 private boolean ignoreCase = false;
165 private boolean singleRecord = false;
166 private boolean cascade = false;
167 private UniqueList selectModifiers = new UniqueList();
168 private UniqueList selectColumns = new UniqueList();
169 private UniqueList orderByColumns = new UniqueList();
170 private UniqueList groupByColumns = new UniqueList();
171 private Criterion having = null;
172 private Hashtable asColumns = new Hashtable(8);
173 private ArrayList joinL = null;
174 private ArrayList joinR = null;
175
176 /*** The name of the database. */
177 private String dbName;
178
179 /*** The name of the database as given in the contructor. */
180 private String originalDbName;
181
182 /***
183 * To limit the number of rows to return. <code>-1</code> means return all
184 * rows.
185 */
186 private int limit = -1;
187
188 /*** To start the results at a row other than the first one. */
189 private int offset = 0;
190
191 private HashMap aliases = null;
192
193 private boolean useTransaction = false;
194
195 /*** the log. */
196 private static Log log = LogFactory.getLog(Criteria.class);
197
198 /***
199 * Creates a new instance with the default capacity.
200 */
201 public Criteria()
202 {
203 this(DEFAULT_CAPACITY);
204 }
205
206 /***
207 * Creates a new instance with the specified capacity.
208 *
209 * @param initialCapacity An int.
210 */
211 public Criteria(int initialCapacity)
212 {
213 this(Torque.getDefaultDB(), initialCapacity);
214 }
215
216 /***
217 * Creates a new instance with the default capacity which corresponds to
218 * the specified database.
219 *
220 * @param dbName The dabase name.
221 */
222 public Criteria(String dbName)
223 {
224 this(dbName, DEFAULT_CAPACITY);
225 }
226
227 /***
228 * Creates a new instance with the specified capacity which corresponds to
229 * the specified database.
230 *
231 * @param dbName The dabase name.
232 * @param initialCapacity The initial capacity.
233 */
234 public Criteria(String dbName, int initialCapacity)
235 {
236 super(initialCapacity);
237 this.dbName = dbName;
238 this.originalDbName = dbName;
239 }
240
241 /***
242 * Brings this criteria back to its initial state, so that it
243 * can be reused as if it was new. Except if the criteria has grown in
244 * capacity, it is left at the current capacity.
245 */
246 public void clear()
247 {
248 super.clear();
249 ignoreCase = false;
250 singleRecord = false;
251 cascade = false;
252 selectModifiers.clear();
253 selectColumns.clear();
254 orderByColumns.clear();
255 groupByColumns.clear();
256 having = null;
257 asColumns.clear();
258 joinL = null;
259 joinR = null;
260 dbName = originalDbName;
261 offset = 0;
262 limit = -1;
263 aliases = null;
264 useTransaction = false;
265 }
266
267 /***
268 * Add an AS clause to the select columns. Usage:
269 * <p>
270 * <code>
271 *
272 * Criteria myCrit = new Criteria();
273 * myCrit.addAsColumn("alias", "ALIAS("+MyPeer.ID+")");
274 *
275 * </code>
276 *
277 * @param name wanted Name of the column
278 * @param clause SQL clause to select from the table
279 *
280 * If the name already exists, it is replaced by the new clause.
281 *
282 * @return A modified Criteria object.
283 */
284 public Criteria addAsColumn(String name, String clause)
285 {
286 asColumns.put(name, clause);
287 return this;
288 }
289
290 /***
291 * Get the column aliases.
292 *
293 * @return A Hashtable which map the column alias names
294 * to the alias clauses.
295 */
296 public Hashtable getAsColumns()
297 {
298 return asColumns;
299 }
300
301 /***
302 * Allows one to specify an alias for a table that can
303 * be used in various parts of the SQL.
304 *
305 * @param alias a <code>String</code> value
306 * @param table a <code>String</code> value
307 */
308 public void addAlias(String alias, String table)
309 {
310 if (aliases == null)
311 {
312 aliases = new HashMap(8);
313 }
314 aliases.put(alias, table);
315 }
316
317 /***
318 * Returns the table name associated with an alias.
319 *
320 * @param alias a <code>String</code> value
321 * @return a <code>String</code> value
322 */
323 public String getTableForAlias(String alias)
324 {
325 if (aliases == null)
326 {
327 return null;
328 }
329 return (String) aliases.get(alias);
330 }
331
332 /***
333 * Does this Criteria Object contain the specified key?
334 *
335 * @param table The name of the table.
336 * @param column The name of the column.
337 * @return True if this Criteria Object contain the specified key.
338 */
339 public boolean containsKey(String table, String column)
340 {
341 return containsKey(table + '.' + column);
342 }
343
344 /***
345 * Convenience method to return value as a boolean.
346 *
347 * @param column String name of column.
348 * @return A boolean.
349 */
350 public boolean getBoolean(String column)
351 {
352 return ((Boolean) getCriterion(column).getValue()).booleanValue();
353 }
354
355 /***
356 * Convenience method to return value as a boolean.
357 *
358 * @param table String name of table.
359 * @param column String name of column.
360 * @return A boolean.
361 */
362 public boolean getBoolean(String table, String column)
363 {
364 return getBoolean(new StringBuffer(table.length() + column.length() + 1)
365 .append(table).append('.').append(column)
366 .toString());
367 }
368
369 /***
370 * Will force the sql represented by this criteria to be executed within
371 * a transaction. This is here primarily to support the oid type in
372 * postgresql. Though it can be used to require any single sql statement
373 * to use a transaction.
374 */
375 public void setUseTransaction(boolean v)
376 {
377 useTransaction = v;
378 }
379
380 /***
381 * called by BasePeer to determine whether the sql command specified by
382 * this criteria must be wrapped in a transaction.
383 *
384 * @return a <code>boolean</code> value
385 */
386 protected boolean isUseTransaction()
387 {
388 return useTransaction;
389 }
390
391 /***
392 * Method to return criteria related to columns in a table.
393 *
394 * @param column String name of column.
395 * @return A Criterion.
396 */
397 public Criterion getCriterion(String column)
398 {
399 return (Criterion) super.get(column);
400 }
401
402 /***
403 * Method to return criteria related to a column in a table.
404 *
405 * @param table String name of table.
406 * @param column String name of column.
407 * @return A Criterion.
408 */
409 public Criterion getCriterion(String table, String column)
410 {
411 return getCriterion(
412 new StringBuffer(table.length() + column.length() + 1)
413 .append(table).append('.').append(column)
414 .toString());
415 }
416
417 /***
418 * Method to return criterion that is not added automatically
419 * to this Criteria. This can be used to chain the
420 * Criterions to form a more complex where clause.
421 *
422 * @param column String full name of column (for example TABLE.COLUMN).
423 * @return A Criterion.
424 */
425 public Criterion getNewCriterion(String column, Object value,
426 SqlEnum comparison)
427 {
428 return new Criterion(column, value, comparison);
429 }
430
431 /***
432 * Method to return criterion that is not added automatically
433 * to this Criteria. This can be used to chain the
434 * Criterions to form a more complex where clause.
435 *
436 * @param table String name of table.
437 * @param column String name of column.
438 * @return A Criterion.
439 */
440 public Criterion getNewCriterion(String table, String column,
441 Object value, SqlEnum comparison)
442 {
443 return new Criterion(table, column, value, comparison);
444 }
445
446 /***
447 * This method adds a prepared Criterion object to the Criteria.
448 * You can get a new, empty Criterion object with the
449 * getNewCriterion() method. If a criterion for the requested column
450 * already exists, it is replaced. This is used as follows:
451 *
452 * <p>
453 * <code>
454 * Criteria crit = new Criteria();
455 * Criteria.Criterion c = crit
456 * .getNewCriterion(BasePeer.ID, new Integer(5), Criteria.LESS_THAN);
457 * crit.add(c);
458 * </code>
459 *
460 * @param c A Criterion object
461 *
462 * @return A modified Criteria object.
463 */
464 public Criteria add(Criterion c)
465 {
466 StringBuffer sb = new StringBuffer(c.getTable().length()
467 + c.getColumn().length() + 1);
468 sb.append(c.getTable());
469 sb.append('.');
470 sb.append(c.getColumn());
471 super.put(sb.toString(), c);
472 return this;
473 }
474
475 /***
476 * Method to return a String table name.
477 *
478 * @param name A String with the name of the key.
479 * @return A String with the value of the object at key.
480 */
481 public String getColumnName(String name)
482 {
483 return getCriterion(name).getColumn();
484 }
485
486 /***
487 * Method to return a comparison String.
488 *
489 * @param key String name of the key.
490 * @return A String with the value of the object at key.
491 */
492 public SqlEnum getComparison(String key)
493 {
494 return getCriterion(key).getComparison();
495 }
496
497 /***
498 * Method to return a comparison String.
499 *
500 * @param table String name of table.
501 * @param column String name of column.
502 * @return A String with the value of the object at key.
503 */
504 public SqlEnum getComparison(String table, String column)
505 {
506 return getComparison(
507 new StringBuffer(table.length() + column.length() + 1)
508 .append(table).append('.').append(column)
509 .toString());
510 }
511
512 /***
513 * Convenience method to return a Date.
514 *
515 * @param name column name (TABLE.COLUMN)
516 * @return A java.util.Date with the value of object at key.
517 */
518 public java.util.Date getDate(String name)
519 {
520 return (java.util.Date) getCriterion(name).getValue();
521 }
522
523 /***
524 * Convenience method to return a Date.
525 *
526 * @param table String name of table.
527 * @param column String name of column.
528 * @return A java.util.Date with the value of object at key.
529 */
530 public java.util.Date getDate(String table, String column)
531 {
532 return getDate(
533 new StringBuffer(table.length() + column.length() + 1)
534 .append(table).append('.').append(column)
535 .toString());
536 }
537
538 /***
539 * Get the Database(Map) name.
540 *
541 * @return A String with the Database(Map) name. By default, this
542 * is PoolBrokerService.DEFAULT.
543 */
544 public String getDbName()
545 {
546 return dbName;
547 }
548
549 /***
550 * Set the DatabaseMap name. If <code>null</code> is supplied, uses value
551 * provided by <code>Torque.getDefaultDB()</code>.
552 *
553 * @param dbName A String with the Database(Map) name.
554 */
555 public void setDbName(String dbName)
556 {
557 this.dbName = (dbName == null ? Torque.getDefaultDB() : dbName.trim());
558 }
559
560 /***
561 * Convenience method to return a double.
562 *
563 * @param name A String with the name of the key.
564 * @return A double with the value of object at key.
565 */
566 public double getDouble(String name)
567 {
568 Object obj = getCriterion(name).getValue();
569 if (obj instanceof String)
570 {
571 return new Double((String) obj).doubleValue();
572 }
573 return ((Double) obj).doubleValue();
574 }
575
576 /***
577 * Convenience method to return a double.
578 *
579 * @param table String name of table.
580 * @param column String name of column.
581 * @return A double with the value of object at key.
582 */
583 public double getDouble(String table, String column)
584 {
585 return getDouble(new StringBuffer(table.length() + column.length() + 1)
586 .append(table).append('.').append(column)
587 .toString());
588 }
589
590 /***
591 * Convenience method to return a float.
592 *
593 * @param name A String with the name of the key.
594 * @return A float with the value of object at key.
595 */
596 public float getFloat(String name)
597 {
598 Object obj = getCriterion(name).getValue();
599 if (obj instanceof String)
600 {
601 return new Float((String) obj).floatValue();
602 }
603 return ((Float) obj).floatValue();
604 }
605
606 /***
607 * Convenience method to return a float.
608 *
609 * @param table String name of table.
610 * @param column String name of column.
611 * @return A float with the value of object at key.
612 */
613 public float getFloat(String table, String column)
614 {
615 return getFloat(new StringBuffer(table.length() + column.length() + 1)
616 .append(table).append('.').append(column)
617 .toString());
618 }
619
620 /***
621 * Convenience method to return an Integer.
622 *
623 * @param name A String with the name of the key.
624 * @return An Integer with the value of object at key.
625 */
626 public Integer getInteger(String name)
627 {
628 Object obj = getCriterion(name).getValue();
629 if (obj instanceof String)
630 {
631 return new Integer((String) obj);
632 }
633 return ((Integer) obj);
634 }
635
636 /***
637 * Convenience method to return an Integer.
638 *
639 * @param table String name of table.
640 * @param column String name of column.
641 * @return An Integer with the value of object at key.
642 */
643 public Integer getInteger(String table, String column)
644 {
645 return getInteger(
646 new StringBuffer(table.length() + column.length() + 1)
647 .append(table).append('.').append(column)
648 .toString());
649 }
650
651 /***
652 * Convenience method to return an int.
653 *
654 * @param name A String with the name of the key.
655 * @return An int with the value of object at key.
656 */
657 public int getInt(String name)
658 {
659 Object obj = getCriterion(name).getValue();
660 if (obj instanceof String)
661 {
662 return new Integer((String) obj).intValue();
663 }
664 return ((Integer) obj).intValue();
665 }
666
667 /***
668 * Convenience method to return an int.
669 *
670 * @param table String name of table.
671 * @param column String name of column.
672 * @return An int with the value of object at key.
673 */
674 public int getInt(String table, String column)
675 {
676 return getInt(
677 new StringBuffer(table.length() + column.length() + 1)
678 .append(table).append('.').append(column)
679 .toString());
680 }
681
682 /***
683 * Convenience method to return a BigDecimal.
684 *
685 * @param name A String with the name of the key.
686 * @return A BigDecimal with the value of object at key.
687 */
688 public BigDecimal getBigDecimal(String name)
689 {
690 Object obj = getCriterion(name).getValue();
691 if (obj instanceof String)
692 {
693 return new BigDecimal((String) obj);
694 }
695 return (BigDecimal) obj;
696 }
697
698 /***
699 * Convenience method to return a BigDecimal.
700 *
701 * @param table String name of table.
702 * @param column String name of column.
703 * @return A BigDecimal with the value of object at key.
704 */
705 public BigDecimal getBigDecimal(String table, String column)
706 {
707 return getBigDecimal(
708 new StringBuffer(table.length() + column.length() + 1)
709 .append(table).append('.').append(column)
710 .toString());
711 }
712
713 /***
714 * Convenience method to return a long.
715 *
716 * @param name A String with the name of the key.
717 * @return A long with the value of object at key.
718 */
719 public long getLong(String name)
720 {
721 Object obj = getCriterion(name).getValue();
722 if (obj instanceof String)
723 {
724 return new Long((String) obj).longValue();
725 }
726 return ((Long) obj).longValue();
727 }
728
729 /***
730 * Convenience method to return a long.
731 *
732 * @param table String name of table.
733 * @param column String name of column.
734 * @return A long with the value of object at key.
735 */
736 public long getLong(String table, String column)
737 {
738 return getLong(
739 new StringBuffer(table.length() + column.length() + 1)
740 .append(table).append('.').append(column)
741 .toString());
742 }
743
744 /***
745 * Convenience method to return a String.
746 *
747 * @param name A String with the name of the key.
748 * @return A String with the value of object at key.
749 */
750 public String getString(String name)
751 {
752 return (String) getCriterion(name).getValue();
753 }
754
755 /***
756 * Convenience method to return a String.
757 *
758 * @param table String name of table.
759 * @param column String name of column.
760 * @return A String with the value of object at key.
761 */
762 public String getString(String table, String column)
763 {
764 return getString(
765 new StringBuffer(table.length() + column.length() + 1)
766 .append(table).append('.').append(column)
767 .toString());
768 }
769
770 /***
771 * Method to return a String table name.
772 *
773 * @param name A String with the name of the key.
774 * @return A String with the value of object at key.
775 */
776 public String getTableName(String name)
777 {
778 return getCriterion(name).getTable();
779 }
780
781 /***
782 * Convenience method to return a List.
783 *
784 * @param name A String with the name of the key.
785 * @return A List with the value of object at key.
786 */
787 public List getList(String name)
788 {
789 return (List) getCriterion(name).getValue();
790 }
791
792 /***
793 * Convenience method to return a List.
794 *
795 * @param table String name of table.
796 * @param column String name of column.
797 * @return A List with the value of object at key.
798 */
799 public List getList(String table, String column)
800 {
801 return getList(
802 new StringBuffer(table.length() + column.length() + 1)
803 .append(table).append('.').append(column)
804 .toString());
805 }
806
807 /***
808 * Method to return the value that was added to Criteria.
809 *
810 * @param name A String with the name of the key.
811 * @return An Object with the value of object at key.
812 */
813 public Object getValue(String name)
814 {
815 return getCriterion(name).getValue();
816 }
817
818 /***
819 * Method to return the value that was added to Criteria.
820 *
821 * @param table String name of table.
822 * @param column String name of column.
823 * @return An Object with the value of object at key.
824 */
825 public Object getValue(String table, String column)
826 {
827 return getValue(
828 new StringBuffer(table.length() + column.length() + 1)
829 .append(table).append('.').append(column)
830 .toString());
831 }
832
833 /***
834 * Convenience method to return an ObjectKey.
835 *
836 * @param name A String with the name of the key.
837 * @return An ObjectKey with the value of object at key.
838 */
839 public ObjectKey getObjectKey(String name)
840 {
841 return (ObjectKey) getCriterion(name).getValue();
842 }
843
844 /***
845 * Convenience method to return an ObjectKey.
846 *
847 * @param table String name of table.
848 * @param column String name of column.
849 * @return A String with the value of object at key.
850 */
851 public ObjectKey getObjectKey(String table, String column)
852 {
853 return getObjectKey(
854 new StringBuffer(table.length() + column.length() + 1)
855 .append(table).append('.').append(column)
856 .toString());
857 }
858
859 /***
860 * Overrides Hashtable get, so that the value placed in the
861 * Criterion is returned instead of the Criterion.
862 *
863 * @param key An Object.
864 * @return An Object.
865 */
866 public Object get(Object key)
867 {
868 return getValue((String) key);
869 }
870
871 /***
872 * Overrides Hashtable put, so that this object is returned
873 * instead of the value previously in the Criteria object.
874 * The reason is so that it more closely matches the behavior
875 * of the add() methods. If you want to get the previous value
876 * then you should first Criteria.get() it yourself. Note, if
877 * you attempt to pass in an Object that is not a String, it will
878 * throw a NPE. The reason for this is that none of the add()
879 * methods support adding anything other than a String as a key.
880 *
881 * @param key An Object. Must be instanceof String!
882 * @param value An Object.
883 * @throws NullPointerException if key != String or key/value is null.
884 * @return Instance of self.
885 */
886 public Object put(Object key, Object value)
887 {
888 if (!(key instanceof String))
889 {
890 throw new NullPointerException(
891 "Criteria: Key must be a String object.");
892 }
893 return add((String) key, value);
894 }
895
896 /***
897 * Copies all of the mappings from the specified Map to this Criteria
898 * These mappings will replace any mappings that this Criteria had for any
899 * of the keys currently in the specified Map.
900 *
901 * if the map was another Criteria, its attributes are copied to this
902 * Criteria, overwriting previous settings.
903 *
904 * @param t Mappings to be stored in this map.
905 */
906 public synchronized void putAll(Map t)
907 {
908 Iterator i = t.entrySet().iterator();
909 while (i.hasNext())
910 {
911 Map.Entry e = (Map.Entry) i.next();
912 Object val = e.getValue();
913 if (val instanceof Criteria.Criterion)
914 {
915 super.put(e.getKey(), val);
916 }
917 else
918 {
919 put(e.getKey(), val);
920 }
921 }
922 if (t instanceof Criteria)
923 {
924 Criteria c = (Criteria) t;
925 this.joinL = c.joinL;
926 this.joinR = c.joinR;
927 }
928 /* this would make a copy, not included
929 but might want to use some of it.
930 if (t instanceof Criteria)
931 {
932 Criteria c = (Criteria)t;
933 this.ignoreCase = c.ignoreCase;
934 this.singleRecord = c.singleRecord;
935 this.cascade = c.cascade;
936 this.selectModifiers = c.selectModifiers;
937 this.selectColumns = c.selectColumns;
938 this.orderByColumns = c.orderByColumns;
939 this.dbName = c.dbName;
940 this.limit = c.limit;
941 this.offset = c.offset;
942 this.aliases = c.aliases;
943 }
944 */
945 }
946
947 /***
948 * This method adds a new criterion to the list of criterias. If a
949 * criterion for the requested column already exists, it is
950 * replaced. This is used as follows:
951 *
952 * <p>
953 * <code>
954 * Criteria crit = new Criteria().add("column",
955 * "value");
956 * </code>
957 *
958 * An EQUAL comparison is used for column and value.
959 *
960 * The name of the table must be used implicitly in the column name,
961 * so the Column name must be something like 'TABLE.id'. If you
962 * don't like this, you can use the add(table, column, value) method.
963 *
964 * @param column The column to run the comparison on
965 * @param value An Object.
966 *
967 * @return A modified Criteria object.
968 */
969 public Criteria add (String column, Object value)
970 {
971 add(column, value, EQUAL);
972 return this;
973 }
974
975 /***
976 * This method adds a new criterion to the list of criterias.
977 * If a criterion for the requested column already exists, it is
978 * replaced. If is used as follow:
979 *
980 * <p>
981 * <code>
982 * Criteria crit = new Criteria().add("column",
983 * "value"
984 * "Criterion.GREATER_THAN");
985 * </code>
986 *
987 * Any comparison can be used.
988 *
989 * The name of the table must be used implicitly in the column name,
990 * so the Column name must be something like 'TABLE.id'. If you
991 * don't like this, you can use the add(table, column, value) method.
992 *
993 * @param column The column to run the comparison on
994 * @param value An Object.
995 * @param comparison A String.
996 *
997 * @return A modified Criteria object.
998 */
999 public Criteria add(String column, Object value, SqlEnum comparison)
1000 {
1001 super.put(column, new Criterion(column, value, comparison));
1002 return this;
1003 }
1004
1005 /***
1006 * This method adds a new criterion to the list of criterias.
1007 * If a criterion for the requested column already exists, it is
1008 * replaced. If is used as follows:
1009 *
1010 * <p>
1011 * <code>
1012 * Criteria crit = new Criteria().add("table",
1013 * "column",
1014 * "value");
1015 * </code>
1016 *
1017 * An EQUAL comparison is used for column and value.
1018 *
1019 * @param table Name of the table which contains the column
1020 * @param column The column to run the comparison on
1021 * @param value An Object.
1022 *
1023 * @return A modified Criteria object.
1024 */
1025 public Criteria add(String table, String column, Object value)
1026 {
1027 add(table, column, value, EQUAL);
1028 return this;
1029 }
1030
1031 /***
1032 * This method adds a new criterion to the list of criterias.
1033 * If a criterion for the requested column already exists, it is
1034 * replaced. If is used as follows:
1035 *
1036 * <p>
1037 * <code>
1038 * Criteria crit = new Criteria().add("table",
1039 * "column",
1040 * "value",
1041 * "Criterion.GREATER_THAN");
1042 * </code>
1043 *
1044 * Any comparison can be used.
1045 *
1046 * @param table Name of table which contains the column
1047 * @param column The column to run the comparison on
1048 * @param value An Object.
1049 * @param comparison String describing how to compare the column with
1050 * the value
1051 * @return A modified Criteria object.
1052 */
1053 public Criteria add(String table,
1054 String column,
1055 Object value,
1056 SqlEnum comparison)
1057 {
1058 StringBuffer sb = new StringBuffer(table.length()
1059 + column.length() + 1);
1060 sb.append(table);
1061 sb.append('.');
1062 sb.append(column);
1063 super.put(sb.toString(),
1064 new Criterion(table, column, value, comparison));
1065 return this;
1066 }
1067
1068 /***
1069 * Convenience method to add a boolean to Criteria.
1070 * Equal to
1071 *
1072 * <p>
1073 * <code>
1074 * add(column, new Boolean(value), EQUAL);
1075 * </code>
1076 *
1077 * @param column The column to run the comparison on
1078 * @param value A Boolean.
1079 *
1080 * @return A modified Criteria object.
1081 */
1082 public Criteria add(String column, boolean value)
1083 {
1084 add(column, (value ? Boolean.TRUE : Boolean.FALSE));
1085 return this;
1086 }
1087
1088 /***
1089 * Convenience method to add a boolean to Criteria.
1090 * Equal to
1091 *
1092 * <p>
1093 * <code>
1094 * add(column, new Boolean(value), comparison);
1095 * </code>
1096 *
1097 * @param column The column to run the comparison on
1098 * @param value A Boolean.
1099 * @param comparison String describing how to compare the column with
1100 * the value
1101 * @return A modified Criteria object.
1102 */
1103 public Criteria add(String column, boolean value, SqlEnum comparison)
1104 {
1105 add(column, new Boolean(value), comparison);
1106 return this;
1107 }
1108
1109 /***
1110 * Convenience method to add an int to Criteria.
1111 * Equal to
1112 *
1113 * <p>
1114 * <code>
1115 * add(column, new Integer(value), EQUAL);
1116 * </code>
1117 *
1118 * @param column The column to run the comparison on
1119 * @param value An int.
1120 * @return A modified Criteria object.
1121 */
1122 public Criteria add(String column, int value)
1123 {
1124 add(column, new Integer(value));
1125 return this;
1126 }
1127
1128 /***
1129 * Convenience method to add an int to Criteria.
1130 * Equal to
1131 *
1132 * <p>
1133 * <code>
1134 * add(column, new Integer(value), comparison);
1135 * </code>
1136 *
1137 * @param column The column to run the comparison on
1138 * @param value An int.
1139 * @param comparison String describing how to compare the column with
1140 * the value
1141 * @return A modified Criteria object.
1142 */
1143 public Criteria add(String column, int value, SqlEnum comparison)
1144 {
1145 add(column, new Integer(value), comparison);
1146 return this;
1147 }
1148
1149 /***
1150 * Convenience method to add a long to Criteria.
1151 * Equal to
1152 *
1153 * <p>
1154 * <code>
1155 * add(column, new Long(value), EQUAL);
1156 * </code>
1157 *
1158 * @param column The column to run the comparison on
1159 * @param value A long.
1160 * @return A modified Criteria object.
1161 */
1162 public Criteria add(String column, long value)
1163 {
1164 add(column, new Long(value));
1165 return this;
1166 }
1167
1168 /***
1169 * Convenience method to add a long to Criteria.
1170 * Equal to
1171 *
1172 * <p>
1173 * <code>
1174 * add(column, new Long(value), comparison);
1175 * </code>
1176 *
1177 * @param column The column to run the comparison on
1178 * @param value A long.
1179 * @param comparison String describing how to compare the column with
1180 * the value
1181 * @return A modified Criteria object.
1182 */
1183 public Criteria add(String column, long value, SqlEnum comparison)
1184 {
1185 add(column, new Long(value), comparison);
1186 return this;
1187 }
1188
1189 /***
1190 * Convenience method to add a float to Criteria.
1191 * Equal to
1192 *
1193 * <p>
1194 * <code>
1195 * add(column, new Float(value), EQUAL);
1196 * </code>
1197 *
1198 * @param column The column to run the comparison on
1199 * @param value A float.
1200 * @return A modified Criteria object.
1201 */
1202 public Criteria add(String column, float value)
1203 {
1204 add(column, new Float(value));
1205 return this;
1206 }
1207
1208 /***
1209 * Convenience method to add a float to Criteria.
1210 * Equal to
1211 *
1212 * <p>
1213 * <code>
1214 * add(column, new Float(value), comparison);
1215 * </code>
1216 *
1217 * @param column The column to run the comparison on
1218 * @param value A float.
1219 * @param comparison String describing how to compare the column with
1220 * the value
1221 * @return A modified Criteria object.
1222 */
1223 public Criteria add(String column, float value, SqlEnum comparison)
1224 {
1225 add(column, new Float(value), comparison);
1226 return this;
1227 }
1228
1229 /***
1230 * Convenience method to add a double to Criteria.
1231 * Equal to
1232 *
1233 * <p>
1234 * <code>
1235 * add(column, new Double(value), EQUAL);
1236 * </code>
1237 *
1238 * @param column The column to run the comparison on
1239 * @param value A double.
1240 * @return A modified Criteria object.
1241 */
1242 public Criteria add(String column, double value)
1243 {
1244 add(column, new Double(value));
1245 return this;
1246 }
1247
1248 /***
1249 * Convenience method to add a double to Criteria.
1250 * Equal to
1251 *
1252 * <p>
1253 * <code>
1254 * add(column, new Double(value), comparison);
1255 * </code>
1256 *
1257 * @param column The column to run the comparison on
1258 * @param value A double.
1259 * @param comparison String describing how to compare the column with
1260 * the value
1261 * @return A modified Criteria object.
1262 */
1263 public Criteria add(String column, double value, SqlEnum comparison)
1264 {
1265 add(column, new Double(value), comparison);
1266 return this;
1267 }
1268
1269 /***
1270 * Convenience method to add a Date object specified by
1271 * year, month, and date into the Criteria.
1272 * Equal to
1273 *
1274 * <p>
1275 * <code>
1276 * add(column, new GregorianCalendar(year, month,date), EQUAL);
1277 * </code>
1278 *
1279 * @param column A String value to use as column.
1280 * @param year An int with the year.
1281 * @param month An int with the month. Month value is 0-based.
1282 * e.g., 0 for January
1283 * @param date An int with the date.
1284 * @return A modified Criteria object.
1285 */
1286 public Criteria addDate(String column, int year, int month, int date)
1287 {
1288 add(column, new GregorianCalendar(year, month, date).getTime());
1289 return this;
1290 }
1291
1292 /***
1293 * Convenience method to add a Date object specified by
1294 * year, month, and date into the Criteria.
1295 * Equal to
1296 *
1297 * <p>
1298 * <code>
1299 * add(column, new GregorianCalendar(year, month,date), comparison);
1300 * </code>
1301 *
1302 * @param column The column to run the comparison on
1303 * @param year An int with the year.
1304 * @param month An int with the month. Month value is 0-based.
1305 * e.g., 0 for January
1306 * @param date An int with the date.
1307 * @param comparison String describing how to compare the column with
1308 * the value
1309 * @return A modified Criteria object.
1310 */
1311 public Criteria addDate(String column, int year, int month, int date,
1312 SqlEnum comparison)
1313 {
1314 add(column, new GregorianCalendar(year, month, date).getTime(),
1315 comparison);
1316 return this;
1317 }
1318
1319 /***
1320 * This is the way that you should add a join of two tables. For
1321 * example:
1322 *
1323 * <p>
1324 * AND PROJECT.PROJECT_ID=FOO.PROJECT_ID
1325 * <p>
1326 *
1327 * left = PROJECT.PROJECT_ID
1328 * right = FOO.PROJECT_ID
1329 *
1330 * @param left A String with the left side of the join.
1331 * @param right A String with the right side of the join.
1332 * @return A modified Criteria object.
1333 */
1334 public Criteria addJoin(String left, String right)
1335 {
1336 if (joinL == null)
1337 {
1338 joinL = new ArrayList(3);
1339 joinR = new ArrayList(3);
1340 }
1341 joinL.add(left);
1342 joinR.add(right);
1343
1344 return this;
1345 }
1346
1347 /***
1348 * get one side of the set of possible joins. This method is meant to
1349 * be called by BasePeer.
1350 */
1351 public List getJoinL()
1352 {
1353 return joinL;
1354 }
1355
1356 /***
1357 * get one side of the set of possible joins. This method is meant to
1358 * be called by BasePeer.
1359 */
1360 public List getJoinR()
1361 {
1362 return joinR;
1363 }
1364
1365 /***
1366 * Adds an 'IN' clause with the criteria supplied as an Object
1367 * array. For example:
1368 *
1369 * <p>
1370 * FOO.NAME IN ('FOO', 'BAR', 'ZOW')
1371 * <p>
1372 *
1373 * where 'values' contains three objects that evaluate to the
1374 * respective strings above when .toString() is called.
1375 *
1376 * If a criterion for the requested column already exists, it is
1377 * replaced.
1378 *
1379 * @param column The column to run the comparison on
1380 * @param values An Object[] with the allowed values.
1381 * @return A modified Criteria object.
1382 */
1383 public Criteria addIn(String column, Object[] values)
1384 {
1385 add(column, (Object) values, Criteria.IN);
1386 return this;
1387 }
1388
1389 /***
1390 * Adds an 'IN' clause with the criteria supplied as an int array.
1391 * For example:
1392 *
1393 * <p>
1394 * FOO.ID IN ('2', '3', '7')
1395 * <p>
1396 *
1397 * where 'values' contains those three integers.
1398 *
1399 * If a criterion for the requested column already exists, it is
1400 * replaced.
1401 *
1402 * @param column The column to run the comparison on
1403 * @param values An int[] with the allowed values.
1404 * @return A modified Criteria object.
1405 */
1406 public Criteria addIn(String column, int[] values)
1407 {
1408 add(column, (Object) values, Criteria.IN);
1409 return this;
1410 }
1411
1412 /***
1413 * Adds an 'IN' clause with the criteria supplied as a List.
1414 * For example:
1415 *
1416 * <p>
1417 * FOO.NAME IN ('FOO', 'BAR', 'ZOW')
1418 * <p>
1419 *
1420 * where 'values' contains three objects that evaluate to the
1421 * respective strings above when .toString() is called.
1422 *
1423 * If a criterion for the requested column already exists, it is
1424 * replaced.
1425 *
1426 * @param column The column to run the comparison on
1427 * @param values A List with the allowed values.
1428 * @return A modified Criteria object.
1429 */
1430 public Criteria addIn(String column, List values)
1431 {
1432 add(column, (Object) values, Criteria.IN);
1433 return this;
1434 }
1435
1436 /***
1437 * Adds a 'NOT IN' clause with the criteria supplied as an Object
1438 * array. For example:
1439 *
1440 * <p>
1441 * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
1442 * <p>
1443 *
1444 * where 'values' contains three objects that evaluate to the
1445 * respective strings above when .toString() is called.
1446 *
1447 * If a criterion for the requested column already exists, it is
1448 * replaced.
1449 *
1450 * @param column The column to run the comparison on
1451 * @param values An Object[] with the disallowed values.
1452 * @return A modified Criteria object.
1453 */
1454 public Criteria addNotIn(String column, Object[] values)
1455 {
1456 add(column, (Object) values, Criteria.NOT_IN);
1457 return this;
1458 }
1459
1460 /***
1461 * Adds a 'NOT IN' clause with the criteria supplied as an int
1462 * array. For example:
1463 *
1464 * <p>
1465 * FOO.ID NOT IN ('2', '3', '7')
1466 * <p>
1467 *
1468 * where 'values' contains those three integers.
1469 *
1470 * If a criterion for the requested column already exists, it is
1471 * replaced.
1472 *
1473 * @param column The column to run the comparison on
1474 * @param values An int[] with the disallowed values.
1475 * @return A modified Criteria object.
1476 */
1477 public Criteria addNotIn(String column, int[] values)
1478 {
1479 add(column, (Object) values, Criteria.NOT_IN);
1480 return this;
1481 }
1482
1483 /***
1484 * Adds a 'NOT IN' clause with the criteria supplied as a List.
1485 * For example:
1486 *
1487 * <p>
1488 * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
1489 * <p>
1490 *
1491 * where 'values' contains three objects that evaluate to the
1492 * respective strings above when .toString() is called.
1493 *
1494 * If a criterion for the requested column already exists, it is
1495 * replaced.
1496 *
1497 * @param column The column to run the comparison on
1498 * @param values A List with the disallowed values.
1499 * @return A modified Criteria object.
1500 */
1501 public Criteria addNotIn(String column, List values)
1502 {
1503 add(column, (Object) values, Criteria.NOT_IN);
1504 return this;
1505 }
1506
1507 /***
1508 * Adds "ALL " to the SQL statement.
1509 */
1510 public void setAll()
1511 {
1512 selectModifiers.add(ALL.toString());
1513 }
1514
1515 /***
1516 * Adds "DISTINCT " to the SQL statement.
1517 */
1518 public void setDistinct()
1519 {
1520 selectModifiers.add(DISTINCT.toString());
1521 }
1522
1523 /***
1524 * Sets ignore case.
1525 *
1526 * @param b True if case should be ignored.
1527 * @return A modified Criteria object.
1528 */
1529 public Criteria setIgnoreCase(boolean b)
1530 {
1531 ignoreCase = b;
1532 return this;
1533 }
1534
1535 /***
1536 * Is ignore case on or off?
1537 *
1538 * @return True if case is ignored.
1539 */
1540 public boolean isIgnoreCase()
1541 {
1542 return ignoreCase;
1543 }
1544
1545 /***
1546 * Set single record? Set this to <code>true</code> if you expect the query
1547 * to result in only a single result record (the default behaviour is to
1548 * throw a TorqueException if multiple records are returned when the query
1549 * is executed). This should be used in situations where returning multiple
1550 * rows would indicate an error of some sort. If your query might return
1551 * multiple records but you are only interested in the first one then you
1552 * should be using setLimit(1).
1553 *
1554 * @param b set to <code>true</code> if you expect the query to select just
1555 * one record.
1556 * @return A modified Criteria object.
1557 */
1558 public Criteria setSingleRecord(boolean b)
1559 {
1560 singleRecord = b;
1561 return this;
1562 }
1563
1564 /***
1565 * Is single record?
1566 *
1567 * @return True if a single record is being returned.
1568 */
1569 public boolean isSingleRecord()
1570 {
1571 return singleRecord;
1572 }
1573
1574 /***
1575 * Set cascade.
1576 *
1577 * @param b True if cascade is set.
1578 * @return A modified Criteria object.
1579 */
1580 public Criteria setCascade(boolean b)
1581 {
1582 cascade = b;
1583 return this;
1584 }
1585
1586 /***
1587 * Is cascade set?
1588 *
1589 * @return True if cascade is set.
1590 */
1591 public boolean isCascade()
1592 {
1593 return cascade;
1594 }
1595
1596 /***
1597 * Set limit.
1598 *
1599 * @param limit An int with the value for limit.
1600 * @return A modified Criteria object.
1601 */
1602 public Criteria setLimit(int limit)
1603 {
1604 this.limit = limit;
1605 return this;
1606 }
1607
1608 /***
1609 * Get limit.
1610 *
1611 * @return An int with the value for limit.
1612 */
1613 public int getLimit()
1614 {
1615 return limit;
1616 }
1617
1618 /***
1619 * Set offset.
1620 *
1621 * @param offset An int with the value for offset.
1622 * @return A modified Criteria object.
1623 */
1624 public Criteria setOffset(int offset)
1625 {
1626 this.offset = offset;
1627 return this;
1628 }
1629
1630 /***
1631 * Get offset.
1632 *
1633 * @return An int with the value for offset.
1634 */
1635 public int getOffset()
1636 {
1637 return offset;
1638 }
1639
1640 /***
1641 * Add select column.
1642 *
1643 * @param name A String with the name of the select column.
1644 * @return A modified Criteria object.
1645 */
1646 public Criteria addSelectColumn(String name)
1647 {
1648 selectColumns.add(name);
1649 return this;
1650 }
1651
1652 /***
1653 * Get select columns.
1654 *
1655 * @return An StringStack with the name of the select
1656 * columns.
1657 */
1658 public UniqueList getSelectColumns()
1659 {
1660 return selectColumns;
1661 }
1662
1663 /***
1664 * Get select modifiers.
1665 *
1666 * @return An UniqueList with the select modifiers.
1667 */
1668 public UniqueList getSelectModifiers()
1669 {
1670 return selectModifiers;
1671 }
1672
1673 /***
1674 * Add group by column name.
1675 *
1676 * @param groupBy The name of the column to group by.
1677 * @return A modified Criteria object.
1678 */
1679 public Criteria addGroupByColumn(String groupBy)
1680 {
1681 groupByColumns.add(groupBy);
1682 return this;
1683 }
1684
1685 /***
1686 * Add order by column name, explicitly specifying ascending.
1687 *
1688 * @param name The name of the column to order by.
1689 * @return A modified Criteria object.
1690 */
1691 public Criteria addAscendingOrderByColumn(String name)
1692 {
1693 orderByColumns.add(name + ' ' + ASC);
1694 return this;
1695 }
1696
1697 /***
1698 * Add order by column name, explicitly specifying descending.
1699 *
1700 * @param name The name of the column to order by.
1701 * @return A modified Criteria object.
1702 */
1703 public Criteria addDescendingOrderByColumn(String name)
1704 {
1705 orderByColumns.add(name + ' ' + DESC);
1706 return this;
1707 }
1708
1709 /***
1710 * Get order by columns.
1711 *
1712 * @return An UniqueList with the name of the order columns.
1713 */
1714 public UniqueList getOrderByColumns()
1715 {
1716 return orderByColumns;
1717 }
1718
1719 /***
1720 * Get group by columns.
1721 *
1722 * @return An UniqueList with the name of the groupBy clause.
1723 */
1724 public UniqueList getGroupByColumns()
1725 {
1726 return groupByColumns;
1727 }
1728
1729 /***
1730 * Get Having Criterion.
1731 *
1732 * @return A Criterion that is the having clause.
1733 */
1734 public Criterion getHaving()
1735 {
1736 return having;
1737 }
1738
1739 /***
1740 * Remove an object from the criteria.
1741 *
1742 * @param key A String with the key to be removed.
1743 * @return The removed object.
1744 */
1745 public Object remove(String key)
1746 {
1747 Object foo = super.remove(key);
1748 if (foo instanceof Criterion)
1749 {
1750 return ((Criterion) foo).getValue();
1751 }
1752 return foo;
1753 }
1754
1755 /***
1756 * Build a string representation of the Criteria.
1757 *
1758 * @return A String with the representation of the Criteria.
1759 */
1760 public String toString()
1761 {
1762 StringBuffer sb = new StringBuffer("Criteria:: ");
1763 Iterator it = keySet().iterator();
1764 while (it.hasNext())
1765 {
1766 String key = (String) it.next();
1767 sb.append(key).append("<=>")
1768 .append(super.get(key).toString()).append(": ");
1769 }
1770
1771 try
1772 {
1773 sb.append("\nCurrent Query SQL (may not be complete or applicable): ")
1774 .append(BasePeer.createQueryDisplayString(this));
1775 }
1776 catch (Exception exc)
1777 {
1778 }
1779
1780 return sb.toString();
1781 }
1782
1783 /***
1784 * This method checks another Criteria to see if they contain
1785 * the same attributes and hashtable entries.
1786 */
1787 public boolean equals(Object crit)
1788 {
1789 boolean isEquiv = false;
1790 if (crit == null || !(crit instanceof Criteria))
1791 {
1792 isEquiv = false;
1793 }
1794 else if (this == crit)
1795 {
1796 isEquiv = true;
1797 }
1798 else if (this.size() == ((Criteria) crit).size())
1799 {
1800 Criteria criteria = (Criteria) crit;
1801 if (this.offset == criteria.getOffset()
1802 && this.limit == criteria.getLimit()
1803 && ignoreCase == criteria.isIgnoreCase()
1804 && singleRecord == criteria.isSingleRecord()
1805 && cascade == criteria.isCascade()
1806 && dbName.equals(criteria.getDbName())
1807 && selectModifiers.equals(criteria.getSelectModifiers())
1808 && selectColumns.equals(criteria.getSelectColumns())
1809 && orderByColumns.equals(criteria.getOrderByColumns())
1810 )
1811 {
1812 isEquiv = true;
1813 for (Iterator it = criteria.keySet().iterator(); it.hasNext();)
1814 {
1815 String key = (String) it.next();
1816 if (this.containsKey(key))
1817 {
1818 Criterion a = this.getCriterion(key);
1819 Criterion b = criteria.getCriterion(key);
1820 if (!a.equals(b))
1821 {
1822 isEquiv = false;
1823 break;
1824 }
1825 }
1826 else
1827 {
1828 isEquiv = false;
1829 break;
1830 }
1831 }
1832 }
1833 }
1834 return isEquiv;
1835 }
1836
1837 /*
1838 *------------------------------------------------------------------------
1839 *
1840 * Start of the "and" methods
1841 *
1842 *------------------------------------------------------------------------
1843 */
1844
1845 /***
1846 * This method adds a prepared Criterion object to the Criteria as a having
1847 * clause. You can get a new, empty Criterion object with the
1848 * getNewCriterion() method.
1849 *
1850 * <p>
1851 * <code>
1852 * Criteria crit = new Criteria();
1853 * Criteria.Criterion c = crit.getNewCriterion(BasePeer.ID, new Integer(5),
1854 * Criteria.LESS_THAN);
1855 * crit.addHaving(c);
1856 * </code>
1857 *
1858 * @param having A Criterion object
1859 * @return A modified Criteria object.
1860 */
1861 public Criteria addHaving(Criterion having)
1862 {
1863 this.having = having;
1864 return this;
1865 }
1866
1867 /***
1868 * This method adds a prepared Criterion object to the Criteria.
1869 * You can get a new, empty Criterion object with the
1870 * getNewCriterion() method. If a criterion for the requested column
1871 * already exists, it is "AND"ed to the existing criterion.
1872 * This is used as follows:
1873 *
1874 * <p>
1875 * <code>
1876 * Criteria crit = new Criteria();
1877 * Criteria.Criterion c = crit.getNewCriterion(BasePeer.ID, new Integer(5),
1878 * Criteria.LESS_THAN);
1879 * crit.and(c);
1880 * </code>
1881 *
1882 * @param c A Criterion object
1883 * @return A modified Criteria object.
1884 */
1885 public Criteria and(Criterion c)
1886 {
1887 Criterion oc = getCriterion(c.getTable() + '.' + c.getColumn());
1888
1889 if (oc == null)
1890 {
1891 add(c);
1892 }
1893 else
1894 {
1895 oc.and(c);
1896 }
1897 return this;
1898 }
1899
1900 /***
1901 * This method adds a new criterion to the list of criterias. If a
1902 * criterion for the requested column already exists, it is
1903 * "AND"ed to the existing criterion. This is used as follows:
1904 *
1905 * <p>
1906 * <code>
1907 * Criteria crit = new Criteria().and("column",
1908 * "value");
1909 * </code>
1910 *
1911 * An EQUAL comparison is used for column and value.
1912 *
1913 * The name of the table must be used implicitly in the column name,
1914 * so the Column name must be something like 'TABLE.id'. If you
1915 * don't like this, you can use the and(table, column, value) method.
1916 *
1917 * @param column The column to run the comparison on
1918 * @param value An Object.
1919 *
1920 * @return A modified Criteria object.
1921 */
1922 public Criteria and(String column, Object value)
1923 {
1924 and(column, value, EQUAL);
1925 return this;
1926 }
1927
1928 /***
1929 * This method adds a new criterion to the list of criterias.
1930 * If a criterion for the requested column already exists, it is
1931 * "AND"ed to the existing criterion. If is used as follow:
1932 *
1933 * <p>
1934 * <code>
1935 * Criteria crit = new Criteria().and("column",
1936 * "value"
1937 * "Criterion.GREATER_THAN");
1938 * </code>
1939 *
1940 * Any comparison can be used.
1941 *
1942 * The name of the table must be used implicitly in the column name,
1943 * so the Column name must be something like 'TABLE.id'. If you
1944 * don't like this, you can use the and(table, column, value) method.
1945 *
1946 * @param column The column to run the comparison on
1947 * @param value An Object.
1948 * @param comparison A String.
1949 *
1950 * @return A modified Criteria object.
1951 */
1952 public Criteria and(String column, Object value, SqlEnum comparison)
1953 {
1954 Criterion oc = getCriterion(column);
1955 Criterion nc = new Criterion(column, value, comparison);
1956
1957 if (oc == null)
1958 {
1959 super.put(column, nc);
1960 }
1961 else
1962 {
1963 oc.and(nc);
1964 }
1965 return this;
1966 }
1967
1968 /***
1969 * This method adds a new criterion to the list of criterias.
1970 * If a criterion for the requested column already exists, it is
1971 * "AND"ed to the existing criterion. If is used as follows:
1972 *
1973 * <p>
1974 * <code>
1975 * Criteria crit = new Criteria().and("table",
1976 * "column",
1977 * "value");
1978 * </code>
1979 *
1980 * An EQUAL comparison is used for column and value.
1981 *
1982 * @param table Name of the table which contains the column
1983 * @param column The column to run the comparison on
1984 * @param value An Object.
1985 * @return A modified Criteria object.
1986 */
1987 public Criteria and(String table, String column, Object value)
1988 {
1989 and(table, column, value, EQUAL);
1990 return this;
1991 }
1992
1993 /***
1994 * This method adds a new criterion to the list of criterias.
1995 * If a criterion for the requested column already exists, it is
1996 * "AND"ed to the existing criterion. If is used as follows:
1997 *
1998 * <p>
1999 * <code>
2000 * Criteria crit = new Criteria().and("table",
2001 * "column",
2002 * "value",
2003 * "Criterion.GREATER_THAN");
2004 * </code>
2005 *
2006 * Any comparison can be used.
2007 *
2008 * @param table Name of table which contains the column
2009 * @param column The column to run the comparison on
2010 * @param value An Object.
2011 * @param comparison String describing how to compare the column with
2012 * the value
2013 * @return A modified Criteria object.
2014 */
2015 public Criteria and(String table, String column, Object value,
2016 SqlEnum comparison)
2017 {
2018 StringBuffer sb = new StringBuffer(table.length()
2019 + column.length() + 1);
2020 sb.append(table);
2021 sb.append('.');
2022 sb.append(column);
2023
2024 Criterion oc = getCriterion(table, column);
2025 Criterion nc = new Criterion(table, column, value, comparison);
2026
2027 if (oc == null)
2028 {
2029 super.put(sb.toString(), nc);
2030 }
2031 else
2032 {
2033 oc.and(nc);
2034 }
2035 return this;
2036 }
2037
2038 /***
2039 * Convenience method to add a boolean to Criteria.
2040 * Equal to
2041 *
2042 * <p>
2043 * <code>
2044 * and(column, new Boolean(value), EQUAL);
2045 * </code>
2046 *
2047 * @param column The column to run the comparison on
2048 * @param value A Boolean.
2049 * @return A modified Criteria object.
2050 */
2051 public Criteria and(String column, boolean value)
2052 {
2053 and(column, new Boolean(value));
2054 return this;
2055 }
2056
2057 /***
2058 * Convenience method to add a boolean to Criteria.
2059 * Equal to
2060 *
2061 * <p>
2062 * <code>
2063 * and(column, new Boolean(value), comparison);
2064 * </code>
2065 *
2066 * @param column The column to run the comparison on
2067 * @param value A Boolean.
2068 * @param comparison String describing how to compare the column
2069 * with the value
2070 * @return A modified Criteria object.
2071 */
2072 public Criteria and(String column, boolean value, SqlEnum comparison)
2073 {
2074 and(column, new Boolean(value), comparison);
2075 return this;
2076 }
2077
2078 /***
2079 * Convenience method to add an int to Criteria.
2080 * Equal to
2081 *
2082 * <p>
2083 * <code>
2084 * and(column, new Integer(value), EQUAL);
2085 * </code>
2086 *
2087 * @param column The column to run the comparison on
2088 * @param value An int.
2089 * @return A modified Criteria object.
2090 */
2091 public Criteria and(String column, int value)
2092 {
2093 and(column, new Integer(value));
2094 return this;
2095 }
2096
2097 /***
2098 * Convenience method to add an int to Criteria.
2099 * Equal to
2100 *
2101 * <p>
2102 * <code>
2103 * and(column, new Integer(value), comparison);
2104 * </code>
2105 *
2106 * @param column The column to run the comparison on
2107 * @param value An int.
2108 * @param comparison String describing how to compare the column with the value
2109 * @return A modified Criteria object.
2110 */
2111 public Criteria and(String column, int value, SqlEnum comparison)
2112 {
2113 and(column, new Integer(value), comparison);
2114 return this;
2115 }
2116
2117 /***
2118 * Convenience method to add a long to Criteria.
2119 * Equal to
2120 *
2121 * <p>
2122 * <code>
2123 * and(column, new Long(value), EQUAL);
2124 * </code>
2125 *
2126 * @param column The column to run the comparison on
2127 * @param value A long.
2128 * @return A modified Criteria object.
2129 */
2130 public Criteria and(String column, long value)
2131 {
2132 and(column, new Long(value));
2133 return this;
2134 }
2135
2136 /***
2137 * Convenience method to add a long to Criteria.
2138 * Equal to
2139 *
2140 * <p>
2141 * <code>
2142 * and(column, new Long(value), comparison);
2143 * </code>
2144 *
2145 * @param column The column to run the comparison on
2146 * @param value A long.
2147 * @param comparison String describing how to compare the column with
2148 * the value
2149 * @return A modified Criteria object.
2150 */
2151 public Criteria and(String column, long value, SqlEnum comparison)
2152 {
2153 and(column, new Long(value), comparison);
2154 return this;
2155 }
2156
2157 /***
2158 * Convenience method to add a float to Criteria.
2159 * Equal to
2160 *
2161 * <p>
2162 * <code>
2163 * and(column, new Float(value), EQUAL);
2164 * </code>
2165 *
2166 * @param column The column to run the comparison on
2167 * @param value A float.
2168 * @return A modified Criteria object.
2169 */
2170 public Criteria and(String column, float value)
2171 {
2172 and(column, new Float(value));
2173 return this;
2174 }
2175
2176 /***
2177 * Convenience method to add a float to Criteria.
2178 * Equal to
2179 *
2180 * <p>
2181 * <code>
2182 * and(column, new Float(value), comparison);
2183 * </code>
2184 *
2185 * @param column The column to run the comparison on
2186 * @param value A float.
2187 * @param comparison String describing how to compare the column with
2188 * the value
2189 * @return A modified Criteria object.
2190 */
2191 public Criteria and(String column, float value, SqlEnum comparison)
2192 {
2193 and(column, new Float(value), comparison);
2194 return this;
2195 }
2196
2197 /***
2198 * Convenience method to add a double to Criteria.
2199 * Equal to
2200 *
2201 * <p>
2202 * <code>
2203 * and(column, new Double(value), EQUAL);
2204 * </code>
2205 *
2206 * @param column The column to run the comparison on
2207 * @param value A double.
2208 * @return A modified Criteria object.
2209 */
2210 public Criteria and(String column, double value)
2211 {
2212 and(column, new Double(value));
2213 return this;
2214 }
2215
2216 /***
2217 * Convenience method to add a double to Criteria.
2218 * Equal to
2219 *
2220 * <p>
2221 * <code>
2222 * and(column, new Double(value), comparison);
2223 * </code>
2224 *
2225 * @param column The column to run the comparison on
2226 * @param value A double.
2227 * @param comparison String describing how to compare the column with
2228 * the value
2229 * @return A modified Criteria object.
2230 */
2231 public Criteria and(String column, double value, SqlEnum comparison)
2232 {
2233 and(column, new Double(value), comparison);
2234 return this;
2235 }
2236
2237 /***
2238 * Convenience method to add a Date object specified by
2239 * year, month, and date into the Criteria.
2240 * Equal to
2241 *
2242 * <p>
2243 * <code>
2244 * and(column, new GregorianCalendar(year, month,date), EQUAL);
2245 * </code>
2246 *
2247 * @param column A String value to use as column.
2248 * @param year An int with the year.
2249 * @param month An int with the month.
2250 * @param date An int with the date.
2251 * @return A modified Criteria object.
2252 */
2253 public Criteria andDate(String column, int year, int month, int date)
2254 {
2255 and(column, new GregorianCalendar(year, month, date));
2256 return this;
2257 }
2258
2259 /***
2260 * Convenience method to add a Date object specified by
2261 * year, month, and date into the Criteria.
2262 * Equal to
2263 *
2264 * <p>
2265 * <code>
2266 * and(column, new GregorianCalendar(year, month,date), comparison);
2267 * </code>
2268 *
2269 * @param column The column to run the comparison on
2270 * @param year An int with the year.
2271 * @param month An int with the month.
2272 * @param date An int with the date.
2273 * @param comparison String describing how to compare the column with
2274 * the value
2275 * @return A modified Criteria object.
2276 */
2277 public Criteria andDate(String column, int year, int month, int date,
2278 SqlEnum comparison)
2279 {
2280 and(column, new GregorianCalendar(year, month, date), comparison);
2281 return this;
2282 }
2283
2284 /***
2285 * Adds an 'IN' clause with the criteria supplied as an Object array.
2286 * For example:
2287 *
2288 * <p>
2289 * FOO.NAME IN ('FOO', 'BAR', 'ZOW')
2290 * <p>
2291 *
2292 * where 'values' contains three objects that evaluate to the
2293 * respective strings above when .toString() is called.
2294 *
2295 * If a criterion for the requested column already exists, it is
2296 * "AND"ed to the existing criterion.
2297 *
2298 * @param column The column to run the comparison on
2299 * @param values An Object[] with the allowed values.
2300 * @return A modified Criteria object.
2301 */
2302 public Criteria andIn(String column, Object[] values)
2303 {
2304 and(column, (Object) values, Criteria.IN);
2305 return this;
2306 }
2307
2308 /***
2309 * Adds an 'IN' clause with the criteria supplied as an int array.
2310 * For example:
2311 *
2312 * <p>
2313 * FOO.ID IN ('2', '3', '7')
2314 * <p>
2315 *
2316 * where 'values' contains those three integers.
2317 *
2318 * If a criterion for the requested column already exists, it is
2319 * "AND"ed to the existing criterion.
2320 *
2321 * @param column The column to run the comparison on
2322 * @param values An int[] with the allowed values.
2323 * @return A modified Criteria object.
2324 */
2325 public Criteria andIn(String column, int[] values)
2326 {
2327 and(column, (Object) values, Criteria.IN);
2328 return this;
2329 }
2330
2331 /***
2332 * Adds an 'IN' clause with the criteria supplied as a List.
2333 * For example:
2334 *
2335 * <p>
2336 * FOO.NAME IN ('FOO', 'BAR', 'ZOW')
2337 * <p>
2338 *
2339 * where 'values' contains three objects that evaluate to the
2340 * respective strings above when .toString() is called.
2341 *
2342 * If a criterion for the requested column already exists, it is
2343 * "AND"ed to the existing criterion.
2344 *
2345 * @param column The column to run the comparison on
2346 * @param values A List with the allowed values.
2347 * @return A modified Criteria object.
2348 */
2349 public Criteria andIn(String column, List values)
2350 {
2351 and(column, (Object) values, Criteria.IN);
2352 return this;
2353 }
2354
2355 /***
2356 * Adds a 'NOT IN' clause with the criteria supplied as an Object
2357 * array. For example:
2358 *
2359 * <p>
2360 * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
2361 * <p>
2362 *
2363 * where 'values' contains three objects that evaluate to the
2364 * respective strings above when .toString() is called.
2365 *
2366 * If a criterion for the requested column already exists, it is
2367 * "AND"ed to the existing criterion.
2368 *
2369 * @param column The column to run the comparison on
2370 * @param values An Object[] with the disallowed values.
2371 * @return A modified Criteria object.
2372 */
2373 public Criteria andNotIn(String column, Object[] values)
2374 {
2375 and(column, (Object) values, Criteria.NOT_IN);
2376 return this;
2377 }
2378
2379 /***
2380 * Adds a 'NOT IN' clause with the criteria supplied as an int
2381 * array. For example:
2382 *
2383 * <p>
2384 * FOO.ID NOT IN ('2', '3', '7')
2385 * <p>
2386 *
2387 * where 'values' contains those three integers.
2388 *
2389 * If a criterion for the requested column already exists, it is
2390 * "AND"ed to the existing criterion.
2391 *
2392 * @param column The column to run the comparison on
2393 * @param values An int[] with the disallowed values.
2394 * @return A modified Criteria object.
2395 */
2396 public Criteria andNotIn(String column, int[] values)
2397 {
2398 and(column, (Object) values, Criteria.NOT_IN);
2399 return this;
2400 }
2401
2402 /***
2403 * Adds a 'NOT IN' clause with the criteria supplied as a List.
2404 * For example:
2405 *
2406 * <p>
2407 * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
2408 * <p>
2409 *
2410 * where 'values' contains three objects that evaluate to the
2411 * respective strings above when .toString() is called.
2412 *
2413 * If a criterion for the requested column already exists, it is
2414 * "AND"ed to the existing criterion.
2415 *
2416 * @param column The column to run the comparison on
2417 * @param values A List with the disallowed values.
2418 * @return A modified Criteria object.
2419 */
2420 public Criteria andNotIn(String column, List values)
2421 {
2422 and(column, (Object) values, Criteria.NOT_IN);
2423 return this;
2424 }
2425
2426 /*
2427 *------------------------------------------------------------------------
2428 *
2429 * Start of the "or" methods
2430 *
2431 *------------------------------------------------------------------------
2432 */
2433
2434 /***
2435 * This method adds a prepared Criterion object to the Criteria.
2436 * You can get a new, empty Criterion object with the
2437 * getNewCriterion() method. If a criterion for the requested column
2438 * already exists, it is "OR"ed to the existing criterion.
2439 * This is used as follows:
2440 *
2441 * <p>
2442 * <code>
2443 * Criteria crit = new Criteria();
2444 * Criteria.Criterion c = crit.getNewCriterion(BasePeer.ID, new Integer(5), Criteria.LESS_THAN);
2445 * crit.or(c);
2446 * </code>
2447 *
2448 * @param c A Criterion object
2449 * @return A modified Criteria object.
2450 */
2451 public Criteria or(Criterion c)
2452 {
2453 Criterion oc = getCriterion(c.getTable() + '.' + c.getColumn());
2454
2455 if (oc == null)
2456 {
2457 add(c);
2458 }
2459 else
2460 {
2461 oc.or(c);
2462 }
2463 return this;
2464 }
2465
2466 /***
2467 * This method adds a new criterion to the list of criterias. If a
2468 * criterion for the requested column already exists, it is
2469 * "OR"ed to the existing criterion. This is used as follows:
2470 *
2471 * <p>
2472 * <code>
2473 * Criteria crit = new Criteria().or("column",
2474 * "value");
2475 * </code>
2476 *
2477 * An EQUAL comparison is used for column and value.
2478 *
2479 * The name of the table must be used implicitly in the column name,
2480 * so the Column name must be something like 'TABLE.id'. If you
2481 * don't like this, you can use the or(table, column, value) method.
2482 *
2483 * @param column The column to run the comparison on
2484 * @param value An Object.
2485 *
2486 * @return A modified Criteria object.
2487 */
2488 public Criteria or(String column, Object value)
2489 {
2490 or(column, value, EQUAL);
2491 return this;
2492 }
2493
2494 /***
2495 * This method adds a new criterion to the list of criterias.
2496 * If a criterion for the requested column already exists, it is
2497 * "OR"ed to the existing criterion. If is used as follow:
2498 *
2499 * <p>
2500 * <code>
2501 * Criteria crit = new Criteria().or("column",
2502 * "value"
2503 * "Criterion.GREATER_THAN");
2504 * </code>
2505 *
2506 * Any comparison can be used.
2507 *
2508 * The name of the table must be used implicitly in the column name,
2509 * so the Column name must be something like 'TABLE.id'. If you
2510 * don't like this, you can use the or(table, column, value) method.
2511 *
2512 * @param column The column to run the comparison on
2513 * @param value An Object.
2514 * @param comparison A String.
2515 * @return A modified Criteria object.
2516 */
2517 public Criteria or(String column, Object value, SqlEnum comparison)
2518 {
2519 Criterion oc = getCriterion(column);
2520 Criterion nc = new Criterion(column, value, comparison);
2521
2522 if (oc == null)
2523 {
2524 super.put(column, nc);
2525 }
2526 else
2527 {
2528 oc.or(nc);
2529 }
2530 return this;
2531 }
2532
2533 /***
2534 * This method adds a new criterion to the list of criterias.
2535 * If a criterion for the requested column already exists, it is
2536 * "OR"ed to the existing criterion. If is used as follows:
2537 *
2538 * <p>
2539 * <code>
2540 * Criteria crit = new Criteria().or("table",
2541 * "column",
2542 * "value");
2543 * </code>
2544 *
2545 * An EQUAL comparison is used for column and value.
2546 *
2547 * @param table Name of the table which contains the column
2548 * @param column The column to run the comparison on
2549 * @param value An Object.
2550 * @return A modified Criteria object.
2551 */
2552 public Criteria or(String table, String column, Object value)
2553 {
2554 or(table, column, value, EQUAL);
2555 return this;
2556 }
2557
2558 /***
2559 * This method adds a new criterion to the list of criterias.
2560 * If a criterion for the requested column already exists, it is
2561 * "OR"ed to the existing criterion. If is used as follows:
2562 *
2563 * <p>
2564 * <code>
2565 * Criteria crit = new Criteria().or("table",
2566 * "column",
2567 * "value",
2568 * "Criterion.GREATER_THAN");
2569 * </code>
2570 *
2571 * Any comparison can be used.
2572 *
2573 * @param table Name of table which contains the column
2574 * @param column The column to run the comparison on
2575 * @param value An Object.
2576 * @param comparison String describing how to compare the column with the value
2577 * @return A modified Criteria object.
2578 */
2579 public Criteria or(String table, String column, Object value,
2580 SqlEnum comparison)
2581 {
2582 StringBuffer sb = new StringBuffer(table.length() + column.length() + 1);
2583 sb.append(table);
2584 sb.append('.');
2585 sb.append(column);
2586
2587 Criterion oc = getCriterion(table, column);
2588 Criterion nc = new Criterion(table, column, value, comparison);
2589 if (oc == null)
2590 {
2591 super.put(sb.toString(), nc);
2592 }
2593 else
2594 {
2595 oc.or(nc);
2596 }
2597 return this;
2598 }
2599
2600 /***
2601 * Convenience method to add a boolean to Criteria.
2602 * Equal to
2603 *
2604 * <p>
2605 * <code>
2606 * or(column, new Boolean(value), EQUAL);
2607 * </code>
2608 *
2609 * @param column The column to run the comparison on
2610 * @param value A Boolean.
2611 * @return A modified Criteria object.
2612 */
2613 public Criteria or(String column, boolean value)
2614 {
2615 or(column, new Boolean(value));
2616 return this;
2617 }
2618
2619 /***
2620 * Convenience method to add a boolean to Criteria.
2621 * Equal to
2622 *
2623 * <p>
2624 * <code>
2625 * or(column, new Boolean(value), comparison);
2626 * </code>
2627 *
2628 * @param column The column to run the comparison on
2629 * @param value A Boolean.
2630 * @param comparison String describing how to compare the column
2631 * with the value
2632 * @return A modified Criteria object.
2633 */
2634 public Criteria or(String column, boolean value, SqlEnum comparison)
2635 {
2636 or(column, new Boolean(value), comparison);
2637 return this;
2638 }
2639
2640 /***
2641 * Convenience method to add an int to Criteria.
2642 * Equal to
2643 *
2644 * <p>
2645 * <code>
2646 * or(column, new Integer(value), EQUAL);
2647 * </code>
2648 *
2649 *
2650 * @param column The column to run the comparison on
2651 * @param value An int.
2652 * @return A modified Criteria object.
2653 */
2654 public Criteria or(String column, int value)
2655 {
2656 or(column, new Integer(value));
2657 return this;
2658 }
2659
2660 /***
2661 * Convenience method to add an int to Criteria.
2662 * Equal to
2663 *
2664 * <p>
2665 * <code>
2666 * or(column, new Integer(value), comparison);
2667 * </code>
2668 *
2669 *
2670 * @param column The column to run the comparison on
2671 * @param value An int.
2672 * @param comparison String describing how to compare the column
2673 * with the value
2674 * @return A modified Criteria object.
2675 */
2676 public Criteria or(String column, int value, SqlEnum comparison)
2677 {
2678 or(column, new Integer(value), comparison);
2679 return this;
2680 }
2681
2682 /***
2683 * Convenience method to add a long to Criteria.
2684 * Equal to
2685 *
2686 * <p>
2687 * <code>
2688 * or(column, new Long(value), EQUAL);
2689 * </code>
2690 *
2691 * @param column The column to run the comparison on
2692 * @param value A long.
2693 * @return A modified Criteria object.
2694 */
2695 public Criteria or(String column, long value)
2696 {
2697 or(column, new Long(value));
2698 return this;
2699 }
2700
2701 /***
2702 * Convenience method to add a long to Criteria.
2703 * Equal to
2704 *
2705 * <p>
2706 * <code>
2707 * or(column, new Long(value), comparison);
2708 * </code>
2709 *
2710 * @param column The column to run the comparison on
2711 * @param value A long.
2712 * @param comparison String describing how to compare the column
2713 * with the value
2714 * @return A modified Criteria object.
2715 */
2716 public Criteria or(String column, long value, SqlEnum comparison)
2717 {
2718 or(column, new Long(value), comparison);
2719 return this;
2720 }
2721
2722 /***
2723 * Convenience method to add a float to Criteria.
2724 * Equal to
2725 *
2726 * <p>
2727 * <code>
2728 * or(column, new Float(value), EQUAL);
2729 * </code>
2730 *
2731 * @param column The column to run the comparison on
2732 * @param value A float.
2733 * @return A modified Criteria object.
2734 */
2735 public Criteria or(String column, float value)
2736 {
2737 or(column, new Float(value));
2738 return this;
2739 }
2740
2741 /***
2742 * Convenience method to add a float to Criteria.
2743 * Equal to
2744 *
2745 * <p>
2746 * <code>
2747 * or(column, new Float(value), comparison);
2748 * </code>
2749 *
2750 * @param column The column to run the comparison on
2751 * @param value A float.
2752 * @param comparison String describing how to compare the column
2753 * with the value
2754 * @return A modified Criteria object.
2755 */
2756 public Criteria or(String column, float value, SqlEnum comparison)
2757 {
2758 or(column, new Float(value), comparison);
2759 return this;
2760 }
2761
2762 /***
2763 * Convenience method to add a double to Criteria.
2764 * Equal to
2765 *
2766 * <p>
2767 * <code>
2768 * or(column, new Double(value), EQUAL);
2769 * </code>
2770 *
2771 * @param column The column to run the comparison on
2772 * @param value A double.
2773 * @return A modified Criteria object.
2774 */
2775 public Criteria or(String column, double value)
2776 {
2777 or(column, new Double(value));
2778 return this;
2779 }
2780
2781 /***
2782 * Convenience method to add a double to Criteria.
2783 * Equal to
2784 *
2785 * <p>
2786 * <code>
2787 * or(column, new Double(value), comparison);
2788 * </code>
2789 *
2790 * @param column The column to run the comparison on
2791 * @param value A double.
2792 * @param comparison String describing how to compare the column
2793 * with the value
2794 * @return A modified Criteria object.
2795 */
2796 public Criteria or(String column, double value, SqlEnum comparison)
2797 {
2798 or(column, new Double(value), comparison);
2799 return this;
2800 }
2801
2802 /***
2803 * Convenience method to add a Date object specified by
2804 * year, month, and date into the Criteria.
2805 * Equal to
2806 *
2807 * <p>
2808 * <code>
2809 * or(column, new GregorianCalendar(year, month,date), EQUAL);
2810 * </code>
2811 *
2812 * @param column A String value to use as column.
2813 * @param year An int with the year.
2814 * @param month An int with the month.
2815 * @param date An int with the date.
2816 * @return A modified Criteria object.
2817 */
2818 public Criteria orDate(String column, int year, int month, int date)
2819 {
2820 or(column, new GregorianCalendar(year, month, date));
2821 return this;
2822 }
2823
2824 /***
2825 * Convenience method to add a Date object specified by
2826 * year, month, and date into the Criteria.
2827 * Equal to
2828 *
2829 * <p>
2830 * <code>
2831 * or(column, new GregorianCalendar(year, month,date), comparison);
2832 * </code>
2833 *
2834 * @param column The column to run the comparison on
2835 * @param year An int with the year.
2836 * @param month An int with the month.
2837 * @param date An int with the date.
2838 * @param comparison String describing how to compare the column
2839 * with the value
2840 * @return A modified Criteria object.
2841 */
2842 public Criteria orDate(String column, int year, int month, int date,
2843 SqlEnum comparison)
2844 {
2845 or(column, new GregorianCalendar(year, month, date), comparison);
2846 return this;
2847 }
2848
2849 /***
2850 * Adds an 'IN' clause with the criteria supplied as an Object
2851 * array. For example:
2852 *
2853 * <p>
2854 * FOO.NAME IN ('FOO', 'BAR', 'ZOW')
2855 * <p>
2856 *
2857 * where 'values' contains three objects that evaluate to the
2858 * respective strings above when .toString() is called.
2859 *
2860 * If a criterion for the requested column already exists, it is
2861 * "OR"ed to the existing criterion.
2862 *
2863 * @param column The column to run the comparison on
2864 * @param values An Object[] with the allowed values.
2865 * @return A modified Criteria object.
2866 */
2867 public Criteria orIn(String column, Object[] values)
2868 {
2869 or(column, (Object) values, Criteria.IN);
2870 return this;
2871 }
2872
2873 /***
2874 * Adds an 'IN' clause with the criteria supplied as an int array.
2875 * For example:
2876 *
2877 * <p>
2878 * FOO.ID IN ('2', '3', '7')
2879 * <p>
2880 *
2881 * where 'values' contains those three integers.
2882 *
2883 * If a criterion for the requested column already exists, it is
2884 * "OR"ed to the existing criterion.
2885 *
2886 * @param column The column to run the comparison on
2887 * @param values An int[] with the allowed values.
2888 * @return A modified Criteria object.
2889 */
2890 public Criteria orIn(String column, int[] values)
2891 {
2892 or(column, (Object) values, Criteria.IN);
2893 return this;
2894 }
2895
2896 /***
2897 * Adds an 'IN' clause with the criteria supplied as a List.
2898 * For example:
2899 *
2900 * <p>
2901 * FOO.NAME IN ('FOO', 'BAR', 'ZOW')
2902 * <p>
2903 *
2904 * where 'values' contains three objects that evaluate to the
2905 * respective strings above when .toString() is called.
2906 *
2907 * If a criterion for the requested column already exists, it is
2908 * "OR"ed to the existing criterion.
2909 *
2910 * @param column The column to run the comparison on
2911 * @param values A List with the allowed values.
2912 * @return A modified Criteria object.
2913 */
2914 public Criteria orIn(String column, List values)
2915 {
2916 or(column, (Object) values, Criteria.IN);
2917 return this;
2918 }
2919
2920 /***
2921 * Adds a 'NOT IN' clause with the criteria supplied as an Object
2922 * array. For example:
2923 *
2924 * <p>
2925 * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
2926 * <p>
2927 *
2928 * where 'values' contains three objects that evaluate to the
2929 * respective strings above when .toString() is called.
2930 *
2931 * If a criterion for the requested column already exists, it is
2932 * "OR"ed to the existing criterion.
2933 *
2934 * @param column The column to run the comparison on
2935 * @param values An Object[] with the disallowed values.
2936 * @return A modified Criteria object.
2937 */
2938 public Criteria orNotIn(String column, Object[] values)
2939 {
2940 or(column, (Object) values, Criteria.NOT_IN);
2941 return this;
2942 }
2943
2944 /***
2945 * Adds a 'NOT IN' clause with the criteria supplied as an int
2946 * array. For example:
2947 *
2948 * <p>
2949 * FOO.ID NOT IN ('2', '3', '7')
2950 * <p>
2951 *
2952 * where 'values' contains those three integers.
2953 *
2954 * If a criterion for the requested column already exists, it is
2955 * "OR"ed to the existing criterion.
2956 *
2957 * @param column The column to run the comparison on
2958 * @param values An int[] with the disallowed values.
2959 * @return A modified Criteria object.
2960 */
2961 public Criteria orNotIn(String column, int[] values)
2962 {
2963 or(column, (Object) values, Criteria.NOT_IN);
2964 return this;
2965 }
2966
2967 /***
2968 * Adds a 'NOT IN' clause with the criteria supplied as a List.
2969 * For example:
2970 *
2971 * <p>
2972 * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
2973 * <p>
2974 *
2975 * where 'values' contains three objects that evaluate to the
2976 * respective strings above when .toString() is called.
2977 *
2978 * If a criterion for the requested column already exists, it is
2979 * "OR"ed to the existing criterion.
2980 *
2981 * @param column The column to run the comparison on
2982 * @param values A List with the disallowed values.
2983 * @return A modified Criteria object.
2984 */
2985 public Criteria orNotIn(String column, List values)
2986 {
2987 or(column, (Object) values, Criteria.NOT_IN);
2988 return this;
2989 }
2990
2991 /***
2992 * Peers can set this flag to notify BasePeer that the table(s) involved
2993 * in the Criteria contain Blobs, so that the operation can be placed
2994 * in a transaction if the db requires it.
2995 * This is primarily to support Postgresql.
2996 *
2997 * @deprecated this flag is not used any longer
2998 */
2999 public void setBlobFlag(boolean b)
3000 {
3001 // do nothing as we don't use the flag any longer
3002 }
3003
3004 /***
3005 * This is an inner class that describes an object in the
3006 * criteria.
3007 */
3008 public final class Criterion implements Serializable
3009 {
3010 public static final String AND = " AND ";
3011 public static final String OR = " OR ";
3012
3013 /*** Value of the CO. */
3014 private Object value;
3015
3016 /*** Comparison value. */
3017 private SqlEnum comparison;
3018
3019 /*** Table name. */
3020 private String table;
3021
3022 /*** Column name. */
3023 private String column;
3024
3025 /*** flag to ignore case in comparision */
3026 private boolean ignoreStringCase = false;
3027
3028 /***
3029 * The DB adaptor which might be used to get db specific
3030 * variations of sql.
3031 */
3032 private DB db;
3033
3034 /***
3035 * other connected criteria and their conjunctions.
3036 */
3037 private List clauses = new ArrayList();
3038 private List conjunctions = new ArrayList();
3039
3040 /***
3041 * Creates a new instance, initializing a couple members.
3042 */
3043 private Criterion(Object val, SqlEnum comp)
3044 {
3045 this.value = val;
3046 this.comparison = comp;
3047 }
3048
3049 /***
3050 * Create a new instance.
3051 *
3052 * @param table A String with the name of the table.
3053 * @param column A String with the name of the column.
3054 * @param val An Object with the value for the Criteria.
3055 * @param comp A String with the comparison value.
3056 */
3057 Criterion(String table, String column, Object val, SqlEnum comp)
3058 {
3059 this(val, comp);
3060 this.table = (table == null ? "" : table);
3061 this.column = (column == null ? "" : column);
3062 }
3063
3064 /***
3065 * Create a new instance.
3066 *
3067 * @param tableColumn A String with the full name of the
3068 * column.
3069 * @param val An Object with the value for the Criteria.
3070 * @param comp A String with the comparison value.
3071 */
3072 Criterion(String tableColumn, Object val, SqlEnum comp)
3073 {
3074 this(val, comp);
3075 int dot = tableColumn.indexOf('.');
3076 if (dot == -1)
3077 {
3078 table = "";
3079 column = tableColumn;
3080 }
3081 else
3082 {
3083 table = tableColumn.substring(0, dot);
3084 column = tableColumn.substring(dot + 1);
3085 }
3086 }
3087
3088 /***
3089 * Create a new instance.
3090 *
3091 * @param table A String with the name of the table.
3092 * @param column A String with the name of the column.
3093 * @param val An Object with the value for the Criteria.
3094 */
3095 Criterion(String table, String column, Object val)
3096 {
3097 this(table, column, val, EQUAL);
3098 }
3099
3100 /***
3101 * Create a new instance.
3102 *
3103 * @param tableColumn A String with the full name of the
3104 * column.
3105 * @param val An Object with the value for the Criteria.
3106 */
3107 Criterion(String tableColumn, Object val)
3108 {
3109 this(tableColumn, val, EQUAL);
3110 }
3111
3112 /***
3113 * Get the column name.
3114 *
3115 * @return A String with the column name.
3116 */
3117 public String getColumn()
3118 {
3119 return this.column;
3120 }
3121
3122 /***
3123 * Set the table name.
3124 *
3125 * @param name A String with the table name.
3126 */
3127 public void setTable(String name)
3128 {
3129 this.table = name;
3130 }
3131
3132 /***
3133 * Get the table name.
3134 *
3135 * @return A String with the table name.
3136 */
3137 public String getTable()
3138 {
3139 return this.table;
3140 }
3141
3142 /***
3143 * Get the comparison.
3144 *
3145 * @return A String with the comparison.
3146 */
3147 public SqlEnum getComparison()
3148 {
3149 return this.comparison;
3150 }
3151
3152 /***
3153 * Get the value.
3154 *
3155 * @return An Object with the value.
3156 */
3157 public Object getValue()
3158 {
3159 return this.value;
3160 }
3161
3162 /***
3163 * Get the value of db.
3164 * The DB adaptor which might be used to get db specific
3165 * variations of sql.
3166 * @return value of db.
3167 */
3168 public DB getDb()
3169 {
3170 DB db = null;
3171 if (this.db == null)
3172 {
3173 // db may not be set if generating preliminary sql for
3174 // debugging.
3175 try
3176 {
3177 db = Torque.getDB(getDbName());
3178 }
3179 catch (Exception e)
3180 {
3181 // we are only doing this to allow easier debugging, so
3182 // no need to throw up the exception, just make note of it.
3183 log.error(
3184 "Could not get a DB adapter, so sql may be wrong");
3185 }
3186 }
3187 else
3188 {
3189 db = this.db;
3190 }
3191
3192 return db;
3193 }
3194
3195 /***
3196 * Set the value of db.
3197 * The DB adaptor might be used to get db specific
3198 * variations of sql.
3199 * @param v Value to assign to db.
3200 */
3201 public void setDB(DB v)
3202 {
3203 this.db = v;
3204
3205 for (int i = 0; i < this.clauses.size(); i++)
3206 {
3207 ((Criterion) (clauses.get(i))).setDB(v);
3208 }
3209 }
3210
3211 /***
3212 * Sets ignore case.
3213 *
3214 * @param b True if case should be ignored.
3215 * @return A modified Criteria object.
3216 */
3217 public Criterion setIgnoreCase(boolean b)
3218 {
3219 ignoreStringCase = b;
3220 return this;
3221 }
3222
3223 /***
3224 * Is ignore case on or off?
3225 *
3226 * @return True if case is ignored.
3227 */
3228 public boolean isIgnoreCase()
3229 {
3230 return ignoreStringCase;
3231 }
3232
3233 /***
3234 * get the list of clauses in this Criterion
3235 */
3236 private List getClauses()
3237 {
3238 return clauses;
3239 }
3240
3241 /***
3242 * get the list of conjunctions in this Criterion
3243 */
3244 private List getConjunctions()
3245 {
3246 return conjunctions;
3247 }
3248
3249 /***
3250 * Append an AND Criterion onto this Criterion's list.
3251 */
3252 public Criterion and(Criterion criterion)
3253 {
3254 this.clauses.add(criterion);
3255 this.conjunctions.add(AND);
3256 return this;
3257 }
3258
3259 /***
3260 * Append an OR Criterion onto this Criterion's list.
3261 */
3262 public Criterion or(Criterion criterion)
3263 {
3264 this.clauses.add(criterion);
3265 this.conjunctions.add(OR);
3266 return this;
3267 }
3268
3269 /***
3270 * Appends a representation of the Criterion onto the buffer.
3271 */
3272 public void appendTo(StringBuffer sb)
3273 {
3274 //
3275 // it is alright if value == null
3276 //
3277
3278 if (column == null)
3279 {
3280 return;
3281 }
3282
3283 Criterion clause = null;
3284 for (int j = 0; j < this.clauses.size(); j++)
3285 {
3286 sb.append('(');
3287 }
3288 if (CUSTOM == comparison)
3289 {
3290 if (value != null && !"".equals(value))
3291 {
3292 sb.append((String) value);
3293 }
3294 }
3295 else
3296 {
3297 String field = null;
3298 if (table == null)
3299 {
3300 field = column;
3301 }
3302 else
3303 {
3304 field = new StringBuffer(
3305 table.length() + 1 + column.length())
3306 .append(table).append('.').append(column)
3307 .toString();
3308 }
3309 SqlExpression.build(field, value, comparison,
3310 ignoreStringCase, getDb(), sb);
3311 }
3312
3313 for (int i = 0; i < this.clauses.size(); i++)
3314 {
3315 sb.append(this.conjunctions.get(i));
3316 clause = (Criterion) (this.clauses.get(i));
3317 clause.appendTo(sb);
3318 sb.append(')');
3319 }
3320 }
3321
3322 /***
3323 * Appends a Prepared Statement representation of the Criterion
3324 * onto the buffer.
3325 *
3326 * @param sb The stringbuffer that will receive the Prepared Statement
3327 * @param params A list to which Prepared Statement parameters
3328 * will be appended
3329 */
3330 public void appendPsTo(StringBuffer sb, List params)
3331 {
3332 if (column == null || value == null)
3333 {
3334 return;
3335 }
3336
3337 DB db = getDb();
3338
3339 for (int j = 0; j < this.clauses.size(); j++)
3340 {
3341 sb.append('(');
3342 }
3343 if (CUSTOM == comparison)
3344 {
3345 if (!"".equals(value))
3346 {
3347 sb.append((String) value);
3348 }
3349 }
3350 else
3351 {
3352 String field = null;
3353 if (table == null)
3354 {
3355 field = column;
3356 }
3357 else
3358 {
3359 field = new StringBuffer(
3360 table.length() + 1 + column.length())
3361 .append(table).append('.').append(column)
3362 .toString();
3363 }
3364
3365 if (comparison.equals(Criteria.IN)
3366 || comparison.equals(Criteria.NOT_IN))
3367 {
3368 sb.append(field)
3369 .append(comparison);
3370
3371 UniqueList inClause = new UniqueList();
3372
3373 if (value instanceof List)
3374 {
3375 value = ((List) value).toArray (new Object[0]);
3376 }
3377
3378 for (int i = 0; i < Array.getLength(value); i++)
3379 {
3380 Object item = Array.get(value, i);
3381
3382 inClause.add(SqlExpression.processInValue(item,
3383 ignoreCase,
3384 db));
3385 }
3386
3387 StringBuffer inString = new StringBuffer();
3388 inString.append('(').append(StringUtils.join(
3389 inClause.iterator(), (","))).append(')');
3390 sb.append(inString.toString());
3391 }
3392 else
3393 {
3394 if (ignoreCase)
3395 {
3396 sb.append(db.ignoreCase(field))
3397 .append(comparison)
3398 .append(db.ignoreCase("?"));
3399 }
3400 else
3401 {
3402 sb.append(field)
3403 .append(comparison)
3404 .append(" ? ");
3405 }
3406
3407 if (value instanceof java.util.Date)
3408 {
3409 params.add(new java.sql.Date(
3410 ((java.util.Date) value).getTime()));
3411 }
3412 else if (value instanceof DateKey)
3413 {
3414 params.add(new java.sql.Date(
3415 ((DateKey) value).getDate().getTime()));
3416 }
3417 else
3418 {
3419 params.add(value.toString());
3420 }
3421 }
3422 }
3423
3424 for (int i = 0; i < this.clauses.size(); i++)
3425 {
3426 sb.append(this.conjunctions.get(i));
3427 Criterion clause = (Criterion) (this.clauses.get(i));
3428 clause.appendPsTo(sb, params);
3429 sb.append(')');
3430 }
3431 }
3432
3433 /***
3434 * Build a string representation of the Criterion.
3435 *
3436 * @return A String with the representation of the Criterion.
3437 */
3438 public String toString()
3439 {
3440 //
3441 // it is alright if value == null
3442 //
3443 if (column == null)
3444 {
3445 return "";
3446 }
3447
3448 StringBuffer expr = new StringBuffer(25);
3449 appendTo(expr);
3450 return expr.toString();
3451 }
3452
3453 /***
3454 * This method checks another Criteria to see if they contain
3455 * the same attributes and hashtable entries.
3456 */
3457 public boolean equals(Object obj)
3458 {
3459 if (this == obj)
3460 {
3461 return true;
3462 }
3463
3464 if ((obj == null) || !(obj instanceof Criterion))
3465 {
3466 return false;
3467 }
3468
3469 Criterion crit = (Criterion) obj;
3470
3471 boolean isEquiv = ((table == null && crit.getTable() == null)
3472 || (table != null && table.equals(crit.getTable()))
3473 )
3474 && column.equals(crit.getColumn())
3475 && comparison.equals(crit.getComparison());
3476
3477 // we need to check for value equality
3478 if (isEquiv)
3479 {
3480 Object b = crit.getValue();
3481 if (value instanceof Object[] && b instanceof Object[])
3482 {
3483 isEquiv &= Arrays.equals((Object[]) value, (Object[]) b);
3484 }
3485 else if (value instanceof int[] && b instanceof int[])
3486 {
3487 isEquiv &= Arrays.equals((int[]) value, (int[]) b);
3488 }
3489 else
3490 {
3491 isEquiv &= value.equals(b);
3492 }
3493 }
3494
3495 // check chained criterion
3496
3497 isEquiv &= this.clauses.size() == crit.getClauses().size();
3498 for (int i = 0; i < this.clauses.size(); i++)
3499 {
3500 isEquiv &= ((String) (conjunctions.get(i)))
3501 .equals((String) (crit.getConjunctions().get(i)));
3502 isEquiv &= ((Criterion) (clauses.get(i)))
3503 .equals((Criterion) (crit.getClauses().get(i)));
3504 }
3505
3506 return isEquiv;
3507 }
3508
3509 /***
3510 * Returns a hash code value for the object.
3511 */
3512 public int hashCode()
3513 {
3514 int h = value.hashCode() ^ comparison.hashCode();
3515
3516 if (table != null)
3517 {
3518 h ^= table.hashCode();
3519 }
3520
3521 if (column != null)
3522 {
3523 h ^= column.hashCode();
3524 }
3525
3526 for (int i = 0; i < this.clauses.size(); i++)
3527 {
3528 h ^= ((Criterion) (clauses.get(i))).hashCode();
3529 }
3530
3531 return h;
3532 }
3533
3534 /***
3535 * get all tables from nested criterion objects
3536 *
3537 * @return the list of tables
3538 */
3539 public List getAllTables()
3540 {
3541 UniqueList tables = new UniqueList();
3542 addCriterionTable(this, tables);
3543 return tables;
3544 }
3545
3546 /***
3547 * method supporting recursion through all criterions to give
3548 * us a StringStack of tables from each criterion
3549 */
3550 private void addCriterionTable(Criterion c, UniqueList s)
3551 {
3552 if (c != null)
3553 {
3554 s.add(c.getTable());
3555 for (int i = 0; i < c.getClauses().size(); i++)
3556 {
3557 addCriterionTable((Criterion) (c.getClauses().get(i)), s);
3558 }
3559 }
3560 }
3561
3562 /***
3563 * get an array of all criterion attached to this
3564 * recursing through all sub criterion
3565 */
3566 public Criterion[] getAttachedCriterion()
3567 {
3568 ArrayList crits = new ArrayList();
3569 traverseCriterion(this, crits);
3570 Criterion[] crita = new Criterion[crits.size()];
3571 for (int i = 0; i < crits.size(); i++)
3572 {
3573 crita[i] = (Criterion) crits.get(i);
3574 }
3575
3576 return crita;
3577 }
3578
3579 /***
3580 * method supporting recursion through all criterions to give
3581 * us an ArrayList of them
3582 */
3583 private void traverseCriterion(Criterion c, ArrayList a)
3584 {
3585 if (c != null)
3586 {
3587 a.add(c);
3588 for (int i = 0; i < c.getClauses().size(); i++)
3589 {
3590 traverseCriterion((Criterion) (c.getClauses().get(i)), a);
3591 }
3592 }
3593 }
3594 }
3595 }
This page was automatically generated by Maven