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