You are viewing a plain text version of this content. The canonical link for it is here.
Posted to torque-dev@db.apache.org by tf...@apache.org on 2005/11/12 12:15:30 UTC
svn commit: r332758 - in /db/torque/runtime/trunk:
src/java/org/apache/torque/util/Criteria.java
src/test/org/apache/torque/util/CriteriaTest.java xdocs/changes.xml
Author: tfischer
Date: Sat Nov 12 03:15:21 2005
New Revision: 332758
URL: http://svn.apache.org/viewcvs?rev=332758&view=rev
Log:
Scott's fix for TRQS321.
Criteria is now serializable, and has an improved equals() method and a
hashCode() method.
Thanks to Martin Goulet for an early version of the patch.
Modified:
db/torque/runtime/trunk/src/java/org/apache/torque/util/Criteria.java
db/torque/runtime/trunk/src/test/org/apache/torque/util/CriteriaTest.java
db/torque/runtime/trunk/xdocs/changes.xml
Modified: db/torque/runtime/trunk/src/java/org/apache/torque/util/Criteria.java
URL: http://svn.apache.org/viewcvs/db/torque/runtime/trunk/src/java/org/apache/torque/util/Criteria.java?rev=332758&r1=332757&r2=332758&view=diff
==============================================================================
--- db/torque/runtime/trunk/src/java/org/apache/torque/util/Criteria.java (original)
+++ db/torque/runtime/trunk/src/java/org/apache/torque/util/Criteria.java Sat Nov 12 03:15:21 2005
@@ -16,6 +16,9 @@
* limitations under the License.
*/
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.math.BigDecimal;
@@ -30,6 +33,7 @@
import org.apache.commons.collections.OrderedMap;
import org.apache.commons.collections.map.ListOrderedMap;
+import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -54,10 +58,13 @@
* @author <a href="mailto:sam@neurogrid.com">Sam Joseph</a>
* @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
* @author <a href="mailto:fischer@seitenbau.de">Thomas Fischer</a>
+ * @author <a href="mailto:seade@backstagetech.com.au">Scott Eade</a>
* @version $Id$
*/
public class Criteria extends Hashtable
{
+ /** Serial version. */
+ private static final long serialVersionUID = -9001666575933085601L;
/** Comparison type. */
public static final SqlEnum EQUAL = SqlEnum.EQUAL;
@@ -148,7 +155,7 @@
private UniqueList groupByColumns = new UniqueList();
private Criterion having = null;
private OrderedMap asColumns = ListOrderedMap.decorate(new HashMap());
- private List joins = null;
+ private transient List joins = null;
/** The name of the database. */
private String dbName;
@@ -275,6 +282,16 @@
}
/**
+ * Get the table aliases.
+ *
+ * @return A Map which maps the table alias names to the actual table names.
+ */
+ public Map getAliases()
+ {
+ return aliases;
+ }
+
+ /**
* Allows one to specify an alias for a table that can
* be used in various parts of the SQL.
*
@@ -1818,6 +1835,9 @@
&& selectModifiers.equals(criteria.getSelectModifiers())
&& selectColumns.equals(criteria.getSelectColumns())
&& orderByColumns.equals(criteria.getOrderByColumns())
+ && ObjectUtils.equals(aliases, criteria.getAliases())
+ && asColumns.equals(criteria.getAsColumns())
+ && joins.equals(criteria.getJoins())
)
{
isEquiv = true;
@@ -1845,6 +1865,30 @@
return isEquiv;
}
+ /**
+ * Returns the hash code value for this Join.
+ *
+ * @return a hash code value for this object.
+ */
+ public int hashCode()
+ {
+ int result = 16;
+ result = 37 * result + offset;
+ result = 37 * result + limit;
+ result = 37 * result + (ignoreCase ? 0 : 1);
+ result = 37 * result + (singleRecord ? 0 : 1);
+ result = 37 * result + (cascade ? 0 : 1);
+ result = 37 * result + dbName.hashCode();
+ result = 37 * result + selectModifiers.hashCode();
+ result = 37 * result + selectColumns.hashCode();
+ result = 37 * result + orderByColumns.hashCode();
+ result = 37 * result + (aliases == null ? 0 : aliases.hashCode());
+ result = 37 * result + asColumns.hashCode();
+ result = 37 * result + joins.hashCode();
+ result = 37 * result + super.hashCode();
+ return result;
+ }
+
/*
* ------------------------------------------------------------------------
*
@@ -3000,11 +3044,90 @@
}
/**
- * This is an inner class that describes an object in the
- * criteria.
+ * Serializes this Criteria.
+ *
+ * @param s The output stream.
+ * @throws IOException if an IO error occurs.
+ */
+ private void writeObject(ObjectOutputStream s) throws IOException
+ {
+ s.defaultWriteObject();
+
+ // Joins need to be serialized manually.
+ ArrayList serializableJoins = null;
+ if (joins != null && joins.size() > 0)
+ {
+ serializableJoins = new ArrayList(joins.size());
+
+ for (Iterator jonisIter = joins.iterator(); jonisIter.hasNext();)
+ {
+ Join join = (Join) jonisIter.next();
+
+ ArrayList joinContent = new ArrayList(3);
+ joinContent.add(join.getLeftColumn());
+ joinContent.add(join.getRightColumn());
+ joinContent.add(join.getJoinType());
+
+ serializableJoins.add(joinContent);
+ }
+ }
+
+ s.writeObject(serializableJoins);
+ }
+
+ /**
+ * Deserialize a Criteria.
+ *
+ * @param s The input stream.
+ * @throws IOException if an IO error occurs.
+ * @throws ClassNotFoundException if the class cannot be located.
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ s.defaultReadObject();
+
+ // Criteria.put() differs somewhat from Hashtable.put().
+ // This necessitates some corrective behavior upon deserialization.
+ for (Iterator iter = keySet().iterator(); iter.hasNext();)
+ {
+ Object key = iter.next();
+ Object value = get(key);
+ if (value instanceof Criteria.Criterion)
+ {
+ super.put(key, value);
+ }
+ }
+
+ // Joins need to be deserialized manually.
+ ArrayList joins = (ArrayList) s.readObject();
+ if (joins != null)
+ {
+ for (int i = 0; i < joins.size(); i++)
+ {
+ ArrayList joinContent = (ArrayList) joins.get(i);
+
+ String leftColumn = (String) joinContent.get(0);
+ String rightColumn = (String) joinContent.get(1);
+ SqlEnum joinType = null;
+ Object joinTypeObj = joinContent.get(2);
+ if (joinTypeObj != null)
+ {
+ joinType = (SqlEnum) joinTypeObj;
+ }
+ addJoin(leftColumn, rightColumn, joinType);
+ }
+ }
+ }
+
+ /**
+ * This is an inner class that describes an object in the criteria.
*/
public final class Criterion implements Serializable
{
+ /** Serial version. */
+ private static final long serialVersionUID = 7157097965404611710L;
+
public static final String AND = " AND ";
public static final String OR = " OR ";
@@ -3449,7 +3572,7 @@
}
/**
- * This method checks another Criteria to see if they contain
+ * This method checks another Criteria.Criterion to see if they contain
* the same attributes and hashtable entries.
*/
public boolean equals(Object obj)
@@ -3589,7 +3712,7 @@
}
}
}
- }
+ } // end of inner class Criterion
/**
* Data object to describe a join between two tables, for example
@@ -3675,5 +3798,43 @@
return result.toString();
}
+
+ /**
+ * This method checks another Criteria.Join to see if they contain the
+ * same attributes.
+ */
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+
+ if ((obj == null) || !(obj instanceof Join))
+ {
+ return false;
+ }
+
+ Join join = (Join) obj;
+
+ return ObjectUtils.equals(leftColumn, join.getLeftColumn())
+ && ObjectUtils.equals(rightColumn, join.getRightColumn())
+ && ObjectUtils.equals(joinType, join.getJoinType());
+ }
+
+ /**
+ * Returns the hash code value for this Join.
+ *
+ * @return a hash code value for this object.
+ */
+ public int hashCode()
+ {
+ int result = 13;
+ result = 37 * result + leftColumn.hashCode();
+ result = 37 * result + rightColumn.hashCode();
+ result = 37 * result + (null == joinType ? 0 : joinType.hashCode());
+ return result;
+ }
+
} // end of inner class Join
}
Modified: db/torque/runtime/trunk/src/test/org/apache/torque/util/CriteriaTest.java
URL: http://svn.apache.org/viewcvs/db/torque/runtime/trunk/src/test/org/apache/torque/util/CriteriaTest.java?rev=332758&r1=332757&r2=332758&view=diff
==============================================================================
--- db/torque/runtime/trunk/src/test/org/apache/torque/util/CriteriaTest.java (original)
+++ db/torque/runtime/trunk/src/test/org/apache/torque/util/CriteriaTest.java Sat Nov 12 03:15:21 2005
@@ -19,19 +19,23 @@
import java.util.Calendar;
import java.util.Date;
import java.util.List;
+import java.util.Map;
import org.apache.commons.configuration.BaseConfiguration;
import org.apache.commons.configuration.Configuration;
-
+import org.apache.commons.lang.SerializationUtils;
import org.apache.torque.BaseTestCase;
import org.apache.torque.TorqueException;
import org.apache.torque.adapter.DBFactory;
+import org.apache.torque.util.Criteria.Criterion;
+import org.apache.torque.util.Criteria.Join;
/**
* Test class for Criteria.
*
* @author <a href="mailto:celkins@scardini.com">Christopher Elkins</a>
* @author <a href="mailto:sam@neurogrid.com">Sam Joseph</a>
+ * @author <a href="mailto:seade@backstagetech.com.au">Scott Eade</a>
* @version $Id$
*/
public class CriteriaTest extends BaseTestCase
@@ -483,29 +487,94 @@
assertTrue(result.equals(firstExpect) || result.equals(secondExpect));
}
-// /**
-// * Very basic test that serialization works.
-// */
-// public void testSerialization()
-// {
-// // Hashtable works:
-// Hashtable h = new Hashtable();
-// h.put("Author.NAME", "author");
-// Hashtable hClone = (Hashtable) SerializationUtils.clone(h);
-// assertEquals(h, hClone);
-//
-// // Criterion works (even though Bloch strongly recommends against inner
-// // classes implementing Serializable):
-// Criterion cn = c.new Criterion("Author.NAME", "author");
-// Criterion cnClone = (Criterion) SerializationUtils.clone(cn);
-// assertEquals(cn, cnClone);
-//
-// // Criteria DOES NOT WORK - i.e. it isn't actually Serializable at present.
-// // http://mail-archives.apache.org/mod_mbox/db-torque-dev/200404.mbox/%3CF4DFE8EDB932F641A9407CFB5CA599C3F17DF1@e2kmtl1.internal.sungard.corp%3E
-// c.add("Author.NAME", "author");
-// Criteria cClone = (Criteria) SerializationUtils.clone(c);
-// assertEquals(c, cClone);
-// }
+ /**
+ * Test that serialization works.
+ */
+ public void testSerialization()
+ {
+ c.setOffset(10);
+ c.setLimit(11);
+ c.setIgnoreCase(true);
+ c.setSingleRecord(true);
+ c.setCascade(true);
+ c.setDbName("myDB");
+ c.setAll();
+ c.setDistinct();
+ c.addSelectColumn("Author.NAME");
+ c.addSelectColumn("Author.AUTHOR_ID");
+ c.addDescendingOrderByColumn("Author.NAME");
+ c.addAscendingOrderByColumn("Author.AUTHOR_ID");
+ c.addAlias("Writer", "Author");
+ c.addAsColumn("AUTHOR_NAME", "Author.NAME");
+ c.addJoin("Author.AUTHOR_ID", "Book.AUTHOR_ID", Criteria.INNER_JOIN);
+ c.add("Author.NAME", (Object) "author%", Criteria.LIKE);
+
+ // Some direct Criterion checks
+ Criterion cn = c.getCriterion("Author.NAME");
+ cn.setIgnoreCase(true);
+ assertEquals("author%", cn.getValue());
+ assertEquals(Criteria.LIKE, cn.getComparison());
+ Criterion cnDirectClone = (Criterion) SerializationUtils.clone(cn);
+ assertEquals(cn, cnDirectClone);
+
+ // Clone the object
+ Criteria cClone = (Criteria) SerializationUtils.clone(c);
+
+ // Check the clone
+ assertEquals(c.size(), cClone.size());
+ assertEquals(10, cClone.getOffset());
+ assertEquals(c.getOffset(), cClone.getOffset());
+ assertEquals(11, cClone.getLimit());
+ assertEquals(c.getLimit(), cClone.getLimit());
+ assertEquals(true, cClone.isIgnoreCase());
+ assertEquals(c.isIgnoreCase(), cClone.isIgnoreCase());
+ assertEquals(true, cClone.isSingleRecord());
+ assertEquals(c.isSingleRecord(), cClone.isSingleRecord());
+ assertEquals(true, cClone.isCascade());
+ assertEquals(c.isCascade(), cClone.isCascade());
+ assertEquals("myDB", cClone.getDbName());
+ assertEquals(c.getDbName(), cClone.getDbName());
+ List selectModifiersClone = cClone.getSelectModifiers();
+ assertTrue(selectModifiersClone.contains(Criteria.ALL.toString()));
+ assertTrue(selectModifiersClone.contains(Criteria.DISTINCT.toString()));
+ assertEquals(c.getSelectModifiers(), cClone.getSelectModifiers());
+ List selectColumnsClone = cClone.getSelectColumns();
+ assertTrue(selectColumnsClone.contains("Author.NAME"));
+ assertTrue(selectColumnsClone.contains("Author.AUTHOR_ID"));
+ assertEquals(c.getSelectColumns(), cClone.getSelectColumns());
+ List orderByColumnsClone = cClone.getOrderByColumns();
+ assertTrue(orderByColumnsClone.contains("Author.NAME DESC"));
+ assertTrue(orderByColumnsClone.contains("Author.AUTHOR_ID ASC"));
+ assertEquals(c.getOrderByColumns(), cClone.getOrderByColumns());
+ Map aliasesClone = cClone.getAliases();
+ assertTrue(aliasesClone.containsKey("Writer"));
+ assertEquals("Author", aliasesClone.get("Writer"));
+ assertEquals(c.getAliases(), cClone.getAliases());
+ Map asColumnsClone = cClone.getAsColumns();
+ assertTrue(asColumnsClone.containsKey("AUTHOR_NAME"));
+ assertEquals("Author.NAME", asColumnsClone.get("AUTHOR_NAME"));
+ assertEquals(c.getAsColumns(), cClone.getAsColumns());
+
+ // Check Joins
+ List joinsClone = cClone.getJoins();
+ Join joinClone = (Join) joinsClone.get(0);
+ assertEquals("Author.AUTHOR_ID", joinClone.getLeftColumn());
+ assertEquals("Book.AUTHOR_ID", joinClone.getRightColumn());
+ assertEquals(Criteria.INNER_JOIN, joinClone.getJoinType());
+ assertEquals(c.getJoins(), cClone.getJoins());
+
+ // Some Criterion checks
+ Criterion cnClone = cClone.getCriterion("Author.NAME");
+ assertEquals("author%", cnClone.getValue());
+ assertEquals(Criteria.LIKE, cnClone.getComparison());
+ assertEquals(cn.isIgnoreCase(), cnClone.isIgnoreCase());
+
+ // Confirm that equals() checks all of the above.
+ assertEquals(c, cClone);
+
+ // Check hashCode() too.
+ assertEquals(c.hashCode(), cClone.hashCode());
+ }
/**
* test for TRQS25
Modified: db/torque/runtime/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewcvs/db/torque/runtime/trunk/xdocs/changes.xml?rev=332758&r1=332757&r2=332758&view=diff
==============================================================================
--- db/torque/runtime/trunk/xdocs/changes.xml (original)
+++ db/torque/runtime/trunk/xdocs/changes.xml Sat Nov 12 03:15:21 2005
@@ -26,6 +26,11 @@
<body>
<release version="3.2-rc3-dev" date="in SVN">
+ <action type="fix" dev="seade">
+ Corrected serialization of Criteria objects. While there also fixed
+ equals() and added hashCode().
+ Thanks to Martin Goulet for a very early version of the serialization fix.
+ </action>
<action type="add" dev="tfischer">
Added scale (i.e number of digits after the decimal point) support
for the sql data types NUMERIC and DECIMAL in the JDBCTransformTask
---------------------------------------------------------------------
To unsubscribe, e-mail: torque-dev-unsubscribe@db.apache.org
For additional commands, e-mail: torque-dev-help@db.apache.org