0001: package org.apache.torque.util;
0002:
0003: /*
0004: * Licensed to the Apache Software Foundation (ASF) under one
0005: * or more contributor license agreements. See the NOTICE file
0006: * distributed with this work for additional information
0007: * regarding copyright ownership. The ASF licenses this file
0008: * to you under the Apache License, Version 2.0 (the
0009: * "License"); you may not use this file except in compliance
0010: * with the License. You may obtain a copy of the License at
0011: *
0012: * http://www.apache.org/licenses/LICENSE-2.0
0013: *
0014: * Unless required by applicable law or agreed to in writing,
0015: * software distributed under the License is distributed on an
0016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0017: * KIND, either express or implied. See the License for the
0018: * specific language governing permissions and limitations
0019: * under the License.
0020: */
0021:
0022: import java.io.IOException;
0023: import java.io.ObjectInputStream;
0024: import java.io.ObjectOutputStream;
0025: import java.io.Serializable;
0026: import java.lang.reflect.Array;
0027: import java.math.BigDecimal;
0028: import java.util.ArrayList;
0029: import java.util.Arrays;
0030: import java.util.GregorianCalendar;
0031: import java.util.HashMap;
0032: import java.util.Hashtable;
0033: import java.util.Iterator;
0034: import java.util.List;
0035: import java.util.Map;
0036:
0037: import org.apache.commons.collections.OrderedMap;
0038: import org.apache.commons.collections.map.ListOrderedMap;
0039: import org.apache.commons.lang.ObjectUtils;
0040: import org.apache.commons.lang.StringUtils;
0041: import org.apache.commons.logging.Log;
0042: import org.apache.commons.logging.LogFactory;
0043: import org.apache.torque.Torque;
0044: import org.apache.torque.TorqueException;
0045: import org.apache.torque.adapter.DB;
0046: import org.apache.torque.om.DateKey;
0047: import org.apache.torque.om.ObjectKey;
0048:
0049: /**
0050: * This is a utility class that is used for retrieving different types
0051: * of values from a hashtable based on a simple name string. This
0052: * class is meant to minimize the amount of casting that needs to be
0053: * done when working with Hashtables.
0054: *
0055: * NOTE: other methods will be added as needed and as time permits.
0056: *
0057: * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
0058: * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
0059: * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
0060: * @author <a href="mailto:eric@dobbse.net">Eric Dobbs</a>
0061: * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
0062: * @author <a href="mailto:sam@neurogrid.com">Sam Joseph</a>
0063: * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
0064: * @author <a href="mailto:fischer@seitenbau.de">Thomas Fischer</a>
0065: * @author <a href="mailto:seade@backstagetech.com.au">Scott Eade</a>
0066: * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
0067: * @version $Id: Criteria.java 591648 2007-11-03 16:34:00Z tfischer $
0068: */
0069: public class Criteria extends Hashtable {
0070: /** Serial version. */
0071: private static final long serialVersionUID = -9001666575933085601L;
0072:
0073: /** Comparison type. */
0074: public static final SqlEnum EQUAL = SqlEnum.EQUAL;
0075:
0076: /** Comparison type. */
0077: public static final SqlEnum NOT_EQUAL = SqlEnum.NOT_EQUAL;
0078:
0079: /** Comparison type. */
0080: public static final SqlEnum ALT_NOT_EQUAL = SqlEnum.ALT_NOT_EQUAL;
0081:
0082: /** Comparison type. */
0083: public static final SqlEnum GREATER_THAN = SqlEnum.GREATER_THAN;
0084:
0085: /** Comparison type. */
0086: public static final SqlEnum LESS_THAN = SqlEnum.LESS_THAN;
0087:
0088: /** Comparison type. */
0089: public static final SqlEnum GREATER_EQUAL = SqlEnum.GREATER_EQUAL;
0090:
0091: /** Comparison type. */
0092: public static final SqlEnum LESS_EQUAL = SqlEnum.LESS_EQUAL;
0093:
0094: /** Comparison type. */
0095: public static final SqlEnum LIKE = SqlEnum.LIKE;
0096:
0097: /** Comparison type. */
0098: public static final SqlEnum NOT_LIKE = SqlEnum.NOT_LIKE;
0099:
0100: /** Comparison type. */
0101: public static final SqlEnum ILIKE = SqlEnum.ILIKE;
0102:
0103: /** Comparison type. */
0104: public static final SqlEnum NOT_ILIKE = SqlEnum.NOT_ILIKE;
0105:
0106: /** Comparison type. */
0107: public static final SqlEnum CUSTOM = SqlEnum.CUSTOM;
0108:
0109: /** Comparison type. */
0110: public static final SqlEnum DISTINCT = SqlEnum.DISTINCT;
0111:
0112: /** Comparison type. */
0113: public static final SqlEnum IN = SqlEnum.IN;
0114:
0115: /** Comparison type. */
0116: public static final SqlEnum NOT_IN = SqlEnum.NOT_IN;
0117:
0118: /** Comparison type. */
0119: public static final SqlEnum ALL = SqlEnum.ALL;
0120:
0121: /** Comparison type. */
0122: public static final SqlEnum JOIN = SqlEnum.JOIN;
0123:
0124: /** "Order by" qualifier - ascending */
0125: private static final SqlEnum ASC = SqlEnum.ASC;
0126:
0127: /** "Order by" qualifier - descending */
0128: private static final SqlEnum DESC = SqlEnum.DESC;
0129:
0130: /** "IS NULL" null comparison */
0131: public static final SqlEnum ISNULL = SqlEnum.ISNULL;
0132:
0133: /** "IS NOT NULL" null comparison */
0134: public static final SqlEnum ISNOTNULL = SqlEnum.ISNOTNULL;
0135:
0136: /** "CURRENT_DATE" ANSI SQL function */
0137: public static final SqlEnum CURRENT_DATE = SqlEnum.CURRENT_DATE;
0138:
0139: /** "CURRENT_TIME" ANSI SQL function */
0140: public static final SqlEnum CURRENT_TIME = SqlEnum.CURRENT_TIME;
0141:
0142: /** "LEFT JOIN" SQL statement */
0143: public static final SqlEnum LEFT_JOIN = SqlEnum.LEFT_JOIN;
0144:
0145: /** "RIGHT JOIN" SQL statement */
0146: public static final SqlEnum RIGHT_JOIN = SqlEnum.RIGHT_JOIN;
0147:
0148: /** "INNER JOIN" SQL statement */
0149: public static final SqlEnum INNER_JOIN = SqlEnum.INNER_JOIN;
0150:
0151: private static final int DEFAULT_CAPACITY = 10;
0152:
0153: private boolean ignoreCase = false;
0154: private boolean singleRecord = false;
0155: private boolean cascade = false;
0156: private UniqueList selectModifiers = new UniqueList();
0157: private UniqueList selectColumns = new UniqueList();
0158: private UniqueList orderByColumns = new UniqueList();
0159: private UniqueList groupByColumns = new UniqueList();
0160: private Criterion having = null;
0161: private OrderedMap asColumns = ListOrderedMap
0162: .decorate(new HashMap());
0163: private transient List joins = new ArrayList(3);
0164:
0165: /** The name of the database. */
0166: private String dbName;
0167:
0168: /** The name of the database as given in the contructor. */
0169: private String originalDbName;
0170:
0171: /**
0172: * To limit the number of rows to return. <code>-1</code> means return all
0173: * rows.
0174: */
0175: private int limit = -1;
0176:
0177: /** To start the results at a row other than the first one. */
0178: private int offset = 0;
0179:
0180: private HashMap aliases = new HashMap(8);
0181:
0182: private boolean useTransaction = false;
0183:
0184: /** the log. */
0185: private static Log log = LogFactory.getLog(Criteria.class);
0186:
0187: /**
0188: * Creates a new instance with the default capacity.
0189: */
0190: public Criteria() {
0191: this (DEFAULT_CAPACITY);
0192: }
0193:
0194: /**
0195: * Creates a new instance with the specified capacity.
0196: *
0197: * @param initialCapacity An int.
0198: */
0199: public Criteria(int initialCapacity) {
0200: this (Torque.getDefaultDB(), initialCapacity);
0201: }
0202:
0203: /**
0204: * Creates a new instance with the default capacity which corresponds to
0205: * the specified database.
0206: *
0207: * @param dbName The dabase name.
0208: */
0209: public Criteria(String dbName) {
0210: this (dbName, DEFAULT_CAPACITY);
0211: }
0212:
0213: /**
0214: * Creates a new instance with the specified capacity which corresponds to
0215: * the specified database.
0216: *
0217: * @param dbName The dabase name.
0218: * @param initialCapacity The initial capacity.
0219: */
0220: public Criteria(String dbName, int initialCapacity) {
0221: super (initialCapacity);
0222: this .dbName = dbName;
0223: this .originalDbName = dbName;
0224: }
0225:
0226: /**
0227: * Brings this criteria back to its initial state, so that it
0228: * can be reused as if it was new. Except if the criteria has grown in
0229: * capacity, it is left at the current capacity.
0230: */
0231: public void clear() {
0232: super .clear();
0233: ignoreCase = false;
0234: singleRecord = false;
0235: cascade = false;
0236: selectModifiers.clear();
0237: selectColumns.clear();
0238: orderByColumns.clear();
0239: groupByColumns.clear();
0240: having = null;
0241: asColumns.clear();
0242: joins.clear();
0243: dbName = originalDbName;
0244: offset = 0;
0245: limit = -1;
0246: aliases.clear();
0247: useTransaction = false;
0248: }
0249:
0250: /**
0251: * Add an AS clause to the select columns. Usage:
0252: * <p>
0253: * <code>
0254: *
0255: * Criteria myCrit = new Criteria();
0256: * myCrit.addAsColumn("alias", "ALIAS("+MyPeer.ID+")");
0257: *
0258: * </code>
0259: *
0260: * @param name wanted Name of the column
0261: * @param clause SQL clause to select from the table
0262: *
0263: * If the name already exists, it is replaced by the new clause.
0264: *
0265: * @return A modified Criteria object.
0266: */
0267: public Criteria addAsColumn(String name, String clause) {
0268: asColumns.put(name, clause);
0269: return this ;
0270: }
0271:
0272: /**
0273: * Get the column aliases.
0274: *
0275: * @return A Map which map the column alias names
0276: * to the alias clauses.
0277: */
0278: public Map getAsColumns() {
0279: return asColumns;
0280: }
0281:
0282: /**
0283: * Get the table aliases.
0284: *
0285: * @return A Map which maps the table alias names to the actual table names.
0286: */
0287: public Map getAliases() {
0288: return aliases;
0289: }
0290:
0291: /**
0292: * Allows one to specify an alias for a table that can
0293: * be used in various parts of the SQL.
0294: *
0295: * @param alias a <code>String</code> value
0296: * @param table a <code>String</code> value
0297: */
0298: public void addAlias(String alias, String table) {
0299: aliases.put(alias, table);
0300: }
0301:
0302: /**
0303: * Returns the table name associated with an alias.
0304: *
0305: * @param alias a <code>String</code> value
0306: * @return a <code>String</code> value
0307: */
0308: public String getTableForAlias(String alias) {
0309: return (String) aliases.get(alias);
0310: }
0311:
0312: /**
0313: * Does this Criteria Object contain the specified key?
0314: *
0315: * @param table The name of the table.
0316: * @param column The name of the column.
0317: * @return True if this Criteria Object contain the specified key.
0318: */
0319: public boolean containsKey(String table, String column) {
0320: return containsKey(table + '.' + column);
0321: }
0322:
0323: /**
0324: * Convenience method to return value as a boolean.
0325: *
0326: * @param column String name of column.
0327: * @return A boolean.
0328: */
0329: public boolean getBoolean(String column) {
0330: return ((Boolean) getCriterion(column).getValue())
0331: .booleanValue();
0332: }
0333:
0334: /**
0335: * Convenience method to return value as a boolean.
0336: *
0337: * @param table String name of table.
0338: * @param column String name of column.
0339: * @return A boolean.
0340: */
0341: public boolean getBoolean(String table, String column) {
0342: return getBoolean(new StringBuffer(table.length()
0343: + column.length() + 1).append(table).append('.')
0344: .append(column).toString());
0345: }
0346:
0347: /**
0348: * Will force the sql represented by this criteria to be executed within
0349: * a transaction. This is here primarily to support the oid type in
0350: * postgresql. Though it can be used to require any single sql statement
0351: * to use a transaction.
0352: */
0353: public void setUseTransaction(boolean v) {
0354: useTransaction = v;
0355: }
0356:
0357: /**
0358: * called by BasePeer to determine whether the sql command specified by
0359: * this criteria must be wrapped in a transaction.
0360: *
0361: * @return a <code>boolean</code> value
0362: */
0363: protected boolean isUseTransaction() {
0364: return useTransaction;
0365: }
0366:
0367: /**
0368: * Method to return criteria related to columns in a table.
0369: *
0370: * @param column String name of column.
0371: * @return A Criterion.
0372: */
0373: public Criterion getCriterion(String column) {
0374: return (Criterion) super .get(column);
0375: }
0376:
0377: /**
0378: * Method to return criteria related to a column in a table.
0379: *
0380: * @param table String name of table.
0381: * @param column String name of column.
0382: * @return A Criterion.
0383: */
0384: public Criterion getCriterion(String table, String column) {
0385: return getCriterion(new StringBuffer(table.length()
0386: + column.length() + 1).append(table).append('.')
0387: .append(column).toString());
0388: }
0389:
0390: /**
0391: * Method to return criterion that is not added automatically
0392: * to this Criteria. This can be used to chain the
0393: * Criterions to form a more complex where clause.
0394: *
0395: * @param column String full name of column (for example TABLE.COLUMN).
0396: * @return A Criterion.
0397: */
0398: public Criterion getNewCriterion(String column, Object value,
0399: SqlEnum comparison) {
0400: return new Criterion(column, value, comparison);
0401: }
0402:
0403: /**
0404: * Method to return criterion that is not added automatically
0405: * to this Criteria. This can be used to chain the
0406: * Criterions to form a more complex where clause.
0407: *
0408: * @param table String name of table.
0409: * @param column String name of column.
0410: * @return A Criterion.
0411: */
0412: public Criterion getNewCriterion(String table, String column,
0413: Object value, SqlEnum comparison) {
0414: return new Criterion(table, column, value, comparison);
0415: }
0416:
0417: /**
0418: * This method adds a prepared Criterion object to the Criteria.
0419: * You can get a new, empty Criterion object with the
0420: * getNewCriterion() method. If a criterion for the requested column
0421: * already exists, it is replaced. This is used as follows:
0422: *
0423: * <p>
0424: * <code>
0425: * Criteria crit = new Criteria();
0426: * Criteria.Criterion c = crit
0427: * .getNewCriterion(BasePeer.ID, new Integer(5), Criteria.LESS_THAN);
0428: * crit.add(c);
0429: * </code>
0430: *
0431: * @param c A Criterion object
0432: *
0433: * @return A modified Criteria object.
0434: */
0435: public Criteria add(Criterion c) {
0436: StringBuffer sb = new StringBuffer(c.getTable().length()
0437: + c.getColumn().length() + 1);
0438: sb.append(c.getTable());
0439: sb.append('.');
0440: sb.append(c.getColumn());
0441: super .put(sb.toString(), c);
0442: return this ;
0443: }
0444:
0445: /**
0446: * Method to return a String table name.
0447: *
0448: * @param name A String with the name of the key.
0449: * @return A String with the value of the object at key.
0450: */
0451: public String getColumnName(String name) {
0452: return getCriterion(name).getColumn();
0453: }
0454:
0455: /**
0456: * Method to return a comparison String.
0457: *
0458: * @param key String name of the key.
0459: * @return A String with the value of the object at key.
0460: */
0461: public SqlEnum getComparison(String key) {
0462: return getCriterion(key).getComparison();
0463: }
0464:
0465: /**
0466: * Method to return a comparison String.
0467: *
0468: * @param table String name of table.
0469: * @param column String name of column.
0470: * @return A String with the value of the object at key.
0471: */
0472: public SqlEnum getComparison(String table, String column) {
0473: return getComparison(new StringBuffer(table.length()
0474: + column.length() + 1).append(table).append('.')
0475: .append(column).toString());
0476: }
0477:
0478: /**
0479: * Convenience method to return a Date.
0480: *
0481: * @param name column name (TABLE.COLUMN)
0482: * @return A java.util.Date with the value of object at key.
0483: */
0484: public java.util.Date getDate(String name) {
0485: return (java.util.Date) getCriterion(name).getValue();
0486: }
0487:
0488: /**
0489: * Convenience method to return a Date.
0490: *
0491: * @param table String name of table.
0492: * @param column String name of column.
0493: * @return A java.util.Date with the value of object at key.
0494: */
0495: public java.util.Date getDate(String table, String column) {
0496: return getDate(new StringBuffer(table.length()
0497: + column.length() + 1).append(table).append('.')
0498: .append(column).toString());
0499: }
0500:
0501: /**
0502: * Get the Database(Map) name.
0503: *
0504: * @return A String with the Database(Map) name. By default, this
0505: * is PoolBrokerService.DEFAULT.
0506: */
0507: public String getDbName() {
0508: return dbName;
0509: }
0510:
0511: /**
0512: * Set the DatabaseMap name. If <code>null</code> is supplied, uses value
0513: * provided by <code>Torque.getDefaultDB()</code>.
0514: *
0515: * @param dbName A String with the Database(Map) name.
0516: */
0517: public void setDbName(String dbName) {
0518: this .dbName = (dbName == null ? Torque.getDefaultDB() : dbName
0519: .trim());
0520: }
0521:
0522: /**
0523: * Convenience method to return a double.
0524: *
0525: * @param name A String with the name of the key.
0526: * @return A double with the value of object at key.
0527: */
0528: public double getDouble(String name) {
0529: Object obj = getCriterion(name).getValue();
0530: if (obj instanceof String) {
0531: return new Double((String) obj).doubleValue();
0532: }
0533: return ((Double) obj).doubleValue();
0534: }
0535:
0536: /**
0537: * Convenience method to return a double.
0538: *
0539: * @param table String name of table.
0540: * @param column String name of column.
0541: * @return A double with the value of object at key.
0542: */
0543: public double getDouble(String table, String column) {
0544: return getDouble(new StringBuffer(table.length()
0545: + column.length() + 1).append(table).append('.')
0546: .append(column).toString());
0547: }
0548:
0549: /**
0550: * Convenience method to return a float.
0551: *
0552: * @param name A String with the name of the key.
0553: * @return A float with the value of object at key.
0554: */
0555: public float getFloat(String name) {
0556: Object obj = getCriterion(name).getValue();
0557: if (obj instanceof String) {
0558: return new Float((String) obj).floatValue();
0559: }
0560: return ((Float) obj).floatValue();
0561: }
0562:
0563: /**
0564: * Convenience method to return a float.
0565: *
0566: * @param table String name of table.
0567: * @param column String name of column.
0568: * @return A float with the value of object at key.
0569: */
0570: public float getFloat(String table, String column) {
0571: return getFloat(new StringBuffer(table.length()
0572: + column.length() + 1).append(table).append('.')
0573: .append(column).toString());
0574: }
0575:
0576: /**
0577: * Convenience method to return an Integer.
0578: *
0579: * @param name A String with the name of the key.
0580: * @return An Integer with the value of object at key.
0581: */
0582: public Integer getInteger(String name) {
0583: Object obj = getCriterion(name).getValue();
0584: if (obj instanceof String) {
0585: return new Integer((String) obj);
0586: }
0587: return ((Integer) obj);
0588: }
0589:
0590: /**
0591: * Convenience method to return an Integer.
0592: *
0593: * @param table String name of table.
0594: * @param column String name of column.
0595: * @return An Integer with the value of object at key.
0596: */
0597: public Integer getInteger(String table, String column) {
0598: return getInteger(new StringBuffer(table.length()
0599: + column.length() + 1).append(table).append('.')
0600: .append(column).toString());
0601: }
0602:
0603: /**
0604: * Convenience method to return an int.
0605: *
0606: * @param name A String with the name of the key.
0607: * @return An int with the value of object at key.
0608: */
0609: public int getInt(String name) {
0610: Object obj = getCriterion(name).getValue();
0611: if (obj instanceof String) {
0612: return new Integer((String) obj).intValue();
0613: }
0614: return ((Integer) obj).intValue();
0615: }
0616:
0617: /**
0618: * Convenience method to return an int.
0619: *
0620: * @param table String name of table.
0621: * @param column String name of column.
0622: * @return An int with the value of object at key.
0623: */
0624: public int getInt(String table, String column) {
0625: return getInt(new StringBuffer(table.length() + column.length()
0626: + 1).append(table).append('.').append(column)
0627: .toString());
0628: }
0629:
0630: /**
0631: * Convenience method to return a BigDecimal.
0632: *
0633: * @param name A String with the name of the key.
0634: * @return A BigDecimal with the value of object at key.
0635: */
0636: public BigDecimal getBigDecimal(String name) {
0637: Object obj = getCriterion(name).getValue();
0638: if (obj instanceof String) {
0639: return new BigDecimal((String) obj);
0640: }
0641: return (BigDecimal) obj;
0642: }
0643:
0644: /**
0645: * Convenience method to return a BigDecimal.
0646: *
0647: * @param table String name of table.
0648: * @param column String name of column.
0649: * @return A BigDecimal with the value of object at key.
0650: */
0651: public BigDecimal getBigDecimal(String table, String column) {
0652: return getBigDecimal(new StringBuffer(table.length()
0653: + column.length() + 1).append(table).append('.')
0654: .append(column).toString());
0655: }
0656:
0657: /**
0658: * Convenience method to return a long.
0659: *
0660: * @param name A String with the name of the key.
0661: * @return A long with the value of object at key.
0662: */
0663: public long getLong(String name) {
0664: Object obj = getCriterion(name).getValue();
0665: if (obj instanceof String) {
0666: return new Long((String) obj).longValue();
0667: }
0668: return ((Long) obj).longValue();
0669: }
0670:
0671: /**
0672: * Convenience method to return a long.
0673: *
0674: * @param table String name of table.
0675: * @param column String name of column.
0676: * @return A long with the value of object at key.
0677: */
0678: public long getLong(String table, String column) {
0679: return getLong(new StringBuffer(table.length()
0680: + column.length() + 1).append(table).append('.')
0681: .append(column).toString());
0682: }
0683:
0684: /**
0685: * Convenience method to return a String.
0686: *
0687: * @param name A String with the name of the key.
0688: * @return A String with the value of object at key.
0689: */
0690: public String getString(String name) {
0691: return (String) getCriterion(name).getValue();
0692: }
0693:
0694: /**
0695: * Convenience method to return a String.
0696: *
0697: * @param table String name of table.
0698: * @param column String name of column.
0699: * @return A String with the value of object at key.
0700: */
0701: public String getString(String table, String column) {
0702: return getString(new StringBuffer(table.length()
0703: + column.length() + 1).append(table).append('.')
0704: .append(column).toString());
0705: }
0706:
0707: /**
0708: * Method to return a String table name.
0709: *
0710: * @param name A String with the name of the key.
0711: * @return A String with the value of object at key.
0712: */
0713: public String getTableName(String name) {
0714: return getCriterion(name).getTable();
0715: }
0716:
0717: /**
0718: * Convenience method to return a List.
0719: *
0720: * @param name A String with the name of the key.
0721: * @return A List with the value of object at key.
0722: */
0723: public List getList(String name) {
0724: return (List) getCriterion(name).getValue();
0725: }
0726:
0727: /**
0728: * Convenience method to return a List.
0729: *
0730: * @param table String name of table.
0731: * @param column String name of column.
0732: * @return A List with the value of object at key.
0733: */
0734: public List getList(String table, String column) {
0735: return getList(new StringBuffer(table.length()
0736: + column.length() + 1).append(table).append('.')
0737: .append(column).toString());
0738: }
0739:
0740: /**
0741: * Method to return the value that was added to Criteria.
0742: *
0743: * @param name A String with the name of the key.
0744: * @return An Object with the value of object at key.
0745: */
0746: public Object getValue(String name) {
0747: return getCriterion(name).getValue();
0748: }
0749:
0750: /**
0751: * Method to return the value that was added to Criteria.
0752: *
0753: * @param table String name of table.
0754: * @param column String name of column.
0755: * @return An Object with the value of object at key.
0756: */
0757: public Object getValue(String table, String column) {
0758: return getValue(new StringBuffer(table.length()
0759: + column.length() + 1).append(table).append('.')
0760: .append(column).toString());
0761: }
0762:
0763: /**
0764: * Convenience method to return an ObjectKey.
0765: *
0766: * @param name A String with the name of the key.
0767: * @return An ObjectKey with the value of object at key.
0768: */
0769: public ObjectKey getObjectKey(String name) {
0770: return (ObjectKey) getCriterion(name).getValue();
0771: }
0772:
0773: /**
0774: * Convenience method to return an ObjectKey.
0775: *
0776: * @param table String name of table.
0777: * @param column String name of column.
0778: * @return A String with the value of object at key.
0779: */
0780: public ObjectKey getObjectKey(String table, String column) {
0781: return getObjectKey(new StringBuffer(table.length()
0782: + column.length() + 1).append(table).append('.')
0783: .append(column).toString());
0784: }
0785:
0786: /**
0787: * Overrides Hashtable get, so that the value placed in the
0788: * Criterion is returned instead of the Criterion.
0789: *
0790: * @param key An Object.
0791: * @return An Object.
0792: */
0793: public Object get(Object key) {
0794: return getValue((String) key);
0795: }
0796:
0797: /**
0798: * Overrides Hashtable put, so that this object is returned
0799: * instead of the value previously in the Criteria object.
0800: * The reason is so that it more closely matches the behavior
0801: * of the add() methods. If you want to get the previous value
0802: * then you should first Criteria.get() it yourself. Note, if
0803: * you attempt to pass in an Object that is not a String, it will
0804: * throw a NPE. The reason for this is that none of the add()
0805: * methods support adding anything other than a String as a key.
0806: *
0807: * @param key An Object. Must be instanceof String!
0808: * @param value An Object.
0809: * @throws NullPointerException if key != String or key/value is null.
0810: * @return Instance of self.
0811: */
0812: public Object put(Object key, Object value) {
0813: if (!(key instanceof String)) {
0814: throw new NullPointerException(
0815: "Criteria: Key must be a String object.");
0816: }
0817: return add((String) key, value);
0818: }
0819:
0820: /**
0821: * Copies all of the mappings from the specified Map to this Criteria
0822: * These mappings will replace any mappings that this Criteria had for any
0823: * of the keys currently in the specified Map.
0824: *
0825: * if the map was another Criteria, its attributes are copied to this
0826: * Criteria, overwriting previous settings.
0827: *
0828: * @param t Mappings to be stored in this map.
0829: */
0830: public synchronized void putAll(Map t) {
0831: Iterator i = t.entrySet().iterator();
0832: while (i.hasNext()) {
0833: Map.Entry e = (Map.Entry) i.next();
0834: Object val = e.getValue();
0835: if (val instanceof Criteria.Criterion) {
0836: super .put(e.getKey(), val);
0837: } else {
0838: put(e.getKey(), val);
0839: }
0840: }
0841: if (t instanceof Criteria) {
0842: Criteria c = (Criteria) t;
0843: this .joins = c.joins;
0844: }
0845: /* this would make a copy, not included
0846: but might want to use some of it.
0847: if (t instanceof Criteria)
0848: {
0849: Criteria c = (Criteria)t;
0850: this.ignoreCase = c.ignoreCase;
0851: this.singleRecord = c.singleRecord;
0852: this.cascade = c.cascade;
0853: this.selectModifiers = c.selectModifiers;
0854: this.selectColumns = c.selectColumns;
0855: this.orderByColumns = c.orderByColumns;
0856: this.dbName = c.dbName;
0857: this.limit = c.limit;
0858: this.offset = c.offset;
0859: this.aliases = c.aliases;
0860: }
0861: */
0862: }
0863:
0864: /**
0865: * This method adds a new criterion to the list of criterias. If a
0866: * criterion for the requested column already exists, it is
0867: * replaced. This is used as follows:
0868: *
0869: * <p>
0870: * <code>
0871: * Criteria crit = new Criteria().add("column",
0872: * "value");
0873: * </code>
0874: *
0875: * An EQUAL comparison is used for column and value.
0876: *
0877: * The name of the table must be used implicitly in the column name,
0878: * so the Column name must be something like 'TABLE.id'. If you
0879: * don't like this, you can use the add(table, column, value) method.
0880: *
0881: * @param column The column to run the comparison on
0882: * @param value An Object.
0883: *
0884: * @return A modified Criteria object.
0885: */
0886: public Criteria add(String column, Object value) {
0887: add(column, value, EQUAL);
0888: return this ;
0889: }
0890:
0891: /**
0892: * This method adds a new criterion to the list of criterias.
0893: * If a criterion for the requested column already exists, it is
0894: * replaced. If is used as follow:
0895: *
0896: * <p>
0897: * <code>
0898: * Criteria crit = new Criteria().add("column",
0899: * "value"
0900: * Criteria.GREATER_THAN);
0901: * </code>
0902: *
0903: * Any comparison can be used.
0904: *
0905: * The name of the table must be used implicitly in the column name,
0906: * so the Column name must be something like 'TABLE.id'. If you
0907: * don't like this, you can use the add(table, column, value) method.
0908: *
0909: * @param column The column to run the comparison on
0910: * @param value An Object.
0911: * @param comparison A String.
0912: *
0913: * @return A modified Criteria object.
0914: */
0915: public Criteria add(String column, Object value, SqlEnum comparison) {
0916: super .put(column, new Criterion(column, value, comparison));
0917: return this ;
0918: }
0919:
0920: /**
0921: * This method adds a new criterion to the list of criterias.
0922: * If a criterion for the requested column already exists, it is
0923: * replaced. If is used as follows:
0924: *
0925: * <p>
0926: * <code>
0927: * Criteria crit = new Criteria().add("table",
0928: * "column",
0929: * "value");
0930: * </code>
0931: *
0932: * An EQUAL comparison is used for column and value.
0933: *
0934: * @param table Name of the table which contains the column
0935: * @param column The column to run the comparison on
0936: * @param value An Object.
0937: *
0938: * @return A modified Criteria object.
0939: */
0940: public Criteria add(String table, String column, Object value) {
0941: add(table, column, value, EQUAL);
0942: return this ;
0943: }
0944:
0945: /**
0946: * This method adds a new criterion to the list of criterias.
0947: * If a criterion for the requested column already exists, it is
0948: * replaced. If is used as follows:
0949: *
0950: * <p>
0951: * <code>
0952: * Criteria crit = new Criteria().add("table",
0953: * "column",
0954: * "value",
0955: * Criteria.GREATER_THAN);
0956: * </code>
0957: *
0958: * Any comparison can be used.
0959: *
0960: * @param table Name of table which contains the column
0961: * @param column The column to run the comparison on
0962: * @param value An Object.
0963: * @param comparison String describing how to compare the column with
0964: * the value
0965: * @return A modified Criteria object.
0966: */
0967: public Criteria add(String table, String column, Object value,
0968: SqlEnum comparison) {
0969: StringBuffer sb = new StringBuffer(table.length()
0970: + column.length() + 1);
0971: sb.append(table);
0972: sb.append('.');
0973: sb.append(column);
0974: super .put(sb.toString(), new Criterion(table, column, value,
0975: comparison));
0976: return this ;
0977: }
0978:
0979: /**
0980: * Convenience method to add a boolean to Criteria.
0981: * Equal to
0982: *
0983: * <p>
0984: * <code>
0985: * add(column, new Boolean(value), EQUAL);
0986: * </code>
0987: *
0988: * @param column The column to run the comparison on
0989: * @param value A Boolean.
0990: *
0991: * @return A modified Criteria object.
0992: */
0993: public Criteria add(String column, boolean value) {
0994: add(column, (value ? Boolean.TRUE : Boolean.FALSE));
0995: return this ;
0996: }
0997:
0998: /**
0999: * Convenience method to add a boolean to Criteria.
1000: * Equal to
1001: *
1002: * <p>
1003: * <code>
1004: * add(column, new Boolean(value), comparison);
1005: * </code>
1006: *
1007: * @param column The column to run the comparison on
1008: * @param value A Boolean.
1009: * @param comparison String describing how to compare the column with
1010: * the value
1011: * @return A modified Criteria object.
1012: */
1013: public Criteria add(String column, boolean value, SqlEnum comparison) {
1014: add(column, new Boolean(value), comparison);
1015: return this ;
1016: }
1017:
1018: /**
1019: * Convenience method to add an int to Criteria.
1020: * Equal to
1021: *
1022: * <p>
1023: * <code>
1024: * add(column, new Integer(value), EQUAL);
1025: * </code>
1026: *
1027: * @param column The column to run the comparison on
1028: * @param value An int.
1029: * @return A modified Criteria object.
1030: */
1031: public Criteria add(String column, int value) {
1032: add(column, new Integer(value));
1033: return this ;
1034: }
1035:
1036: /**
1037: * Convenience method to add an int to Criteria.
1038: * Equal to
1039: *
1040: * <p>
1041: * <code>
1042: * add(column, new Integer(value), comparison);
1043: * </code>
1044: *
1045: * @param column The column to run the comparison on
1046: * @param value An int.
1047: * @param comparison String describing how to compare the column with
1048: * the value
1049: * @return A modified Criteria object.
1050: */
1051: public Criteria add(String column, int value, SqlEnum comparison) {
1052: add(column, new Integer(value), comparison);
1053: return this ;
1054: }
1055:
1056: /**
1057: * Convenience method to add a long to Criteria.
1058: * Equal to
1059: *
1060: * <p>
1061: * <code>
1062: * add(column, new Long(value), EQUAL);
1063: * </code>
1064: *
1065: * @param column The column to run the comparison on
1066: * @param value A long.
1067: * @return A modified Criteria object.
1068: */
1069: public Criteria add(String column, long value) {
1070: add(column, new Long(value));
1071: return this ;
1072: }
1073:
1074: /**
1075: * Convenience method to add a long to Criteria.
1076: * Equal to
1077: *
1078: * <p>
1079: * <code>
1080: * add(column, new Long(value), comparison);
1081: * </code>
1082: *
1083: * @param column The column to run the comparison on
1084: * @param value A long.
1085: * @param comparison String describing how to compare the column with
1086: * the value
1087: * @return A modified Criteria object.
1088: */
1089: public Criteria add(String column, long value, SqlEnum comparison) {
1090: add(column, new Long(value), comparison);
1091: return this ;
1092: }
1093:
1094: /**
1095: * Convenience method to add a float to Criteria.
1096: * Equal to
1097: *
1098: * <p>
1099: * <code>
1100: * add(column, new Float(value), EQUAL);
1101: * </code>
1102: *
1103: * @param column The column to run the comparison on
1104: * @param value A float.
1105: * @return A modified Criteria object.
1106: */
1107: public Criteria add(String column, float value) {
1108: add(column, new Float(value));
1109: return this ;
1110: }
1111:
1112: /**
1113: * Convenience method to add a float to Criteria.
1114: * Equal to
1115: *
1116: * <p>
1117: * <code>
1118: * add(column, new Float(value), comparison);
1119: * </code>
1120: *
1121: * @param column The column to run the comparison on
1122: * @param value A float.
1123: * @param comparison String describing how to compare the column with
1124: * the value
1125: * @return A modified Criteria object.
1126: */
1127: public Criteria add(String column, float value, SqlEnum comparison) {
1128: add(column, new Float(value), comparison);
1129: return this ;
1130: }
1131:
1132: /**
1133: * Convenience method to add a double to Criteria.
1134: * Equal to
1135: *
1136: * <p>
1137: * <code>
1138: * add(column, new Double(value), EQUAL);
1139: * </code>
1140: *
1141: * @param column The column to run the comparison on
1142: * @param value A double.
1143: * @return A modified Criteria object.
1144: */
1145: public Criteria add(String column, double value) {
1146: add(column, new Double(value));
1147: return this ;
1148: }
1149:
1150: /**
1151: * Convenience method to add a double to Criteria.
1152: * Equal to
1153: *
1154: * <p>
1155: * <code>
1156: * add(column, new Double(value), comparison);
1157: * </code>
1158: *
1159: * @param column The column to run the comparison on
1160: * @param value A double.
1161: * @param comparison String describing how to compare the column with
1162: * the value
1163: * @return A modified Criteria object.
1164: */
1165: public Criteria add(String column, double value, SqlEnum comparison) {
1166: add(column, new Double(value), comparison);
1167: return this ;
1168: }
1169:
1170: /**
1171: * Convenience method to add a Date object specified by
1172: * year, month, and date into the Criteria.
1173: * Equal to
1174: *
1175: * <p>
1176: * <code>
1177: * add(column, new GregorianCalendar(year, month,date), EQUAL);
1178: * </code>
1179: *
1180: * @param column A String value to use as column.
1181: * @param year An int with the year.
1182: * @param month An int with the month. Month value is 0-based.
1183: * e.g., 0 for January
1184: * @param date An int with the date.
1185: * @return A modified Criteria object.
1186: */
1187: public Criteria addDate(String column, int year, int month, int date) {
1188: add(column, new GregorianCalendar(year, month, date).getTime());
1189: return this ;
1190: }
1191:
1192: /**
1193: * Convenience method to add a Date object specified by
1194: * year, month, and date into the Criteria.
1195: * Equal to
1196: *
1197: * <p>
1198: * <code>
1199: * add(column, new GregorianCalendar(year, month,date), comparison);
1200: * </code>
1201: *
1202: * @param column The column to run the comparison on
1203: * @param year An int with the year.
1204: * @param month An int with the month. Month value is 0-based.
1205: * e.g., 0 for January
1206: * @param date An int with the date.
1207: * @param comparison String describing how to compare the column with
1208: * the value
1209: * @return A modified Criteria object.
1210: */
1211: public Criteria addDate(String column, int year, int month,
1212: int date, SqlEnum comparison) {
1213: add(column, new GregorianCalendar(year, month, date).getTime(),
1214: comparison);
1215: return this ;
1216: }
1217:
1218: /**
1219: * This is the way that you should add a join of two tables. For
1220: * example:
1221: *
1222: * <p>
1223: * AND PROJECT.PROJECT_ID=FOO.PROJECT_ID
1224: * <p>
1225: *
1226: * left = PROJECT.PROJECT_ID
1227: * right = FOO.PROJECT_ID
1228: *
1229: * @param left A String with the left side of the join.
1230: * @param right A String with the right side of the join.
1231: * @return A modified Criteria object.
1232: */
1233: public Criteria addJoin(String left, String right) {
1234: return addJoin(left, right, null);
1235: }
1236:
1237: /**
1238: * This is the way that you should add a join of two tables. For
1239: * example:
1240: *
1241: * <p>
1242: * PROJECT LEFT JOIN FOO ON PROJECT.PROJECT_ID=FOO.PROJECT_ID
1243: * <p>
1244: *
1245: * left = "PROJECT.PROJECT_ID"
1246: * right = "FOO.PROJECT_ID"
1247: * operator = Criteria.LEFT_JOIN
1248: *
1249: * @param left A String with the left side of the join.
1250: * @param right A String with the right side of the join.
1251: * @param operator The operator used for the join: must be one of null,
1252: * Criteria.LEFT_JOIN, Criteria.RIGHT_JOIN, Criteria.INNER_JOIN
1253: * @return A modified Criteria object.
1254: */
1255: public Criteria addJoin(String left, String right, SqlEnum operator) {
1256: joins.add(new Join(left, right, operator));
1257:
1258: return this ;
1259: }
1260:
1261: /**
1262: * get the List of Joins. This method is meant to
1263: * be called by BasePeer.
1264: * @return a List which contains objects of type Join.
1265: * If the criteria does not contains any joins, the list is empty
1266: */
1267: public List getJoins() {
1268: return joins;
1269: }
1270:
1271: /**
1272: * get one side of the set of possible joins. This method is meant to
1273: * be called by BasePeer.
1274: *
1275: * @deprecated This method is no longer used by BasePeer.
1276: */
1277: public List getJoinL() {
1278: throw new RuntimeException(
1279: "getJoinL() in Criteria is no longer supported!");
1280: }
1281:
1282: /**
1283: * get one side of the set of possible joins. This method is meant to
1284: * be called by BasePeer.
1285: *
1286: * @deprecated This method is no longer used by BasePeer.
1287: */
1288: public List getJoinR() {
1289: throw new RuntimeException(
1290: "getJoinL() in Criteria is no longer supported!");
1291: }
1292:
1293: /**
1294: * Adds an 'IN' clause with the criteria supplied as an Object
1295: * array. For example:
1296: *
1297: * <p>
1298: * FOO.NAME IN ('FOO', 'BAR', 'ZOW')
1299: * <p>
1300: *
1301: * where 'values' contains three objects that evaluate to the
1302: * respective strings above when .toString() is called.
1303: *
1304: * If a criterion for the requested column already exists, it is
1305: * replaced.
1306: *
1307: * @param column The column to run the comparison on
1308: * @param values An Object[] with the allowed values.
1309: * @return A modified Criteria object.
1310: */
1311: public Criteria addIn(String column, Object[] values) {
1312: add(column, (Object) values, Criteria.IN);
1313: return this ;
1314: }
1315:
1316: /**
1317: * Adds an 'IN' clause with the criteria supplied as an int array.
1318: * For example:
1319: *
1320: * <p>
1321: * FOO.ID IN ('2', '3', '7')
1322: * <p>
1323: *
1324: * where 'values' contains those three integers.
1325: *
1326: * If a criterion for the requested column already exists, it is
1327: * replaced.
1328: *
1329: * @param column The column to run the comparison on
1330: * @param values An int[] with the allowed values.
1331: * @return A modified Criteria object.
1332: */
1333: public Criteria addIn(String column, int[] values) {
1334: add(column, (Object) values, Criteria.IN);
1335: return this ;
1336: }
1337:
1338: /**
1339: * Adds an 'IN' clause with the criteria supplied as a List.
1340: * For example:
1341: *
1342: * <p>
1343: * FOO.NAME IN ('FOO', 'BAR', 'ZOW')
1344: * <p>
1345: *
1346: * where 'values' contains three objects that evaluate to the
1347: * respective strings above when .toString() is called.
1348: *
1349: * If a criterion for the requested column already exists, it is
1350: * replaced.
1351: *
1352: * @param column The column to run the comparison on
1353: * @param values A List with the allowed values.
1354: * @return A modified Criteria object.
1355: */
1356: public Criteria addIn(String column, List values) {
1357: add(column, (Object) values, Criteria.IN);
1358: return this ;
1359: }
1360:
1361: /**
1362: * Adds a 'NOT IN' clause with the criteria supplied as an Object
1363: * array. For example:
1364: *
1365: * <p>
1366: * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
1367: * <p>
1368: *
1369: * where 'values' contains three objects that evaluate to the
1370: * respective strings above when .toString() is called.
1371: *
1372: * If a criterion for the requested column already exists, it is
1373: * replaced.
1374: *
1375: * @param column The column to run the comparison on
1376: * @param values An Object[] with the disallowed values.
1377: * @return A modified Criteria object.
1378: */
1379: public Criteria addNotIn(String column, Object[] values) {
1380: add(column, (Object) values, Criteria.NOT_IN);
1381: return this ;
1382: }
1383:
1384: /**
1385: * Adds a 'NOT IN' clause with the criteria supplied as an int
1386: * array. For example:
1387: *
1388: * <p>
1389: * FOO.ID NOT IN ('2', '3', '7')
1390: * <p>
1391: *
1392: * where 'values' contains those three integers.
1393: *
1394: * If a criterion for the requested column already exists, it is
1395: * replaced.
1396: *
1397: * @param column The column to run the comparison on
1398: * @param values An int[] with the disallowed values.
1399: * @return A modified Criteria object.
1400: */
1401: public Criteria addNotIn(String column, int[] values) {
1402: add(column, (Object) values, Criteria.NOT_IN);
1403: return this ;
1404: }
1405:
1406: /**
1407: * Adds a 'NOT IN' clause with the criteria supplied as a List.
1408: * For example:
1409: *
1410: * <p>
1411: * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
1412: * <p>
1413: *
1414: * where 'values' contains three objects that evaluate to the
1415: * respective strings above when .toString() is called.
1416: *
1417: * If a criterion for the requested column already exists, it is
1418: * replaced.
1419: *
1420: * @param column The column to run the comparison on
1421: * @param values A List with the disallowed values.
1422: * @return A modified Criteria object.
1423: */
1424: public Criteria addNotIn(String column, List values) {
1425: add(column, (Object) values, Criteria.NOT_IN);
1426: return this ;
1427: }
1428:
1429: /**
1430: * Adds "ALL " to the SQL statement.
1431: */
1432: public void setAll() {
1433: selectModifiers.add(ALL.toString());
1434: }
1435:
1436: /**
1437: * Adds "DISTINCT " to the SQL statement.
1438: */
1439: public void setDistinct() {
1440: selectModifiers.add(DISTINCT.toString());
1441: }
1442:
1443: /**
1444: * Sets ignore case.
1445: *
1446: * @param b True if case should be ignored.
1447: * @return A modified Criteria object.
1448: */
1449: public Criteria setIgnoreCase(boolean b) {
1450: ignoreCase = b;
1451: return this ;
1452: }
1453:
1454: /**
1455: * Is ignore case on or off?
1456: *
1457: * @return True if case is ignored.
1458: */
1459: public boolean isIgnoreCase() {
1460: return ignoreCase;
1461: }
1462:
1463: /**
1464: * Set single record? Set this to <code>true</code> if you expect the query
1465: * to result in only a single result record (the default behaviour is to
1466: * throw a TorqueException if multiple records are returned when the query
1467: * is executed). This should be used in situations where returning multiple
1468: * rows would indicate an error of some sort. If your query might return
1469: * multiple records but you are only interested in the first one then you
1470: * should be using setLimit(1).
1471: *
1472: * @param b set to <code>true</code> if you expect the query to select just
1473: * one record.
1474: * @return A modified Criteria object.
1475: */
1476: public Criteria setSingleRecord(boolean b) {
1477: singleRecord = b;
1478: return this ;
1479: }
1480:
1481: /**
1482: * Is single record?
1483: *
1484: * @return True if a single record is being returned.
1485: */
1486: public boolean isSingleRecord() {
1487: return singleRecord;
1488: }
1489:
1490: /**
1491: * Set cascade.
1492: *
1493: * @param b True if cascade is set.
1494: * @return A modified Criteria object.
1495: */
1496: public Criteria setCascade(boolean b) {
1497: cascade = b;
1498: return this ;
1499: }
1500:
1501: /**
1502: * Is cascade set?
1503: *
1504: * @return True if cascade is set.
1505: */
1506: public boolean isCascade() {
1507: return cascade;
1508: }
1509:
1510: /**
1511: * Set limit.
1512: *
1513: * @param limit An int with the value for limit.
1514: * @return A modified Criteria object.
1515: */
1516: public Criteria setLimit(int limit) {
1517: this .limit = limit;
1518: return this ;
1519: }
1520:
1521: /**
1522: * Get limit.
1523: *
1524: * @return An int with the value for limit.
1525: */
1526: public int getLimit() {
1527: return limit;
1528: }
1529:
1530: /**
1531: * Set offset.
1532: *
1533: * @param offset An int with the value for offset.
1534: * @return A modified Criteria object.
1535: */
1536: public Criteria setOffset(int offset) {
1537: this .offset = offset;
1538: return this ;
1539: }
1540:
1541: /**
1542: * Get offset.
1543: *
1544: * @return An int with the value for offset.
1545: */
1546: public int getOffset() {
1547: return offset;
1548: }
1549:
1550: /**
1551: * Add select column.
1552: *
1553: * @param name A String with the name of the select column.
1554: * @return A modified Criteria object.
1555: */
1556: public Criteria addSelectColumn(String name) {
1557: selectColumns.add(name);
1558: return this ;
1559: }
1560:
1561: /**
1562: * Get select columns.
1563: *
1564: * @return An StringStack with the name of the select
1565: * columns.
1566: */
1567: public UniqueList getSelectColumns() {
1568: return selectColumns;
1569: }
1570:
1571: /**
1572: * Get select modifiers.
1573: *
1574: * @return An UniqueList with the select modifiers.
1575: */
1576: public UniqueList getSelectModifiers() {
1577: return selectModifiers;
1578: }
1579:
1580: /**
1581: * Add group by column name.
1582: *
1583: * @param groupBy The name of the column to group by.
1584: * @return A modified Criteria object.
1585: */
1586: public Criteria addGroupByColumn(String groupBy) {
1587: groupByColumns.add(groupBy);
1588: return this ;
1589: }
1590:
1591: /**
1592: * Add order by column name, explicitly specifying ascending.
1593: *
1594: * @param name The name of the column to order by.
1595: * @return A modified Criteria object.
1596: */
1597: public Criteria addAscendingOrderByColumn(String name) {
1598: orderByColumns.add(name + ' ' + ASC);
1599: return this ;
1600: }
1601:
1602: /**
1603: * Add order by column name, explicitly specifying descending.
1604: *
1605: * @param name The name of the column to order by.
1606: * @return A modified Criteria object.
1607: */
1608: public Criteria addDescendingOrderByColumn(String name) {
1609: orderByColumns.add(name + ' ' + DESC);
1610: return this ;
1611: }
1612:
1613: /**
1614: * Get order by columns.
1615: *
1616: * @return An UniqueList with the name of the order columns.
1617: */
1618: public UniqueList getOrderByColumns() {
1619: return orderByColumns;
1620: }
1621:
1622: /**
1623: * Get group by columns.
1624: *
1625: * @return An UniqueList with the name of the groupBy clause.
1626: */
1627: public UniqueList getGroupByColumns() {
1628: return groupByColumns;
1629: }
1630:
1631: /**
1632: * Get Having Criterion.
1633: *
1634: * @return A Criterion that is the having clause.
1635: */
1636: public Criterion getHaving() {
1637: return having;
1638: }
1639:
1640: /**
1641: * Remove an object from the criteria.
1642: *
1643: * @param key A String with the key to be removed.
1644: * @return The removed object.
1645: */
1646: public Object remove(String key) {
1647: Object foo = super .remove(key);
1648: if (foo instanceof Criterion) {
1649: return ((Criterion) foo).getValue();
1650: }
1651: return foo;
1652: }
1653:
1654: /**
1655: * Build a string representation of the Criteria.
1656: *
1657: * @return A String with the representation of the Criteria.
1658: */
1659: public String toString() {
1660: StringBuffer sb = new StringBuffer("Criteria:: ");
1661: Iterator it = keySet().iterator();
1662: while (it.hasNext()) {
1663: String key = (String) it.next();
1664: sb.append(key).append("<=>").append(
1665: super .get(key).toString()).append(": ");
1666: }
1667:
1668: try {
1669: sb
1670: .append(
1671: "\nCurrent Query SQL (may not be complete or applicable): ")
1672: .append(BasePeer.createQueryDisplayString(this ));
1673: } catch (Exception exc) {
1674: log.debug("Exception when evaluating a Criteria", exc);
1675: }
1676:
1677: return sb.toString();
1678: }
1679:
1680: /**
1681: * This method checks another Criteria to see if they contain
1682: * the same attributes and hashtable entries.
1683: */
1684: public boolean equals(Object crit) {
1685: boolean isEquiv = false;
1686: if (crit == null || !(crit instanceof Criteria)) {
1687: isEquiv = false;
1688: } else if (this == crit) {
1689: isEquiv = true;
1690: } else if (this .size() == ((Criteria) crit).size()) {
1691: Criteria criteria = (Criteria) crit;
1692: if (this .offset == criteria.getOffset()
1693: && this .limit == criteria.getLimit()
1694: && ignoreCase == criteria.isIgnoreCase()
1695: && singleRecord == criteria.isSingleRecord()
1696: && cascade == criteria.isCascade()
1697: && dbName.equals(criteria.getDbName())
1698: && selectModifiers.equals(criteria
1699: .getSelectModifiers())
1700: && selectColumns
1701: .equals(criteria.getSelectColumns())
1702: && orderByColumns.equals(criteria
1703: .getOrderByColumns())
1704: && aliases.equals(criteria.getAliases())
1705: && asColumns.equals(criteria.getAsColumns())
1706: && joins.equals(criteria.getJoins())) {
1707: isEquiv = true;
1708: for (Iterator it = criteria.keySet().iterator(); it
1709: .hasNext();) {
1710: String key = (String) it.next();
1711: if (this .containsKey(key)) {
1712: Criterion a = this .getCriterion(key);
1713: Criterion b = criteria.getCriterion(key);
1714: if (!a.equals(b)) {
1715: isEquiv = false;
1716: break;
1717: }
1718: } else {
1719: isEquiv = false;
1720: break;
1721: }
1722: }
1723: }
1724: }
1725: return isEquiv;
1726: }
1727:
1728: /**
1729: * Returns the hash code value for this Join.
1730: *
1731: * @return a hash code value for this object.
1732: */
1733: public int hashCode() {
1734: int result = 16;
1735: result = 37 * result + offset;
1736: result = 37 * result + limit;
1737: result = 37 * result + (ignoreCase ? 0 : 1);
1738: result = 37 * result + (singleRecord ? 0 : 1);
1739: result = 37 * result + (cascade ? 0 : 1);
1740: result = 37 * result + dbName.hashCode();
1741: result = 37 * result + selectModifiers.hashCode();
1742: result = 37 * result + selectColumns.hashCode();
1743: result = 37 * result + orderByColumns.hashCode();
1744: result = 37 * result + aliases.hashCode();
1745: result = 37 * result + asColumns.hashCode();
1746: result = 37 * result + joins.hashCode();
1747: result = 37 * result + super .hashCode();
1748: return result;
1749: }
1750:
1751: /*
1752: * ------------------------------------------------------------------------
1753: *
1754: * Start of the "and" methods
1755: *
1756: * ------------------------------------------------------------------------
1757: */
1758:
1759: /**
1760: * This method adds a prepared Criterion object to the Criteria as a having
1761: * clause. You can get a new, empty Criterion object with the
1762: * getNewCriterion() method.
1763: *
1764: * <p>
1765: * <code>
1766: * Criteria crit = new Criteria();
1767: * Criteria.Criterion c = crit.getNewCriterion(BasePeer.ID, new Integer(5),
1768: * Criteria.LESS_THAN);
1769: * crit.addHaving(c);
1770: * </code>
1771: *
1772: * @param having A Criterion object
1773: * @return A modified Criteria object.
1774: */
1775: public Criteria addHaving(Criterion having) {
1776: this .having = having;
1777: return this ;
1778: }
1779:
1780: /**
1781: * This method adds a prepared Criterion object to the Criteria.
1782: * You can get a new, empty Criterion object with the
1783: * getNewCriterion() method. If a criterion for the requested column
1784: * already exists, it is "AND"ed to the existing criterion.
1785: * This is used as follows:
1786: *
1787: * <p>
1788: * <code>
1789: * Criteria crit = new Criteria();
1790: * Criteria.Criterion c = crit.getNewCriterion(BasePeer.ID, new Integer(5),
1791: * Criteria.LESS_THAN);
1792: * crit.and(c);
1793: * </code>
1794: *
1795: * @param c A Criterion object
1796: * @return A modified Criteria object.
1797: */
1798: public Criteria and(Criterion c) {
1799: Criterion oc = getCriterion(c.getTable() + '.' + c.getColumn());
1800:
1801: if (oc == null) {
1802: add(c);
1803: } else {
1804: oc.and(c);
1805: }
1806: return this ;
1807: }
1808:
1809: /**
1810: * This method adds a new criterion to the list of criterias. If a
1811: * criterion for the requested column already exists, it is
1812: * "AND"ed to the existing criterion. This is used as follows:
1813: *
1814: * <p>
1815: * <code>
1816: * Criteria crit = new Criteria().and("column",
1817: * "value");
1818: * </code>
1819: *
1820: * An EQUAL comparison is used for column and value.
1821: *
1822: * The name of the table must be used implicitly in the column name,
1823: * so the Column name must be something like 'TABLE.id'. If you
1824: * don't like this, you can use the and(table, column, value) method.
1825: *
1826: * @param column The column to run the comparison on
1827: * @param value An Object.
1828: *
1829: * @return A modified Criteria object.
1830: */
1831: public Criteria and(String column, Object value) {
1832: and(column, value, EQUAL);
1833: return this ;
1834: }
1835:
1836: /**
1837: * This method adds a new criterion to the list of criterias.
1838: * If a criterion for the requested column already exists, it is
1839: * "AND"ed to the existing criterion. If is used as follow:
1840: *
1841: * <p>
1842: * <code>
1843: * Criteria crit = new Criteria().and("column",
1844: * "value"
1845: * Criteria.GREATER_THAN);
1846: * </code>
1847: *
1848: * Any comparison can be used.
1849: *
1850: * The name of the table must be used implicitly in the column name,
1851: * so the Column name must be something like 'TABLE.id'. If you
1852: * don't like this, you can use the and(table, column, value) method.
1853: *
1854: * @param column The column to run the comparison on
1855: * @param value An Object.
1856: * @param comparison A String.
1857: *
1858: * @return A modified Criteria object.
1859: */
1860: public Criteria and(String column, Object value, SqlEnum comparison) {
1861: Criterion oc = getCriterion(column);
1862: Criterion nc = new Criterion(column, value, comparison);
1863:
1864: if (oc == null) {
1865: super .put(column, nc);
1866: } else {
1867: oc.and(nc);
1868: }
1869: return this ;
1870: }
1871:
1872: /**
1873: * This method adds a new criterion to the list of criterias.
1874: * If a criterion for the requested column already exists, it is
1875: * "AND"ed to the existing criterion. If is used as follows:
1876: *
1877: * <p>
1878: * <code>
1879: * Criteria crit = new Criteria().and("table",
1880: * "column",
1881: * "value");
1882: * </code>
1883: *
1884: * An EQUAL comparison is used for column and value.
1885: *
1886: * @param table Name of the table which contains the column
1887: * @param column The column to run the comparison on
1888: * @param value An Object.
1889: * @return A modified Criteria object.
1890: */
1891: public Criteria and(String table, String column, Object value) {
1892: and(table, column, value, EQUAL);
1893: return this ;
1894: }
1895:
1896: /**
1897: * This method adds a new criterion to the list of criterias.
1898: * If a criterion for the requested column already exists, it is
1899: * "AND"ed to the existing criterion. If is used as follows:
1900: *
1901: * <p>
1902: * <code>
1903: * Criteria crit = new Criteria().and("table",
1904: * "column",
1905: * "value",
1906: * "Criterion.GREATER_THAN");
1907: * </code>
1908: *
1909: * Any comparison can be used.
1910: *
1911: * @param table Name of table which contains the column
1912: * @param column The column to run the comparison on
1913: * @param value An Object.
1914: * @param comparison String describing how to compare the column with
1915: * the value
1916: * @return A modified Criteria object.
1917: */
1918: public Criteria and(String table, String column, Object value,
1919: SqlEnum comparison) {
1920: StringBuffer sb = new StringBuffer(table.length()
1921: + column.length() + 1);
1922: sb.append(table);
1923: sb.append('.');
1924: sb.append(column);
1925:
1926: Criterion oc = getCriterion(table, column);
1927: Criterion nc = new Criterion(table, column, value, comparison);
1928:
1929: if (oc == null) {
1930: super .put(sb.toString(), nc);
1931: } else {
1932: oc.and(nc);
1933: }
1934: return this ;
1935: }
1936:
1937: /**
1938: * Convenience method to add a boolean to Criteria.
1939: * Equal to
1940: *
1941: * <p>
1942: * <code>
1943: * and(column, new Boolean(value), EQUAL);
1944: * </code>
1945: *
1946: * @param column The column to run the comparison on
1947: * @param value A Boolean.
1948: * @return A modified Criteria object.
1949: */
1950: public Criteria and(String column, boolean value) {
1951: and(column, new Boolean(value));
1952: return this ;
1953: }
1954:
1955: /**
1956: * Convenience method to add a boolean to Criteria.
1957: * Equal to
1958: *
1959: * <p>
1960: * <code>
1961: * and(column, new Boolean(value), comparison);
1962: * </code>
1963: *
1964: * @param column The column to run the comparison on
1965: * @param value A Boolean.
1966: * @param comparison String describing how to compare the column
1967: * with the value
1968: * @return A modified Criteria object.
1969: */
1970: public Criteria and(String column, boolean value, SqlEnum comparison) {
1971: and(column, new Boolean(value), comparison);
1972: return this ;
1973: }
1974:
1975: /**
1976: * Convenience method to add an int to Criteria.
1977: * Equal to
1978: *
1979: * <p>
1980: * <code>
1981: * and(column, new Integer(value), EQUAL);
1982: * </code>
1983: *
1984: * @param column The column to run the comparison on
1985: * @param value An int.
1986: * @return A modified Criteria object.
1987: */
1988: public Criteria and(String column, int value) {
1989: and(column, new Integer(value));
1990: return this ;
1991: }
1992:
1993: /**
1994: * Convenience method to add an int to Criteria.
1995: * Equal to
1996: *
1997: * <p>
1998: * <code>
1999: * and(column, new Integer(value), comparison);
2000: * </code>
2001: *
2002: * @param column The column to run the comparison on
2003: * @param value An int.
2004: * @param comparison String describing how to compare the column with the value
2005: * @return A modified Criteria object.
2006: */
2007: public Criteria and(String column, int value, SqlEnum comparison) {
2008: and(column, new Integer(value), comparison);
2009: return this ;
2010: }
2011:
2012: /**
2013: * Convenience method to add a long to Criteria.
2014: * Equal to
2015: *
2016: * <p>
2017: * <code>
2018: * and(column, new Long(value), EQUAL);
2019: * </code>
2020: *
2021: * @param column The column to run the comparison on
2022: * @param value A long.
2023: * @return A modified Criteria object.
2024: */
2025: public Criteria and(String column, long value) {
2026: and(column, new Long(value));
2027: return this ;
2028: }
2029:
2030: /**
2031: * Convenience method to add a long to Criteria.
2032: * Equal to
2033: *
2034: * <p>
2035: * <code>
2036: * and(column, new Long(value), comparison);
2037: * </code>
2038: *
2039: * @param column The column to run the comparison on
2040: * @param value A long.
2041: * @param comparison String describing how to compare the column with
2042: * the value
2043: * @return A modified Criteria object.
2044: */
2045: public Criteria and(String column, long value, SqlEnum comparison) {
2046: and(column, new Long(value), comparison);
2047: return this ;
2048: }
2049:
2050: /**
2051: * Convenience method to add a float to Criteria.
2052: * Equal to
2053: *
2054: * <p>
2055: * <code>
2056: * and(column, new Float(value), EQUAL);
2057: * </code>
2058: *
2059: * @param column The column to run the comparison on
2060: * @param value A float.
2061: * @return A modified Criteria object.
2062: */
2063: public Criteria and(String column, float value) {
2064: and(column, new Float(value));
2065: return this ;
2066: }
2067:
2068: /**
2069: * Convenience method to add a float to Criteria.
2070: * Equal to
2071: *
2072: * <p>
2073: * <code>
2074: * and(column, new Float(value), comparison);
2075: * </code>
2076: *
2077: * @param column The column to run the comparison on
2078: * @param value A float.
2079: * @param comparison String describing how to compare the column with
2080: * the value
2081: * @return A modified Criteria object.
2082: */
2083: public Criteria and(String column, float value, SqlEnum comparison) {
2084: and(column, new Float(value), comparison);
2085: return this ;
2086: }
2087:
2088: /**
2089: * Convenience method to add a double to Criteria.
2090: * Equal to
2091: *
2092: * <p>
2093: * <code>
2094: * and(column, new Double(value), EQUAL);
2095: * </code>
2096: *
2097: * @param column The column to run the comparison on
2098: * @param value A double.
2099: * @return A modified Criteria object.
2100: */
2101: public Criteria and(String column, double value) {
2102: and(column, new Double(value));
2103: return this ;
2104: }
2105:
2106: /**
2107: * Convenience method to add a double to Criteria.
2108: * Equal to
2109: *
2110: * <p>
2111: * <code>
2112: * and(column, new Double(value), comparison);
2113: * </code>
2114: *
2115: * @param column The column to run the comparison on
2116: * @param value A double.
2117: * @param comparison String describing how to compare the column with
2118: * the value
2119: * @return A modified Criteria object.
2120: */
2121: public Criteria and(String column, double value, SqlEnum comparison) {
2122: and(column, new Double(value), comparison);
2123: return this ;
2124: }
2125:
2126: /**
2127: * Convenience method to add a Date object specified by
2128: * year, month, and date into the Criteria.
2129: * Equal to
2130: *
2131: * <p>
2132: * <code>
2133: * and(column, new GregorianCalendar(year, month,date), EQUAL);
2134: * </code>
2135: *
2136: * @param column A String value to use as column.
2137: * @param year An int with the year.
2138: * @param month An int with the month.
2139: * @param date An int with the date.
2140: * @return A modified Criteria object.
2141: */
2142: public Criteria andDate(String column, int year, int month, int date) {
2143: and(column, new GregorianCalendar(year, month, date).getTime());
2144: return this ;
2145: }
2146:
2147: /**
2148: * Convenience method to add a Date object specified by
2149: * year, month, and date into the Criteria.
2150: * Equal to
2151: *
2152: * <p>
2153: * <code>
2154: * and(column, new GregorianCalendar(year, month,date), comparison);
2155: * </code>
2156: *
2157: * @param column The column to run the comparison on
2158: * @param year An int with the year.
2159: * @param month An int with the month.
2160: * @param date An int with the date.
2161: * @param comparison String describing how to compare the column with
2162: * the value
2163: * @return A modified Criteria object.
2164: */
2165: public Criteria andDate(String column, int year, int month,
2166: int date, SqlEnum comparison) {
2167: and(column, new GregorianCalendar(year, month, date).getTime(),
2168: comparison);
2169: return this ;
2170: }
2171:
2172: /**
2173: * Adds an 'IN' clause with the criteria supplied as an Object array.
2174: * For example:
2175: *
2176: * <p>
2177: * FOO.NAME IN ('FOO', 'BAR', 'ZOW')
2178: * <p>
2179: *
2180: * where 'values' contains three objects that evaluate to the
2181: * respective strings above when .toString() is called.
2182: *
2183: * If a criterion for the requested column already exists, it is
2184: * "AND"ed to the existing criterion.
2185: *
2186: * @param column The column to run the comparison on
2187: * @param values An Object[] with the allowed values.
2188: * @return A modified Criteria object.
2189: */
2190: public Criteria andIn(String column, Object[] values) {
2191: and(column, (Object) values, Criteria.IN);
2192: return this ;
2193: }
2194:
2195: /**
2196: * Adds an 'IN' clause with the criteria supplied as an int array.
2197: * For example:
2198: *
2199: * <p>
2200: * FOO.ID IN ('2', '3', '7')
2201: * <p>
2202: *
2203: * where 'values' contains those three integers.
2204: *
2205: * If a criterion for the requested column already exists, it is
2206: * "AND"ed to the existing criterion.
2207: *
2208: * @param column The column to run the comparison on
2209: * @param values An int[] with the allowed values.
2210: * @return A modified Criteria object.
2211: */
2212: public Criteria andIn(String column, int[] values) {
2213: and(column, (Object) values, Criteria.IN);
2214: return this ;
2215: }
2216:
2217: /**
2218: * Adds an 'IN' clause with the criteria supplied as a List.
2219: * For example:
2220: *
2221: * <p>
2222: * FOO.NAME IN ('FOO', 'BAR', 'ZOW')
2223: * <p>
2224: *
2225: * where 'values' contains three objects that evaluate to the
2226: * respective strings above when .toString() is called.
2227: *
2228: * If a criterion for the requested column already exists, it is
2229: * "AND"ed to the existing criterion.
2230: *
2231: * @param column The column to run the comparison on
2232: * @param values A List with the allowed values.
2233: * @return A modified Criteria object.
2234: */
2235: public Criteria andIn(String column, List values) {
2236: and(column, (Object) values, Criteria.IN);
2237: return this ;
2238: }
2239:
2240: /**
2241: * Adds a 'NOT IN' clause with the criteria supplied as an Object
2242: * array. For example:
2243: *
2244: * <p>
2245: * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
2246: * <p>
2247: *
2248: * where 'values' contains three objects that evaluate to the
2249: * respective strings above when .toString() is called.
2250: *
2251: * If a criterion for the requested column already exists, it is
2252: * "AND"ed to the existing criterion.
2253: *
2254: * @param column The column to run the comparison on
2255: * @param values An Object[] with the disallowed values.
2256: * @return A modified Criteria object.
2257: */
2258: public Criteria andNotIn(String column, Object[] values) {
2259: and(column, (Object) values, Criteria.NOT_IN);
2260: return this ;
2261: }
2262:
2263: /**
2264: * Adds a 'NOT IN' clause with the criteria supplied as an int
2265: * array. For example:
2266: *
2267: * <p>
2268: * FOO.ID NOT IN ('2', '3', '7')
2269: * <p>
2270: *
2271: * where 'values' contains those three integers.
2272: *
2273: * If a criterion for the requested column already exists, it is
2274: * "AND"ed to the existing criterion.
2275: *
2276: * @param column The column to run the comparison on
2277: * @param values An int[] with the disallowed values.
2278: * @return A modified Criteria object.
2279: */
2280: public Criteria andNotIn(String column, int[] values) {
2281: and(column, (Object) values, Criteria.NOT_IN);
2282: return this ;
2283: }
2284:
2285: /**
2286: * Adds a 'NOT IN' clause with the criteria supplied as a List.
2287: * For example:
2288: *
2289: * <p>
2290: * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
2291: * <p>
2292: *
2293: * where 'values' contains three objects that evaluate to the
2294: * respective strings above when .toString() is called.
2295: *
2296: * If a criterion for the requested column already exists, it is
2297: * "AND"ed to the existing criterion.
2298: *
2299: * @param column The column to run the comparison on
2300: * @param values A List with the disallowed values.
2301: * @return A modified Criteria object.
2302: */
2303: public Criteria andNotIn(String column, List values) {
2304: and(column, (Object) values, Criteria.NOT_IN);
2305: return this ;
2306: }
2307:
2308: /*
2309: * ------------------------------------------------------------------------
2310: *
2311: * Start of the "or" methods
2312: *
2313: * ------------------------------------------------------------------------
2314: */
2315:
2316: /**
2317: * This method adds a prepared Criterion object to the Criteria.
2318: * You can get a new, empty Criterion object with the
2319: * getNewCriterion() method. If a criterion for the requested column
2320: * already exists, it is "OR"ed to the existing criterion.
2321: * This is used as follows:
2322: *
2323: * <p>
2324: * <code>
2325: * Criteria crit = new Criteria();
2326: * Criteria.Criterion c = crit.getNewCriterion(BasePeer.ID, new Integer(5), Criteria.LESS_THAN);
2327: * crit.or(c);
2328: * </code>
2329: *
2330: * @param c A Criterion object
2331: * @return A modified Criteria object.
2332: */
2333: public Criteria or(Criterion c) {
2334: Criterion oc = getCriterion(c.getTable() + '.' + c.getColumn());
2335:
2336: if (oc == null) {
2337: add(c);
2338: } else {
2339: oc.or(c);
2340: }
2341: return this ;
2342: }
2343:
2344: /**
2345: * This method adds a new criterion to the list of criterias. If a
2346: * criterion for the requested column already exists, it is
2347: * "OR"ed to the existing criterion. This is used as follows:
2348: *
2349: * <p>
2350: * <code>
2351: * Criteria crit = new Criteria().or("column",
2352: * "value");
2353: * </code>
2354: *
2355: * An EQUAL comparison is used for column and value.
2356: *
2357: * The name of the table must be used implicitly in the column name,
2358: * so the Column name must be something like 'TABLE.id'. If you
2359: * don't like this, you can use the or(table, column, value) method.
2360: *
2361: * @param column The column to run the comparison on
2362: * @param value An Object.
2363: *
2364: * @return A modified Criteria object.
2365: */
2366: public Criteria or(String column, Object value) {
2367: or(column, value, EQUAL);
2368: return this ;
2369: }
2370:
2371: /**
2372: * This method adds a new criterion to the list of criterias.
2373: * If a criterion for the requested column already exists, it is
2374: * "OR"ed to the existing criterion. If is used as follow:
2375: *
2376: * <p>
2377: * <code>
2378: * Criteria crit = new Criteria().or("column",
2379: * "value"
2380: * "Criterion.GREATER_THAN");
2381: * </code>
2382: *
2383: * Any comparison can be used.
2384: *
2385: * The name of the table must be used implicitly in the column name,
2386: * so the Column name must be something like 'TABLE.id'. If you
2387: * don't like this, you can use the or(table, column, value) method.
2388: *
2389: * @param column The column to run the comparison on
2390: * @param value An Object.
2391: * @param comparison A String.
2392: * @return A modified Criteria object.
2393: */
2394: public Criteria or(String column, Object value, SqlEnum comparison) {
2395: Criterion oc = getCriterion(column);
2396: Criterion nc = new Criterion(column, value, comparison);
2397:
2398: if (oc == null) {
2399: super .put(column, nc);
2400: } else {
2401: oc.or(nc);
2402: }
2403: return this ;
2404: }
2405:
2406: /**
2407: * This method adds a new criterion to the list of criterias.
2408: * If a criterion for the requested column already exists, it is
2409: * "OR"ed to the existing criterion. If is used as follows:
2410: *
2411: * <p>
2412: * <code>
2413: * Criteria crit = new Criteria().or("table",
2414: * "column",
2415: * "value");
2416: * </code>
2417: *
2418: * An EQUAL comparison is used for column and value.
2419: *
2420: * @param table Name of the table which contains the column
2421: * @param column The column to run the comparison on
2422: * @param value An Object.
2423: * @return A modified Criteria object.
2424: */
2425: public Criteria or(String table, String column, Object value) {
2426: or(table, column, value, EQUAL);
2427: return this ;
2428: }
2429:
2430: /**
2431: * This method adds a new criterion to the list of criterias.
2432: * If a criterion for the requested column already exists, it is
2433: * "OR"ed to the existing criterion. If is used as follows:
2434: *
2435: * <p>
2436: * <code>
2437: * Criteria crit = new Criteria().or("table",
2438: * "column",
2439: * "value",
2440: * "Criterion.GREATER_THAN");
2441: * </code>
2442: *
2443: * Any comparison can be used.
2444: *
2445: * @param table Name of table which contains the column
2446: * @param column The column to run the comparison on
2447: * @param value An Object.
2448: * @param comparison String describing how to compare the column with the value
2449: * @return A modified Criteria object.
2450: */
2451: public Criteria or(String table, String column, Object value,
2452: SqlEnum comparison) {
2453: StringBuffer sb = new StringBuffer(table.length()
2454: + column.length() + 1);
2455: sb.append(table);
2456: sb.append('.');
2457: sb.append(column);
2458:
2459: Criterion oc = getCriterion(table, column);
2460: Criterion nc = new Criterion(table, column, value, comparison);
2461: if (oc == null) {
2462: super .put(sb.toString(), nc);
2463: } else {
2464: oc.or(nc);
2465: }
2466: return this ;
2467: }
2468:
2469: /**
2470: * Convenience method to add a boolean to Criteria.
2471: * Equal to
2472: *
2473: * <p>
2474: * <code>
2475: * or(column, new Boolean(value), EQUAL);
2476: * </code>
2477: *
2478: * @param column The column to run the comparison on
2479: * @param value A Boolean.
2480: * @return A modified Criteria object.
2481: */
2482: public Criteria or(String column, boolean value) {
2483: or(column, new Boolean(value));
2484: return this ;
2485: }
2486:
2487: /**
2488: * Convenience method to add a boolean to Criteria.
2489: * Equal to
2490: *
2491: * <p>
2492: * <code>
2493: * or(column, new Boolean(value), comparison);
2494: * </code>
2495: *
2496: * @param column The column to run the comparison on
2497: * @param value A Boolean.
2498: * @param comparison String describing how to compare the column
2499: * with the value
2500: * @return A modified Criteria object.
2501: */
2502: public Criteria or(String column, boolean value, SqlEnum comparison) {
2503: or(column, new Boolean(value), comparison);
2504: return this ;
2505: }
2506:
2507: /**
2508: * Convenience method to add an int to Criteria.
2509: * Equal to
2510: *
2511: * <p>
2512: * <code>
2513: * or(column, new Integer(value), EQUAL);
2514: * </code>
2515: *
2516: *
2517: * @param column The column to run the comparison on
2518: * @param value An int.
2519: * @return A modified Criteria object.
2520: */
2521: public Criteria or(String column, int value) {
2522: or(column, new Integer(value));
2523: return this ;
2524: }
2525:
2526: /**
2527: * Convenience method to add an int to Criteria.
2528: * Equal to
2529: *
2530: * <p>
2531: * <code>
2532: * or(column, new Integer(value), comparison);
2533: * </code>
2534: *
2535: *
2536: * @param column The column to run the comparison on
2537: * @param value An int.
2538: * @param comparison String describing how to compare the column
2539: * with the value
2540: * @return A modified Criteria object.
2541: */
2542: public Criteria or(String column, int value, SqlEnum comparison) {
2543: or(column, new Integer(value), comparison);
2544: return this ;
2545: }
2546:
2547: /**
2548: * Convenience method to add a long to Criteria.
2549: * Equal to
2550: *
2551: * <p>
2552: * <code>
2553: * or(column, new Long(value), EQUAL);
2554: * </code>
2555: *
2556: * @param column The column to run the comparison on
2557: * @param value A long.
2558: * @return A modified Criteria object.
2559: */
2560: public Criteria or(String column, long value) {
2561: or(column, new Long(value));
2562: return this ;
2563: }
2564:
2565: /**
2566: * Convenience method to add a long to Criteria.
2567: * Equal to
2568: *
2569: * <p>
2570: * <code>
2571: * or(column, new Long(value), comparison);
2572: * </code>
2573: *
2574: * @param column The column to run the comparison on
2575: * @param value A long.
2576: * @param comparison String describing how to compare the column
2577: * with the value
2578: * @return A modified Criteria object.
2579: */
2580: public Criteria or(String column, long value, SqlEnum comparison) {
2581: or(column, new Long(value), comparison);
2582: return this ;
2583: }
2584:
2585: /**
2586: * Convenience method to add a float to Criteria.
2587: * Equal to
2588: *
2589: * <p>
2590: * <code>
2591: * or(column, new Float(value), EQUAL);
2592: * </code>
2593: *
2594: * @param column The column to run the comparison on
2595: * @param value A float.
2596: * @return A modified Criteria object.
2597: */
2598: public Criteria or(String column, float value) {
2599: or(column, new Float(value));
2600: return this ;
2601: }
2602:
2603: /**
2604: * Convenience method to add a float to Criteria.
2605: * Equal to
2606: *
2607: * <p>
2608: * <code>
2609: * or(column, new Float(value), comparison);
2610: * </code>
2611: *
2612: * @param column The column to run the comparison on
2613: * @param value A float.
2614: * @param comparison String describing how to compare the column
2615: * with the value
2616: * @return A modified Criteria object.
2617: */
2618: public Criteria or(String column, float value, SqlEnum comparison) {
2619: or(column, new Float(value), comparison);
2620: return this ;
2621: }
2622:
2623: /**
2624: * Convenience method to add a double to Criteria.
2625: * Equal to
2626: *
2627: * <p>
2628: * <code>
2629: * or(column, new Double(value), EQUAL);
2630: * </code>
2631: *
2632: * @param column The column to run the comparison on
2633: * @param value A double.
2634: * @return A modified Criteria object.
2635: */
2636: public Criteria or(String column, double value) {
2637: or(column, new Double(value));
2638: return this ;
2639: }
2640:
2641: /**
2642: * Convenience method to add a double to Criteria.
2643: * Equal to
2644: *
2645: * <p>
2646: * <code>
2647: * or(column, new Double(value), comparison);
2648: * </code>
2649: *
2650: * @param column The column to run the comparison on
2651: * @param value A double.
2652: * @param comparison String describing how to compare the column
2653: * with the value
2654: * @return A modified Criteria object.
2655: */
2656: public Criteria or(String column, double value, SqlEnum comparison) {
2657: or(column, new Double(value), comparison);
2658: return this ;
2659: }
2660:
2661: /**
2662: * Convenience method to add a Date object specified by
2663: * year, month, and date into the Criteria.
2664: * Equal to
2665: *
2666: * <p>
2667: * <code>
2668: * or(column, new GregorianCalendar(year, month,date), EQUAL);
2669: * </code>
2670: *
2671: * @param column A String value to use as column.
2672: * @param year An int with the year.
2673: * @param month An int with the month.
2674: * @param date An int with the date.
2675: * @return A modified Criteria object.
2676: */
2677: public Criteria orDate(String column, int year, int month, int date) {
2678: or(column, new GregorianCalendar(year, month, date));
2679: return this ;
2680: }
2681:
2682: /**
2683: * Convenience method to add a Date object specified by
2684: * year, month, and date into the Criteria.
2685: * Equal to
2686: *
2687: * <p>
2688: * <code>
2689: * or(column, new GregorianCalendar(year, month,date), comparison);
2690: * </code>
2691: *
2692: * @param column The column to run the comparison on
2693: * @param year An int with the year.
2694: * @param month An int with the month.
2695: * @param date An int with the date.
2696: * @param comparison String describing how to compare the column
2697: * with the value
2698: * @return A modified Criteria object.
2699: */
2700: public Criteria orDate(String column, int year, int month,
2701: int date, SqlEnum comparison) {
2702: or(column, new GregorianCalendar(year, month, date), comparison);
2703: return this ;
2704: }
2705:
2706: /**
2707: * Adds an 'IN' clause with the criteria supplied as an Object
2708: * array. For example:
2709: *
2710: * <p>
2711: * FOO.NAME IN ('FOO', 'BAR', 'ZOW')
2712: * <p>
2713: *
2714: * where 'values' contains three objects that evaluate to the
2715: * respective strings above when .toString() is called.
2716: *
2717: * If a criterion for the requested column already exists, it is
2718: * "OR"ed to the existing criterion.
2719: *
2720: * @param column The column to run the comparison on
2721: * @param values An Object[] with the allowed values.
2722: * @return A modified Criteria object.
2723: */
2724: public Criteria orIn(String column, Object[] values) {
2725: or(column, (Object) values, Criteria.IN);
2726: return this ;
2727: }
2728:
2729: /**
2730: * Adds an 'IN' clause with the criteria supplied as an int array.
2731: * For example:
2732: *
2733: * <p>
2734: * FOO.ID IN ('2', '3', '7')
2735: * <p>
2736: *
2737: * where 'values' contains those three integers.
2738: *
2739: * If a criterion for the requested column already exists, it is
2740: * "OR"ed to the existing criterion.
2741: *
2742: * @param column The column to run the comparison on
2743: * @param values An int[] with the allowed values.
2744: * @return A modified Criteria object.
2745: */
2746: public Criteria orIn(String column, int[] values) {
2747: or(column, (Object) values, Criteria.IN);
2748: return this ;
2749: }
2750:
2751: /**
2752: * Adds an 'IN' clause with the criteria supplied as a List.
2753: * For example:
2754: *
2755: * <p>
2756: * FOO.NAME IN ('FOO', 'BAR', 'ZOW')
2757: * <p>
2758: *
2759: * where 'values' contains three objects that evaluate to the
2760: * respective strings above when .toString() is called.
2761: *
2762: * If a criterion for the requested column already exists, it is
2763: * "OR"ed to the existing criterion.
2764: *
2765: * @param column The column to run the comparison on
2766: * @param values A List with the allowed values.
2767: * @return A modified Criteria object.
2768: */
2769: public Criteria orIn(String column, List values) {
2770: or(column, (Object) values, Criteria.IN);
2771: return this ;
2772: }
2773:
2774: /**
2775: * Adds a 'NOT IN' clause with the criteria supplied as an Object
2776: * array. For example:
2777: *
2778: * <p>
2779: * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
2780: * <p>
2781: *
2782: * where 'values' contains three objects that evaluate to the
2783: * respective strings above when .toString() is called.
2784: *
2785: * If a criterion for the requested column already exists, it is
2786: * "OR"ed to the existing criterion.
2787: *
2788: * @param column The column to run the comparison on
2789: * @param values An Object[] with the disallowed values.
2790: * @return A modified Criteria object.
2791: */
2792: public Criteria orNotIn(String column, Object[] values) {
2793: or(column, (Object) values, Criteria.NOT_IN);
2794: return this ;
2795: }
2796:
2797: /**
2798: * Adds a 'NOT IN' clause with the criteria supplied as an int
2799: * array. For example:
2800: *
2801: * <p>
2802: * FOO.ID NOT IN ('2', '3', '7')
2803: * <p>
2804: *
2805: * where 'values' contains those three integers.
2806: *
2807: * If a criterion for the requested column already exists, it is
2808: * "OR"ed to the existing criterion.
2809: *
2810: * @param column The column to run the comparison on
2811: * @param values An int[] with the disallowed values.
2812: * @return A modified Criteria object.
2813: */
2814: public Criteria orNotIn(String column, int[] values) {
2815: or(column, (Object) values, Criteria.NOT_IN);
2816: return this ;
2817: }
2818:
2819: /**
2820: * Adds a 'NOT IN' clause with the criteria supplied as a List.
2821: * For example:
2822: *
2823: * <p>
2824: * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW')
2825: * <p>
2826: *
2827: * where 'values' contains three objects that evaluate to the
2828: * respective strings above when .toString() is called.
2829: *
2830: * If a criterion for the requested column already exists, it is
2831: * "OR"ed to the existing criterion.
2832: *
2833: * @param column The column to run the comparison on
2834: * @param values A List with the disallowed values.
2835: * @return A modified Criteria object.
2836: */
2837: public Criteria orNotIn(String column, List values) {
2838: or(column, (Object) values, Criteria.NOT_IN);
2839: return this ;
2840: }
2841:
2842: /**
2843: * Serializes this Criteria.
2844: *
2845: * @param s The output stream.
2846: * @throws IOException if an IO error occurs.
2847: */
2848: private void writeObject(ObjectOutputStream s) throws IOException {
2849: s.defaultWriteObject();
2850:
2851: // Joins need to be serialized manually.
2852: ArrayList serializableJoins = null;
2853: if (!joins.isEmpty()) {
2854: serializableJoins = new ArrayList(joins.size());
2855:
2856: for (Iterator jonisIter = joins.iterator(); jonisIter
2857: .hasNext();) {
2858: Join join = (Join) jonisIter.next();
2859:
2860: ArrayList joinContent = new ArrayList(3);
2861: joinContent.add(join.getLeftColumn());
2862: joinContent.add(join.getRightColumn());
2863: joinContent.add(join.getJoinType());
2864:
2865: serializableJoins.add(joinContent);
2866: }
2867: }
2868:
2869: s.writeObject(serializableJoins);
2870: }
2871:
2872: /**
2873: * Deserialize a Criteria.
2874: *
2875: * @param s The input stream.
2876: * @throws IOException if an IO error occurs.
2877: * @throws ClassNotFoundException if the class cannot be located.
2878: */
2879: private void readObject(ObjectInputStream s) throws IOException,
2880: ClassNotFoundException {
2881: s.defaultReadObject();
2882:
2883: // Criteria.put() differs somewhat from Hashtable.put().
2884: // This necessitates some corrective behavior upon deserialization.
2885: for (Iterator iter = keySet().iterator(); iter.hasNext();) {
2886: Object key = iter.next();
2887: Object value = get(key);
2888: if (value instanceof Criteria.Criterion) {
2889: super .put(key, value);
2890: }
2891: }
2892:
2893: // Joins need to be deserialized manually.
2894: this .joins = new ArrayList(3);
2895:
2896: ArrayList joins = (ArrayList) s.readObject();
2897: if (joins != null) {
2898: for (int i = 0; i < joins.size(); i++) {
2899: ArrayList joinContent = (ArrayList) joins.get(i);
2900:
2901: String leftColumn = (String) joinContent.get(0);
2902: String rightColumn = (String) joinContent.get(1);
2903: SqlEnum joinType = null;
2904: Object joinTypeObj = joinContent.get(2);
2905: if (joinTypeObj != null) {
2906: joinType = (SqlEnum) joinTypeObj;
2907: }
2908: addJoin(leftColumn, rightColumn, joinType);
2909: }
2910: }
2911: }
2912:
2913: /**
2914: * This is an inner class that describes an object in the criteria.
2915: */
2916: public final class Criterion implements Serializable {
2917: /** Serial version. */
2918: private static final long serialVersionUID = 7157097965404611710L;
2919:
2920: public static final String AND = " AND ";
2921: public static final String OR = " OR ";
2922:
2923: /** Value of the CO. */
2924: private Object value;
2925:
2926: /** Comparison value. */
2927: private SqlEnum comparison;
2928:
2929: /** Table name. */
2930: private String table;
2931:
2932: /** Column name. */
2933: private String column;
2934:
2935: /** flag to ignore case in comparision */
2936: private boolean ignoreStringCase = false;
2937:
2938: /**
2939: * The DB adaptor which might be used to get db specific
2940: * variations of sql.
2941: */
2942: private DB db;
2943:
2944: /**
2945: * other connected criteria and their conjunctions.
2946: */
2947: private List clauses = new ArrayList();
2948: private List conjunctions = new ArrayList();
2949:
2950: /**
2951: * Creates a new instance, initializing a couple members.
2952: */
2953: private Criterion(Object val, SqlEnum comp) {
2954: this .value = val;
2955: this .comparison = comp;
2956: }
2957:
2958: /**
2959: * Create a new instance.
2960: *
2961: * @param table A String with the name of the table.
2962: * @param column A String with the name of the column.
2963: * @param val An Object with the value for the Criteria.
2964: * @param comp A String with the comparison value.
2965: */
2966: Criterion(String table, String column, Object val, SqlEnum comp) {
2967: this (val, comp);
2968: this .table = (table == null ? "" : table);
2969: this .column = (column == null ? "" : column);
2970: }
2971:
2972: /**
2973: * Create a new instance.
2974: *
2975: * @param tableColumn A String with the full name of the
2976: * column.
2977: * @param val An Object with the value for the Criteria.
2978: * @param comp A String with the comparison value.
2979: */
2980: Criterion(String tableColumn, Object val, SqlEnum comp) {
2981: this (val, comp);
2982: int dot = tableColumn.lastIndexOf('.');
2983: if (dot == -1) {
2984: table = "";
2985: column = tableColumn;
2986: } else {
2987: table = tableColumn.substring(0, dot);
2988: column = tableColumn.substring(dot + 1);
2989: }
2990: }
2991:
2992: /**
2993: * Create a new instance.
2994: *
2995: * @param table A String with the name of the table.
2996: * @param column A String with the name of the column.
2997: * @param val An Object with the value for the Criteria.
2998: */
2999: Criterion(String table, String column, Object val) {
3000: this (table, column, val, EQUAL);
3001: }
3002:
3003: /**
3004: * Create a new instance.
3005: *
3006: * @param tableColumn A String with the full name of the
3007: * column.
3008: * @param val An Object with the value for the Criteria.
3009: */
3010: Criterion(String tableColumn, Object val) {
3011: this (tableColumn, val, EQUAL);
3012: }
3013:
3014: /**
3015: * Get the column name.
3016: *
3017: * @return A String with the column name.
3018: */
3019: public String getColumn() {
3020: return this .column;
3021: }
3022:
3023: /**
3024: * Set the table name.
3025: *
3026: * @param name A String with the table name.
3027: */
3028: public void setTable(String name) {
3029: this .table = name;
3030: }
3031:
3032: /**
3033: * Get the table name.
3034: *
3035: * @return A String with the table name.
3036: */
3037: public String getTable() {
3038: return this .table;
3039: }
3040:
3041: /**
3042: * Get the comparison.
3043: *
3044: * @return A String with the comparison.
3045: */
3046: public SqlEnum getComparison() {
3047: return this .comparison;
3048: }
3049:
3050: /**
3051: * Get the value.
3052: *
3053: * @return An Object with the value.
3054: */
3055: public Object getValue() {
3056: return this .value;
3057: }
3058:
3059: /**
3060: * Set the value of the criterion.
3061: *
3062: * @param value the new value.
3063: */
3064: public void setValue(Object value) {
3065: this .value = value;
3066: }
3067:
3068: /**
3069: * Get the value of db.
3070: * The DB adaptor which might be used to get db specific
3071: * variations of sql.
3072: * @return value of db.
3073: */
3074: public DB getDb() {
3075: DB db = null;
3076: if (this .db == null) {
3077: // db may not be set if generating preliminary sql for
3078: // debugging.
3079: try {
3080: db = Torque.getDB(getDbName());
3081: } catch (Exception e) {
3082: // we are only doing this to allow easier debugging, so
3083: // no need to throw up the exception, just make note of it.
3084: log
3085: .error("Could not get a DB adapter, so sql may be wrong");
3086: }
3087: } else {
3088: db = this .db;
3089: }
3090:
3091: return db;
3092: }
3093:
3094: /**
3095: * Set the value of db.
3096: * The DB adaptor might be used to get db specific
3097: * variations of sql.
3098: * @param v Value to assign to db.
3099: */
3100: public void setDB(DB v) {
3101: this .db = v;
3102:
3103: for (int i = 0; i < this .clauses.size(); i++) {
3104: ((Criterion) (clauses.get(i))).setDB(v);
3105: }
3106: }
3107:
3108: /**
3109: * Sets ignore case.
3110: *
3111: * @param b True if case should be ignored.
3112: * @return A modified Criteria object.
3113: */
3114: public Criterion setIgnoreCase(boolean b) {
3115: ignoreStringCase = b;
3116: return this ;
3117: }
3118:
3119: /**
3120: * Is ignore case on or off?
3121: *
3122: * @return True if case is ignored.
3123: */
3124: public boolean isIgnoreCase() {
3125: return ignoreStringCase;
3126: }
3127:
3128: /**
3129: * get the list of clauses in this Criterion
3130: */
3131: private List getClauses() {
3132: return clauses;
3133: }
3134:
3135: /**
3136: * get the list of conjunctions in this Criterion
3137: */
3138: private List getConjunctions() {
3139: return conjunctions;
3140: }
3141:
3142: /**
3143: * Append an AND Criterion onto this Criterion's list.
3144: */
3145: public Criterion and(Criterion criterion) {
3146: this .clauses.add(criterion);
3147: this .conjunctions.add(AND);
3148: return this ;
3149: }
3150:
3151: /**
3152: * Append an OR Criterion onto this Criterion's list.
3153: */
3154: public Criterion or(Criterion criterion) {
3155: this .clauses.add(criterion);
3156: this .conjunctions.add(OR);
3157: return this ;
3158: }
3159:
3160: /**
3161: * Appends a representation of the Criterion onto the buffer.
3162: */
3163: public void appendTo(StringBuffer sb) throws TorqueException {
3164: //
3165: // it is alright if value == null
3166: //
3167:
3168: if (column == null) {
3169: return;
3170: }
3171:
3172: Criterion clause = null;
3173: for (int j = 0; j < this .clauses.size(); j++) {
3174: sb.append('(');
3175: }
3176: if (CUSTOM == comparison) {
3177: if (value != null && !"".equals(value)) {
3178: sb.append((String) value);
3179: }
3180: } else {
3181: String field = null;
3182: if (table == null) {
3183: field = column;
3184: } else {
3185: field = new StringBuffer(table.length() + 1
3186: + column.length()).append(table)
3187: .append('.').append(column).toString();
3188: }
3189: SqlExpression.build(field, value, comparison,
3190: ignoreStringCase || ignoreCase, getDb(), sb);
3191: }
3192:
3193: for (int i = 0; i < this .clauses.size(); i++) {
3194: sb.append(this .conjunctions.get(i));
3195: clause = (Criterion) (this .clauses.get(i));
3196: clause.appendTo(sb);
3197: sb.append(')');
3198: }
3199: }
3200:
3201: /**
3202: * Appends a Prepared Statement representation of the Criterion
3203: * onto the buffer.
3204: *
3205: * @param sb The stringbuffer that will receive the Prepared Statement
3206: * @param params A list to which Prepared Statement parameters
3207: * will be appended
3208: */
3209: public void appendPsTo(StringBuffer sb, List params) {
3210: if (column == null || value == null) {
3211: return;
3212: }
3213:
3214: DB db = getDb();
3215:
3216: for (int j = 0; j < this .clauses.size(); j++) {
3217: sb.append('(');
3218: }
3219: if (CUSTOM == comparison) {
3220: if (!"".equals(value)) {
3221: sb.append((String) value);
3222: }
3223: } else {
3224: String field = null;
3225: if (table == null) {
3226: field = column;
3227: } else {
3228: field = new StringBuffer(table.length() + 1
3229: + column.length()).append(table)
3230: .append('.').append(column).toString();
3231: }
3232:
3233: if (comparison.equals(Criteria.IN)
3234: || comparison.equals(Criteria.NOT_IN)) {
3235: sb.append(field).append(comparison);
3236:
3237: UniqueList inClause = new UniqueList();
3238:
3239: if (value instanceof List) {
3240: value = ((List) value).toArray(new Object[0]);
3241: }
3242:
3243: for (int i = 0; i < Array.getLength(value); i++) {
3244: Object item = Array.get(value, i);
3245:
3246: inClause.add(SqlExpression.processInValue(item,
3247: ignoreStringCase || ignoreCase, db));
3248: }
3249:
3250: StringBuffer inString = new StringBuffer();
3251: inString.append('(').append(
3252: StringUtils
3253: .join(inClause.iterator(), (",")))
3254: .append(')');
3255: sb.append(inString.toString());
3256: } else {
3257: if (ignoreStringCase || ignoreCase) {
3258: sb.append(db.ignoreCase(field)).append(
3259: comparison).append(db.ignoreCase("?"));
3260: } else {
3261: sb.append(field).append(comparison).append(
3262: " ? ");
3263: }
3264:
3265: if (value instanceof java.util.Date) {
3266: params.add(new java.sql.Date(
3267: ((java.util.Date) value).getTime()));
3268: } else if (value instanceof DateKey) {
3269: params.add(new java.sql.Date(((DateKey) value)
3270: .getDate().getTime()));
3271: } else if (value instanceof Integer) {
3272: params.add(value);
3273: } else {
3274: params.add(value.toString());
3275: }
3276: }
3277: }
3278:
3279: for (int i = 0; i < this .clauses.size(); i++) {
3280: sb.append(this .conjunctions.get(i));
3281: Criterion clause = (Criterion) (this .clauses.get(i));
3282: clause.appendPsTo(sb, params);
3283: sb.append(')');
3284: }
3285: }
3286:
3287: /**
3288: * Build a string representation of the Criterion.
3289: *
3290: * @return A String with the representation of the Criterion.
3291: */
3292: public String toString() {
3293: //
3294: // it is alright if value == null
3295: //
3296: if (column == null) {
3297: return "";
3298: }
3299:
3300: StringBuffer expr = new StringBuffer(25);
3301: try {
3302: appendTo(expr);
3303: } catch (TorqueException e) {
3304: return "Criterion cannot be evaluated";
3305: }
3306: return expr.toString();
3307: }
3308:
3309: /**
3310: * This method checks another Criteria.Criterion to see if they contain
3311: * the same attributes and hashtable entries.
3312: */
3313: public boolean equals(Object obj) {
3314: if (this == obj) {
3315: return true;
3316: }
3317:
3318: if ((obj == null) || !(obj instanceof Criterion)) {
3319: return false;
3320: }
3321:
3322: Criterion crit = (Criterion) obj;
3323:
3324: boolean isEquiv = ((table == null && crit.getTable() == null) || (table != null && table
3325: .equals(crit.getTable())))
3326: && column.equals(crit.getColumn())
3327: && comparison.equals(crit.getComparison());
3328:
3329: // we need to check for value equality
3330: if (isEquiv) {
3331: Object b = crit.getValue();
3332: if (value instanceof Object[] && b instanceof Object[]) {
3333: isEquiv &= Arrays.equals((Object[]) value,
3334: (Object[]) b);
3335: } else if (value instanceof int[] && b instanceof int[]) {
3336: isEquiv &= Arrays.equals((int[]) value, (int[]) b);
3337: } else {
3338: isEquiv &= value.equals(b);
3339: }
3340: }
3341:
3342: // check chained criterion
3343:
3344: isEquiv &= this .clauses.size() == crit.getClauses().size();
3345: for (int i = 0; i < this .clauses.size(); i++) {
3346: isEquiv &= ((String) (conjunctions.get(i)))
3347: .equals((String) (crit.getConjunctions().get(i)));
3348: isEquiv &= ((Criterion) (clauses.get(i)))
3349: .equals((Criterion) (crit.getClauses().get(i)));
3350: }
3351:
3352: return isEquiv;
3353: }
3354:
3355: /**
3356: * Returns a hash code value for the object.
3357: */
3358: public int hashCode() {
3359: int h = value.hashCode() ^ comparison.hashCode();
3360:
3361: if (table != null) {
3362: h ^= table.hashCode();
3363: }
3364:
3365: if (column != null) {
3366: h ^= column.hashCode();
3367: }
3368:
3369: for (int i = 0; i < this .clauses.size(); i++) {
3370: h ^= ((Criterion) (clauses.get(i))).hashCode();
3371: }
3372:
3373: return h;
3374: }
3375:
3376: /**
3377: * get all tables from nested criterion objects
3378: *
3379: * @return the list of tables
3380: */
3381: public List getAllTables() {
3382: UniqueList tables = new UniqueList();
3383: addCriterionTable(this , tables);
3384: return tables;
3385: }
3386:
3387: /**
3388: * method supporting recursion through all criterions to give
3389: * us a StringStack of tables from each criterion
3390: */
3391: private void addCriterionTable(Criterion c, UniqueList s) {
3392: if (c != null) {
3393: s.add(c.getTable());
3394: for (int i = 0; i < c.getClauses().size(); i++) {
3395: addCriterionTable((Criterion) (c.getClauses()
3396: .get(i)), s);
3397: }
3398: }
3399: }
3400:
3401: /**
3402: * get an array of all criterion attached to this
3403: * recursing through all sub criterion
3404: */
3405: public Criterion[] getAttachedCriterion() {
3406: ArrayList crits = new ArrayList();
3407: traverseCriterion(this , crits);
3408: Criterion[] crita = new Criterion[crits.size()];
3409: for (int i = 0; i < crits.size(); i++) {
3410: crita[i] = (Criterion) crits.get(i);
3411: }
3412:
3413: return crita;
3414: }
3415:
3416: /**
3417: * method supporting recursion through all criterions to give
3418: * us an ArrayList of them
3419: */
3420: private void traverseCriterion(Criterion c, ArrayList a) {
3421: if (c != null) {
3422: a.add(c);
3423: for (int i = 0; i < c.getClauses().size(); i++) {
3424: traverseCriterion((Criterion) (c.getClauses()
3425: .get(i)), a);
3426: }
3427: }
3428: }
3429: } // end of inner class Criterion
3430:
3431: /**
3432: * Data object to describe a join between two tables, for example
3433: * <pre>
3434: * table_a LEFT JOIN table_b ON table_a.id = table_b.a_id
3435: * </pre>
3436: * The class is immutable. Because the class is also used by
3437: * {@link org.apache.torque.util.BasePeer}, it is visible from the package.
3438: */
3439: public static class Join {
3440: /** the left column of the join condition */
3441: private String leftColumn = null;
3442:
3443: /** the right column of the join condition */
3444: private String rightColumn = null;
3445:
3446: /** the type of the join (LEFT JOIN, ...), or null */
3447: private SqlEnum joinType = null;
3448:
3449: /**
3450: * Constructor
3451: * @param leftColumn the left column of the join condition;
3452: * might contain an alias name
3453: * @param rightColumn the right column of the join condition
3454: * might contain an alias name
3455: * @param joinType the type of the join. Valid join types are
3456: * null (adding the join condition to the where clause),
3457: * SqlEnum.LEFT_JOIN, SqlEnum.RIGHT_JOIN, and SqlEnum.INNER_JOIN
3458: */
3459: public Join(final String leftColumn, final String rightColumn,
3460: final SqlEnum joinType) {
3461: this .leftColumn = leftColumn;
3462: this .rightColumn = rightColumn;
3463: this .joinType = joinType;
3464: }
3465:
3466: /**
3467: * @return the type of the join, i.e. SqlEnum.LEFT_JOIN, ...,
3468: * or null for adding the join condition to the where Clause
3469: */
3470: public final SqlEnum getJoinType() {
3471: return joinType;
3472: }
3473:
3474: /**
3475: * @return the left column of the join condition
3476: */
3477: public final String getLeftColumn() {
3478: return leftColumn;
3479: }
3480:
3481: /**
3482: * @return the right column of the join condition
3483: */
3484: public final String getRightColumn() {
3485: return rightColumn;
3486: }
3487:
3488: /**
3489: * returns a String representation of the class,
3490: * mainly for debuggung purposes
3491: * @return a String representation of the class
3492: */
3493: public String toString() {
3494: StringBuffer result = new StringBuffer();
3495: if (joinType != null) {
3496: result.append(joinType).append(" : ");
3497: }
3498: result.append(leftColumn).append("=").append(rightColumn)
3499: .append(" (ignoreCase not considered)");
3500:
3501: return result.toString();
3502: }
3503:
3504: /**
3505: * This method checks another Criteria.Join to see if they contain the
3506: * same attributes.
3507: */
3508: public boolean equals(Object obj) {
3509: if (this == obj) {
3510: return true;
3511: }
3512:
3513: if ((obj == null) || !(obj instanceof Join)) {
3514: return false;
3515: }
3516:
3517: Join join = (Join) obj;
3518:
3519: return ObjectUtils.equals(leftColumn, join.getLeftColumn())
3520: && ObjectUtils.equals(rightColumn, join
3521: .getRightColumn())
3522: && ObjectUtils.equals(joinType, join.getJoinType());
3523: }
3524:
3525: /**
3526: * Returns the hash code value for this Join.
3527: *
3528: * @return a hash code value for this object.
3529: */
3530: public int hashCode() {
3531: int result = 13;
3532: result = 37 * result + leftColumn.hashCode();
3533: result = 37 * result + rightColumn.hashCode();
3534: result = 37 * result
3535: + (null == joinType ? 0 : joinType.hashCode());
3536: return result;
3537: }
3538:
3539: } // end of inner class Join
3540: }
|