Author: max...@jb... Date: 2006-05-02 07:07:06 -0400 (Tue, 02 May 2006) New Revision: 9850 Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashEquals.hbm.xml trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashcodeEqualsTest.java trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Group.java trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/ManyToManyTest.java trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/User.java trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/UserGroup.hbm.xml Modified: trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/pojo/BasicPOJOClass.java Log: HBX-652 generated equals method doesn't work with byte[] + Initial many-to-many tests Modified: trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/pojo/BasicPOJOClass.java =================================================================== --- trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/pojo/BasicPOJOClass.java 2006-05-02 11:06:09 UTC (rev 9849) +++ trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/pojo/BasicPOJOClass.java 2006-05-02 11:07:06 UTC (rev 9850) @@ -251,10 +251,12 @@ else { if(useCompareTo( typeName )) { return "( (" + lh + "==" + rh + ") || ( " + lh + "!=null && " + rh + "!=null && " + lh + ".compareTo(" + rh + ")==0 ) )"; - } else if ( c2j.isArray( typeName ) ) { - return "( java.util.Arrays.equals(" + lh + "," + rh + ") )"; } else { - return "( (" + lh + "==" + rh + ") || ( " + lh + "!=null && " + rh + "!=null && " + lh + ".equals(" + rh + ") ) )"; + if(typeName.endsWith("[]")) { + return "( (" + lh + "==" + rh + ") || ( " + lh + "!=null && " + rh + "!=null && " + importType("java.util.Arrays") + ".equals(" + lh + ", " + rh + ") ) )"; + } else { + return "( (" + lh + "==" + rh + ") || ( " + lh + "!=null && " + rh + "!=null && " + lh + ".equals(" + rh + ") ) )"; + } } } @@ -568,32 +570,16 @@ } } - public String generateHashCode(Property property, String result, String thisName, boolean useGenerics) { + public String generateHashCode(Property property, String result, String thisName, boolean jdk5) { StringBuffer buf = new StringBuffer(); if ( c2j.getMetaAsBool( property, "use-in-equals" ) ) { - String javaTypeName = c2j.getJavaTypeName( property, useGenerics, this ); + String javaTypeName = c2j.getJavaTypeName( property, jdk5, this ); boolean isPrimitive = c2j.isPrimitive( javaTypeName ); - if ( !isPrimitive ) { + if ( isPrimitive ) { buf.append( result ) .append( " = 37 * " ) .append( result ) .append( " + " ); - buf.append( "( " ) - .append( getGetterSignature( property ) ) - .append( "() == null ? 0 : " ) - .append( thisName ) - .append( "." ) - .append( getGetterSignature( property ) ) - .append( "()" ) - .append( ".hashCode()" ) - .append( " )" ) - .append(";"); - } - else { - buf.append( result ) - .append( " = 37 * " ) - .append( result ) - .append( " + " ); String thisValue = thisName + "." + getGetterSignature( property ) + "()"; if("char".equals(javaTypeName)||"int".equals(javaTypeName)||"short".equals(javaTypeName)||"byte".equals(javaTypeName)) { buf.append( thisValue ); @@ -605,10 +591,170 @@ } buf.append(";"); } + else { + if(javaTypeName.endsWith("[]")) { + if(jdk5) { + buf.append( result ) + .append( " = 37 * " ) + .append( result ) + .append( " + " ); + buf.append( "( " ) + .append( getGetterSignature( property ) ) + .append( "() == null ? 0 : " + importType("java.util.Arrays") + ".hashCode(" ) + .append( thisName ) + .append( "." ) + .append( getGetterSignature( property ) ) + .append( "())" ) + .append( " )" ) + .append(";"); + } + else { + buf.append(internalGenerateArrayHashcode(property, javaTypeName, result, thisName)); + } + } else { + buf.append( result ) + .append( " = 37 * " ) + .append( result ) + .append( " + " ); + buf.append( "( " ) + .append( getGetterSignature( property ) ) + .append( "() == null ? 0 : " ) + .append( thisName ) + .append( "." ) + .append( getGetterSignature( property ) ) + .append( "()" ) + .append( ".hashCode()" ) + .append( " )" ) + .append(";"); + } + } } return buf.toString(); } + + private String internalGenerateArrayHashcode(Property property, String javaTypeName, String result, String thisName) + { + StringBuffer buf = new StringBuffer(); + + String propertyHashVarName = property.getName() + "Hashcode"; + String propertyArrayName = property.getName() + "Property"; + +// int propertyHash = 0; + buf.append( "int ") + .append( propertyHashVarName ) + .append( " = 0;\n" ); + +// type[] proterty = getProperty(); + buf.append( " " ) + .append( javaTypeName ) + .append( " " ) + .append( propertyArrayName ) + .append( " = " ) + .append( thisName ) + .append( "." ) + .append( getGetterSignature( property ) ) + .append( "();\n"); + +// if(property != null) { + buf.append( " if(" ) + .append( propertyArrayName ) + .append( " != null) {\n" ); + +// propertyHash = 1; + buf.append( " " ) + .append( propertyHashVarName ) + .append( " = 1;\n" ); + +// for (int i=0; i<property.length; i++) + String elementType = javaTypeName.replaceAll("\\[\\]", ""); + buf.append( " for (int i=0; i<" ) + .append( propertyArrayName ) + .append( ".length; i++) {\n" ); + + if(javaTypeName.startsWith("long")) { +// int elementHash = (int)(propertyArray[i] ^ (propertyArray[i] >>> 32)); + buf.append( " int elementHash = (int)(" ) + .append( propertyArrayName ) + .append( "[i] ^ (" ) + .append( propertyArrayName ) + .append( "[i] >>> 32));\n" ); + +// propertyHash = 37 * propertyHash + elementHash; + buf.append( " " ) + .append( propertyHashVarName ) + .append( " = 37 * " ) + .append( propertyHashVarName ) + .append( " + elementHash;\n" ); + } else if(javaTypeName.startsWith("boolean")) { +// propertyHash = 37 * propertyHash + (propertyArray[i] ? 1231 : 1237); + buf.append( " " ) + .append( propertyHashVarName ) + .append( " = 37 * " ) + .append( propertyHashVarName ) + .append( " + (" ) + .append( propertyArrayName ) + .append( "[i] ? 1231 : 1237);\n" ); + } else if(javaTypeName.startsWith("float")) { +// propertyHash = 37 * propertyHash + Float.floatToIntBits(propertyArray[i]); + buf.append( " " ) + .append( propertyHashVarName ) + .append( " = 37 * " ) + .append( propertyHashVarName ) + .append( " + Float.floatToIntBits(" ) + .append( propertyArrayName ) + .append( "[i]);\n" ); + } else if(javaTypeName.startsWith("double")) { +// long bits = Double.doubleToLongBits(propertyArray[i]); + buf.append( " long bits = Double.doubleToLongBits(" ) + .append( propertyArrayName ) + .append( "[i]);\n" ); + +// propertyHash = 37 * propertyHash + (int)(bits ^ (bits >>> 32)); + buf.append( " " ) + .append( propertyHashVarName ) + .append( " = 37 * " ) + .append( propertyHashVarName ) + .append( " + (int)(bits ^ (bits >>> 32));\n" ); + } else if(javaTypeName.startsWith("int") + || javaTypeName.startsWith("short") + || javaTypeName.startsWith("char") + || javaTypeName.startsWith("byte")) { +// propertyHash = 37 * propertyHash + propertyArray[i]; + buf.append( " " ) + .append( propertyHashVarName ) + .append( " = 37 * " ) + .append( propertyHashVarName ) + .append( " + " ) + .append( propertyArrayName ) + .append( "[i];\n" ); + } else {// Object[] +// propertyHash = 37 * propertyHash + propertyArray[i].hashCode(); + buf.append( " " ) + .append( propertyHashVarName ) + .append( " = 37 * " ) + .append( propertyHashVarName ) + .append( " + " ) + .append( propertyArrayName ) + .append( "[i].hashCode();\n" ); + } + + buf.append( " }\n" ); + buf.append( " }\n\n" ); + +// result = 37 * result + arrayHashcode; + buf.append( " " ) + .append( result ) + .append( " = 37 * " ) + .append( result ) + .append( " + " ) + .append( propertyHashVarName ) + .append( ";\n" ); + + return buf.toString(); + } + + public String getFieldModifiers(Property property) { return getModifiers( property, "scope-field", "private" ); } Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashEquals.hbm.xml =================================================================== --- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashEquals.hbm.xml 2006-05-02 11:06:09 UTC (rev 9849) +++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashEquals.hbm.xml 2006-05-02 11:07:06 UTC (rev 9850) @@ -0,0 +1,55 @@ +<?xml version="1.0"?> +<!DOCTYPE hibernate-mapping PUBLIC + "-//Hibernate/Hibernate Mapping DTD 3.0//EN" + "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> + +<!-- + + This mapping demonstrates how to map a collection + <key> to one of the primary key columns of an + associated child class with a composite key. This + is very useful for legacy data! + +--> + +<hibernate-mapping package="org.hibernate.tool.hbm2x"> + + <class name="HashEquals"> + <!-- Normally *bad* practice to put global use-in-equals. Only here for testing --> + <meta attribute="use-in-equals">true</meta> + <id name="id" type="string"/> + + <property name="name" type="java.lang.String[]"/> + <property name="byteArray" type="byte[]"/> + <property name="floatArray" type="float[]"/> + <property name="intArray" type="int[]"/> + <property name="shortArray" type="int[]"/> + <property name="booleanArray" type="boolean[]"/> + + <component name="addressComponent" class="Address"> + <property name="streetAddress1" type="string" + column="StreetAddress1" not-null="true"> + <meta attribute="use-in-equals">true</meta> + </property> + <property name="streetAddress2" type="string" + column="StreetAddress2" /> + <property name="city" type="short" column="City" + not-null="true"> + <meta attribute="use-in-tostring">true</meta> + <meta attribute="use-in-equals">true</meta> + <meta attribute="property-type">short</meta> + </property> + <property name="postcode" type="java.lang.String[]" column="postcode" + not-null="true" /> + <!-- <many-to-one name="state" class="au.com.groupware.model.State" column="StateId" + foreign-key="FK_Address_State" not-null="true" /> --> + <property name="verified" type="boolean"> + <meta attribute="use-in-equals">true</meta> + </property> + </component> + + + </class> + + +</hibernate-mapping> Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashcodeEqualsTest.java =================================================================== --- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashcodeEqualsTest.java 2006-05-02 11:06:09 UTC (rev 9849) +++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/HashcodeEqualsTest.java 2006-05-02 11:07:06 UTC (rev 9850) @@ -0,0 +1,112 @@ +/* + * Created on 2004-12-01 + * + */ +package org.hibernate.tool.hbm2x; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.hibernate.mapping.Component; +import org.hibernate.mapping.MetaAttribute; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.mapping.Property; +import org.hibernate.mapping.RootClass; +import org.hibernate.mapping.SingleTableSubclass; +import org.hibernate.mapping.Value; +import org.hibernate.tool.NonReflectiveTestCase; +import org.hibernate.tool.hbm2x.pojo.BasicPOJOClass; +import org.hibernate.tool.hbm2x.pojo.ImportContext; +import org.hibernate.tool.hbm2x.pojo.ImportContextImpl; +import org.hibernate.tool.hbm2x.pojo.NoopImportContext; +import org.hibernate.tool.hbm2x.pojo.POJOClass; +import org.hibernate.tool.test.TestHelper; + +/** + * @author max + * + */ +public class HashcodeEqualsTest extends NonReflectiveTestCase { + + private ArtifactCollector artifactCollector; + + public HashcodeEqualsTest(String name) { + super( name, "hashcodeequals" ); + } + + protected void tearDown() throws Exception { + // TODO Auto-generated method stub + // super.tearDown(); + } + protected void setUp() throws Exception { + super.setUp(); + + Exporter exporter = new POJOExporter( getCfg(), getOutputDir() ); + artifactCollector = new ArtifactCollector(); + exporter.setArtifactCollector(artifactCollector); + exporter.start(); + } + + + public void testJDK5FailureExpectedOnJDK4() { + + POJOExporter exporter = new POJOExporter( getCfg(), getOutputDir() ); + exporter.getProperties().setProperty("jdk5", "true"); + + artifactCollector = new ArtifactCollector(); + exporter.setArtifactCollector(artifactCollector); + exporter.start(); + + testFileExistence(); + testNoVelocityLeftOvers(); + testCompilable(); + + } + + + public void testFileExistence() { + + assertFileAndExists( new File( getOutputDir(), + "org/hibernate/tool/hbm2x/HashEquals.java" ) ); + assertFileAndExists( new File( getOutputDir(), + "org/hibernate/tool/hbm2x/Address.java" ) ); + + assertEquals(2, artifactCollector.getFileCount("java")); + } + + public void testCompilable() { + + File file = new File( "compilable" ); + file.mkdir(); + + ArrayList list = new ArrayList(); + TestHelper.compile( getOutputDir(), file, TestHelper.visitAllFiles( + getOutputDir(), list ) ); + + TestHelper.deleteDir( file ); + } + + + + public void testNoVelocityLeftOvers() { + + assertEquals( null, findFirstString( "$", new File( getOutputDir(), + "org/hibernate/tool/hbm2x/HashEquals.java" ) ) ); + assertEquals( null, findFirstString( "$", new File( getOutputDir(), + "org/hibernate/tool/hbm2x/Address.java" ) ) ); + + } + + protected String getBaseForMappings() { + return "org/hibernate/tool/hbm2x/"; + } + + protected String[] getMappings() { + return new String[] { "HashEquals.hbm.xml" }; + } + +} Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Group.java =================================================================== --- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Group.java 2006-05-02 11:06:09 UTC (rev 9849) +++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Group.java 2006-05-02 11:07:06 UTC (rev 9850) @@ -0,0 +1,56 @@ +//$Id: Group.java 7085 2005-06-08 17:59:47Z oneovthafew $ +package org.hibernate.tool.hbm2x.hbm2hbmxml; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +public class Group implements Serializable { + + private String org; + private String name; + private String description; + + private Set users = new HashSet(); + + public Group(String name, String org) { + this.org = org; + this.name = name; + } + + public Group() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getOrg() { + return org; + } + + public void setOrg(String org) { + this.org = org; + } + + public Set getUsers() { + return users; + } + + public void setUsers(Set users) { + this.users = users; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/ManyToManyTest.java =================================================================== --- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/ManyToManyTest.java 2006-05-02 11:06:09 UTC (rev 9849) +++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/ManyToManyTest.java 2006-05-02 11:07:06 UTC (rev 9850) @@ -0,0 +1,86 @@ +//$Id$ + +/* + * Tests for generating the HBM documents from the Configuration data structure. + * The generated XML document will be validated and queried to make sure the + * basic structure is correct in each test. + */ +package org.hibernate.tool.hbm2x.hbm2hbmxml; + +import java.io.File; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.dom4j.io.SAXReader; +import org.hibernate.cfg.Configuration; +import org.hibernate.tool.NonReflectiveTestCase; +import org.hibernate.tool.hbm2x.Exporter; +import org.hibernate.tool.hbm2x.HibernateMappingExporter; +import org.hibernate.util.DTDEntityResolver; + +public class ManyToManyTest extends NonReflectiveTestCase { + + private Exporter hbmexporter; + + public ManyToManyTest(String name) { + super( name, "cfg2hbmoutput" ); + } + + protected void setUp() throws Exception { + super.setUp(); + + hbmexporter = new HibernateMappingExporter(getCfg(), getOutputDir() ); + hbmexporter.start(); + } + + public void testAllFilesExistence() { + + assertFalse(new File(getOutputDir().getAbsolutePath() + "/GeneralHbmSettings.hbm.xml").exists() ); + assertFileAndExists(new File(getOutputDir().getAbsolutePath() + "/org/hibernate/tool/hbm2x/hbm2hbmxml/User.hbm.xml") ); + assertFileAndExists(new File(getOutputDir().getAbsolutePath() + "/org/hibernate/tool/hbm2x/hbm2hbmxml/Group.hbm.xml") ); + } + + public void testArtifactCollection() { + + assertEquals(2,hbmexporter.getArtifactCollector().getFileCount("hbm.xml")); + + } + + public void testReadable() { + Configuration cfg = new Configuration(); + + cfg.addFile(new File(getOutputDir(), getBaseForMappings() + "User.hbm.xml")); + cfg.addFile(new File(getOutputDir(), getBaseForMappings() + "Group.hbm.xml")); + + cfg.buildMappings(); + + } + + protected void tearDown() throws Exception { + // TODO Auto-generated method stub + // super.tearDown(); + } + + private SAXReader getSAXReader() { + SAXReader xmlReader = new SAXReader(); + xmlReader.setEntityResolver(new DTDEntityResolver() ); + xmlReader.setValidation(true); + return xmlReader; + } + + protected String getBaseForMappings() { + return "org/hibernate/tool/hbm2x/hbm2hbmxml/"; + } + + protected String[] getMappings() { + return new String[] { + "UserGroup.hbm.xml" + }; + } + + public static Test suite() { + return new TestSuite(ManyToManyTest.class); + } + +} Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/User.java =================================================================== --- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/User.java 2006-05-02 11:06:09 UTC (rev 9849) +++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/User.java 2006-05-02 11:07:06 UTC (rev 9850) @@ -0,0 +1,46 @@ +//$Id: User.java 7085 2005-06-08 17:59:47Z oneovthafew $ +package org.hibernate.tool.hbm2x.hbm2hbmxml; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +public class User implements Serializable { + + private String org; + private String name; + private Set groups = new HashSet(); + + public User(String name, String org) { + this.org = org; + this.name = name; + } + + public User() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getOrg() { + return org; + } + + public void setOrg(String org) { + this.org = org; + } + + public Set getGroups() { + return groups; + } + + public void setGroups(Set groups) { + this.groups = groups; + } + +} Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/UserGroup.hbm.xml =================================================================== --- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/UserGroup.hbm.xml 2006-05-02 11:06:09 UTC (rev 9849) +++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/UserGroup.hbm.xml 2006-05-02 11:07:06 UTC (rev 9850) @@ -0,0 +1,52 @@ +<?xml version="1.0"?> +<!DOCTYPE hibernate-mapping PUBLIC + "-//Hibernate/Hibernate Mapping DTD 3.0//EN" + "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> + +<!-- + + This mapping demonstrates how to map a many-to-many + association with a shared attribute in the primary keys + of the associated entities. + +--> + +<hibernate-mapping + package="org.hibernate.tool.hbm2x.hbm2hbmxml"> + + <class name="User" table="`User`"> + <composite-id> + <key-property name="name"/> + <key-property name="org"/> + </composite-id> + <set name="groups" table="UserGroup"> + <key> + <column name="userName"/> + <column name="org"/> + </key> + <many-to-many class="Group"> + <column name="groupName"/> + <formula>org</formula> + </many-to-many> + </set> + </class> + + <class name="Group" table="`Group`"> + <composite-id> + <key-property name="name"/> + <key-property name="org"/> + </composite-id> + <property name="description"/> + <set name="users" table="UserGroup" inverse="true"> + <key> + <column name="groupName"/> + <column name="org"/> + </key> + <many-to-many class="User"> + <column name="userName"/> + <formula>org</formula> + </many-to-many> + </set> + </class> + +</hibernate-mapping> |