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