Java tutorial
package org.apache.torque.util; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001-2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Turbine" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache Turbine", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ import java.lang.reflect.Array; import java.math.BigDecimal; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.torque.Torque; import org.apache.torque.TorqueException; import org.apache.torque.adapter.DB; import org.apache.torque.map.DatabaseMap; import org.apache.torque.om.DateKey; import org.apache.torque.om.ObjectKey; import org.apache.commons.collections.StringStack; import org.apache.log4j.Category; /** * This is a utility class that is used for retrieving different types * of values from a hashtable based on a simple name string. This * class is meant to minimize the amount of casting that needs to be * done when working with Hashtables. * * NOTE: other methods will be added as needed and as time permits. * * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a> * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a> * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a> * @author <a href="mailto:eric@dobbse.net">Eric Dobbs</a> * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> * @author <a href="mailto:sam@neurogrid.com">Sam Joseph</a> * @version $Id: Criteria.java,v 1.1 2003/03/27 21:08:24 wolfj Exp $ */ public class Criteria extends Hashtable { /** Comparison type. */ public static final SqlEnum EQUAL = SqlEnum.EQUAL; /** Comparison type. */ public static final SqlEnum NOT_EQUAL = SqlEnum.NOT_EQUAL; /** Comparison type. */ public static final SqlEnum ALT_NOT_EQUAL = SqlEnum.ALT_NOT_EQUAL; /** Comparison type. */ public static final SqlEnum GREATER_THAN = SqlEnum.GREATER_THAN; /** Comparison type. */ public static final SqlEnum LESS_THAN = SqlEnum.LESS_THAN; /** Comparison type. */ public static final SqlEnum GREATER_EQUAL = SqlEnum.GREATER_EQUAL; /** Comparison type. */ public static final SqlEnum LESS_EQUAL = SqlEnum.LESS_EQUAL; /** Comparison type. */ public static final SqlEnum LIKE = SqlEnum.LIKE; /** Comparison type. */ public static final SqlEnum NOT_LIKE = SqlEnum.NOT_LIKE; /** Comparison type. */ public static final SqlEnum CUSTOM = SqlEnum.CUSTOM; /** Comparison type. */ public static final SqlEnum DISTINCT = SqlEnum.DISTINCT; /** Comparison type. */ public static final SqlEnum IN = SqlEnum.IN; /** Comparison type. */ public static final SqlEnum NOT_IN = SqlEnum.NOT_IN; /** Comparison type. */ public static final SqlEnum ALL = SqlEnum.ALL; /** Comparison type. */ public static final SqlEnum JOIN = SqlEnum.JOIN; /** "Order by" qualifier - ascending */ private static final SqlEnum ASC = SqlEnum.ASC; /** "Order by" qualifier - descending */ private static final SqlEnum DESC = SqlEnum.DESC; /** "IS NULL" null comparison */ public static final SqlEnum ISNULL = SqlEnum.ISNULL; /** "IS NOT NULL" null comparison */ public static final SqlEnum ISNOTNULL = SqlEnum.ISNOTNULL; /** "CURRENT_DATE" ANSI SQL function */ public static final SqlEnum CURRENT_DATE = SqlEnum.CURRENT_DATE; /** "CURRENT_TIME" ANSI SQL function */ public static final SqlEnum CURRENT_TIME = SqlEnum.CURRENT_TIME; private static final int DEFAULT_CAPACITY = 10; private boolean ignoreCase = false; private boolean singleRecord = false; private boolean cascade = false; private StringStack selectModifiers = new StringStack(); private StringStack selectColumns = new StringStack(); private StringStack orderByColumns = new StringStack(); private StringStack groupByColumns = new StringStack(); private Criterion having = null; private Hashtable asColumns = new Hashtable(8); private ArrayList joinL = null; private ArrayList joinR = null; /** The name of the database. */ private String dbName; /** The name of the database as given in the contructor. */ private String originalDbName; /** * To limit the number of rows to return. <code>-1</code> means return all * rows. */ private int limit = -1; /** To start the results at a row other than the first one. */ private int offset = 0; // flag to note that the criteria involves a blob. private Boolean blobFlag = null; private HashMap aliases = null; private boolean useTransaction = false; /** Log4j category used for logging. */ private static Category category = Category.getInstance(Criteria.class.getName()); /** * Creates a new instance with the default capacity. */ public Criteria() { this(DEFAULT_CAPACITY); } /** * Creates a new instance with the specified capacity. * * @param initialCapacity An int. */ public Criteria(int initialCapacity) { this(Torque.getDefaultDB(), initialCapacity); } /** * Creates a new instance with the default capacity which corresponds to * the specified database. * * @param dbName The dabase name. */ public Criteria(String dbName) { this(dbName, DEFAULT_CAPACITY); } /** * Creates a new instance with the specified capacity which corresponds to * the specified database. * * @param dbName The dabase name. * @param initialCapacity The initial capacity. */ public Criteria(String dbName, int initialCapacity) { super(initialCapacity); this.dbName = dbName; this.originalDbName = dbName; } /** * Brings this criteria back to its initial state, so that it * can be reused as if it was new. Except if the criteria has grown in * capacity, it is left at the current capacity. */ public void clear() { super.clear(); ignoreCase = false; singleRecord = false; cascade = false; selectModifiers.clear(); selectColumns.clear(); orderByColumns.clear(); groupByColumns.clear(); having = null; asColumns.clear(); joinL = null; joinR = null; dbName = originalDbName; offset = 0; limit = -1; blobFlag = null; aliases = null; useTransaction = false; } /** * Add an AS clause to the select columns. Usage: * <p> * <code> * * Criteria myCrit = new Criteria(); * myCrit.addAsColumn("alias", "ALIAS("+MyPeer.ID+")"); * * </code> * * @param name wanted Name of the column * @param clause SQL clause to select from the table * * If the name already exists, it is replaced by the new clause. * * @return A modified Criteria object. */ public Criteria addAsColumn(String name, String clause) { asColumns.put(name, clause); return this; } /** * Get the column aliases. * * @return A Hashtable which map the column alias names * to the alias clauses. */ public Hashtable getAsColumns() { return asColumns; } /** * Allows one to specify an alias for a table that can * be used in various parts of the SQL. * * @param alias a <code>String</code> value * @param table a <code>String</code> value */ public void addAlias(String alias, String table) { if (aliases == null) { aliases = new HashMap(8); } aliases.put(alias, table); } /** * Returns the table name associated with an alias. * * @param alias a <code>String</code> value * @return a <code>String</code> value */ public String getTableForAlias(String alias) { if (aliases == null) { return null; } return (String) aliases.get(alias); } /** * Does this Criteria Object contain the specified key? * * @param table The name of the table. * @param column The name of the column. * @return True if this Criteria Object contain the specified key. */ public boolean containsKey(String table, String column) { return containsKey(table + '.' + column); } /** * Convenience method to return value as a boolean. * * @param column String name of column. * @return A boolean. */ public boolean getBoolean(String column) { return ((Boolean) getCriterion(column).getValue()).booleanValue(); } /** * Convenience method to return value as a boolean. * * @param table String name of table. * @param column String name of column. * @return A boolean. */ public boolean getBoolean(String table, String column) { return getBoolean(new StringBuffer(table.length() + column.length() + 1).append(table).append('.') .append(column).toString()); } /** * Returns true if any of the tables in the criteria contain an * Object column. * * @return A boolean. * @throws TorqueException Any exceptions caught during processing will be * rethrown wrapped into a TorqueException. */ public boolean containsObjectColumn() throws TorqueException { return containsObjectColumn(dbName); } /** * Returns true if any of the tables in the criteria contain an * Object column. * * @param databaseMapName A String. * @return A boolean. * @throws TorqueException Any exceptions caught during processing will be * rethrown wrapped into a TorqueException. * @deprecated not sure why anyone would need to use this outside of its * use in BasePeer, but it was public, so its now deprecated. * It was used to decide whether a transaction should be used, this can * be done with the useTransaction() method. */ public boolean containsObjectColumn(String databaseMapName) throws TorqueException { // Peer or application may have noted the existence of a blob // so we can save the lookup. if (blobFlag != null) { return blobFlag.booleanValue(); } DatabaseMap map = Torque.getDatabaseMap(databaseMapName); StringStack tables = new StringStack(); for (Iterator it = super.values().iterator(); it.hasNext();) { Criterion co = (Criterion) it.next(); String tableName = co.getTable(); String tableName2 = getTableForAlias(tableName); if (tableName2 != null) { tableName = tableName2; } if (!tables.contains(tableName)) { if (map.getTable(tableName).containsObjectColumn()) { return true; } tables.add(tableName); } } return false; } /** * Will force the sql represented by this criteria to be executed within * a transaction. This is here primarily to support the oid type in * postgresql. Though it can be used to require any single sql statement * to use a transaction. */ public void setUseTransaction(boolean v) { useTransaction = v; } /** * called by BasePeer to determine whether the sql command specified by * this criteria must be wrapped in a transaction. * * @return a <code>boolean</code> value */ protected boolean isUseTransaction() { return useTransaction; } /** * Method to return criteria related to columns in a table. * * @param column String name of column. * @return A Criterion. */ public Criterion getCriterion(String column) { return (Criterion) super.get(column); } /** * Method to return criteria related to a column in a table. * * @param table String name of table. * @param column String name of column. * @return A Criterion. */ public Criterion getCriterion(String table, String column) { return getCriterion(new StringBuffer(table.length() + column.length() + 1).append(table).append('.') .append(column).toString()); } /** * Method to return criterion that is not added automatically * to this Criteria. This can be used to chain the * Criterions to form a more complex where clause. * * @param column String full name of column (for example TABLE.COLUMN). * @return A Criterion. */ public Criterion getNewCriterion(String column, Object value, SqlEnum comparison) { return new Criterion(column, value, comparison); } /** * Method to return criterion that is not added automatically * to this Criteria. This can be used to chain the * Criterions to form a more complex where clause. * * @param table String name of table. * @param column String name of column. * @return A Criterion. */ public Criterion getNewCriterion(String table, String column, Object value, SqlEnum comparison) { return new Criterion(table, column, value, comparison); } /** * This method adds a prepared Criterion object to the Criteria. * You can get a new, empty Criterion object with the * getNewCriterion() method. If a criterion for the requested column * already exists, it is replaced. This is used as follows: * * <p> * <code> * Criteria crit = new Criteria(); * Criteria.Criterion c = crit * .getNewCriterion(BasePeer.ID, new Integer(5), Criteria.LESS_THAN); * crit.add(c); * </code> * * @param c A Criterion object * * @return A modified Criteria object. */ public Criteria add(Criterion c) { StringBuffer sb = new StringBuffer(c.getTable().length() + c.getColumn().length() + 1); sb.append(c.getTable()); sb.append('.'); sb.append(c.getColumn()); super.put(sb.toString(), c); return this; } /** * Method to return a String table name. * * @param name A String with the name of the key. * @return A String with the value of the object at key. */ public String getColumnName(String name) { return getCriterion(name).getColumn(); } /** * Method to return a comparison String. * * @param key String name of the key. * @return A String with the value of the object at key. */ public SqlEnum getComparison(String key) { return getCriterion(key).getComparison(); } /** * Method to return a comparison String. * * @param table String name of table. * @param column String name of column. * @return A String with the value of the object at key. */ public SqlEnum getComparison(String table, String column) { return getComparison(new StringBuffer(table.length() + column.length() + 1).append(table).append('.') .append(column).toString()); } /** * Convenience method to return a Date. * * @param name column name (TABLE.COLUMN) * @return A java.util.Date with the value of object at key. */ public java.util.Date getDate(String name) { return (java.util.Date) getCriterion(name).getValue(); } /** * Convenience method to return a Date. * * @param table String name of table. * @param column String name of column. * @return A java.util.Date with the value of object at key. */ public java.util.Date getDate(String table, String column) { return getDate(new StringBuffer(table.length() + column.length() + 1).append(table).append('.') .append(column).toString()); } /** * Get the Database(Map) name. * * @return A String with the Database(Map) name. By default, this * is PoolBrokerService.DEFAULT. */ public String getDbName() { return dbName; } /** * Set the DatabaseMap name. If <code>null</code> is supplied, uses value * provided by <code>Torque.getDefaultDB()</code>. * * @param dbName A String with the Database(Map) name. */ public void setDbName(String dbName) { this.dbName = (dbName == null ? Torque.getDefaultDB() : dbName); } /** * Convenience method to return a double. * * @param name A String with the name of the key. * @return A double with the value of object at key. */ public double getDouble(String name) { Object obj = getCriterion(name).getValue(); if (obj instanceof String) { return new Double((String) obj).doubleValue(); } return ((Double) obj).doubleValue(); } /** * Convenience method to return a double. * * @param table String name of table. * @param column String name of column. * @return A double with the value of object at key. */ public double getDouble(String table, String column) { return getDouble(new StringBuffer(table.length() + column.length() + 1).append(table).append('.') .append(column).toString()); } /** * Convenience method to return a float. * * @param name A String with the name of the key. * @return A float with the value of object at key. */ public float getFloat(String name) { Object obj = getCriterion(name).getValue(); if (obj instanceof String) { return new Float((String) obj).floatValue(); } return ((Float) obj).floatValue(); } /** * Convenience method to return a float. * * @param table String name of table. * @param column String name of column. * @return A float with the value of object at key. */ public float getFloat(String table, String column) { return getFloat(new StringBuffer(table.length() + column.length() + 1).append(table).append('.') .append(column).toString()); } /** * Convenience method to return an Integer. * * @param name A String with the name of the key. * @return An Integer with the value of object at key. */ public Integer getInteger(String name) { Object obj = getCriterion(name).getValue(); if (obj instanceof String) { return new Integer((String) obj); } return ((Integer) obj); } /** * Convenience method to return an Integer. * * @param table String name of table. * @param column String name of column. * @return An Integer with the value of object at key. */ public Integer getInteger(String table, String column) { return getInteger(new StringBuffer(table.length() + column.length() + 1).append(table).append('.') .append(column).toString()); } /** * Convenience method to return an int. * * @param name A String with the name of the key. * @return An int with the value of object at key. */ public int getInt(String name) { Object obj = getCriterion(name).getValue(); if (obj instanceof String) { return new Integer((String) obj).intValue(); } return ((Integer) obj).intValue(); } /** * Convenience method to return an int. * * @param table String name of table. * @param column String name of column. * @return An int with the value of object at key. */ public int getInt(String table, String column) { return getInt(new StringBuffer(table.length() + column.length() + 1).append(table).append('.') .append(column).toString()); } /** * Convenience method to return a BigDecimal. * * @param name A String with the name of the key. * @return A BigDecimal with the value of object at key. */ public BigDecimal getBigDecimal(String name) { Object obj = getCriterion(name).getValue(); if (obj instanceof String) { return new BigDecimal((String) obj); } return (BigDecimal) obj; } /** * Convenience method to return a BigDecimal. * * @param table String name of table. * @param column String name of column. * @return A BigDecimal with the value of object at key. */ public BigDecimal getBigDecimal(String table, String column) { return getBigDecimal(new StringBuffer(table.length() + column.length() + 1).append(table).append('.') .append(column).toString()); } /** * Convenience method to return a long. * * @param name A String with the name of the key. * @return A long with the value of object at key. */ public long getLong(String name) { Object obj = getCriterion(name).getValue(); if (obj instanceof String) { return new Long((String) obj).longValue(); } return ((Long) obj).longValue(); } /** * Convenience method to return a long. * * @param table String name of table. * @param column String name of column. * @return A long with the value of object at key. */ public long getLong(String table, String column) { return getLong(new StringBuffer(table.length() + column.length() + 1).append(table).append('.') .append(column).toString()); } /** * Convenience method to return a String. * * @param name A String with the name of the key. * @return A String with the value of object at key. */ public String getString(String name) { return (String) getCriterion(name).getValue(); } /** * Convenience method to return a String. * * @param table String name of table. * @param column String name of column. * @return A String with the value of object at key. */ public String getString(String table, String column) { return getString(new StringBuffer(table.length() + column.length() + 1).append(table).append('.') .append(column).toString()); } /** * Method to return a String table name. * * @param name A String with the name of the key. * @return A String with the value of object at key. */ public String getTableName(String name) { return getCriterion(name).getTable(); } /** * Convenience method to return a List. * * @param name A String with the name of the key. * @return A List with the value of object at key. */ public List getList(String name) { return (List) getCriterion(name).getValue(); } /** * Convenience method to return a List. * * @param table String name of table. * @param column String name of column. * @return A List with the value of object at key. */ public List getList(String table, String column) { return getList(new StringBuffer(table.length() + column.length() + 1).append(table).append('.') .append(column).toString()); } /** * Method to return the value that was added to Criteria. * * @param name A String with the name of the key. * @return An Object with the value of object at key. */ public Object getValue(String name) { return getCriterion(name).getValue(); } /** * Method to return the value that was added to Criteria. * * @param table String name of table. * @param column String name of column. * @return An Object with the value of object at key. */ public Object getValue(String table, String column) { return getValue(new StringBuffer(table.length() + column.length() + 1).append(table).append('.') .append(column).toString()); } /** * Convenience method to return an ObjectKey. * * @param name A String with the name of the key. * @return An ObjectKey with the value of object at key. */ public ObjectKey getObjectKey(String name) { return (ObjectKey) getCriterion(name).getValue(); } /** * Convenience method to return an ObjectKey. * * @param table String name of table. * @param column String name of column. * @return A String with the value of object at key. */ public ObjectKey getObjectKey(String table, String column) { return getObjectKey(new StringBuffer(table.length() + column.length() + 1).append(table).append('.') .append(column).toString()); } /** * Overrides Hashtable get, so that the value placed in the * Criterion is returned instead of the Criterion. * * @param key An Object. * @return An Object. */ public Object get(Object key) { return getValue((String) key); } /** * Overrides Hashtable put, so that this object is returned * instead of the value previously in the Criteria object. * The reason is so that it more closely matches the behavior * of the add() methods. If you want to get the previous value * then you should first Criteria.get() it yourself. Note, if * you attempt to pass in an Object that is not a String, it will * throw a NPE. The reason for this is that none of the add() * methods support adding anything other than a String as a key. * * @param key An Object. Must be instanceof String! * @param value An Object. * @throws NullPointerException if key != String or key/value is null. * @return Instance of self. */ public Object put(Object key, Object value) { if (!(key instanceof String)) { throw new NullPointerException("Criteria: Key must be a String object."); } return add((String) key, value); } /** * Copies all of the mappings from the specified Map to this Criteria * These mappings will replace any mappings that this Criteria had for any * of the keys currently in the specified Map. * * if the map was another Criteria, its attributes are copied to this * Criteria, overwriting previous settings. * * @param t Mappings to be stored in this map. */ public synchronized void putAll(Map t) { Iterator i = t.entrySet().iterator(); while (i.hasNext()) { Map.Entry e = (Map.Entry) i.next(); Object val = e.getValue(); if (val instanceof Criteria.Criterion) { super.put(e.getKey(), val); } else { put(e.getKey(), val); } } if (t instanceof Criteria) { Criteria c = (Criteria) t; this.joinL = c.joinL; this.joinR = c.joinR; } /* this would make a copy, not included but might want to use some of it. if (t instanceof Criteria) { Criteria c = (Criteria)t; this.ignoreCase = c.ignoreCase; this.singleRecord = c.singleRecord; this.cascade = c.cascade; this.selectModifiers = c.selectModifiers; this.selectColumns = c.selectColumns; this.orderByColumns = c.orderByColumns; this.dbName = c.dbName; this.limit = c.limit; this.offset = c.offset; this.aliases = c.aliases; } */ } /** * This method adds a new criterion to the list of criterias. If a * criterion for the requested column already exists, it is * replaced. This is used as follows: * * <p> * <code> * Criteria crit = new Criteria().add("column", * "value"); * </code> * * An EQUAL comparison is used for column and value. * * The name of the table must be used implicitly in the column name, * so the Column name must be something like 'TABLE.id'. If you * don't like this, you can use the add(table, column, value) method. * * @param column The column to run the comparison on * @param value An Object. * * @return A modified Criteria object. */ public Criteria add(String column, Object value) { add(column, value, EQUAL); return this; } /** * This method adds a new criterion to the list of criterias. * If a criterion for the requested column already exists, it is * replaced. If is used as follow: * * <p> * <code> * Criteria crit = new Criteria().add("column", * "value" * "Criterion.GREATER_THAN"); * </code> * * Any comparison can be used. * * The name of the table must be used implicitly in the column name, * so the Column name must be something like 'TABLE.id'. If you * don't like this, you can use the add(table, column, value) method. * * @param column The column to run the comparison on * @param value An Object. * @param comparison A String. * * @return A modified Criteria object. */ public Criteria add(String column, Object value, SqlEnum comparison) { super.put(column, new Criterion(column, value, comparison)); return this; } /** * This method adds a new criterion to the list of criterias. * If a criterion for the requested column already exists, it is * replaced. If is used as follows: * * <p> * <code> * Criteria crit = new Criteria().add("table", * "column", * "value"); * </code> * * An EQUAL comparison is used for column and value. * * @param table Name of the table which contains the column * @param column The column to run the comparison on * @param value An Object. * * @return A modified Criteria object. */ public Criteria add(String table, String column, Object value) { add(table, column, value, EQUAL); return this; } /** * This method adds a new criterion to the list of criterias. * If a criterion for the requested column already exists, it is * replaced. If is used as follows: * * <p> * <code> * Criteria crit = new Criteria().add("table", * "column", * "value", * "Criterion.GREATER_THAN"); * </code> * * Any comparison can be used. * * @param table Name of table which contains the column * @param column The column to run the comparison on * @param value An Object. * @param comparison String describing how to compare the column with the value * * @return A modified Criteria object. */ public Criteria add(String table, String column, Object value, SqlEnum comparison) { StringBuffer sb = new StringBuffer(table.length() + column.length() + 1); sb.append(table); sb.append('.'); sb.append(column); super.put(sb.toString(), new Criterion(table, column, value, comparison)); return this; } /** * Convenience method to add a boolean to Criteria. * Equal to * * <p> * <code> * add(column, new Boolean(value), EQUAL); * </code> * * @param column The column to run the comparison on * @param value A Boolean. * * @return A modified Criteria object. */ public Criteria add(String column, boolean value) { add(column, (value ? Boolean.TRUE : Boolean.FALSE)); return this; } /** * Convenience method to add a boolean to Criteria. * Equal to * * <p> * <code> * add(column, new Boolean(value), comparison); * </code> * * @param column The column to run the comparison on * @param value A Boolean. * @param comparison String describing how to compare the column with the value * * @return A modified Criteria object. */ public Criteria add(String column, boolean value, SqlEnum comparison) { add(column, new Boolean(value), comparison); return this; } /** * Convenience method to add an int to Criteria. * Equal to * * <p> * <code> * add(column, new Integer(value), EQUAL); * </code> * * * @param column The column to run the comparison on * @param value An int. * * @return A modified Criteria object. */ public Criteria add(String column, int value) { add(column, new Integer(value)); return this; } /** * Convenience method to add an int to Criteria. * Equal to * * <p> * <code> * add(column, new Integer(value), comparison); * </code> * * @param column The column to run the comparison on * @param value An int. * @param comparison String describing how to compare the column with the value * * @return A modified Criteria object. */ public Criteria add(String column, int value, SqlEnum comparison) { add(column, new Integer(value), comparison); return this; } /** * Convenience method to add a long to Criteria. * Equal to * * <p> * <code> * add(column, new Long(value), EQUAL); * </code> * * @param column The column to run the comparison on * @param value A long. * * @return A modified Criteria object. */ public Criteria add(String column, long value) { add(column, new Long(value)); return this; } /** * Convenience method to add a long to Criteria. * Equal to * * <p> * <code> * add(column, new Long(value), comparison); * </code> * * * @param column The column to run the comparison on * @param value A long. * @param comparison String describing how to compare the column with the value * * @return A modified Criteria object. */ public Criteria add(String column, long value, SqlEnum comparison) { add(column, new Long(value), comparison); return this; } /** * Convenience method to add a float to Criteria. * Equal to * * <p> * <code> * add(column, new Float(value), EQUAL); * </code> * * @param column The column to run the comparison on * @param value A float. * @return A modified Criteria object. */ public Criteria add(String column, float value) { add(column, new Float(value)); return this; } /** * Convenience method to add a float to Criteria. * Equal to * * <p> * <code> * add(column, new Float(value), comparison); * </code> * * @param column The column to run the comparison on * @param value A float. * @param comparison String describing how to compare the column with the value * * @return A modified Criteria object. */ public Criteria add(String column, float value, SqlEnum comparison) { add(column, new Float(value), comparison); return this; } /** * Convenience method to add a double to Criteria. * Equal to * * <p> * <code> * add(column, new Double(value), EQUAL); * </code> * * @param column The column to run the comparison on * @param value A double. * * @return A modified Criteria object. */ public Criteria add(String column, double value) { add(column, new Double(value)); return this; } /** * Convenience method to add a double to Criteria. * Equal to * * <p> * <code> * add(column, new Double(value), comparison); * </code> * * @param column The column to run the comparison on * @param value A double. * @param comparison String describing how to compare the column with the value * * @return A modified Criteria object. */ public Criteria add(String column, double value, SqlEnum comparison) { add(column, new Double(value), comparison); return this; } /** * @deprecated These methods were wrongly named and are misleading. * Use addDate() instead. */ public Criteria addTime(String column, int year, int month, int date) { return addDate(column, year, month, date); } /** * @deprecated These methods were wrongly named and are misleading. * Use addDate() instead. */ public Criteria addTime(String column, int year, int month, int date, SqlEnum comparison) { return addDate(column, year, month, date, comparison); } /** * Convenience method to add a Date object specified by * year, month, and date into the Criteria. * Equal to * * <p> * <code> * add(column, new GregorianCalendar(year, month,date), EQUAL); * </code> * * @param column A String value to use as column. * @param year An int with the year. * @param month An int with the month. * @param date An int with the date. * @return A modified Criteria object. */ public Criteria addDate(String column, int year, int month, int date) { add(column, new GregorianCalendar(year, month, date)); return this; } /** * Convenience method to add a Date object specified by * year, month, and date into the Criteria. * Equal to * * <p> * <code> * add(column, new GregorianCalendar(year, month,date), comparison); * </code> * * @param column The column to run the comparison on * @param year An int with the year. * @param month An int with the month. * @param date An int with the date. * @param comparison String describing how to compare the column with the value * @return A modified Criteria object. */ public Criteria addDate(String column, int year, int month, int date, SqlEnum comparison) { add(column, new GregorianCalendar(year, month, date), comparison); return this; } /* * * Convenience method to add a Key to Criteria. * * @param key A String value to use as key. * @param value A Key. * @return A modified Criteria object. * / public Criteria add (String key, Key value) { add(key, value.getInternalObject()); return this; } */ /** * This is the way that you should add a join of two tables. For * example: * * <p> * AND PROJECT.PROJECT_ID=FOO.PROJECT_ID * <p> * * left = PROJECT.PROJECT_ID * right = FOO.PROJECT_ID * * @param left A String with the left side of the join. * @param right A String with the right side of the join. * @return A modified Criteria object. */ public Criteria addJoin(String left, String right) { if (joinL == null) { joinL = new ArrayList(3); joinR = new ArrayList(3); } joinL.add(left); joinR.add(right); return this; } /** * get one side of the set of possible joins. This method is meant to * be called by BasePeer. */ public List getJoinL() { return joinL; } /** * get one side of the set of possible joins. This method is meant to * be called by BasePeer. */ public List getJoinR() { return joinR; } /** * Adds an 'IN' clause with the criteria supplied as an Object * array. For example: * * <p> * FOO.NAME IN ('FOO', 'BAR', 'ZOW') * <p> * * where 'values' contains three objects that evaluate to the * respective strings above when .toString() is called. * * If a criterion for the requested column already exists, it is * replaced. * * @param column The column to run the comparison on * @param values An Object[] with the allowed values. * @return A modified Criteria object. */ public Criteria addIn(String column, Object[] values) { add(column, (Object) values, Criteria.IN); return this; } /** * Adds an 'IN' clause with the criteria supplied as an int array. * For example: * * <p> * FOO.ID IN ('2', '3', '7') * <p> * * where 'values' contains those three integers. * * If a criterion for the requested column already exists, it is * replaced. * * @param column The column to run the comparison on * @param values An int[] with the allowed values. * @return A modified Criteria object. */ public Criteria addIn(String column, int[] values) { add(column, (Object) values, Criteria.IN); return this; } /** * Adds an 'IN' clause with the criteria supplied as a List. * For example: * * <p> * FOO.NAME IN ('FOO', 'BAR', 'ZOW') * <p> * * where 'values' contains three objects that evaluate to the * respective strings above when .toString() is called. * * If a criterion for the requested column already exists, it is * replaced. * * @param column The column to run the comparison on * @param values A List with the allowed values. * @return A modified Criteria object. */ public Criteria addIn(String column, List values) { add(column, (Object) values, Criteria.IN); return this; } /** * Adds a 'NOT IN' clause with the criteria supplied as an Object * array. For example: * * <p> * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW') * <p> * * where 'values' contains three objects that evaluate to the * respective strings above when .toString() is called. * * If a criterion for the requested column already exists, it is * replaced. * * @param column The column to run the comparison on * @param values An Object[] with the disallowed values. * @return A modified Criteria object. */ public Criteria addNotIn(String column, Object[] values) { add(column, (Object) values, Criteria.NOT_IN); return this; } /** * Adds a 'NOT IN' clause with the criteria supplied as an int * array. For example: * * <p> * FOO.ID NOT IN ('2', '3', '7') * <p> * * where 'values' contains those three integers. * * If a criterion for the requested column already exists, it is * replaced. * * @param column The column to run the comparison on * @param values An int[] with the disallowed values. * @return A modified Criteria object. */ public Criteria addNotIn(String column, int[] values) { add(column, (Object) values, Criteria.NOT_IN); return this; } /** * Adds a 'NOT IN' clause with the criteria supplied as a List. * For example: * * <p> * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW') * <p> * * where 'values' contains three objects that evaluate to the * respective strings above when .toString() is called. * * If a criterion for the requested column already exists, it is * replaced. * * @param column The column to run the comparison on * @param values A List with the disallowed values. * @return A modified Criteria object. */ public Criteria addNotIn(String column, List values) { add(column, (Object) values, Criteria.NOT_IN); return this; } /** * Adds "ALL " to the SQL statement. */ public void setAll() { selectModifiers.add(ALL.toString()); } /** * Adds "DISTINCT " to the SQL statement. */ public void setDistinct() { selectModifiers.add(DISTINCT.toString()); } /** * Sets ignore case. * * @param b True if case should be ignored. * @return A modified Criteria object. */ public Criteria setIgnoreCase(boolean b) { ignoreCase = b; return this; } /** * Is ignore case on or off? * * @return True if case is ignored. */ public boolean isIgnoreCase() { return ignoreCase; } /** * Set single record? Set this to <code>true</code> if you expect the query * to result in only a single result record (the default behaviour is to * throw a TorqueException if multiple records are returned when the query * is executed). This should be used in situations where returning multiple * rows would indicate an error of some sort. If your query might return * multiple records but you are only interested in the first one then you * should be using setLimit(1). * * @param b set to <code>true</code> if you expect the query to select just * one record. * @return A modified Criteria object. */ public Criteria setSingleRecord(boolean b) { singleRecord = b; return this; } /** * Is single record? * * @return True if a single record is being returned. */ public boolean isSingleRecord() { return singleRecord; } /** * Set cascade. * * @param b True if cascade is set. * @return A modified Criteria object. */ public Criteria setCascade(boolean b) { cascade = b; return this; } /** * Is cascade set? * * @return True if cascade is set. */ public boolean isCascade() { return cascade; } /** * Set limit. * * @param limit An int with the value for limit. * @return A modified Criteria object. */ public Criteria setLimit(int limit) { this.limit = limit; return this; } /** * Get limit. * * @return An int with the value for limit. */ public int getLimit() { return limit; } /** * Set offset. * * @param offset An int with the value for offset. * @return A modified Criteria object. */ public Criteria setOffset(int offset) { this.offset = offset; return this; } /** * Get offset. * * @return An int with the value for offset. */ public int getOffset() { return offset; } /** * Add select column. * * @param name A String with the name of the select column. * @return A modified Criteria object. */ public Criteria addSelectColumn(String name) { selectColumns.add(name); return this; } /** * Get select columns. * * @return A StringStack with the name of the select * columns. */ public StringStack getSelectColumns() { return selectColumns; } /** * Get select modifiers. * * @return A StringStack with the select modifiers. */ public StringStack getSelectModifiers() { return selectModifiers; } /** * @deprecated Use addAscendingOrderByColumn() instead. */ public Criteria addOrderByColumn(String name) { orderByColumns.add(name); return this; } /** * Add group by column name. * * @param groupBy The name of the column to group by. * @return A modified Criteria object. */ public Criteria addGroupByColumn(String groupBy) { groupByColumns.add(groupBy); return this; } /** * Add order by column name, explicitly specifying ascending. * * @param name The name of the column to order by. * @return A modified Criteria object. */ public Criteria addAscendingOrderByColumn(String name) { orderByColumns.add(name + ' ' + ASC); return this; } /** * Add order by column name, explicitly specifying descending. * * @param name The name of the column to order by. * @return A modified Criteria object. */ public Criteria addDescendingOrderByColumn(String name) { orderByColumns.add(name + ' ' + DESC); return this; } /** * Get order by columns. * * @return A StringStack with the name of the order columns. */ public StringStack getOrderByColumns() { return orderByColumns; } /** * Get group by columns. * * @return A StringStack with the name of the groupBy clause. */ public StringStack getGroupByColumns() { return groupByColumns; } /** * Get Having Criterion. * * @return A Criterion that is the having clause. */ public Criterion getHaving() { return having; } /** * Remove an object from the criteria. * * @param key A String with the key to be removed. * @return The removed object. */ public Object remove(String key) { Object foo = super.remove(key); if (foo instanceof Criterion) { return ((Criterion) foo).getValue(); } return foo; } /** * Build a string representation of the Criteria. * * @return A String with the representation of the Criteria. */ public String toString() { StringBuffer sb = new StringBuffer("Criteria:: "); Iterator it = keySet().iterator(); while (it.hasNext()) { String key = (String) it.next(); sb.append(key).append("<=>").append(super.get(key).toString()).append(": "); } try { sb.append("\nCurrent Query SQL (may not be complete or applicable): ") .append(BasePeer.createQueryDisplayString(this)); } catch (Exception exc) { } return sb.toString(); } /** * This method checks another Criteria to see if they contain * the same attributes and hashtable entries. */ public boolean equals(Object crit) { boolean isEquiv = false; if (crit == null || !(crit instanceof Criteria)) { isEquiv = false; } else if (this == crit) { isEquiv = true; } else if (this.size() == ((Criteria) crit).size()) { Criteria criteria = (Criteria) crit; if (this.offset == criteria.getOffset() && this.limit == criteria.getLimit() && ignoreCase == criteria.isIgnoreCase() && singleRecord == criteria.isSingleRecord() && cascade == criteria.isCascade() && dbName.equals(criteria.getDbName()) && selectModifiers.equals(criteria.getSelectModifiers()) && selectColumns.equals(criteria.getSelectColumns()) && orderByColumns.equals(criteria.getOrderByColumns())) { isEquiv = true; for (Iterator it = criteria.keySet().iterator(); it.hasNext();) { String key = (String) it.next(); if (this.containsKey(key)) { Criterion a = this.getCriterion(key); Criterion b = criteria.getCriterion(key); if (!a.equals(b)) { isEquiv = false; break; } } else { isEquiv = false; break; } } } } return isEquiv; } /* *------------------------------------------------------------------------ * * Start of the "and" methods * *------------------------------------------------------------------------ */ /** * This method adds a prepared Criterion object to the Criteria as a having clause. * You can get a new, empty Criterion object with the * getNewCriterion() method. * * <p> * <code> * Criteria crit = new Criteria(); * Criteria.Criterion c = crit.getNewCriterion(BasePeer.ID, new Integer(5), Criteria.LESS_THAN); * crit.addHaving(c); * </code> * * @param having A Criterion object * * @return A modified Criteria object. */ public Criteria addHaving(Criterion having) { this.having = having; return this; } /** * This method adds a prepared Criterion object to the Criteria. * You can get a new, empty Criterion object with the * getNewCriterion() method. If a criterion for the requested column * already exists, it is "AND"ed to the existing criterion. * This is used as follows: * * <p> * <code> * Criteria crit = new Criteria(); * Criteria.Criterion c = crit.getNewCriterion(BasePeer.ID, new Integer(5), Criteria.LESS_THAN); * crit.and(c); * </code> * * @param c A Criterion object * * @return A modified Criteria object. */ public Criteria and(Criterion c) { Criterion oc = getCriterion(c.getTable() + '.' + c.getColumn()); if (oc == null) { add(c); } else { oc.and(c); } return this; } /** * This method adds a new criterion to the list of criterias. If a * criterion for the requested column already exists, it is * "AND"ed to the existing criterion. This is used as follows: * * <p> * <code> * Criteria crit = new Criteria().and("column", * "value"); * </code> * * An EQUAL comparison is used for column and value. * * The name of the table must be used implicitly in the column name, * so the Column name must be something like 'TABLE.id'. If you * don't like this, you can use the and(table, column, value) method. * * @param column The column to run the comparison on * @param value An Object. * * @return A modified Criteria object. */ public Criteria and(String column, Object value) { and(column, value, EQUAL); return this; } /** * This method adds a new criterion to the list of criterias. * If a criterion for the requested column already exists, it is * "AND"ed to the existing criterion. If is used as follow: * * <p> * <code> * Criteria crit = new Criteria().and("column", * "value" * "Criterion.GREATER_THAN"); * </code> * * Any comparison can be used. * * The name of the table must be used implicitly in the column name, * so the Column name must be something like 'TABLE.id'. If you * don't like this, you can use the and(table, column, value) method. * * @param column The column to run the comparison on * @param value An Object. * @param comparison A String. * * @return A modified Criteria object. */ public Criteria and(String column, Object value, SqlEnum comparison) { Criterion oc = getCriterion(column); Criterion nc = new Criterion(column, value, comparison); if (oc == null) { super.put(column, nc); } else { oc.and(nc); } return this; } /** * This method adds a new criterion to the list of criterias. * If a criterion for the requested column already exists, it is * "AND"ed to the existing criterion. If is used as follows: * * <p> * <code> * Criteria crit = new Criteria().and("table", * "column", * "value"); * </code> * * An EQUAL comparison is used for column and value. * * @param table Name of the table which contains the column * @param column The column to run the comparison on * @param value An Object. * * @return A modified Criteria object. */ public Criteria and(String table, String column, Object value) { and(table, column, value, EQUAL); return this; } /** * This method adds a new criterion to the list of criterias. * If a criterion for the requested column already exists, it is * "AND"ed to the existing criterion. If is used as follows: * * <p> * <code> * Criteria crit = new Criteria().and("table", * "column", * "value", * "Criterion.GREATER_THAN"); * </code> * * Any comparison can be used. * * @param table Name of table which contains the column * @param column The column to run the comparison on * @param value An Object. * @param comparison String describing how to compare the column with the value * * @return A modified Criteria object. */ public Criteria and(String table, String column, Object value, SqlEnum comparison) { StringBuffer sb = new StringBuffer(table.length() + column.length() + 1); sb.append(table); sb.append('.'); sb.append(column); Criterion oc = getCriterion(table, column); Criterion nc = new Criterion(table, column, value, comparison); if (oc == null) { super.put(sb.toString(), nc); } else { oc.and(nc); } return this; } /** * Convenience method to add a boolean to Criteria. * Equal to * * <p> * <code> * and(column, new Boolean(value), EQUAL); * </code> * * @param column The column to run the comparison on * @param value A Boolean. * * @return A modified Criteria object. */ public Criteria and(String column, boolean value) { and(column, new Boolean(value)); return this; } /** * Convenience method to add a boolean to Criteria. * Equal to * * <p> * <code> * and(column, new Boolean(value), comparison); * </code> * * @param column The column to run the comparison on * @param value A Boolean. * @param comparison String describing how to compare the column * with the value * * @return A modified Criteria object. */ public Criteria and(String column, boolean value, SqlEnum comparison) { and(column, new Boolean(value), comparison); return this; } /** * Convenience method to add an int to Criteria. * Equal to * * <p> * <code> * and(column, new Integer(value), EQUAL); * </code> * * * @param column The column to run the comparison on * @param value An int. * * @return A modified Criteria object. */ public Criteria and(String column, int value) { and(column, new Integer(value)); return this; } /** * Convenience method to add an int to Criteria. * Equal to * * <p> * <code> * and(column, new Integer(value), comparison); * </code> * * * @param column The column to run the comparison on * @param value An int. * @param comparison String describing how to compare the column with the value * * @return A modified Criteria object. */ public Criteria and(String column, int value, SqlEnum comparison) { and(column, new Integer(value), comparison); return this; } /** * Convenience method to add a long to Criteria. * Equal to * * <p> * <code> * and(column, new Long(value), EQUAL); * </code> * * * @param column The column to run the comparison on * @param value A long. * * @return A modified Criteria object. */ public Criteria and(String column, long value) { and(column, new Long(value)); return this; } /** * Convenience method to add a long to Criteria. * Equal to * * <p> * <code> * and(column, new Long(value), comparison); * </code> * * @param column The column to run the comparison on * @param value A long. * @param comparison String describing how to compare the column with the value * * @return A modified Criteria object. */ public Criteria and(String column, long value, SqlEnum comparison) { and(column, new Long(value), comparison); return this; } /** * Convenience method to add a float to Criteria. * Equal to * * <p> * <code> * and(column, new Float(value), EQUAL); * </code> * * @param column The column to run the comparison on * @param value A float. * * @return A modified Criteria object. */ public Criteria and(String column, float value) { and(column, new Float(value)); return this; } /** * Convenience method to add a float to Criteria. * Equal to * * <p> * <code> * and(column, new Float(value), comparison); * </code> * * @param column The column to run the comparison on * @param value A float. * @param comparison String describing how to compare the column with the value * * @return A modified Criteria object. */ public Criteria and(String column, float value, SqlEnum comparison) { and(column, new Float(value), comparison); return this; } /** * Convenience method to add a double to Criteria. * Equal to * * <p> * <code> * and(column, new Double(value), EQUAL); * </code> * * @param column The column to run the comparison on * @param value A double. * * @return A modified Criteria object. */ public Criteria and(String column, double value) { and(column, new Double(value)); return this; } /** * Convenience method to add a double to Criteria. * Equal to * * <p> * <code> * and(column, new Double(value), comparison); * </code> * * @param column The column to run the comparison on * @param value A double. * @param comparison String describing how to compare the column with the value * * @return A modified Criteria object. */ public Criteria and(String column, double value, SqlEnum comparison) { and(column, new Double(value), comparison); return this; } /** * Convenience method to add a Date object specified by * year, month, and date into the Criteria. * Equal to * * <p> * <code> * and(column, new GregorianCalendar(year, month,date), EQUAL); * </code> * * @param column A String value to use as column. * @param year An int with the year. * @param month An int with the month. * @param date An int with the date. * @return A modified Criteria object. */ public Criteria andDate(String column, int year, int month, int date) { and(column, new GregorianCalendar(year, month, date)); return this; } /** * Convenience method to add a Date object specified by * year, month, and date into the Criteria. * Equal to * * <p> * <code> * and(column, new GregorianCalendar(year, month,date), comparison); * </code> * * @param column The column to run the comparison on * @param year An int with the year. * @param month An int with the month. * @param date An int with the date. * @param comparison String describing how to compare the column with the value * @return A modified Criteria object. */ public Criteria andDate(String column, int year, int month, int date, SqlEnum comparison) { and(column, new GregorianCalendar(year, month, date), comparison); return this; } /** * Adds an 'IN' clause with the criteria supplied as an Object array. * For example: * * <p> * FOO.NAME IN ('FOO', 'BAR', 'ZOW') * <p> * * where 'values' contains three objects that evaluate to the * respective strings above when .toString() is called. * * If a criterion for the requested column already exists, it is * "AND"ed to the existing criterion. * * @param column The column to run the comparison on * @param values An Object[] with the allowed values. * @return A modified Criteria object. */ public Criteria andIn(String column, Object[] values) { and(column, (Object) values, Criteria.IN); return this; } /** * Adds an 'IN' clause with the criteria supplied as an int array. * For example: * * <p> * FOO.ID IN ('2', '3', '7') * <p> * * where 'values' contains those three integers. * * If a criterion for the requested column already exists, it is * "AND"ed to the existing criterion. * * @param column The column to run the comparison on * @param values An int[] with the allowed values. * @return A modified Criteria object. */ public Criteria andIn(String column, int[] values) { and(column, (Object) values, Criteria.IN); return this; } /** * Adds an 'IN' clause with the criteria supplied as a List. * For example: * * <p> * FOO.NAME IN ('FOO', 'BAR', 'ZOW') * <p> * * where 'values' contains three objects that evaluate to the * respective strings above when .toString() is called. * * If a criterion for the requested column already exists, it is * "AND"ed to the existing criterion. * * @param column The column to run the comparison on * @param values A List with the allowed values. * @return A modified Criteria object. */ public Criteria andIn(String column, List values) { and(column, (Object) values, Criteria.IN); return this; } /** * Adds a 'NOT IN' clause with the criteria supplied as an Object * array. For example: * * <p> * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW') * <p> * * where 'values' contains three objects that evaluate to the * respective strings above when .toString() is called. * * If a criterion for the requested column already exists, it is * "AND"ed to the existing criterion. * * @param column The column to run the comparison on * @param values An Object[] with the disallowed values. * @return A modified Criteria object. */ public Criteria andNotIn(String column, Object[] values) { and(column, (Object) values, Criteria.NOT_IN); return this; } /** * Adds a 'NOT IN' clause with the criteria supplied as an int * array. For example: * * <p> * FOO.ID NOT IN ('2', '3', '7') * <p> * * where 'values' contains those three integers. * * If a criterion for the requested column already exists, it is * "AND"ed to the existing criterion. * * @param column The column to run the comparison on * @param values An int[] with the disallowed values. * @return A modified Criteria object. */ public Criteria andNotIn(String column, int[] values) { and(column, (Object) values, Criteria.NOT_IN); return this; } /** * Adds a 'NOT IN' clause with the criteria supplied as a List. * For example: * * <p> * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW') * <p> * * where 'values' contains three objects that evaluate to the * respective strings above when .toString() is called. * * If a criterion for the requested column already exists, it is * "AND"ed to the existing criterion. * * @param column The column to run the comparison on * @param values A List with the disallowed values. * @return A modified Criteria object. */ public Criteria andNotIn(String column, List values) { and(column, (Object) values, Criteria.NOT_IN); return this; } /* *------------------------------------------------------------------------ * * Start of the "or" methods * *------------------------------------------------------------------------ */ /** * This method adds a prepared Criterion object to the Criteria. * You can get a new, empty Criterion object with the * getNewCriterion() method. If a criterion for the requested column * already exists, it is "OR"ed to the existing criterion. * This is used as follows: * * <p> * <code> * Criteria crit = new Criteria(); * Criteria.Criterion c = crit.getNewCriterion(BasePeer.ID, new Integer(5), Criteria.LESS_THAN); * crit.or(c); * </code> * * @param c A Criterion object * * @return A modified Criteria object. */ public Criteria or(Criterion c) { Criterion oc = getCriterion(c.getTable() + '.' + c.getColumn()); if (oc == null) { add(c); } else { oc.or(c); } return this; } /** * This method adds a new criterion to the list of criterias. If a * criterion for the requested column already exists, it is * "OR"ed to the existing criterion. This is used as follows: * * <p> * <code> * Criteria crit = new Criteria().or("column", * "value"); * </code> * * An EQUAL comparison is used for column and value. * * The name of the table must be used implicitly in the column name, * so the Column name must be something like 'TABLE.id'. If you * don't like this, you can use the or(table, column, value) method. * * @param column The column to run the comparison on * @param value An Object. * * @return A modified Criteria object. */ public Criteria or(String column, Object value) { or(column, value, EQUAL); return this; } /** * This method adds a new criterion to the list of criterias. * If a criterion for the requested column already exists, it is * "OR"ed to the existing criterion. If is used as follow: * * <p> * <code> * Criteria crit = new Criteria().or("column", * "value" * "Criterion.GREATER_THAN"); * </code> * * Any comparison can be used. * * The name of the table must be used implicitly in the column name, * so the Column name must be something like 'TABLE.id'. If you * don't like this, you can use the or(table, column, value) method. * * @param column The column to run the comparison on * @param value An Object. * @param comparison A String. * * @return A modified Criteria object. */ public Criteria or(String column, Object value, SqlEnum comparison) { Criterion oc = getCriterion(column); Criterion nc = new Criterion(column, value, comparison); if (oc == null) { super.put(column, nc); } else { oc.or(nc); } return this; } /** * This method adds a new criterion to the list of criterias. * If a criterion for the requested column already exists, it is * "OR"ed to the existing criterion. If is used as follows: * * <p> * <code> * Criteria crit = new Criteria().or("table", * "column", * "value"); * </code> * * An EQUAL comparison is used for column and value. * * @param table Name of the table which contains the column * @param column The column to run the comparison on * @param value An Object. * * @return A modified Criteria object. */ public Criteria or(String table, String column, Object value) { or(table, column, value, EQUAL); return this; } /** * This method adds a new criterion to the list of criterias. * If a criterion for the requested column already exists, it is * "OR"ed to the existing criterion. If is used as follows: * * <p> * <code> * Criteria crit = new Criteria().or("table", * "column", * "value", * "Criterion.GREATER_THAN"); * </code> * * Any comparison can be used. * * @param table Name of table which contains the column * @param column The column to run the comparison on * @param value An Object. * @param comparison String describing how to compare the column with the value * * @return A modified Criteria object. */ public Criteria or(String table, String column, Object value, SqlEnum comparison) { StringBuffer sb = new StringBuffer(table.length() + column.length() + 1); sb.append(table); sb.append('.'); sb.append(column); Criterion oc = getCriterion(table, column); Criterion nc = new Criterion(table, column, value, comparison); if (oc == null) { super.put(sb.toString(), nc); } else { oc.or(nc); } return this; } /** * Convenience method to add a boolean to Criteria. * Equal to * * <p> * <code> * or(column, new Boolean(value), EQUAL); * </code> * * @param column The column to run the comparison on * @param value A Boolean. * * @return A modified Criteria object. */ public Criteria or(String column, boolean value) { or(column, new Boolean(value)); return this; } /** * Convenience method to add a boolean to Criteria. * Equal to * * <p> * <code> * or(column, new Boolean(value), comparison); * </code> * * @param column The column to run the comparison on * @param value A Boolean. * @param comparison String describing how to compare the column * with the value * * @return A modified Criteria object. */ public Criteria or(String column, boolean value, SqlEnum comparison) { or(column, new Boolean(value), comparison); return this; } /** * Convenience method to add an int to Criteria. * Equal to * * <p> * <code> * or(column, new Integer(value), EQUAL); * </code> * * * @param column The column to run the comparison on * @param value An int. * * @return A modified Criteria object. */ public Criteria or(String column, int value) { or(column, new Integer(value)); return this; } /** * Convenience method to add an int to Criteria. * Equal to * * <p> * <code> * or(column, new Integer(value), comparison); * </code> * * * @param column The column to run the comparison on * @param value An int. * @param comparison String describing how to compare the column * with the value * * @return A modified Criteria object. */ public Criteria or(String column, int value, SqlEnum comparison) { or(column, new Integer(value), comparison); return this; } /** * Convenience method to add a long to Criteria. * Equal to * * <p> * <code> * or(column, new Long(value), EQUAL); * </code> * * * @param column The column to run the comparison on * @param value A long. * * @return A modified Criteria object. */ public Criteria or(String column, long value) { or(column, new Long(value)); return this; } /** * Convenience method to add a long to Criteria. * Equal to * * <p> * <code> * or(column, new Long(value), comparison); * </code> * * @param column The column to run the comparison on * @param value A long. * @param comparison String describing how to compare the column * with the value * * @return A modified Criteria object. */ public Criteria or(String column, long value, SqlEnum comparison) { or(column, new Long(value), comparison); return this; } /** * Convenience method to add a float to Criteria. * Equal to * * <p> * <code> * or(column, new Float(value), EQUAL); * </code> * * @param column The column to run the comparison on * @param value A float. * * @return A modified Criteria object. */ public Criteria or(String column, float value) { or(column, new Float(value)); return this; } /** * Convenience method to add a float to Criteria. * Equal to * * <p> * <code> * or(column, new Float(value), comparison); * </code> * * @param column The column to run the comparison on * @param value A float. * @param comparison String describing how to compare the column * with the value * * @return A modified Criteria object. */ public Criteria or(String column, float value, SqlEnum comparison) { or(column, new Float(value), comparison); return this; } /** * Convenience method to add a double to Criteria. * Equal to * * <p> * <code> * or(column, new Double(value), EQUAL); * </code> * * @param column The column to run the comparison on * @param value A double. * * @return A modified Criteria object. */ public Criteria or(String column, double value) { or(column, new Double(value)); return this; } /** * Convenience method to add a double to Criteria. * Equal to * * <p> * <code> * or(column, new Double(value), comparison); * </code> * * @param column The column to run the comparison on * @param value A double. * @param comparison String describing how to compare the column * with the value * * @return A modified Criteria object. */ public Criteria or(String column, double value, SqlEnum comparison) { or(column, new Double(value), comparison); return this; } /** * Convenience method to add a Date object specified by * year, month, and date into the Criteria. * Equal to * * <p> * <code> * or(column, new GregorianCalendar(year, month,date), EQUAL); * </code> * * @param column A String value to use as column. * @param year An int with the year. * @param month An int with the month. * @param date An int with the date. * @return A modified Criteria object. */ public Criteria orDate(String column, int year, int month, int date) { or(column, new GregorianCalendar(year, month, date)); return this; } /** * Convenience method to add a Date object specified by * year, month, and date into the Criteria. * Equal to * * <p> * <code> * or(column, new GregorianCalendar(year, month,date), comparison); * </code> * * @param column The column to run the comparison on * @param year An int with the year. * @param month An int with the month. * @param date An int with the date. * @param comparison String describing how to compare the column * with the value * @return A modified Criteria object. */ public Criteria orDate(String column, int year, int month, int date, SqlEnum comparison) { or(column, new GregorianCalendar(year, month, date), comparison); return this; } /** * Adds an 'IN' clause with the criteria supplied as an Object * array. For example: * * <p> * FOO.NAME IN ('FOO', 'BAR', 'ZOW') * <p> * * where 'values' contains three objects that evaluate to the * respective strings above when .toString() is called. * * If a criterion for the requested column already exists, it is * "OR"ed to the existing criterion. * * @param column The column to run the comparison on * @param values An Object[] with the allowed values. * @return A modified Criteria object. */ public Criteria orIn(String column, Object[] values) { or(column, (Object) values, Criteria.IN); return this; } /** * Adds an 'IN' clause with the criteria supplied as an int array. * For example: * * <p> * FOO.ID IN ('2', '3', '7') * <p> * * where 'values' contains those three integers. * * If a criterion for the requested column already exists, it is * "OR"ed to the existing criterion. * * @param column The column to run the comparison on * @param values An int[] with the allowed values. * @return A modified Criteria object. */ public Criteria orIn(String column, int[] values) { or(column, (Object) values, Criteria.IN); return this; } /** * Adds an 'IN' clause with the criteria supplied as a List. * For example: * * <p> * FOO.NAME IN ('FOO', 'BAR', 'ZOW') * <p> * * where 'values' contains three objects that evaluate to the * respective strings above when .toString() is called. * * If a criterion for the requested column already exists, it is * "OR"ed to the existing criterion. * * @param column The column to run the comparison on * @param values A List with the allowed values. * @return A modified Criteria object. */ public Criteria orIn(String column, List values) { or(column, (Object) values, Criteria.IN); return this; } /** * Adds a 'NOT IN' clause with the criteria supplied as an Object * array. For example: * * <p> * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW') * <p> * * where 'values' contains three objects that evaluate to the * respective strings above when .toString() is called. * * If a criterion for the requested column already exists, it is * "OR"ed to the existing criterion. * * @param column The column to run the comparison on * @param values An Object[] with the disallowed values. * @return A modified Criteria object. */ public Criteria orNotIn(String column, Object[] values) { or(column, (Object) values, Criteria.NOT_IN); return this; } /** * Adds a 'NOT IN' clause with the criteria supplied as an int * array. For example: * * <p> * FOO.ID NOT IN ('2', '3', '7') * <p> * * where 'values' contains those three integers. * * If a criterion for the requested column already exists, it is * "OR"ed to the existing criterion. * * @param column The column to run the comparison on * @param values An int[] with the disallowed values. * @return A modified Criteria object. */ public Criteria orNotIn(String column, int[] values) { or(column, (Object) values, Criteria.NOT_IN); return this; } /** * Adds a 'NOT IN' clause with the criteria supplied as a List. * For example: * * <p> * FOO.NAME NOT IN ('FOO', 'BAR', 'ZOW') * <p> * * where 'values' contains three objects that evaluate to the * respective strings above when .toString() is called. * * If a criterion for the requested column already exists, it is * "OR"ed to the existing criterion. * * @param column The column to run the comparison on * @param values A List with the disallowed values. * @return A modified Criteria object. */ public Criteria orNotIn(String column, List values) { or(column, (Object) values, Criteria.NOT_IN); return this; } /** * Peers can set this flag to notify BasePeer that the table(s) involved * in the Criteria contain Blobs, so that the operation can be placed * in a transaction if the db requires it. * This is primarily to support Postgresql. * The flag is set to true by this method. * @deprecated Use @see #setBlobFlag(boolean) */ public void setBlobFlag() { blobFlag = Boolean.TRUE; } /** * Peers can set this flag to notify BasePeer that the table(s) involved * in the Criteria contain Blobs, so that the operation can be placed * in a transaction if the db requires it. * This is primarily to support Postgresql. */ public void setBlobFlag(boolean b) { blobFlag = (b ? Boolean.TRUE : Boolean.FALSE); } /** * This is an inner class that describes an object in the * criteria. */ public final class Criterion implements Serializable { public static final String AND = " AND "; public static final String OR = " OR "; /** Value of the CO. */ private Object value; /** Comparison value. */ private SqlEnum comparison; /** Table name. */ private String table; /** Column name. */ private String column; /** flag to ignore case in comparision */ private boolean ignoreStringCase = false; /** * The DB adaptor which might be used to get db specific * variations of sql. */ private DB db; /** * other connected criteria and their conjunctions. */ private List clauses = new ArrayList(); private List conjunctions = new ArrayList(); /** * Creates a new instance, initializing a couple members. */ private Criterion(Object val, SqlEnum comp) { this.value = val; this.comparison = comp; } /** * Create a new instance. * * @param table A String with the name of the table. * @param column A String with the name of the column. * @param val An Object with the value for the Criteria. * @param comp A String with the comparison value. */ Criterion(String table, String column, Object val, SqlEnum comp) { this(val, comp); this.table = (table == null ? "" : table); this.column = (column == null ? "" : column); } /** * Create a new instance. * * @param tableColumn A String with the full name of the * column. * @param val An Object with the value for the Criteria. * @param comp A String with the comparison value. */ Criterion(String tableColumn, Object val, SqlEnum comp) { this(val, comp); int dot = tableColumn.lastIndexOf('.'); if (dot == -1) { table = ""; column = tableColumn; } else { table = tableColumn.substring(0, dot); column = tableColumn.substring(dot + 1); } } /** * Create a new instance. * * @param table A String with the name of the table. * @param column A String with the name of the column. * @param val An Object with the value for the Criteria. */ Criterion(String table, String column, Object val) { this(table, column, val, EQUAL); } /** * Create a new instance. * * @param tableColumn A String with the full name of the * column. * @param val An Object with the value for the Criteria. */ Criterion(String tableColumn, Object val) { this(tableColumn, val, EQUAL); } /** * Get the column name. * * @return A String with the column name. */ public String getColumn() { return this.column; } /** * Set the table name. * * @param name A String with the table name. */ public void setTable(String name) { this.table = name; } /** * Get the table name. * * @return A String with the table name. */ public String getTable() { return this.table; } /** * Get the comparison. * * @return A String with the comparison. */ public SqlEnum getComparison() { return this.comparison; } /** * Get the value. * * @return An Object with the value. */ public Object getValue() { return this.value; } /** * Get the value of db. * The DB adaptor which might be used to get db specific * variations of sql. * @return value of db. */ public DB getDb() { DB db = null; if (this.db == null) { // db may not be set if generating preliminary sql for // debugging. try { db = Torque.getDB(getDbName()); } catch (Exception e) { // we are only doing this to allow easier debugging, so // no need to throw up the exception, just make note of it. category.error("Could not get a DB adapter, so sql may be wrong"); } } else { db = this.db; } return db; } /** * Set the value of db. * The DB adaptor might be used to get db specific * variations of sql. * @param v Value to assign to db. */ public void setDB(DB v) { this.db = v; for (int i = 0; i < this.clauses.size(); i++) { ((Criterion) (clauses.get(i))).setDB(v); } } /** * Sets ignore case. * * @param b True if case should be ignored. * @return A modified Criteria object. */ public Criterion setIgnoreCase(boolean b) { ignoreStringCase = b; return this; } /** * Is ignore case on or off? * * @return True if case is ignored. */ public boolean isIgnoreCase() { return ignoreStringCase; } /** * get the list of clauses in this Criterion */ private List getClauses() { return clauses; } /** * get the list of conjunctions in this Criterion */ private List getConjunctions() { return conjunctions; } /** * Append an AND Criterion onto this Criterion's list. */ public Criterion and(Criterion criterion) { this.clauses.add(criterion); this.conjunctions.add(AND); return this; } /** * Append an OR Criterion onto this Criterion's list. */ public Criterion or(Criterion criterion) { this.clauses.add(criterion); this.conjunctions.add(OR); return this; } /** * Appends a representation of the Criterion onto the buffer. */ public void appendTo(StringBuffer sb) { // // it is alright if value == null // if (column == null) { return; } Criterion clause = null; for (int j = 0; j < this.clauses.size(); j++) { sb.append('('); } if (CUSTOM == comparison) { if (value != null && !"".equals(value)) { sb.append((String) value); } } else { String field = null; if (table == null) { field = column; } else { field = new StringBuffer(table.length() + 1 + column.length()).append(table).append('.') .append(column).toString(); } SqlExpression.build(field, value, comparison, ignoreStringCase, getDb(), sb); } for (int i = 0; i < this.clauses.size(); i++) { sb.append(this.conjunctions.get(i)); clause = (Criterion) (this.clauses.get(i)); clause.appendTo(sb); sb.append(')'); } } /** * Appends a Prepared Statement representation of the Criterion * onto the buffer. * * @param sb The stringbuffer that will receive the Prepared Statement * @param params A list to which Prepared Statement parameters * will be appended */ public void appendPsTo(StringBuffer sb, List params) { if (column == null || value == null) { return; } DB db = getDb(); for (int j = 0; j < this.clauses.size(); j++) { sb.append('('); } if (CUSTOM == comparison) { if (!"".equals(value)) { sb.append((String) value); } } else { String field = null; if (table == null) { field = column; } else { field = new StringBuffer(table.length() + 1 + column.length()).append(table).append('.') .append(column).toString(); } if (comparison.equals(Criteria.IN) || comparison.equals(Criteria.NOT_IN)) { sb.append(field).append(comparison); StringStack inClause = new StringStack(); if (value instanceof List) { value = ((List) value).toArray(new Object[0]); } for (int i = 0; i < Array.getLength(value); i++) { Object item = Array.get(value, i); inClause.add(SqlExpression.processInValue(item, ignoreCase, db)); } StringBuffer inString = new StringBuffer(); inString.append('(').append(inClause.toString(",")).append(')'); sb.append(inString.toString()); } else { if (ignoreCase) { sb.append(db.ignoreCase(field)).append(comparison).append(db.ignoreCase("?")); } else { sb.append(field).append(comparison).append(" ? "); } if (value instanceof java.util.Date) { params.add(new java.sql.Date(((java.util.Date) value).getTime())); } else if (value instanceof DateKey) { params.add(new java.sql.Date(((DateKey) value).getDate().getTime())); } else { params.add(value.toString()); } } } for (int i = 0; i < this.clauses.size(); i++) { sb.append(this.conjunctions.get(i)); Criterion clause = (Criterion) (this.clauses.get(i)); clause.appendPsTo(sb, params); sb.append(')'); } } /** * Build a string representation of the Criterion. * * @return A String with the representation of the Criterion. */ public String toString() { // // it is alright if value == null // if (column == null) { return ""; } StringBuffer expr = new StringBuffer(25); appendTo(expr); return expr.toString(); } /** * This method checks another Criteria to see if they contain * the same attributes and hashtable entries. */ public boolean equals(Object obj) { if (this == obj) { return true; } if ((obj == null) || !(obj instanceof Criterion)) { return false; } Criterion crit = (Criterion) obj; boolean isEquiv = ((table == null && crit.getTable() == null) || (table != null && table.equals(crit.getTable()))) && column.equals(crit.getColumn()) && comparison.equals(crit.getComparison()); // we need to check for value equality if (isEquiv) { Object b = crit.getValue(); if (value instanceof Object[] && b instanceof Object[]) { isEquiv &= Arrays.equals((Object[]) value, (Object[]) b); } else if (value instanceof int[] && b instanceof int[]) { isEquiv &= Arrays.equals((int[]) value, (int[]) b); } else { isEquiv &= value.equals(b); } } // check chained criterion isEquiv &= this.clauses.size() == crit.getClauses().size(); for (int i = 0; i < this.clauses.size(); i++) { isEquiv &= ((String) (conjunctions.get(i))).equals((String) (crit.getConjunctions().get(i))); isEquiv &= ((Criterion) (clauses.get(i))).equals((Criterion) (crit.getClauses().get(i))); } return isEquiv; } /** * Returns a hash code value for the object. */ public int hashCode() { int h = value.hashCode() ^ comparison.hashCode(); if (table != null) { h ^= table.hashCode(); } if (column != null) { h ^= column.hashCode(); } for (int i = 0; i < this.clauses.size(); i++) { h ^= ((Criterion) (clauses.get(i))).hashCode(); } return h; } /** * get all tables from nested criterion objects */ public String[] getAllTables() { StringStack tables = new StringStack(); addCriterionTable(this, tables); return tables.toStringArray(); } /** * method supporting recursion through all criterions to give * us a StringStack of tables from each criterion */ private void addCriterionTable(Criterion c, StringStack s) { if (c != null) { s.add(c.getTable()); for (int i = 0; i < c.getClauses().size(); i++) { addCriterionTable((Criterion) (c.getClauses().get(i)), s); } } } /** * get an array of all criterion attached to this * recursing through all sub criterion */ public Criterion[] getAttachedCriterion() { ArrayList crits = new ArrayList(); traverseCriterion(this, crits); Criterion[] crita = new Criterion[crits.size()]; for (int i = 0; i < crits.size(); i++) { crita[i] = (Criterion) crits.get(i); } return crita; } /** * method supporting recursion through all criterions to give * us an ArrayList of them */ private void traverseCriterion(Criterion c, ArrayList a) { if (c != null) { a.add(c); for (int i = 0; i < c.getClauses().size(); i++) { traverseCriterion((Criterion) (c.getClauses().get(i)), a); } } } } }