You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(22) |
Nov
(308) |
Dec
(131) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(369) |
Feb
(171) |
Mar
(236) |
Apr
(187) |
May
(218) |
Jun
(217) |
Jul
(127) |
Aug
(448) |
Sep
(270) |
Oct
(231) |
Nov
(422) |
Dec
(255) |
2004 |
Jan
(111) |
Feb
(73) |
Mar
(338) |
Apr
(351) |
May
(349) |
Jun
(495) |
Jul
(394) |
Aug
(1048) |
Sep
(499) |
Oct
(142) |
Nov
(269) |
Dec
(638) |
2005 |
Jan
(825) |
Feb
(1272) |
Mar
(593) |
Apr
(690) |
May
(950) |
Jun
(958) |
Jul
(767) |
Aug
(839) |
Sep
(525) |
Oct
(449) |
Nov
(585) |
Dec
(455) |
2006 |
Jan
(603) |
Feb
(656) |
Mar
(195) |
Apr
(114) |
May
(136) |
Jun
(100) |
Jul
(128) |
Aug
(68) |
Sep
(7) |
Oct
(1) |
Nov
(1) |
Dec
(8) |
2007 |
Jan
(4) |
Feb
(3) |
Mar
(8) |
Apr
(16) |
May
(5) |
Jun
(4) |
Jul
(6) |
Aug
(23) |
Sep
(15) |
Oct
(5) |
Nov
(7) |
Dec
(5) |
2008 |
Jan
(5) |
Feb
(1) |
Mar
(1) |
Apr
(5) |
May
(1) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2012 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
(1) |
Jul
(1) |
Aug
(1) |
Sep
|
Oct
(2) |
Nov
(3) |
Dec
(2) |
2013 |
Jan
(1) |
Feb
|
Mar
(2) |
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(2) |
Jun
(1) |
Jul
|
Aug
(1) |
Sep
(1) |
Oct
|
Nov
(1) |
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2017 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <max...@us...> - 2006-02-14 10:12:16
|
Update of /cvsroot/hibernate/HibernateExt/tools/src/templates/hbm In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30826/src/templates/hbm Modified Files: persistentclass.hbm.ftl column.hbm.ftl Log Message: HBX-594 Use database table comments when generating hbm.xml Index: persistentclass.hbm.ftl =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/tools/src/templates/hbm/persistentclass.hbm.ftl,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- persistentclass.hbm.ftl 7 Feb 2006 14:02:15 -0000 1.3 +++ persistentclass.hbm.ftl 14 Feb 2006 10:11:54 -0000 1.4 @@ -57,7 +57,9 @@ <#if clazz.table.rowId?exists> rowid="${clazz.table.rowId}" </#if>> - +<#if clazz.table.comment?exists> + <comment>${clazz.table.comment}</comment> +</#if> <#-- TODO: move this to id.hbm.ftl --> <#if clazz.hasIdentifierProperty()> <#assign property=clazz.getIdentifierProperty()/> Index: column.hbm.ftl =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/tools/src/templates/hbm/column.hbm.ftl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- column.hbm.ftl 6 Feb 2006 09:08:07 -0000 1.2 +++ column.hbm.ftl 14 Feb 2006 10:11:54 -0000 1.3 @@ -1,5 +1,11 @@ <#if column.isFormula()> <formula>${column.formula}</formula> <#else> -<column name="${column.quotedName}" ${c2h.columnAttributes(column)}/> +<column name="${column.quotedName}" ${c2h.columnAttributes(column)} +<#if column.comment?exists>> + <comment>${column.comment}</comment> +</column> +<#else> +/> +</#if> </#if> \ No newline at end of file |
From: <max...@us...> - 2006-02-14 10:12:15
|
Update of /cvsroot/hibernate/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30826/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml Modified Files: Hbm2HbmXmlTest.java ClassFullAttribute.hbm.xml Log Message: HBX-594 Use database table comments when generating hbm.xml Index: Hbm2HbmXmlTest.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Hbm2HbmXmlTest.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- Hbm2HbmXmlTest.java 26 Jan 2006 12:07:39 -0000 1.1 +++ Hbm2HbmXmlTest.java 14 Feb 2006 10:11:54 -0000 1.2 @@ -15,8 +15,10 @@ import org.dom4j.Attribute; import org.dom4j.Document; +import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; +import org.dom4j.Node; import org.dom4j.XPath; import org.dom4j.io.SAXReader; import org.hibernate.mapping.PersistentClass; @@ -119,6 +121,50 @@ } + public void testComments() throws DocumentException { + File outputXml = new File(getOutputDir().getAbsolutePath() + "/org/hibernate/tool/hbm2x/hbm2hbmxml/ClassFullAttribute.hbm.xml"); + assertFileAndExists(outputXml); + + SAXReader xmlReader = this.getSAXReader(); + + Document document = xmlReader.read(outputXml); + Element root = document.getRootElement(); + + XPath xpath = DocumentHelper.createXPath("//hibernate-mapping/class/comment"); + List list = xpath.selectNodes(document); + assertEquals("Expected to get one comment element", 1, list.size()); + Node node = (Node) list.get(0); + assertEquals(node.getText(),"A comment for ClassFullAttribute"); + + xpath = DocumentHelper.createXPath("//hibernate-mapping/class/property/column/comment"); + list = xpath.selectNodes(document); + assertEquals("Expected to get one comment element", 1, list.size()); + node = (Node) list.get(0); + assertEquals(node.getText(),"columnd comment"); + + + } + + public void testNoComments() throws DocumentException { + File outputXml = new File(getOutputDir().getAbsolutePath() + "/org/hibernate/tool/hbm2x/hbm2hbmxml/Basic.hbm.xml"); + assertFileAndExists(outputXml); + + SAXReader xmlReader = this.getSAXReader(); + + Document document = xmlReader.read(outputXml); + Element root = document.getRootElement(); + + XPath xpath = DocumentHelper.createXPath("//hibernate-mapping/class/comment"); + List list = xpath.selectNodes(document); + assertEquals("Expected to get no comment element", list.size(), 0); + + xpath = DocumentHelper.createXPath("//hibernate-mapping/class/property/column/comment"); + list = xpath.selectNodes(document); + assertEquals("Expected to get no comment element", 0, list.size()); + + + } + /** * Special test for external Global settings were generated. * Test Access and Cacade setting but they are default values Index: ClassFullAttribute.hbm.xml =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/ClassFullAttribute.hbm.xml,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- ClassFullAttribute.hbm.xml 27 Sep 2005 07:35:45 -0000 1.1 +++ ClassFullAttribute.hbm.xml 14 Feb 2006 10:11:54 -0000 1.2 @@ -28,7 +28,7 @@ persister="org.hibernate.tool.hbm2x.hbm2hbmxml.mypersister" rowid="rowid" > - + <comment>A comment for ClassFullAttribute</comment> <id name="basicId" length="10" type="string" @@ -54,7 +54,9 @@ <property name="columnDetails" type="string" > - <column name="columnd" length="200" not-null="true" sql-type="varchar(200)" unique="true" /> + <column name="columnd" length="200" not-null="true" sql-type="varchar(200)" unique="true" > + <comment>columnd comment</comment> + </column> </property> <property name="vitualValue" |
From: <max...@us...> - 2006-02-14 09:48:07
|
Update of /cvsroot/hibernate/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23898/src/java/org/hibernate/tool/hbm2x Modified Files: Cfg2HbmTool.java Log Message: fix missing spaces in hbm.xml generation Index: Cfg2HbmTool.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/Cfg2HbmTool.java,v retrieving revision 1.28 retrieving revision 1.29 diff -u -d -r1.28 -r1.29 --- Cfg2HbmTool.java 25 Jan 2006 15:59:28 -0000 1.28 +++ Cfg2HbmTool.java 14 Feb 2006 09:47:54 -0000 1.29 @@ -214,10 +214,10 @@ } if (!isPrimaryKeyColumn) { if (!column.isNullable() ) { - sb.append("not-null=\"true\""); + sb.append("not-null=\"true\" "); } if (column.isUnique() ) { - sb.append("unique=\"true\""); + sb.append("unique=\"true\" "); } } if (column.getSqlType() != null) { |
From: <ste...@us...> - 2006-02-14 03:24:26
|
Update of /cvsroot/hibernate/Hibernate3/test/org/hibernate/test/ejb3/lock In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10165/test/org/hibernate/test/ejb3/lock Added Files: EJB3LockTest.java RepeatableReadTest.java Log Message: HHH-1416 & HHH-1421 : EJB3 LockModeTypes --- NEW FILE: EJB3LockTest.java --- package org.hibernate.test.ejb3.lock; import org.hibernate.test.TestCase; import org.hibernate.test.ejb3.Item; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.LockMode; import junit.framework.Test; import junit.framework.TestSuite; /** * Tests specifically relating to section 3.3.5.3 [Lock Modes] of the * EJB3 persistence specification (as of the <i>Proposed Final Draft</i>). * * @author Steve Ebersole */ public class EJB3LockTest extends TestCase { public EJB3LockTest(String name) { super( name ); } public static Test suite() { return new TestSuite( EJB3LockTest.class ); } protected String[] getMappings() { return new String[] { "ejb3/Item.hbm.xml", "ejb3/Part.hbm.xml" }; } public String getCacheConcurrencyStrategy() { // no second level caching return null; } protected void configure(Configuration cfg) { super.configure( cfg ); // error on Oracle 10g // cfg.setProperty( Environment.ISOLATION, "" + java.sql.Connection.TRANSACTION_READ_UNCOMMITTED ); cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" ); } /** * Test the equivalent of EJB3 LockModeType.READ * <p/> * From the spec: * <p/> * If transaction T1 calls lock(entity, LockModeType.READ) on a versioned object, the entity * manager must ensure that neither of the following phenomena can occur:<ul> * <li>P1 (Dirty read): Transaction T1 modifies a row. Another transaction T2 then reads that row and * obtains the modified value, before T1 has committed or rolled back. Transaction T2 eventually * commits successfully; it does not matter whether T1 commits or rolls back and whether it does * so before or after T2 commits. * <li>P2 (Non-repeatable read): Transaction T1 reads a row. Another transaction T2 then modifies or * deletes that row, before T1 has committed. Both transactions eventually commit successfully. * <p/> * This will generally be achieved by the entity manager acquiring a lock on the underlying database row. * Any such lock may be obtained immediately (so long as it is retained until commit completes), or the * lock may be deferred until commit time (although even then it must be retained until the commit completes). * Any implementation that supports repeatable reads in a way that prevents the above phenomena * is permissible. * <p/> * The persistence implementation is not required to support calling lock(entity, LockMode-Type.READ) * on a non-versioned object. When it cannot support such a lock call, it must throw the * PersistenceException. When supported, whether for versioned or non-versioned objects, LockMode-Type.READ * must always prevent the phenomena P1 and P2. Applications that call lock(entity, LockModeType.READ) * on non-versioned objects will not be portable. * <p/> * Odd as it may sound, EJB3 LockModeType.READ actually maps to the Hibernate LockMode.UPGRADE */ public void testLockModeTypeRead() { // todo : add some protections here for databases which have issues with concurrent access... final String initialName = "lock test"; // set up some test data Session s1 = getSessions().openSession(); Transaction t1 = s1.beginTransaction(); Item item = new Item(); item.setName( initialName ); s1.save( item ); t1.commit(); s1.close(); Long itemId = item.getId(); // perform the isolated update s1 = getSessions().openSession(); t1 = s1.beginTransaction(); item = ( Item ) s1.get( Item.class, itemId ); s1.lock( item, LockMode.UPGRADE ); item.setName( "updated" ); s1.flush(); Session s2 = getSessions().openSession(); Transaction t2 = s2.beginTransaction(); Item item2 = ( Item ) s2.get( Item.class, itemId ); assertEquals( "isolation not maintained", initialName, item2.getName() ); t1.commit(); s1.close(); item2 = ( Item ) s2.get( Item.class, itemId ); assertEquals( "repeatable read not maintained", initialName, item2.getName() ); t2.commit(); s2.close(); s1 = getSessions().openSession(); t1 = s1.beginTransaction(); s1.delete( item ); t1.commit(); s1.close(); } /** * Test the equivalent of EJB3 LockModeType.WRITE * <p/> * From the spec: * <p/> * If transaction T1 calls lock(entity, LockModeType.WRITE) on a versioned object, the entity * manager must avoid the phenomena P1 and P2 (as with LockModeType.READ) and must also force * an update (increment) to the entity's version column. A forced version update may be performed immediately, * or may be deferred until a flush or commit. If an entity is removed before a deferred version * update was to have been applied, the forced version update is omitted, since the underlying database * row no longer exists. * <p/> * The persistence implementation is not required to support calling lock(entity, LockMode-Type.WRITE) * on a non-versioned object. When it cannot support a such lock call, it must throw the * PersistenceException. When supported, whether for versioned or non-versioned objects, LockMode-Type.WRITE * must always prevent the phenomena P1 and P2. For non-versioned objects, whether or * not LockModeType.WRITE has any additional behaviour is vendor-specific. Applications that call * lock(entity, LockModeType.WRITE) on non-versioned objects will not be portable. * <p/> * Due to the requirement that LockModeType.WRITE needs to force a version increment, * a new Hibernate LockMode was added to support this behavior: {@link LockMode#FORCE}. */ public void testLockModeTypeWrite() { // todo : add some protections here for databases which have issues with concurrent access... final String initialName = "lock test"; // set up some test data Session s1 = getSessions().openSession(); Transaction t1 = s1.beginTransaction(); Item item = new Item(); item.setName( initialName ); s1.save( item ); t1.commit(); s1.close(); Long itemId = item.getId(); long initialVersion = item.getVersion(); s1 = getSessions().openSession(); t1 = s1.beginTransaction(); item = ( Item ) s1.get( Item.class, itemId ); s1.lock( item, LockMode.FORCE ); assertEquals( "no forced version increment", initialVersion + 1, item.getVersion() ); s1.lock( item, LockMode.FORCE ); assertEquals( "subsequent LockMode.FORCE did not no-op", initialVersion + 1, item.getVersion() ); Session s2 = getSessions().openSession(); Transaction t2 = s2.beginTransaction(); Item item2 = ( Item ) s2.get( Item.class, itemId ); assertEquals( "isolation not maintained", initialName, item2.getName() ); item.setName( "updated-1" ); s1.flush(); // currently an unfortunate side effect... assertEquals( initialVersion + 2, item.getVersion() ); t1.commit(); s1.close(); item2.setName( "updated" ); try { t2.commit(); fail( "optimisitc lock should have failed" ); } catch( Throwable ignore ) { // expected behavior t2.rollback(); } finally { s2.close(); } s1 = getSessions().openSession(); t1 = s1.beginTransaction(); s1.delete( item ); t1.commit(); s1.close(); } } --- NEW FILE: RepeatableReadTest.java --- package org.hibernate.test.ejb3.lock; import org.hibernate.test.TestCase; import org.hibernate.test.ejb3.Item; import org.hibernate.test.ejb3.Part; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.LockMode; import org.hibernate.StaleObjectStateException; import junit.framework.Test; import junit.framework.TestSuite; import java.math.BigDecimal; /** * Test that the Hibernate Session complies with REPEATABLE_READ isolation * semantics. * * @author Steve Ebersole */ public class RepeatableReadTest extends TestCase { public RepeatableReadTest(String name) { super( name ); } public static Test suite() { return new TestSuite( RepeatableReadTest.class ); } protected String[] getMappings() { return new String[] { "ejb3/Item.hbm.xml", "ejb3/Part.hbm.xml" }; } public String getCacheConcurrencyStrategy() { // no second level caching return null; } protected void configure(Configuration cfg) { super.configure( cfg ); // error on Oracle 10g // cfg.setProperty( Environment.ISOLATION, "" + java.sql.Connection.TRANSACTION_READ_UNCOMMITTED ); cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" ); } // versioned entity tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public void testStaleVersionedInstanceFoundInQueryResult() { String check = "EJB3 Specification"; Session s1 = getSessions().openSession(); Transaction t1 = s1.beginTransaction(); Item item = new Item( check ); s1.save( item ); t1.commit(); s1.close(); Long itemId = item.getId(); long initialVersion = item.getVersion(); // Now, open a new Session and re-load the item... s1 = getSessions().openSession(); t1 = s1.beginTransaction(); item = ( Item ) s1.get( Item.class, itemId ); // now that the item is associated with the persistence-context of that session, // open a new session and modify it "behind the back" of the first session Session s2 = getSessions().openSession(); Transaction t2 = s2.beginTransaction(); Item item2 = ( Item ) s2.get( Item.class, itemId ); item2.setName( "EJB3 Persistence Spec" ); t2.commit(); s2.close(); // at this point, s1 now contains stale data, so try an hql query which // returns said item and make sure we get the previously associated state // (i.e., the old name and the old version) item2 = ( Item ) s1.createQuery( "from Item" ).list().get( 0 ); assertTrue( item == item2 ); assertEquals( "encountered non-repeatable read", check, item2.getName() ); assertEquals( "encountered non-repeatable read", initialVersion, item2.getVersion() ); // clean up s1.refresh( item ); s1.delete( item ); t1.commit(); s1.close(); } public void testStaleVersionedInstanceFoundOnLock() { String check = "EJB3 Specification"; Session s1 = getSessions().openSession(); Transaction t1 = s1.beginTransaction(); Item item = new Item( check ); s1.save( item ); t1.commit(); s1.close(); Long itemId = item.getId(); long initialVersion = item.getVersion(); // Now, open a new Session and re-load the item... s1 = getSessions().openSession(); t1 = s1.beginTransaction(); item = ( Item ) s1.get( Item.class, itemId ); // now that the item is associated with the persistence-context of that session, // open a new session and modify it "behind the back" of the first session Session s2 = getSessions().openSession(); Transaction t2 = s2.beginTransaction(); Item item2 = ( Item ) s2.get( Item.class, itemId ); item2.setName( "EJB3 Persistence Spec" ); t2.commit(); s2.close(); // at this point, s1 now contains stale data, so acquire a READ lock // and make sure we get the already associated state (i.e., the old // name and the old version) s1.lock( item, LockMode.READ ); item2 = ( Item ) s1.get( Item.class, itemId ); assertTrue( item == item2 ); assertEquals( "encountered non-repeatable read", check, item2.getName() ); assertEquals( "encountered non-repeatable read", initialVersion, item2.getVersion() ); // attempt to acquire an UPGRADE lock; this should fail try { s1.lock( item, LockMode.UPGRADE ); fail( "expected UPGRADE lock failure" ); } catch( StaleObjectStateException expected ) { // this is the expected behavior } // clean up s1.refresh( item ); s1.delete( item ); t1.commit(); s1.close(); } // non-versioned entity tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public void testStaleNonVersionedInstanceFoundInQueryResult() { String check = "Lock Modes"; Session s1 = getSessions().openSession(); Transaction t1 = s1.beginTransaction(); Part part = new Part( new Item( "EJB3 Specification" ), check, "3.3.5.3", new BigDecimal( 0.0 ) ); s1.save( part ); t1.commit(); s1.close(); Long partId = part.getId(); // Now, open a new Session and re-load the part... s1 = getSessions().openSession(); t1 = s1.beginTransaction(); part = ( Part ) s1.get( Part.class, partId ); // now that the item is associated with the persistence-context of that session, // open a new session and modify it "behind the back" of the first session Session s2 = getSessions().openSession(); Transaction t2 = s2.beginTransaction(); Part part2 = ( Part ) s2.get( Part.class, partId ); part2.setName( "Lock Mode Types" ); t2.commit(); s2.close(); // at this point, s1 now contains stale data, so try an hql query which // returns said part and make sure we get the previously associated state // (i.e., the old name) part2 = ( Part ) s1.createQuery( "from Part" ).list().get( 0 ); assertTrue( part == part2 ); assertEquals( "encountered non-repeatable read", check, part2.getName() ); // clean up s1.delete( part ); t1.commit(); s1.close(); } public void testStaleNonVersionedInstanceFoundOnLock() { String check = "Lock Modes"; Session s1 = getSessions().openSession(); Transaction t1 = s1.beginTransaction(); Part part = new Part( new Item( "EJB3 Specification" ), check, "3.3.5.3", new BigDecimal( 0.0 ) ); s1.save( part ); t1.commit(); s1.close(); Long partId = part.getId(); // Now, open a new Session and re-load the part... s1 = getSessions().openSession(); t1 = s1.beginTransaction(); part = ( Part ) s1.get( Part.class, partId ); // now that the item is associated with the persistence-context of that session, // open a new session and modify it "behind the back" of the first session Session s2 = getSessions().openSession(); Transaction t2 = s2.beginTransaction(); Part part2 = ( Part ) s2.get( Part.class, partId ); part2.setName( "Lock Mode Types" ); t2.commit(); s2.close(); // at this point, s1 now contains stale data, so acquire a READ lock // and make sure we get the already associated state (i.e., the old // name and the old version) s1.lock( part, LockMode.READ ); part2 = ( Part ) s1.get( Part.class, partId ); assertTrue( part == part2 ); assertEquals( "encountered non-repeatable read", check, part2.getName() ); // then acquire an UPGRADE lock; this should fail s1.lock( part, LockMode.UPGRADE ); part2 = ( Part ) s1.get( Part.class, partId ); assertTrue( part == part2 ); assertEquals( "encountered non-repeatable read", check, part2.getName() ); // clean up // s1.refresh( item ); s1.delete( part ); t1.commit(); s1.close(); } } |
From: <ste...@us...> - 2006-02-14 03:24:26
|
Update of /cvsroot/hibernate/Hibernate3/test/org/hibernate/test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10165/test/org/hibernate/test Modified Files: AllTests.java Log Message: HHH-1416 & HHH-1421 : EJB3 LockModeTypes Index: AllTests.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/test/org/hibernate/test/AllTests.java,v retrieving revision 1.89 retrieving revision 1.90 diff -u -d -r1.89 -r1.90 --- AllTests.java 9 Feb 2006 20:51:39 -0000 1.89 +++ AllTests.java 14 Feb 2006 03:24:18 -0000 1.90 @@ -124,6 +124,7 @@ import org.hibernate.test.version.db.DbVersionTest; import org.hibernate.test.version.sybase.SybaseTimestampVersioningTest; import org.hibernate.test.where.WhereTest; +import org.hibernate.test.ejb3.EJB3Suite; import org.hibernate.dialect.Dialect; /** @@ -325,6 +326,7 @@ suite.addTest( TuplizerDynamicEntityTest.suite() ); suite.addTest( org.hibernate.test.bytecode.cglib.ReflectionOptimizerTest.suite() ); suite.addTest( org.hibernate.test.bytecode.javassist.ReflectionOptimizerTest.suite() ); + suite.addTest( EJB3Suite.suite() ); return filter( suite ); //return suite; |
Update of /cvsroot/hibernate/Hibernate3/test/org/hibernate/test/ejb3 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10165/test/org/hibernate/test/ejb3 Added Files: EJB3Suite.java Item.hbm.xml Item.java Part.hbm.xml Part.java package.html Log Message: HHH-1416 & HHH-1421 : EJB3 LockModeTypes --- NEW FILE: EJB3Suite.java --- package org.hibernate.test.ejb3; import junit.framework.Test; import junit.framework.TestSuite; import org.hibernate.test.ejb3.lock.EJB3LockTest; import org.hibernate.test.ejb3.lock.RepeatableReadTest; /** * @author Steve Ebersole */ public class EJB3Suite { public static Test suite() { TestSuite suite = new TestSuite( "EJB3-compliance tests"); suite.addTest( EJB3LockTest.suite() ); suite.addTest( RepeatableReadTest.suite() ); return suite; } } --- NEW FILE: Item.hbm.xml --- <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="org.hibernate.test.ejb3"> <class name="Item" table="EJB3_ITEM"> <id name="id" column="ITEM_ID" type="long"> <generator class="increment"/> </id> <version name="version" column="VERS" type="long"/> <property name="name" column="NAME" not-null="true"/> <!-- modeled as many-to-one even though, yes, in real life would normally be many-to-many --> <set name="parts" cascade="all" fetch="subselect" inverse="true"> <key column="ITEM_ID"/> <one-to-many class="Part"/> </set> </class> </hibernate-mapping> --- NEW FILE: Item.java --- package org.hibernate.test.ejb3; import java.util.Set; import java.util.HashSet; /** * @author Steve Ebersole */ public class Item { private Long id; private String name; private long version; private Set parts = new HashSet(); public Item() { } public Item(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getVersion() { return version; } public void setVersion(long version) { this.version = version; } public Set getParts() { return parts; } public void setParts(Set parts) { this.parts = parts; } } --- NEW FILE: Part.hbm.xml --- <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="org.hibernate.test.ejb3"> <class name="Part" table="EJB3_PART"> <id name="id" column="PART_ID" type="long"> <generator class="increment"/> </id> <many-to-one name="item" class="Item" column="ITEM_ID" cascade="save-update, lock" not-null="true"/> <property name="name" column="NAME" not-null="true" type="string"/> <property name="stockNumber" column="STOCK_NUM" not-null="true" type="string"/> <property name="unitPrice" column="UNIT_PRICE" not-null="true" type="big_decimal"/> </class> </hibernate-mapping> --- NEW FILE: Part.java --- package org.hibernate.test.ejb3; import java.math.BigDecimal; /** * @author Steve Ebersole */ public class Part { private Long id; private Item item; private String name; private String stockNumber; private BigDecimal unitPrice; public Part() { } public Part(Item item, String name, String stockNumber, BigDecimal unitPrice) { this.item = item; this.name = name; this.stockNumber = stockNumber; this.unitPrice = unitPrice; this.item.getParts().add( this ); } public Long getId() { return id; } private void setId(Long id) { this.id = id; } public Item getItem() { return item; } private void setItem(Item item) { this.item = item; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getStockNumber() { return stockNumber; } public void setStockNumber(String stockNumber) { this.stockNumber = stockNumber; } public BigDecimal getUnitPrice() { return unitPrice; } public void setUnitPrice(BigDecimal unitPrice) { this.unitPrice = unitPrice; } } --- NEW FILE: package.html --- <html> <head></head> <body> <p> Tests for any ejb3-specific behavior for which we need to ensure compliance. </p> </body> </html> |
From: <ste...@us...> - 2006-02-14 03:24:26
|
Update of /cvsroot/hibernate/Hibernate3/test/org/hibernate/test/legacy In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10165/test/org/hibernate/test/legacy Modified Files: CustomPersister.java Log Message: HHH-1416 & HHH-1421 : EJB3 LockModeTypes Index: CustomPersister.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/test/org/hibernate/test/legacy/CustomPersister.java,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- CustomPersister.java 12 Feb 2006 02:47:38 -0000 1.30 +++ CustomPersister.java 14 Feb 2006 03:24:18 -0000 1.31 @@ -509,6 +509,11 @@ return INSTANCES.get(id); } + public Object forceVersionIncrement(Serializable id, Object currentVersion, SessionImplementor session) + throws HibernateException { + return null; + } + public EntityMode guessEntityMode(Object object) { if ( !isInstance(object, EntityMode.POJO) ) { return null; |
From: <ste...@us...> - 2006-02-14 03:24:05
|
Update of /cvsroot/hibernate/Hibernate3/src/org/hibernate/persister/entity In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9926/src/org/hibernate/persister/entity Modified Files: AbstractEntityPersister.java EntityPersister.java Log Message: HHH-1416 & HHH-1421 : EJB3 LockModeTypes Index: AbstractEntityPersister.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java,v retrieving revision 1.28 retrieving revision 1.29 diff -u -d -r1.28 -r1.29 --- AbstractEntityPersister.java 12 Feb 2006 00:21:44 -0000 1.28 +++ AbstractEntityPersister.java 14 Feb 2006 03:23:55 -0000 1.29 @@ -1210,6 +1210,69 @@ } + public Object forceVersionIncrement(Serializable id, Object currentVersion, SessionImplementor session) { + if ( !isVersioned() ) { + throw new AssertionFailure( "cannot force version increment on non-versioned entity" ); + } + + if ( isVersionPropertyGenerated() ) { + // the difficulty here is exactly what do we update in order to + // force the version to be incremented in the db... + throw new HibernateException( "LockMode.FORCE is currently not supported for generated version properties" ); + } + + Object nextVersion = getVersionType().next( currentVersion, session ); + if ( log.isTraceEnabled() ) { + log.trace( + "Forcing version increment [" + MessageHelper.infoString( this, id, getFactory() ) + + "; " + getVersionType().toLoggableString( currentVersion, getFactory() ) + + " -> " + getVersionType().toLoggableString( nextVersion, getFactory() ) + "]" + ); + } + + // todo : cache this sql... + String versionIncrementString = generateVersionIncrementUpdateString(); + PreparedStatement st = null; + try { + try { + st = session.getBatcher().prepareStatement( versionIncrementString ); + getVersionType().nullSafeSet( st, nextVersion, 1, session ); + getIdentifierType().nullSafeSet( st, id, 2, session ); + getVersionType().nullSafeSet( st, currentVersion, 2 + getIdentifierColumnSpan(), session ); + int rows = st.executeUpdate(); + if ( rows != 1 ) { + throw new StaleObjectStateException( getEntityName(), id ); + } + } + finally { + session.getBatcher().closeStatement( st ); + } + } + catch ( SQLException sqle ) { + throw JDBCExceptionHelper.convert( + getFactory().getSQLExceptionConverter(), + sqle, + "could not retrieve version: " + + MessageHelper.infoString( this, id, getFactory() ), + getVersionSelectString() + ); + } + + return nextVersion; + } + + private String generateVersionIncrementUpdateString() { + Update update = new Update( getFactory().getDialect() ); + update.setTableName( getTableName( 0 ) ); + if ( getFactory().getSettings().isCommentsEnabled() ) { + update.setComment( "forced version increment" ); + } + update.addColumn( getVersionColumnName() ); + update.setPrimaryKeyColumnNames( getIdentifierColumnNames() ); + update.setVersionColumnName( getVersionColumnName() ); + return update.toStatementString(); + } + /** * Retrieve the version number */ Index: EntityPersister.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/persister/entity/EntityPersister.java,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- EntityPersister.java 9 Feb 2006 20:48:43 -0000 1.23 +++ EntityPersister.java 14 Feb 2006 03:23:55 -0000 1.24 @@ -364,7 +364,10 @@ */ public Object getCurrentVersion(Serializable id, SessionImplementor session) throws HibernateException; - + + public Object forceVersionIncrement(Serializable id, Object currentVersion, SessionImplementor session) + throws HibernateException; + /** * Try to discover the entity mode from the entity instance */ |
From: <ste...@us...> - 2006-02-14 03:24:05
|
Update of /cvsroot/hibernate/Hibernate3/src/org/hibernate In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9926/src/org/hibernate Modified Files: LockMode.java Log Message: HHH-1416 & HHH-1421 : EJB3 LockModeTypes Index: LockMode.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/LockMode.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- LockMode.java 1 Feb 2006 19:58:28 -0000 1.2 +++ LockMode.java 14 Feb 2006 03:23:56 -0000 1.3 @@ -75,11 +75,18 @@ public static final LockMode UPGRADE_NOWAIT = new LockMode(10, "UPGRADE_NOWAIT"); /** * A <tt>WRITE</tt> lock is obtained when an object is updated - * or inserted. This is not a valid mode for <tt>load()</tt> - * or <tt>lock()</tt>. + * or inserted. This lock mode is for internal use only and is + * not a valid mode for <tt>load()</tt> or <tt>lock()</tt> (both + * of which throw exceptions if WRITE is specified). */ public static final LockMode WRITE = new LockMode(10, "WRITE"); + /** + * Similiar to {@link #UPGRADE} except that, for versioned entities, + * it results in a forced version increment. + */ + public static final LockMode FORCE = new LockMode( 15, "FORCE" ); + static { INSTANCES.put( NONE.name, NONE ); INSTANCES.put( READ.name, READ ); |
From: <ste...@us...> - 2006-02-14 03:24:04
|
Update of /cvsroot/hibernate/Hibernate3/src/org/hibernate/event/def In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9926/src/org/hibernate/event/def Modified Files: AbstractLockUpgradeEventListener.java Log Message: HHH-1416 & HHH-1421 : EJB3 LockModeTypes Index: AbstractLockUpgradeEventListener.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/event/def/AbstractLockUpgradeEventListener.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- AbstractLockUpgradeEventListener.java 11 May 2005 22:12:45 -0000 1.4 +++ AbstractLockUpgradeEventListener.java 14 Feb 2006 03:23:55 -0000 1.5 @@ -38,6 +38,8 @@ throws HibernateException { if ( requestedLockMode.greaterThan( entry.getLockMode() ) ) { + // The user requested a "greater" (i.e. more restrictive) form of + // pessimistic lock if ( entry.getStatus() != Status.MANAGED ) { throw new ObjectDeletedException( @@ -75,7 +77,15 @@ } try { - persister.lock( entry.getId(), entry.getVersion(), object, requestedLockMode, source ); + if ( persister.isVersioned() && requestedLockMode == LockMode.FORCE ) { + Object nextVersion = persister.forceVersionIncrement( + entry.getId(), entry.getVersion(), source + ); + entry.forceLocked( object, nextVersion ); + } + else { + persister.lock( entry.getId(), entry.getVersion(), object, requestedLockMode, source ); + } entry.setLockMode(requestedLockMode); } finally { |
From: <ste...@us...> - 2006-02-14 03:24:04
|
Update of /cvsroot/hibernate/Hibernate3/src/org/hibernate/engine In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9926/src/org/hibernate/engine Modified Files: EntityEntry.java Log Message: HHH-1416 & HHH-1421 : EJB3 LockModeTypes Index: EntityEntry.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/engine/EntityEntry.java,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 --- EntityEntry.java 3 Feb 2006 22:08:24 -0000 1.19 +++ EntityEntry.java 14 Feb 2006 03:23:55 -0000 1.20 @@ -225,7 +225,19 @@ ); } - + + public void forceLocked(Object entity, Object nextVersion) { + version = nextVersion; + loadedState[ persister.getVersionProperty() ] = version; + setLockMode( LockMode.FORCE ); + persister.setPropertyValue( + entity, + getPersister().getVersionProperty(), + nextVersion, + entityMode + ); + } + public void setReadOnly(boolean readOnly, Object entity) { if (status!=Status.MANAGED && status!=Status.READ_ONLY) { throw new HibernateException("instance was not in a valid state"); |
From: <ste...@us...> - 2006-02-14 03:19:31
|
Update of /cvsroot/hibernate/Hibernate3/test/org/hibernate/test/ejb3/lock In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8849/test/org/hibernate/test/ejb3/lock Log Message: Directory /cvsroot/hibernate/Hibernate3/test/org/hibernate/test/ejb3/lock added to the repository |
From: <ste...@us...> - 2006-02-14 03:19:26
|
Update of /cvsroot/hibernate/Hibernate3/test/org/hibernate/test/ejb3 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8824/test/org/hibernate/test/ejb3 Log Message: Directory /cvsroot/hibernate/Hibernate3/test/org/hibernate/test/ejb3 added to the repository |
Update of /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/java In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21308/metadata/src/java/org/hibernate/reflection/java Modified Files: JavaXProperty.java XMLAnnotationReader.java JavaAnnotationReader.java JavaXAnnotatedElement.java JavaXPackage.java JavaXClass.java Added Files: JavaXSimpleProperty.java JavaXFactory.java Util.java Couplet.java JavaXCollectionProperty.java JavaXArrayProperty.java Removed Files: JavaXMethod.java JavaReflectionManager.java JavaXField.java Log Message: Support for generics in reflection layer --- NEW FILE: JavaXSimpleProperty.java --- package org.hibernate.reflection.java; import java.lang.reflect.Member; import java.lang.reflect.Type; import java.util.Collection; import org.hibernate.reflection.XClass; import org.hibernate.reflection.java.generics.TypeEnvironment; class JavaXSimpleProperty extends JavaXProperty { JavaXSimpleProperty(Member member, Type type, TypeEnvironment env, JavaXFactory rm) { super( member, type, env, rm ); } public boolean isArray() { return false; } public boolean isCollection() { return false; } public Class<? extends Collection> getCollectionClass() { return null; } public XClass getElementClass() { return getType(); } public XClass getClassOrElementClass() { return getType( ); } } --- NEW FILE: JavaXFactory.java --- package org.hibernate.reflection.java; import java.lang.reflect.Member; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; import org.dom4j.Document; import org.hibernate.reflection.ReflectionManager; import org.hibernate.reflection.XClass; import org.hibernate.reflection.XPackage; import org.hibernate.reflection.XProperty; import org.hibernate.reflection.java.generics.IdentityTypeEnvironment; import org.hibernate.reflection.java.generics.TypeEnvironment; import org.hibernate.reflection.java.generics.TypeEnvironmentFactory; import org.hibernate.reflection.java.generics.TypeSwitch; import org.hibernate.util.ReflectHelper; /** * The factory for all the objects in this package. * * @author Paolo Perrotta * @author Davide Marchignoli */ public class JavaXFactory implements ReflectionManager { private static class PropertyKey extends Couplet<Member, XClass> { PropertyKey( Member member, XClass owner ) { super( member, owner ); } } private static class TypeKey extends Couplet<Type, TypeEnvironment> { TypeKey( Type t, TypeEnvironment context ) { super( t, context ); } } private final Map<TypeKey, JavaXClass> xClasses = new HashMap<TypeKey, JavaXClass>(); private final Map<Package, JavaXPackage> packagesToXPackages = new HashMap<Package, JavaXPackage>(); private final Map<PropertyKey, JavaXProperty> xProperties = new HashMap<PropertyKey, JavaXProperty>(); private final TypeEnvironmentFactory typeEnvs = new TypeEnvironmentFactory(); private final Document xml; public JavaXFactory() { this.xml = null; } public JavaXFactory( Document xmlDescriptor ) { this.xml = xmlDescriptor; } public XClass toXClass(Class clazz) { return toXClass( clazz, IdentityTypeEnvironment.INSTANCE ); } public XClass classForName(String name, Class caller) throws ClassNotFoundException { return toXClass( ReflectHelper.classForName( name, caller ) ); } public XPackage packageForName(String packageName) throws ClassNotFoundException { return getXAnnotatedElement( ReflectHelper.classForName( packageName + ".package-info" ).getPackage() ); } XClass toXClass(Type t, final TypeEnvironment context) { return new TypeSwitch<XClass>() { @Override public XClass caseClass(Class classType) { TypeKey key = new TypeKey( classType, context ); JavaXClass result = xClasses.get( key ); if ( result == null ) { result = new JavaXClass( classType, context, JavaXFactory.this ); result.setXMLDescriptor( xml ); xClasses.put( key, result ); } return result; } @Override public XClass caseParameterizedType(ParameterizedType parameterizedType) { return toXClass( parameterizedType.getRawType(), context ); } }.doSwitch( t ); } XPackage getXAnnotatedElement(Package pkg) { JavaXPackage xPackage = packagesToXPackages.get( pkg ); if ( xPackage == null ) { xPackage = new JavaXPackage( pkg, this ); xPackage.setXMLDescriptor( xml ); packagesToXPackages.put( pkg, xPackage ); } return xPackage; } XProperty getXAnnotatedElement(Member member, JavaXClass owner) { PropertyKey key = new PropertyKey( member, owner ); JavaXProperty xProperty = xProperties.get( key ); if ( xProperty != null ) return xProperty; TypeEnvironment context = owner.getTypeEnvironment(); Type propType = Util.typeOf( member, context ); JavaXProperty result = null; if ( JavaXProperty.isArrayType( propType ) ) return new JavaXArrayProperty( member, propType, context, this ); else if ( JavaXProperty.isCollectionType( propType ) ) result = new JavaXCollectionProperty( member, propType, context, JavaXFactory.this ); else if ( JavaXProperty.isBaseType( propType ) ) result = new JavaXSimpleProperty( member, propType, context, this ); else return null; xProperties.put( key, result ); return result; } TypeEnvironment getTypeEnvironment(final Type t) { return new TypeSwitch<TypeEnvironment>() { @Override public TypeEnvironment caseClass(Class classType) { return typeEnvs.getEnvironment( classType ); } @Override public TypeEnvironment caseParameterizedType(ParameterizedType parameterizedType) { return typeEnvs.getEnvironment( parameterizedType ); } @Override public TypeEnvironment defaultCase(Type type) { return IdentityTypeEnvironment.INSTANCE; } }.doSwitch( t ); } public boolean equals(XClass class1, Class class2) { if ( class1 == null ) return class2 == null; return ( (JavaXClass) class1 ).toClass().equals( class2 ); } } --- NEW FILE: Util.java --- package org.hibernate.reflection.java; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Type; import org.hibernate.reflection.java.generics.IdentityTypeEnvironment; import org.hibernate.reflection.java.generics.TypeEnvironment; class Util { static Type typeOf(Member member) { return typeOf( member, IdentityTypeEnvironment.INSTANCE ); } static Type typeOf(Member member, TypeEnvironment env) { if ( member instanceof Field ) return env.bind( ( (Field) member ).getGenericType() ); if ( member instanceof Method ) return env.bind( ( (Method) member ).getGenericReturnType() ); throw new IllegalArgumentException( "Member " + member + " is neither a field nor a method" ); } } --- NEW FILE: Couplet.java --- package org.hibernate.reflection.java; /** * A pair of objects that can be used as a key in a Map. * * @author Paolo Perrotta * @author Davide Marchignoli */ abstract class Couplet<T, U> { private final T o1; private final U o2; Couplet( T o1, U o2 ) { this.o1 = o1; this.o2 = o2; } @Override public boolean equals(Object obj) { Couplet other = (Couplet) obj; return safeEquals( o1, other.o1 ) && safeEquals( o2, other.o2 ); } @Override public int hashCode() { return safeHashCode( o1 ) ^ safeHashCode( o2 ); } private int safeHashCode(Object o) { if( o == null ) return 0; return o.hashCode(); } private boolean safeEquals(Object obj1, Object obj2) { if ( obj1 == null ) return obj2 == null; boolean result = obj1.equals( obj2 ); return result; } } --- NEW FILE: JavaXCollectionProperty.java --- package org.hibernate.reflection.java; import java.lang.reflect.Member; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Map; import org.hibernate.reflection.XClass; import org.hibernate.reflection.java.generics.TypeEnvironment; import org.hibernate.reflection.java.generics.TypeSwitch; class JavaXCollectionProperty extends JavaXProperty { JavaXCollectionProperty( Member member, Type type, TypeEnvironment env, JavaXFactory rm ) { super( member, type, env, rm ); } public boolean isArray() { return false; } public boolean isCollection() { return true; } public XClass getElementClass() { return new TypeSwitch<XClass>() { @Override public XClass caseParameterizedType(ParameterizedType parameterizedType) { Type[] args = parameterizedType.getActualTypeArguments(); Type componentType; if ( getCollectionClass().isAssignableFrom( Map.class ) ) componentType = args[1]; else componentType = args[0]; return getFactory().toXClass( componentType, getTypeEnvironment() ); } }.doSwitch( getJavaType() ); } public XClass getClassOrElementClass() { return getType(); } } --- NEW FILE: JavaXArrayProperty.java --- package org.hibernate.reflection.java; import java.lang.reflect.GenericArrayType; import java.lang.reflect.Member; import java.lang.reflect.Type; import java.util.Collection; import org.hibernate.reflection.XClass; import org.hibernate.reflection.java.generics.TypeEnvironment; import org.hibernate.reflection.java.generics.TypeSwitch; class JavaXArrayProperty extends JavaXProperty { JavaXArrayProperty( Member member, Type type, TypeEnvironment env, JavaXFactory rm ) { super( member, type, env, rm ); assert ( type instanceof Class && ((Class)type).isArray() ) || type instanceof GenericArrayType; } public boolean isArray() { return true; } public boolean isCollection() { return false; } public Class<? extends Collection> getCollectionClass() { return null; } public XClass getElementClass() { return new TypeSwitch<XClass>() { @Override public XClass caseClass(Class classType) { return getFactory().toXClass( classType.getComponentType(), getTypeEnvironment() ); } @Override public XClass caseGenericArrayType(GenericArrayType genericArrayType) { return getFactory().toXClass( genericArrayType.getGenericComponentType(), getTypeEnvironment() ); } @Override public XClass defaultCase(Type t) { throw new IllegalArgumentException( t + " is not an array type" ); } }.doSwitch( getJavaType() ); } public XClass getClassOrElementClass() { return getElementClass(); } } Index: JavaXProperty.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXProperty.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- JavaXProperty.java 25 Jan 2006 21:48:21 -0000 1.2 +++ JavaXProperty.java 13 Feb 2006 19:14:35 -0000 1.3 @@ -1,127 +1,175 @@ package org.hibernate.reflection.java; +import java.beans.Introspector; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Field; +import java.lang.reflect.GenericArrayType; import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; import java.util.Collection; -import org.hibernate.AssertionFailure; -import org.hibernate.reflection.ReflectionManager; import org.hibernate.reflection.XClass; import org.hibernate.reflection.XProperty; +import org.hibernate.reflection.java.generics.TypeEnvironment; +import org.hibernate.reflection.java.generics.TypeSwitch; /** * @author Paolo Perrotta * @author Davide Marchignoli */ -@SuppressWarnings("unchecked") abstract class JavaXProperty extends JavaXAnnotatedElement implements XProperty { - - protected abstract Type getGenericType(); - - protected abstract JavaXClass getRawType(); - protected abstract Member toJavaMember(); + private final Type type; - public boolean isCollection() { - return getRawType().isCollection(); - } - - public boolean isArray() { - return getRawType().isArray(); - } - - public Class<? extends Collection> getCollectionClass() { - if(!isCollection()) - throw new RuntimeException("Property " + toJavaMember() + " is not a collection"); - return getRawType().toClass(); - } + private final TypeEnvironment env; - public XClass getClassOrElementClass() { - if(isArray()) - return ReflectionManager.INSTANCE.toXClass(getRawType().toClass().getComponentType()); - if(isCollection()) { - Type t = getGenericType(); - if(t instanceof Class) - return null; - if(t instanceof ParameterizedType) { - Type[] typeArgs = ((ParameterizedType)t).getActualTypeArguments(); - Type result; - if(typeArgs.length == 1 && typeArgs[0] instanceof Class) // List, Set - result = typeArgs[0]; - else if(typeArgs.length == 2 && typeArgs[1] instanceof Class) // Map - result = typeArgs[1]; - else - return null; - return ReflectionManager.INSTANCE.toXClass((Class)result); - } - return null; - } - return getRawType(); - } - - // TODO: refactor - public XClass getClassOrElement(XClass rootEntity) { - XClass c = getType(rootEntity); - if ( ((JavaXClass)c).isArray() ) - return getClassOrElementClass(); - else - return c; - } - - // TODO: refactor - public final XClass getType(XClass rootEntity) { - Type t = getGenericType(); - - if (t instanceof Class) - return ReflectionManager.INSTANCE.toXClass((Class) t); + static boolean isCollectionType(Type t) { + return getCollectionClass( t ) != null; + } - else if ( t instanceof ParameterizedType ) { - ParameterizedType pt = (ParameterizedType) t; - Type rawType = pt.getRawType(); - if ( rawType instanceof Class ) { - return ReflectionManager.INSTANCE.toXClass((Class) rawType); - } - else { - throw new AssertionFailure("rawType of parameterized type is not a class for type " + t); - } - } + static boolean isArrayType(Type t) { + return new TypeSwitch<Boolean>() { + @Override + public Boolean caseClass(Class clazz) { + return clazz.isArray(); + } + + @Override + public Boolean caseGenericArrayType(GenericArrayType genericArrayType) { + return isBaseType( genericArrayType.getGenericComponentType() ); + } + + @Override + public Boolean defaultCase(Type type) { + return false; + } + }.doSwitch( t ); + } - if ( t instanceof TypeVariable ) { - TypeVariable neededType = (TypeVariable) t; - String varName = neededType.getName(); - Class clazz = (Class) neededType.getGenericDeclaration(); - TypeVariable[] tvs = clazz.getTypeParameters(); - int typeIndexInGenerics = 0; - if (varName != null) { - for (int index = 0 ; index < tvs.length ; index++) { - if ( varName.equals( tvs[index].getName() ) ) { - typeIndexInGenerics = index; - break; - } - } - } - Type type = rootEntity.toClass().getGenericSuperclass(); - do { - if (type != null && type instanceof ParameterizedType) { - ParameterizedType paramType = (ParameterizedType) type; - if ( clazz.equals( paramType.getRawType() ) - && paramType.getActualTypeArguments()[typeIndexInGenerics] instanceof Class) { - return ReflectionManager.INSTANCE.toXClass((Class) paramType.getActualTypeArguments()[typeIndexInGenerics]); - } - //useful to go to the next level - type = paramType.getRawType(); - } - if (type instanceof Class) { - type = ( (Class) type ).getGenericSuperclass(); - } - else { - type = null; - } - } - while (type != null); - } - throw new AssertionFailure("Unknown type Java type: " + t); - } -} + static boolean isBaseType(Type type) { + return new TypeSwitch<Boolean>() { + @Override + public Boolean caseClass(Class classType) { + return classType != void.class; + } + + @Override + public Boolean caseParameterizedType(ParameterizedType parameterizedType) { + for ( Type actualTypeArgument : parameterizedType.getActualTypeArguments() ) + if ( !isBaseType( actualTypeArgument ) ) + return false; + return true; + } + + @Override + public Boolean defaultCase(Type t) { + return false; + } + }.doSwitch( type ); + } + + static boolean isProperty(Field f, Type boundType) { + return isPropertyType( boundType ) + && !f.isSynthetic() + && !Modifier.isStatic( f.getModifiers() ) + && !Modifier.isTransient( f.getModifiers() ); + } + + private static Class<? extends Collection> getCollectionClass(Type type) { + return new TypeSwitch<Class<? extends Collection>>() { + @Override + public Class<? extends Collection> caseClass(Class clazz) { + return isCollectionClass( clazz ) ? (Class<? extends Collection>) clazz : null; + } + + @Override + public Class<? extends Collection> caseParameterizedType(ParameterizedType parameterizedType) { + Class rawType = (Class) parameterizedType.getRawType(); + for ( Type actualTypeArgument : parameterizedType.getActualTypeArguments() ) + if ( !isBaseType( actualTypeArgument ) ) + return null; + return getCollectionClass( rawType ); + } + + @Override + public Class<? extends Collection> defaultCase(Type t) { + return null; + } + }.doSwitch( type ); + } + + private static boolean isCollectionClass(Class<?> clazz) { + return clazz == java.util.Collection.class + || clazz == java.util.List.class + || clazz == java.util.Set.class + || clazz == java.util.Map.class + || clazz == java.util.SortedSet.class // extension to the specs + || clazz == java.util.SortedMap.class; // extension to the specs + } + + private static boolean isPropertyType(Type type) { + return isArrayType( type ) || isCollectionType( type ) || isBaseType( type ); + } + + static boolean isProperty(Method m, Type boundType) { + return isPropertyType( boundType ) + &&!m.isSynthetic() + && !m.isBridge() + && !Modifier.isStatic( m.getModifiers() ) + && m.getParameterTypes().length == 0 + && ( m.getName().startsWith( "get" ) || m.getName().startsWith( "is" ) ); + // TODO should we use stronger checking on the naming of getters/setters, or just leave this to the validator? + } + + protected JavaXProperty(Member member, Type type, TypeEnvironment env, JavaXFactory factory) { + super( (AnnotatedElement) member, factory ); + assert member instanceof Field || member instanceof Method; + this.type = type; + this.env = env; + } + + public XClass getType() { + return getFactory().toXClass( env.bind( type ), env ); + } + + public String getName() { + String fullName = getMember().getName(); + if ( getMember() instanceof Method ) { + // FIXME emmanuel: + // get/is and RE otherwise is an issue in my opinion + // this layer is needed for Validator and EntityManager + // EM for example needs to work on non-getter/setter methods for + // entity + // listeners + // Only the caller know if it expect a getter or a regular method + // a slighly dirty solution might be to add a isJavaBeanAttribute() + // method?? + if ( fullName.startsWith( "get" ) ) + return Introspector.decapitalize( fullName.substring( "get".length() ) ); + if ( fullName.startsWith( "is" ) ) + return Introspector.decapitalize( fullName.substring( "is".length() ) ); + throw new RuntimeException( "Method " + fullName + " is not a property getter" ); + } + else + return fullName; + } + + public Class<? extends Collection> getCollectionClass() { + return getCollectionClass( getJavaType() ); + } + + protected Type getJavaType() { + return type; + } + + protected TypeEnvironment getTypeEnvironment() { + return env; + } + + private Member getMember() { + return (Member) toAnnotatedElement(); + } +} \ No newline at end of file Index: XMLAnnotationReader.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/java/XMLAnnotationReader.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- XMLAnnotationReader.java 25 Jan 2006 21:48:21 -0000 1.2 +++ XMLAnnotationReader.java 13 Feb 2006 19:14:35 -0000 1.3 @@ -3,6 +3,8 @@ import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; +import org.dom4j.Document; + /** * Encapsulates the overriding of Java annotations from an EJB 3.0 descriptor. * @@ -11,29 +13,24 @@ */ class XMLAnnotationReader extends JavaAnnotationReader { - public XMLAnnotationReader(AnnotatedElement el, String xmlDescriptor) { - super(el); - // TODO: it just ignores the XML for now. write the overriding mechanism - // (and use something smarter than a String to represent the xml, - // such as the DOM tree) - // - // This class is supposed to use the facilities in package annotationfactory - // to actually instance annotations (maybe we should move the whole package - // here?) - } - - public <T extends Annotation> T getAnnotation(Class<T> annotationType) { - // TODO: override - return super.getAnnotation(annotationType); - } + public XMLAnnotationReader( AnnotatedElement el, Document xmlDescriptor ) { + super( el ); + // TODO: it just ignores the XML for now. write the overrides + // + // This class is supposed to use the facilities in package + // annotationfactory to actually instance annotations (maybe we should + // move the whole package here?) + } - public <T extends Annotation> boolean isAnnotationPresent(Class<T> annotationType) { - // TODO: override - return super.isAnnotationPresent(annotationType); - } + public <T extends Annotation> T getAnnotation(Class<T> annotationType) { + return super.getAnnotation( annotationType ); + } - public Annotation[] getAnnotations() { - // TODO: override (this is also a good place to cache the xml annotations) - return super.getAnnotations(); - } + public <T extends Annotation> boolean isAnnotationPresent(Class<T> annotationType) { + return super.isAnnotationPresent( annotationType ); + } + + public Annotation[] getAnnotations() { + return super.getAnnotations(); + } } Index: JavaAnnotationReader.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaAnnotationReader.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- JavaAnnotationReader.java 24 Jan 2006 16:01:03 -0000 1.1 +++ JavaAnnotationReader.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -11,21 +11,21 @@ */ class JavaAnnotationReader { - private final AnnotatedElement element; + private final AnnotatedElement element; - public JavaAnnotationReader(AnnotatedElement el) { - this.element = el; - } - - public <T extends Annotation> T getAnnotation(Class<T> annotationType) { - return element.getAnnotation(annotationType); - } + public JavaAnnotationReader( AnnotatedElement el ) { + this.element = el; + } - public <T extends Annotation> boolean isAnnotationPresent(Class<T> annotationType) { - return element.isAnnotationPresent(annotationType); - } + public <T extends Annotation> T getAnnotation(Class<T> annotationType) { + return element.getAnnotation( annotationType ); + } - public Annotation[] getAnnotations() { - return element.getAnnotations(); - } + public <T extends Annotation> boolean isAnnotationPresent(Class<T> annotationType) { + return element.isAnnotationPresent( annotationType ); + } + + public Annotation[] getAnnotations() { + return element.getAnnotations(); + } } Index: JavaXAnnotatedElement.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXAnnotatedElement.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- JavaXAnnotatedElement.java 26 Jan 2006 15:02:55 -0000 1.3 +++ JavaXAnnotatedElement.java 13 Feb 2006 19:14:35 -0000 1.4 @@ -5,45 +5,70 @@ import org.hibernate.reflection.XAnnotatedElement; +import org.dom4j.Document; + /** * @author Paolo Perrotta * @author Davide Marchignoli */ abstract class JavaXAnnotatedElement implements XAnnotatedElement { - // does the actual job of extracting annotations - private JavaAnnotationReader annotationReader; + // responsible for extracting annotations + private JavaAnnotationReader annotationReader; - private JavaAnnotationReader getAnnotationReader() { - //FIXME emmanuel prossibly refactor that to initialize the value in the constructor - if(annotationReader == null) - annotationReader = new JavaAnnotationReader(this.toAnnotatedElement()); - return annotationReader; - } - - public void setXMLDescriptor(String xml) { - if(xml == null) - return; - annotationReader = new XMLAnnotationReader(this.toAnnotatedElement(), xml); - } - - public <T extends Annotation> T getAnnotation(Class<T> annotationType) { - return getAnnotationReader().getAnnotation(annotationType); - } + private final JavaXFactory factory; - public <T extends Annotation> boolean isAnnotationPresent( - Class<T> annotationType) { - return getAnnotationReader().isAnnotationPresent(annotationType); - } - - public Annotation[] getAnnotations() { - return getAnnotationReader().getAnnotations(); - } - - protected abstract AnnotatedElement toAnnotatedElement(); + private final AnnotatedElement annotatedElement; + + public JavaXAnnotatedElement( AnnotatedElement annotatedElement, JavaXFactory factory ) { + this.annotationReader = new JavaAnnotationReader( annotatedElement ); + this.factory = factory; + this.annotatedElement = annotatedElement; + } - @Override - public String toString() { - return toAnnotatedElement().toString(); - } + protected JavaXFactory getFactory() { + return factory; + } + + private JavaAnnotationReader getAnnotationReader() { + return annotationReader; + } + + public void setXMLDescriptor(Document xml) { + if ( xml == null ) + return; + annotationReader = new XMLAnnotationReader( this.toAnnotatedElement(), xml ); + } + + public <T extends Annotation> T getAnnotation(Class<T> annotationType) { + return getAnnotationReader().getAnnotation( annotationType ); + } + + public <T extends Annotation> boolean isAnnotationPresent(Class<T> annotationType) { + return getAnnotationReader().isAnnotationPresent( annotationType ); + } + + public Annotation[] getAnnotations() { + return getAnnotationReader().getAnnotations(); + } + + protected AnnotatedElement toAnnotatedElement() { + return annotatedElement; + } + + @Override + public boolean equals(Object obj) { + JavaXClass other = (JavaXClass) obj; + return toAnnotatedElement().equals( other.toAnnotatedElement() ); + } + + @Override + public int hashCode() { + return toAnnotatedElement().hashCode(); + } + + @Override + public String toString() { + return toAnnotatedElement().toString(); + } } Index: JavaXPackage.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXPackage.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- JavaXPackage.java 24 Jan 2006 16:01:03 -0000 1.1 +++ JavaXPackage.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -1,7 +1,5 @@ package org.hibernate.reflection.java; -import java.lang.reflect.AnnotatedElement; - import org.hibernate.reflection.XPackage; /** @@ -10,18 +8,11 @@ */ class JavaXPackage extends JavaXAnnotatedElement implements XPackage { - private final Package pkg; - - public JavaXPackage(Package p) { - pkg = p; - } - - public String getName() { - return pkg.getName(); - } + public JavaXPackage( Package pkg, JavaXFactory factory ) { + super( pkg, factory ); + } - @Override - protected AnnotatedElement toAnnotatedElement() { - return pkg; - } + public String getName() { + return ((Package) toAnnotatedElement()).getName(); + } } Index: JavaXClass.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/java/JavaXClass.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- JavaXClass.java 26 Jan 2006 15:02:55 -0000 1.2 +++ JavaXClass.java 13 Feb 2006 19:14:35 -0000 1.3 @@ -1,119 +1,96 @@ package org.hibernate.reflection.java; -import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; +import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.LinkedList; import java.util.List; -import org.hibernate.AssertionFailure; -import org.hibernate.reflection.ReflectionManager; import org.hibernate.reflection.XClass; import org.hibernate.reflection.XProperty; -import org.hibernate.reflection.XPackage; +import org.hibernate.reflection.java.generics.TypeEnvironment; /** * @author Paolo Perrotta * @author Davide Marchignoli */ -class JavaXClass<T> extends JavaXAnnotatedElement implements XClass { +class JavaXClass extends JavaXAnnotatedElement implements XClass { - private final Class<T> clazz; - - public JavaXClass(Class<T> c) { - clazz = c; - } + private final TypeEnvironment context; - public String getName() { - return toClass().getName(); - } + public JavaXClass( Class clazz, TypeEnvironment env, JavaXFactory factory ) { + super( clazz, factory ); + this.context = env; + } - public XClass getSuperclass() { - return ReflectionManager.INSTANCE.toXClass( toClass().getSuperclass() ); - } + public String getName() { + return toClass().getName(); + } - public boolean isAbstract() { - return Modifier.isAbstract( toClass().getModifiers() ); - } + public XClass getSuperclass() { + return getFactory().toXClass( toClass().getSuperclass(), getFactory().getTypeEnvironment( toClass() ) ); + } - public boolean isPrimitive() { - return toClass().isPrimitive(); - } + public boolean isAbstract() { + return Modifier.isAbstract( toClass().getModifiers() ); + } - public boolean isEnum() { - return toClass().isEnum(); - } + public boolean isPrimitive() { + return toClass().isPrimitive(); + } - private List<XProperty> getDeclaredMethodProperties() { - Method[] declaredMethods = toClass().getDeclaredMethods(); - List<XProperty> result = new LinkedList<XProperty>(); - for (int i = 0; i < declaredMethods.length; i++) - if(isProperty(declaredMethods[i])) - result.add(new JavaXMethod(declaredMethods[i])); - return result; - } + public boolean isEnum() { + return toClass().isEnum(); + } - private boolean isProperty(Method m) { - return !m.isSynthetic() && - !m.isBridge() && - !Modifier.isStatic( m.getModifiers() ) && - m.getParameterTypes().length == 0 && - m.getReturnType() != void.class && - ( m.getName().startsWith( "get" ) || m.getName().startsWith( "is" ) ); - } + private List<XProperty> getDeclaredFieldProperties() { + List<XProperty> result = new LinkedList<XProperty>(); + for ( Field f : toClass().getDeclaredFields() ) + if ( JavaXProperty.isProperty( f, getTypeEnvironment().bind( f.getGenericType() ) ) ) + maybeAdd( f, result ); + return result; + } - private List<XProperty> getDeclaredFieldProperties() { - Field[] declaredFields = toClass().getDeclaredFields(); - List<XProperty> result = new LinkedList<XProperty>(); - for (int i = 0; i < declaredFields.length; i++) - if(isProperty(declaredFields[i])) - result.add(new JavaXField(declaredFields[i])); - return result; - } - - private boolean isProperty(Field f) { - return !f.isSynthetic() && - !Modifier.isStatic( f.getModifiers() ) && - !Modifier.isTransient( f.getModifiers() ); - } + private List<XProperty> getDeclaredMethodProperties() { + List<XProperty> result = new LinkedList<XProperty>(); + for ( Method m : toClass().getDeclaredMethods() ) + if ( JavaXProperty.isProperty( m, getTypeEnvironment().bind( m.getGenericReturnType() ) ) ) + maybeAdd( m, result ); + return result; + } - public List getDeclaredProperties(String accessType) { - if(accessType.equals("field")) - return getDeclaredFieldProperties(); - if(accessType.equals("property")) - return getDeclaredMethodProperties(); - throw new AssertionFailure("Unknown access type " + accessType); - } + private void maybeAdd(Member m, List<XProperty> result) { + XProperty p = getFactory().getXAnnotatedElement( m, this ); + if ( p != null ) + result.add( p ); + } - public Class<T> toClass() { - return clazz; - } + public List<XProperty> getDeclaredProperties(String accessType) { + if ( accessType.equals( "field" ) ) + return getDeclaredFieldProperties(); + if ( accessType.equals( "property" ) ) + return getDeclaredMethodProperties(); + throw new IllegalArgumentException( "Unknown access type " + accessType ); + } - public XPackage getPackage() { - return ReflectionManager.INSTANCE.toXPackage(toClass().getPackage()); - } + public Class<?> toClass() { + return (Class) toAnnotatedElement(); + } - public boolean isAssignableFrom(XClass c) { - return toClass().isAssignableFrom( ((JavaXClass)c).toClass() ); - } + public boolean isAssignableFrom(XClass c) { + return toClass().isAssignableFrom( ( (JavaXClass) c ).toClass() ); + } - boolean isCollection() { - return - toClass() == java.util.Collection.class || - toClass() == java.util.List.class || - toClass() == java.util.Set.class || - toClass() == java.util.Map.class || - toClass() == java.util.SortedSet.class || // extension to the specs - toClass() == java.util.SortedMap.class; // extension to the specs + boolean isArray() { + return toClass().isArray(); } - @Override - protected AnnotatedElement toAnnotatedElement() { - return clazz; - } + public Method[] getDeclaredMethods() { + return toClass().getDeclaredMethods(); + } - boolean isArray() { - return toClass().isArray(); - } + TypeEnvironment getTypeEnvironment() { + return context; + } } --- JavaXMethod.java DELETED --- --- JavaReflectionManager.java DELETED --- --- JavaXField.java DELETED --- |
From: <pao...@us...> - 2006-02-13 19:14:44
|
Update of /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21308/metadata/src/java/org/hibernate/cfg Modified Files: AnnotationConfiguration.java PropertyData.java InheritanceState.java Ejb3Column.java PropertyInferredData.java AnnotationBinder.java PropertyPreloadedData.java Log Message: Support for generics in reflection layer Index: AnnotationConfiguration.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java,v retrieving revision 1.49 retrieving revision 1.50 diff -u -d -r1.49 -r1.50 --- AnnotationConfiguration.java 10 Feb 2006 16:32:55 -0000 1.49 +++ AnnotationConfiguration.java 13 Feb 2006 19:14:35 -0000 1.50 @@ -75,7 +75,7 @@ //for each class, copy all the relevent hierarchy for (XClass clazz : original) { XClass superClass = clazz.getSuperclass(); - while ( ! ReflectionManager.INSTANCE.toXClass( Object.class ).equals( superClass ) && ! copy.contains( superClass ) ) { + while ( ! ReflectionManager.INSTANCE.equals( superClass, Object.class ) && ! copy.contains( superClass ) ) { if (superClass.isAnnotationPresent( Entity.class ) || superClass.isAnnotationPresent( MappedSuperclass.class) ) { copy.add( superClass ); @@ -93,7 +93,7 @@ } private static void orderHierarchy(List<XClass> copy, List<XClass> newList, List<XClass> original, XClass clazz) { - if ( ReflectionManager.INSTANCE.toXClass( Object.class ).equals( clazz ) ) return; + if ( ReflectionManager.INSTANCE.equals( clazz, Object.class ) ) return; //process superclass first orderHierarchy( copy, newList, original, clazz.getSuperclass() ); if ( original.contains( clazz ) ) { Index: PropertyData.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/PropertyData.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- PropertyData.java 25 Jan 2006 21:48:21 -0000 1.1 +++ PropertyData.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -10,7 +10,7 @@ * @return default member access (whether field or property) * @throws MappingException No getter or field found or wrong JavaBean spec usage */ - public String getDefaultAccess() throws MappingException; + public String getDefaultAccess(); /** * @return property name @@ -21,24 +21,22 @@ /** * Returns the returned class itself or the element type if an array */ - public XClass getReturnedClassOrElement() throws MappingException; + public XClass getClassOrElement() throws MappingException; /** * Return the class itself */ - public XClass getReturnedClass() throws MappingException; + public XClass getPropertyClass() throws MappingException; /** * Returns the returned class name itself or the element type if an array */ - public String getReturnedClassOrElementName() throws MappingException; + public String getClassOrElementName() throws MappingException; /** * Returns the returned class name itself */ - public String getReturnedClassName() throws MappingException; - - public boolean skip(); + public String getTypeName() throws MappingException; public XProperty getProperty(); } Index: InheritanceState.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/InheritanceState.java,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- InheritanceState.java 25 Jan 2006 21:48:21 -0000 1.11 +++ InheritanceState.java 13 Feb 2006 19:14:35 -0000 1.12 @@ -28,12 +28,7 @@ public boolean hasParents = false; public InheritanceType type; public boolean isEmbeddableSuperclass = false; - /** - * used only to keep track of the root entity of a embeddedablesuperclass - * this root entity can vary during the process a embeddable superclass could - * be the superclass of several entities. - */ - public XClass rootEntity; + /** * only defined on embedded superclasses */ @@ -67,7 +62,7 @@ superclass = superclass.getSuperclass(); InheritanceState currentState = states.get( superclass ); if (currentState != null && ! currentState.isEmbeddableSuperclass) return currentState; - } while (! ReflectionManager.INSTANCE.toXClass( Object.class ).equals( superclass )); + } while ( ! ReflectionManager.INSTANCE.equals( superclass, Object.class ) ); return null; } @@ -77,7 +72,7 @@ superclass = superclass.getSuperclass(); InheritanceState currentState = states.get( superclass ); if (currentState != null) return currentState; - } while (! ReflectionManager.INSTANCE.toXClass( Object.class ).equals( superclass )); + } while ( ! ReflectionManager.INSTANCE.equals( superclass, Object.class ) ); return null; } } Index: Ejb3Column.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/Ejb3Column.java,v retrieving revision 1.36 retrieving revision 1.37 diff -u -d -r1.36 -r1.37 --- Ejb3Column.java 25 Jan 2006 21:48:21 -0000 1.36 +++ Ejb3Column.java 13 Feb 2006 19:14:35 -0000 1.37 @@ -383,7 +383,7 @@ column.setImplicit( false ); //not following the spec but more clean if ( nullability != Nullability.FORCED_NULL - && inferredData.getReturnedClassOrElement().isPrimitive() + && inferredData.getClassOrElement().isPrimitive() && ! inferredData.getProperty().isArray() ) { column.setNullable( false ); } Index: PropertyInferredData.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/PropertyInferredData.java,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- PropertyInferredData.java 25 Jan 2006 21:48:21 -0000 1.14 +++ PropertyInferredData.java 13 Feb 2006 19:14:35 -0000 1.15 @@ -1,72 +1,62 @@ //$Id$ package org.hibernate.cfg; -import javax.persistence.Transient; - -import net.sf.cglib.transform.impl.InterceptFieldCallback; - import org.hibernate.MappingException; import org.hibernate.annotations.AccessType; -import org.hibernate.reflection.ReflectionManager; import org.hibernate.reflection.XClass; import org.hibernate.reflection.XProperty; /** * Retrieve all inferred data from an annnoted element - * + * * @author Emmanuel Bernard * @author Paolo Perrotta */ public class PropertyInferredData implements PropertyData { private final String defaultAccess; + private final XProperty property; - private final XClass rootEntity; /** * Take the annoted element for lazy process - * - * @param annotedElt element to process + * + * @param annotedElt + * element to process * @param propertyAccessor */ - public PropertyInferredData(XProperty property, XClass rootEntity, String propertyAccessor) { + public PropertyInferredData( XProperty property, String propertyAccessor ) { this.property = property; - this.rootEntity = rootEntity; this.defaultAccess = propertyAccessor; } public String getDefaultAccess() throws MappingException { -// if(skip()) -// return defaultAccess; - AccessType access = property.getAnnotation( AccessType.class ); - return access != null ? access.value() : defaultAccess; + // if(skip()) + // return defaultAccess; + AccessType access = property.getAnnotation( AccessType.class ); + return access != null ? access.value() : defaultAccess; } public String getPropertyName() throws MappingException { return property.getName(); } - public XClass getReturnedClassOrElement() throws MappingException { - return property.getClassOrElement(rootEntity); + public XClass getPropertyClass() throws MappingException { + return property.getType(); } - public XClass getReturnedClass() throws MappingException { - return property.getType(rootEntity); + public XClass getClassOrElement() throws MappingException { + return property.getClassOrElementClass(); } - public String getReturnedClassOrElementName() throws MappingException { - return getReturnedClassOrElement().getName(); + public String getClassOrElementName() throws MappingException { + return property.getClassOrElementClass().getName(); } - public String getReturnedClassName() throws MappingException { - return getReturnedClass().getName(); + public String getTypeName() throws MappingException { + return property.getType().getName(); } - public boolean skip() { - return property.isAnnotationPresent( Transient.class ) || - ReflectionManager.INSTANCE.toXClass(InterceptFieldCallback.class).equals(getReturnedClass()); - } - - public XProperty getProperty() { - return property; - } + public XProperty getProperty() { + return property; + } } Index: AnnotationBinder.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java,v retrieving revision 1.174 retrieving revision 1.175 diff -u -d -r1.174 -r1.175 --- AnnotationBinder.java 13 Feb 2006 18:18:25 -0000 1.174 +++ AnnotationBinder.java 13 Feb 2006 19:14:35 -0000 1.175 @@ -42,8 +42,11 @@ import javax.persistence.SequenceGenerator; import javax.persistence.SqlResultSetMapping; import javax.persistence.TableGenerator; +import javax.persistence.Transient; import javax.persistence.Version; +import net.sf.cglib.transform.impl.InterceptFieldCallback; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.AnnotationException; @@ -547,7 +550,7 @@ HashMap<String, IdGenerator> classGenerators = buildLocalGenerators( annotatedClass, mappings ); // check properties - List<PropertyAnnotatedElement> elements = + List<PropertyData> elements = getElementsToProcess( clazzToProcess, inheritanceStatePerClass, propertyHolder, entityBinder ); if ( elements == null ) { throw new AnnotationException( "No identifier specified for entity: " + propertyHolder.getEntityName() ); @@ -626,14 +629,14 @@ } } Set<String> missingIdProperties = new HashSet<String>( idProperties ); - for ( PropertyAnnotatedElement propertyAnnotatedElement : elements ) { - String propertyName = propertyAnnotatedElement.inferredData.getPropertyName(); + for ( PropertyData propertyAnnotatedElement : elements ) { + String propertyName = propertyAnnotatedElement.getPropertyName(); if ( ! idProperties.contains( propertyName ) ) { processElementAnnotations( propertyHolder, subclassAndSingleTableStrategy ? Nullability.FORCED_NULL : Nullability.NO_CONSTRAINT, - propertyAnnotatedElement.element, - propertyAnnotatedElement.inferredData, classGenerators, entityBinder, + propertyAnnotatedElement.getProperty(), + propertyAnnotatedElement, classGenerators, entityBinder, false, false, entityBinder.getPropertyAccessor(), mappings ); } @@ -675,7 +678,7 @@ * Guess the annotated element from @Id or @EmbeddedId presence * Change EntityBinder by side effect */ - private static List<PropertyAnnotatedElement> getElementsToProcess( + private static List<PropertyData> getElementsToProcess( XClass clazzToProcess, Map<XClass, InheritanceState> inheritanceStatePerClass, PropertyHolder propertyHolder, EntityBinder entityBinder ) { @@ -683,7 +686,7 @@ List<XClass> classesToProcess = orderClassesToBeProcessed( clazzToProcess, inheritanceStatePerClass, inheritanceState ); - List<PropertyAnnotatedElement> elements = new ArrayList<PropertyAnnotatedElement>(); + List<PropertyData> elements = new ArrayList<PropertyData>(); int deep = classesToProcess.size(); boolean hasIdentifier = false; @@ -716,7 +719,7 @@ InheritanceState state = inheritanceStatePerClass.get( clazz ); boolean currentHasIdentifier = addElementsOfAClass( elements, propertyHolder, isPropertyAnnotated, - accessType, clazz, state.rootEntity ); + accessType, clazz ); hasIdentifier = hasIdentifier || currentHasIdentifier; } @@ -729,7 +732,7 @@ XClass clazz = classesToProcess.get( index ); InheritanceState state = inheritanceStatePerClass.get( clazz ); boolean currentHasIdentifier = addElementsOfAClass( elements, propertyHolder, isPropertyAnnotated, - accessType, clazz, state.rootEntity ); + accessType, clazz ); hasIdentifier = hasIdentifier || currentHasIdentifier; } } @@ -756,11 +759,8 @@ superClass = superClass.getSuperclass(); superclassState = inheritanceStatePerClass.get( superClass ); } - while (!ReflectionManager.INSTANCE.toXClass( Object.class ).equals(superClass) && superclassState == null); + while ( !ReflectionManager.INSTANCE.equals( superClass, Object.class ) && superclassState == null ); - if (superclassState != null && superclassState.isEmbeddableSuperclass) { - superclassState.rootEntity = annotatedClass; - } currentClassInHierarchy = superClass; } while ( superclassState != null && superclassState.isEmbeddableSuperclass ); @@ -837,12 +837,10 @@ * Add elements of a class */ private static boolean addElementsOfAClass( - List<PropertyAnnotatedElement> elements, PropertyHolder propertyHolder, boolean isPropertyAnnotated, - String propertyAccessor, final XClass annotatedClass, - final XClass rootEntity + List<PropertyData> elements, PropertyHolder propertyHolder, boolean isPropertyAnnotated, + String propertyAccessor, final XClass annotatedClass ) { boolean hasIdentifier = false; - // TODO: push the access guessing down to the reflection layer // emmanuel I'm -1 on that I think AccessType access = (AccessType) annotatedClass.getAnnotation( AccessType.class ); String localPropertyAccessor = access != null ? access.value() : null; String accessType = null; @@ -865,28 +863,24 @@ log.debug( "Processing " + propertyHolder.getEntityName() + " " + accessType + " annotation" ); List<XProperty> properties = annotatedClass.getDeclaredProperties(accessType); for ( XProperty p : properties ) { - final boolean currentHasIdentifier = addProperty( p, elements, rootEntity, - localPropertyAccessor - ); + final boolean currentHasIdentifier = addProperty( p, elements, localPropertyAccessor ); hasIdentifier = hasIdentifier || currentHasIdentifier; } return hasIdentifier; } private static boolean addProperty( - XProperty property, List<PropertyAnnotatedElement> annElts, XClass rootEntity, + XProperty property, List<PropertyData> annElts, String propertyAccessor ) { boolean hasIdentifier = false; - PropertyAnnotatedElement propertyAnnotatedElement = new PropertyAnnotatedElement( property, rootEntity, - propertyAccessor - ); - if ( ! propertyAnnotatedElement.inferredData.skip() ) { + PropertyData propertyAnnotatedElement = new PropertyInferredData( property, propertyAccessor); + if ( ! mustBeSkipped( propertyAnnotatedElement.getProperty() ) ) { /* * put element annotated by @Id in front * since it has to be parsed before any assoctation by Hibernate */ - final XAnnotatedElement element = propertyAnnotatedElement.element; + final XAnnotatedElement element = propertyAnnotatedElement.getProperty(); if ( element.isAnnotationPresent( Id.class ) || element.isAnnotationPresent( EmbeddedId.class ) ) { annElts.add( 0, propertyAnnotatedElement ); hasIdentifier = true; @@ -899,6 +893,11 @@ return hasIdentifier; } + private static boolean mustBeSkipped(XProperty property) { + return property.isAnnotationPresent( Transient.class ) + || ReflectionManager.INSTANCE.equals( property.getType(), InterceptFieldCallback.class ); + } + /** * Process annotation of a particular property */ @@ -1016,7 +1015,7 @@ } } - final XClass returnedClass = inferredData.getReturnedClassOrElement(); + final XClass returnedClass = inferredData.getClassOrElement(); if ( !entityBinder.isIgnoreIdAnnotations() && ( property.isAnnotationPresent( Id.class ) || property.isAnnotationPresent( EmbeddedId.class ) ) ) { @@ -1084,13 +1083,13 @@ boolean lazy = false; PropertyBinder propBinder = new PropertyBinder(); propBinder.setName( inferredData.getPropertyName() ); - propBinder.setReturnedClassName( inferredData.getReturnedClassName() ); + propBinder.setReturnedClassName( inferredData.getTypeName() ); propBinder.setLazy( lazy ); propBinder.setPropertyAccessorName( inferredData.getDefaultAccess() ); propBinder.setColumns( columns ); propBinder.setHolder( propertyHolder ); //PropertyHolderBuilder.buildPropertyHolder(rootClass) propBinder.setProperty( property ); - propBinder.setReturnedClass( inferredData.getReturnedClass() ); + propBinder.setReturnedClass( inferredData.getPropertyClass() ); propBinder.setMappings( mappings ); Property prop = propBinder.bind(); @@ -1116,7 +1115,7 @@ ann.optional(), getFetchMode( ann.fetch() ), ignoreNotFound, inferredData.getPropertyName(), - inferredData.getReturnedClassOrElementName(), + inferredData.getClassOrElementName(), ReflectionManager.INSTANCE.toXClass( ann.targetEntity() ), inferredData.getDefaultAccess(), propertyHolder, @@ -1135,7 +1134,7 @@ ann.optional(), getFetchMode( ann.fetch() ), ignoreNotFound, inferredData.getPropertyName(), - inferredData.getReturnedClassOrElementName(), + inferredData.getClassOrElementName(), ReflectionManager.INSTANCE.toXClass( ann.targetEntity() ), inferredData.getDefaultAccess(), propertyHolder, @@ -1192,7 +1191,7 @@ NotFound notFound = property.getAnnotation( NotFound.class ); boolean ignoreNotFound = notFound != null && notFound.action().equals( NotFoundAction.IGNORE ); collectionBinder.setIgnoreNotFound(ignoreNotFound); - collectionBinder.setCollectionType( inferredData.getProperty().getClassOrElementClass() ); + collectionBinder.setCollectionType( inferredData.getProperty().getElementClass() ); collectionBinder.setMappings( mappings ); collectionBinder.setPropertyAccessorName( inferredData.getDefaultAccess() ); @@ -1320,13 +1319,13 @@ PropertyBinder propBinder = new PropertyBinder(); propBinder.setName( inferredData.getPropertyName() ); - propBinder.setReturnedClassName( inferredData.getReturnedClassName() ); + propBinder.setReturnedClassName( inferredData.getTypeName() ); propBinder.setLazy( lazy ); propBinder.setPropertyAccessorName( inferredData.getDefaultAccess() ); propBinder.setColumns( columns ); propBinder.setHolder( propertyHolder ); propBinder.setProperty( property ); - propBinder.setReturnedClass( inferredData.getReturnedClass() ); + propBinder.setReturnedClass( inferredData.getPropertyClass() ); propBinder.setMappings( mappings ); if ( isIdentifierMapper ) { propBinder.setInsertable( false ); @@ -1470,7 +1469,7 @@ //yuk comp.setTable( propertyHolder.getTable() ); if ( !isIdentifierMapper ) { - comp.setComponentClassName( inferredData.getReturnedClassOrElementName() ); + comp.setComponentClassName( inferredData.getClassOrElementName() ); } else { comp.setComponentClassName( comp.getOwner().getClassName() ); @@ -1480,32 +1479,30 @@ Map<String, Column[]> localColumnOverride = propertyHolder.mergeOverridenColumns( columnOverride ); //TODO work on it PropertyHolder subHolder = PropertyHolderBuilder.buildPropertyHolder( comp, subpath, localColumnOverride ); - List<PropertyAnnotatedElement> classElements = new ArrayList<PropertyAnnotatedElement>(); - XClass returnedClassOrElement = inferredData.getReturnedClassOrElement(); + List<PropertyData> classElements = new ArrayList<PropertyData>(); + XClass returnedClassOrElement = inferredData.getClassOrElement(); addElementsOfAClass( classElements, subHolder, propertyAnnotated, - propertyAccessor, returnedClassOrElement, - null + propertyAccessor, returnedClassOrElement ); //add elements of the embeddable superclass - XClass superClass = inferredData.getReturnedClass().getSuperclass(); + XClass superClass = inferredData.getPropertyClass().getSuperclass(); while ( superClass != null && superClass.isAnnotationPresent( MappedSuperclass.class ) ) { //FIXME: proper support of typevariables incl var resolved at upper levels addElementsOfAClass( classElements, subHolder, entityBinder.isPropertyAnnotated( superClass ), - propertyAccessor, superClass, - returnedClassOrElement + propertyAccessor, superClass ); superClass = superClass.getSuperclass(); } - for ( PropertyAnnotatedElement propertyAnnotatedElement : classElements ) { + for ( PropertyData propertyAnnotatedElement : classElements ) { processElementAnnotations( subHolder, isNullable ? Nullability.NO_CONSTRAINT : Nullability.FORCED_NOT_NULL, - propertyAnnotatedElement.element, propertyAnnotatedElement.inferredData, + propertyAnnotatedElement.getProperty(), propertyAnnotatedElement, new HashMap<String, IdGenerator>(), entityBinder, isIdentifierMapper, isComponentEmbedded, propertyAccessor, mappings ); @@ -1552,7 +1549,7 @@ } SimpleValueBinder value = new SimpleValueBinder(); value.setPropertyName( inferredData.getPropertyName() ); - value.setReturnedClassName( inferredData.getReturnedClassName() ); + value.setReturnedClassName( inferredData.getTypeName() ); value.setColumns( columns ); value.setPersistentClassName( persistentClassName ); value.setMappings( mappings ); @@ -1601,7 +1598,7 @@ if ( generatorType == "assigned" ) id.setNullValue( "undefined" ); id.setIdentifierGeneratorProperties( params ); if ( isEmbedded ) { - rootClass.setEmbeddedIdentifier( inferredData.getReturnedClass() == null ); + rootClass.setEmbeddedIdentifier( inferredData.getPropertyClass() == null ); } else { PropertyBinder binder = new PropertyBinder(); @@ -1886,7 +1883,7 @@ } public static boolean isDefault(XClass clazz) { - return ReflectionManager.INSTANCE.toXClass( void.class ).equals( clazz ); + return ReflectionManager.INSTANCE.equals( clazz, void.class ); } public static Map<XClass, InheritanceState> buildInheritanceStates(List<XClass> orderedClasses) { @@ -1918,14 +1915,4 @@ } return inheritanceStatePerClass; } - - private static class PropertyAnnotatedElement { - public PropertyAnnotatedElement(XProperty property, XClass rootEntity, String propertyAccessor) { - element = property; - inferredData = new PropertyInferredData( property, rootEntity, propertyAccessor ); - } - - public XProperty element; - public PropertyData inferredData; - } } Index: PropertyPreloadedData.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/PropertyPreloadedData.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- PropertyPreloadedData.java 25 Jan 2006 21:48:21 -0000 1.1 +++ PropertyPreloadedData.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -7,10 +7,12 @@ public class PropertyPreloadedData implements PropertyData { private final String defaultAccess; + private final String propertyName; + private final XClass returnedClass; - public PropertyPreloadedData(String defaultAccess, String propertyName, XClass returnedClass) { + public PropertyPreloadedData( String defaultAccess, String propertyName, XClass returnedClass ) { this.defaultAccess = defaultAccess; this.propertyName = propertyName; this.returnedClass = returnedClass; @@ -24,27 +26,23 @@ return propertyName; } - public XClass getReturnedClassOrElement() throws MappingException { - return getReturnedClass(); + public XClass getClassOrElement() throws MappingException { + return getPropertyClass(); } - public XClass getReturnedClass() throws MappingException { + public XClass getPropertyClass() throws MappingException { return returnedClass; } - public String getReturnedClassOrElementName() throws MappingException { - return getReturnedClassName(); + public String getClassOrElementName() throws MappingException { + return getTypeName(); } - public String getReturnedClassName() throws MappingException { + public String getTypeName() throws MappingException { return returnedClass == null ? null : returnedClass.getName(); } - public boolean skip() { - throw new UnsupportedOperationException(); - } - - public XProperty getProperty() { - throw new UnsupportedOperationException(); - } + public XProperty getProperty() { + throw new UnsupportedOperationException(); + } } |
From: <pao...@us...> - 2006-02-13 19:14:44
|
Update of /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/java/generics In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21308/metadata/src/java/org/hibernate/reflection/java/generics Modified Files: IdentityTypeEnvironment.java TypeSwitch.java SimpleTypeEnvironment.java CompoundTypeEnvironment.java TypeEnvironment.java Added Files: TypeEnvironmentFactory.java Removed Files: GenericsEnvironment.java Log Message: Support for generics in reflection layer --- NEW FILE: TypeEnvironmentFactory.java --- package org.hibernate.reflection.java.generics; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.HashMap; import java.util.Map; /** * Returns the type context for a given <code>Class</code> or <code>ParameterizedType</code>. * <p> * Does not support bindings involving inner classes, nor upper/lower bounds. * * @author Davide Marchignoli * @author Paolo Perrotta */ public class TypeEnvironmentFactory { private final Map<Type, TypeEnvironment> typeToEnvironment = new HashMap<Type, TypeEnvironment>(); /** * @return Returns a type environment suitable for resolving types occurring * in subclasses of the context class. */ public TypeEnvironment getEnvironment(Class context) { return doGetEnvironment( context ); } public TypeEnvironment getEnvironment(ParameterizedType context) { return doGetEnvironment( context ); } private TypeEnvironment doGetEnvironment(Type context) { if ( context == null ) return IdentityTypeEnvironment.INSTANCE; TypeEnvironment result = typeToEnvironment.get( context ); if ( result == null ) { result = createEnvironment( context ); typeToEnvironment.put( context, result ); } return result; } private TypeEnvironment createEnvironment(Type context) { return new TypeSwitch<TypeEnvironment>() { @Override public TypeEnvironment caseClass(Class classType) { return new CompoundTypeEnvironment( createSuperTypeEnvironment( classType ), getEnvironment( classType.getSuperclass() ) ); } @Override public TypeEnvironment caseParameterizedType(ParameterizedType parameterizedType) { return createEnvironment( parameterizedType ); } @Override public TypeEnvironment defaultCase(Type t) { throw new IllegalArgumentException( "Invalid type for generating environment: " + t ); } }.doSwitch( context ); } private TypeEnvironment createSuperTypeEnvironment(Class clazz) { Class superclass = clazz.getSuperclass(); if ( superclass == null ) return IdentityTypeEnvironment.INSTANCE; Type[] formalArgs = superclass.getTypeParameters(); Type genericSuperclass = clazz.getGenericSuperclass(); if ( genericSuperclass instanceof Class ) return IdentityTypeEnvironment.INSTANCE; if ( genericSuperclass instanceof ParameterizedType ) { Type[] actualArgs = ( (ParameterizedType) genericSuperclass ).getActualTypeArguments(); return new SimpleTypeEnvironment( formalArgs, actualArgs ); } throw new AssertionError( "Should be unreachable" ); } private TypeEnvironment createEnvironment(ParameterizedType t) { Type[] tactuals = t.getActualTypeArguments(); Type rawType = t.getRawType(); if ( rawType instanceof Class ) { TypeVariable[] tparms = ( (Class) rawType ).getTypeParameters(); return new SimpleTypeEnvironment( tparms, tactuals ); } return IdentityTypeEnvironment.INSTANCE; } } Index: IdentityTypeEnvironment.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/java/generics/IdentityTypeEnvironment.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- IdentityTypeEnvironment.java 1 Feb 2006 13:43:33 -0000 1.1 +++ IdentityTypeEnvironment.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -3,19 +3,19 @@ import java.lang.reflect.Type; /** - * Substitutes a <tt>Type</tt> for itself. + * Substitutes a <code>Type</code> for itself. * * @author Davide Marchignoli * @author Paolo Perrotta */ -class IdentityTypeEnvironment implements TypeEnvironment { +public class IdentityTypeEnvironment implements TypeEnvironment { public static final TypeEnvironment INSTANCE = new IdentityTypeEnvironment(); private IdentityTypeEnvironment() { } - public Type substitute(Type type) { + public Type bind(Type type) { return type; } } Index: TypeSwitch.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/java/generics/TypeSwitch.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- TypeSwitch.java 1 Feb 2006 13:43:33 -0000 1.1 +++ TypeSwitch.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -7,39 +7,48 @@ import java.lang.reflect.WildcardType; /** - * A visitor for the <tt>java.lang.reflect.Type</tt> hierarchy. + * A visitor for the <code>java.lang.reflect.Type</code> hierarchy. * * @author Davide Marchignoli * @author Paolo Perrotta */ -abstract class TypeSwitch<T> { +public class TypeSwitch<T> { - public final T visit(Type type) { - if ( type instanceof Class ) { + public final T doSwitch(Type type) { + if ( type instanceof Class ) return caseClass( (Class) type ); - } - else if ( type instanceof GenericArrayType ) { + if ( type instanceof GenericArrayType ) return caseGenericArrayType( (GenericArrayType) type ); - } - else if ( type instanceof ParameterizedType ) { + if ( type instanceof ParameterizedType ) return caseParameterizedType( (ParameterizedType) type ); - } - else if ( type instanceof TypeVariable ) { + if ( type instanceof TypeVariable ) return caseTypeVariable( (TypeVariable) type ); - } - else if ( type instanceof WildcardType ) { + if ( type instanceof WildcardType ) return caseWildcardType( (WildcardType) type ); - } - throw new IllegalArgumentException( "Unexpected Type: " + type ); + return defaultCase( type ); } - public abstract T caseWildcardType(WildcardType wildcardType); + public T caseWildcardType(WildcardType wildcardType) { + return defaultCase( wildcardType ); + } - public abstract T caseTypeVariable(TypeVariable typeVariable); + public T caseTypeVariable(TypeVariable typeVariable) { + return defaultCase( typeVariable ); + } - public abstract T caseClass(Class classType); + public T caseClass(Class classType) { + return defaultCase( classType ); + } - public abstract T caseGenericArrayType(GenericArrayType genericArrayType); + public T caseGenericArrayType(GenericArrayType genericArrayType) { + return defaultCase( genericArrayType ); + } - public abstract T caseParameterizedType(ParameterizedType parameterizedType); + public T caseParameterizedType(ParameterizedType parameterizedType) { + return defaultCase( parameterizedType ); + } + + public T defaultCase(Type t) { + return null; + } } Index: SimpleTypeEnvironment.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/java/generics/SimpleTypeEnvironment.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- SimpleTypeEnvironment.java 1 Feb 2006 13:43:33 -0000 1.1 +++ SimpleTypeEnvironment.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -5,6 +5,7 @@ import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; +import java.util.Arrays; /** * @author Davide Marchignoli @@ -24,14 +25,13 @@ @Override public Type caseGenericArrayType(GenericArrayType genericArrayType) { - return createGenericArrayType( substitute( genericArrayType.getGenericComponentType() ) ); + return createGenericArrayType( bind( genericArrayType.getGenericComponentType() ) ); } @Override public Type caseParameterizedType(ParameterizedType parameterizedType) { - return createParameterizedType( parameterizedType.getRawType(), - substitute( parameterizedType.getActualTypeArguments() ), - parameterizedType.getOwnerType() ); + return createParameterizedType( parameterizedType.getRawType(), substitute( parameterizedType + .getActualTypeArguments() ), parameterizedType.getOwnerType() ); } @Override @@ -58,12 +58,12 @@ formalArguments = formal; } - // We instance our own ParameterizedTypes and GenericArrayType. These instances are not - // supposed to be mixed with Java's own. If they did, we might have trouble with - // equality/identity when checking against Java's implementations. - - protected ParameterizedType createParameterizedType(final Type rawType, - final Type[] substTypeArgs, final Type ownerType) { + // We instance our own ParameterizedTypes and GenericArrayType. These + // are not supposed to be mixed with Java's implementations. If they + // did, we might have equality/identity problems. + + private ParameterizedType createParameterizedType(final Type rawType, final Type[] substTypeArgs, + final Type ownerType) { return new ParameterizedType() { public Type[] getActualTypeArguments() { @@ -77,6 +77,18 @@ public Type getOwnerType() { return ownerType; } + + @Override + public boolean equals(Object obj) { + ParameterizedType other = (ParameterizedType) obj; + return Arrays.equals( getActualTypeArguments(), other.getActualTypeArguments() ) + && getRawType().equals( other.getRawType() ) && getOwnerType().equals( other.getOwnerType() ); + } + + @Override + public int hashCode() { + return safeHashCode( getActualTypeArguments() ) ^ safeHashCode( getRawType() ) ^ safeHashCode( getOwnerType() ); + } }; } @@ -86,17 +98,34 @@ public Type getGenericComponentType() { return componentType; } + + @Override + public boolean equals(Object obj) { + GenericArrayType other = (GenericArrayType) obj; + return getGenericComponentType().equals( other.getGenericComponentType() ); + } + + @Override + public int hashCode() { + return safeHashCode( getGenericComponentType() ); + } }; } - public Type substitute(Type type) { - return substitute.visit( type ); + private int safeHashCode(Object o) { + if( o == null ) + return 1; + return o.hashCode(); } - public Type[] substitute(Type[] types) { + public Type bind(Type type) { + return substitute.doSwitch( type ); + } + + private Type[] substitute(Type[] types) { Type[] substTypes = new Type[types.length]; for ( int i = 0; i < substTypes.length; i++ ) - substTypes[i] = substitute( types[i] ); + substTypes[i] = bind( types[i] ); return substTypes; } } Index: CompoundTypeEnvironment.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/java/generics/CompoundTypeEnvironment.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- CompoundTypeEnvironment.java 1 Feb 2006 13:43:33 -0000 1.1 +++ CompoundTypeEnvironment.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -3,7 +3,7 @@ import java.lang.reflect.Type; /** - * A composition of two <tt>TypeEnvironment</tt> functions. + * A composition of two <code>TypeEnvironment</code> functions. * * @author Davide Marchignoli * @author Paolo Perrotta @@ -19,7 +19,7 @@ this.g = g; } - public Type substitute(Type type) { - return f.substitute( g.substitute( type ) ); + public Type bind(Type type) { + return f.bind( g.bind( type ) ); } } Index: TypeEnvironment.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/java/generics/TypeEnvironment.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- TypeEnvironment.java 1 Feb 2006 13:43:33 -0000 1.1 +++ TypeEnvironment.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -3,10 +3,51 @@ import java.lang.reflect.Type; /** + * A typing context that knows how to "resolve" the generic parameters of a + * <code>Type</code>. + * <p> + * For example: + * <p> + * + * <blockquote> + * + * <pre> + * class Shop&ltT&gt{ + * List&ltT&gt getCatalog() { ... } + * } + * + * class Bakery extends Shop&ltBread&gt{} + * </pre> + * + * </blockquote> + * + * Consider the type returned by method <code>getCatalog()</code>. There are + * two possible contexts here. In the context of <code>Shop</code>, the type + * is <code>List<T></code>. In the context of <code>Bakery</code>, the + * type is <code>List<Bread></code>. Each of these contexts can be + * represented by a <code>TypeEnvironment</code>. + * * @author Davide Marchignoli * @author Paolo Perrotta */ -interface TypeEnvironment { +public interface TypeEnvironment { - public Type substitute(Type type); + /** + * Binds as many generic components of the given type as possible in this + * context. + * <p> + * Warning: if the returned <code>Type</code> is a <code>Class</code>, + * then it's guaranteed to be a regular Java <code>Class</code>. In all + * other cases, this method might return a custom implementation of some + * interface that extends <code>Type</code>. Be sure not to mix these + * objects with with Java's implementations of <code>Type</code> to avoid + * potential identity problems. + * <p> + * This class does not support bindings involving inner classes or + * upper/lower bounds. + * + * @return a type where the generic arguments have been replaced by raw + * classes whenever this is possible. + */ + public Type bind(Type type); } \ No newline at end of file --- GenericsEnvironment.java DELETED --- |
From: <pao...@us...> - 2006-02-13 19:14:44
|
Update of /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21308/metadata/src/java/org/hibernate/cfg/annotations Modified Files: QueryBinder.java CollectionBinder.java SimpleValueBinder.java Log Message: Support for generics in reflection layer Index: QueryBinder.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/QueryBinder.java,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- QueryBinder.java 25 Jan 2006 21:48:20 -0000 1.21 +++ QueryBinder.java 13 Feb 2006 19:14:35 -0000 1.22 @@ -26,7 +26,6 @@ import org.hibernate.loader.custom.SQLQueryReturn; import org.hibernate.loader.custom.SQLQueryRootReturn; import org.hibernate.loader.custom.SQLQueryScalarReturn; -import org.hibernate.reflection.ReflectionManager; /** * Query binder @@ -90,7 +89,7 @@ getBoolean(queryName, "org.hibernate.callable", hints) ); } - else if ( ! ReflectionManager.INSTANCE.toXClass( void.class ).equals( queryAnn.resultClass() ) ) { + else if ( ! void.class.equals( queryAnn.resultClass() ) ) { //class mapping usage //FIXME should be done in a second pass due to entity name? final SQLQueryRootReturn entityQueryReturn = @@ -145,7 +144,7 @@ queryAnn.callable() ); } - else if ( ! ReflectionManager.INSTANCE.toXClass( void.class ).equals( queryAnn.resultClass() ) ) { + else if ( ! void.class.equals( queryAnn.resultClass() ) ) { //class mapping usage //FIXME should be done in a second pass due to entity name? final SQLQueryRootReturn entityQueryReturn = Index: CollectionBinder.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/CollectionBinder.java,v retrieving revision 1.32 retrieving revision 1.33 diff -u -d -r1.32 -r1.33 --- CollectionBinder.java 27 Jan 2006 10:18:49 -0000 1.32 +++ CollectionBinder.java 13 Feb 2006 19:14:35 -0000 1.33 @@ -168,7 +168,7 @@ ) { XProperty property = inferredData.getProperty(); if ( property.isArray() ) { - if ( property.getClassOrElementClass().isPrimitive() ) { + if ( property.getElementClass().isPrimitive() ) { return new PrimitiveArrayBinder(); } else { Index: SimpleValueBinder.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/SimpleValueBinder.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- SimpleValueBinder.java 6 Feb 2006 09:16:01 -0000 1.8 +++ SimpleValueBinder.java 13 Feb 2006 19:14:35 -0000 1.9 @@ -66,7 +66,7 @@ XClass returnedClassOrElement = returnedClass; boolean isArray = false; if ( property.isArray() ) { - returnedClassOrElement = property.getClassOrElementClass(); + returnedClassOrElement = property.getElementClass(); isArray = true; } Properties typeParameters = this.typeParameters; @@ -90,24 +90,24 @@ } else if ( property.isAnnotationPresent( Lob.class ) ) { - if ( ReflectionManager.INSTANCE.toXClass( java.sql.Clob.class ).equals( returnedClassOrElement ) ) { + if ( ReflectionManager.INSTANCE.equals( returnedClassOrElement, java.sql.Clob.class ) ) { type = "clob"; } - else if ( ReflectionManager.INSTANCE.toXClass( java.sql.Blob.class ).equals( returnedClassOrElement ) ) { + else if ( ReflectionManager.INSTANCE.equals( returnedClassOrElement, java.sql.Blob.class ) ) { type = "blob"; } - else if ( ReflectionManager.INSTANCE.toXClass( String.class ).equals( returnedClassOrElement ) ) { + else if ( ReflectionManager.INSTANCE.equals( returnedClassOrElement, String.class ) ) { type = StringClobType.class.getName(); } - else if ( ReflectionManager.INSTANCE.toXClass( Character.class ).equals( returnedClassOrElement ) && isArray ) { + else if ( ReflectionManager.INSTANCE.equals( returnedClassOrElement, Character.class ) && isArray ) { type = CharacterArrayClobType.class.getName(); } - else if ( ReflectionManager.INSTANCE.toXClass( char.class ).equals( returnedClassOrElement ) && isArray ) { + else if ( ReflectionManager.INSTANCE.equals( returnedClassOrElement, char.class ) && isArray ) { type = PrimitiveCharacterArrayClobType.class.getName(); - } else if ( ReflectionManager.INSTANCE.toXClass( Byte.class ).equals( returnedClassOrElement ) && isArray ) { + } else if ( ReflectionManager.INSTANCE.equals( returnedClassOrElement, Byte.class ) && isArray ) { type = ByteArrayBlobType.class.getName(); } - else if ( ReflectionManager.INSTANCE.toXClass( byte.class ).equals( returnedClassOrElement ) && isArray ) { + else if ( ReflectionManager.INSTANCE.equals( returnedClassOrElement, byte.class ) && isArray ) { type = PrimitiveByteArrayBlobType.class.getName(); } else if ( ReflectionManager.INSTANCE.toXClass( Serializable.class ).isAssignableFrom( returnedClassOrElement ) ) { |
From: <pao...@us...> - 2006-02-13 19:14:43
|
Update of /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21308/metadata/src/test/org/hibernate/test/reflection/java Modified Files: JavaReflectionManagerTest.java Foo.java FooFather.java JavaXClassTest.java Added Files: TestAnnotation.java XAnnotatedElementTest.java JavaXPropertyTest.java Removed Files: JavaXAnnotatedElementTest.java JavaXMemberTest.java Log Message: Support for generics in reflection layer --- NEW FILE: TestAnnotation.java --- package org.hibernate.test.reflection.java; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; @Target( { TYPE, METHOD, FIELD }) @Retention(RUNTIME) public @interface TestAnnotation { String name() default "abc"; } --- NEW FILE: XAnnotatedElementTest.java --- package org.hibernate.test.reflection.java; import javax.persistence.Transient; import junit.framework.TestCase; import org.hibernate.reflection.XAnnotatedElement; import org.hibernate.test.reflection.java.generics.TestAnnotation; /** * @author Paolo Perrotta */ public abstract class XAnnotatedElementTest extends TestCase { public void testKnowsWhetherAnAnnotationIsPresent() { assertTrue( getConcreteInstance().isAnnotationPresent( TestAnnotation.class ) ); assertFalse( getConcreteInstance().isAnnotationPresent( Transient.class ) ); } public void testReturnsSpecificAnnotations() { TestAnnotation ent = getConcreteInstance().getAnnotation( TestAnnotation.class ); assertEquals( "xyz", ent.name() ); } protected abstract XAnnotatedElement getConcreteInstance(); } --- NEW FILE: JavaXPropertyTest.java --- package org.hibernate.test.reflection.java; import java.util.LinkedList; import java.util.List; import java.util.Map; import junit.framework.AssertionFailedError; import org.hibernate.reflection.ReflectionManager; import org.hibernate.reflection.XClass; import org.hibernate.reflection.XProperty; import org.hibernate.reflection.java.JavaXFactory; import org.hibernate.test.reflection.java.generics.Dad; import org.hibernate.test.reflection.java.generics.Son; /** * @author Paolo Perrotta */ public class JavaXPropertyTest extends XAnnotatedElementTest { private ReflectionManager factory = new JavaXFactory(); private XClass dadAsSeenFromSon = factory.toXClass( Son.class ).getSuperclass(); public void testFollowsJavaBeansConventionsForPropertyNames() throws Exception { List<String> properties = new LinkedList<String>(); properties.add( "collectionProperty" ); properties.add( "methodProperty" ); properties.add( "primitiveProperty" ); properties.add( "primitiveArrayProperty" ); properties.add( "arrayProperty" ); properties.add( "propertyStartingWithIs" ); List<XProperty> methodProperties = dadAsSeenFromSon.getDeclaredProperties( "property" ); assertEquals( properties.size(), methodProperties.size() ); for ( XProperty member : methodProperties ) assertTrue( properties.contains( member.getName() ) ); List<XProperty> fieldProperties = dadAsSeenFromSon.getDeclaredProperties( "field" ); XProperty field = fieldProperties.get( 0 ); assertEquals( "fieldProperty", field.getName() ); } public void testPropertiesWithParametricTypesAreIgnored() { assertEquals( 6, dadAsSeenFromSon.getDeclaredProperties( "property" ).size() ); XClass dadAsSeenFromItself = ReflectionManager.INSTANCE.toXClass( Dad.class ); assertEquals( 4, dadAsSeenFromItself.getDeclaredProperties( "property" ).size() ); } public void testCanBeASimpleType() { List<XProperty> declaredProperties = dadAsSeenFromSon.getDeclaredProperties( "field" ); XProperty p = getPropertyNamed_from( "fieldProperty", declaredProperties ); assertTrue( factory.equals( p.getType(), String.class )); assertTrue( factory.equals( p.getElementClass(), String.class )); assertTrue( factory.equals( p.getClassOrElementClass(), String.class )); assertNull( p.getCollectionClass() ); assertFalse( p.isArray() ); assertFalse( p.isCollection() ); } public void testCanBeAnArray() { List<XProperty> declaredProperties = dadAsSeenFromSon.getDeclaredProperties( "property" ); XProperty p = getPropertyNamed_from( "arrayProperty", declaredProperties ); // TODO: this truly sucks. the problem is that I can't get a reference to a specific array class // at runtime. is there any way to do that in Java? assertNull( p.getType() ); assertTrue( factory.equals( p.getElementClass(), String.class )); assertTrue( factory.equals( p.getClassOrElementClass(), String.class )); assertNull( p.getCollectionClass() ); assertTrue( p.isArray() ); assertFalse( p.isCollection() ); } public void testCanBeAnArrayOfPrimitives() { List<XProperty> declaredProperties = dadAsSeenFromSon.getDeclaredProperties( "property" ); XProperty p = getPropertyNamed_from( "primitiveArrayProperty", declaredProperties ); assertTrue( factory.equals( p.getType(), int[].class )); assertTrue( factory.equals( p.getElementClass(), int.class )); assertTrue( factory.equals( p.getClassOrElementClass(), int.class )); assertNull( p.getCollectionClass() ); assertTrue( p.isArray() ); assertFalse( p.isCollection() ); } public void testCanBeACollection() { List<XProperty> declaredProperties = dadAsSeenFromSon.getDeclaredProperties( "property" ); XProperty p = getPropertyNamed_from( "collectionProperty", declaredProperties ); assertTrue( factory.equals( p.getType(), Map.class )); assertTrue( factory.equals( p.getElementClass(), String.class )); assertTrue( factory.equals( p.getClassOrElementClass(), Map.class )); assertEquals( Map.class, p.getCollectionClass() ); assertFalse( p.isArray() ); assertTrue( p.isCollection() ); } private XProperty getPropertyNamed_from(String name, List<XProperty> properties) { for ( XProperty p : properties ) if ( p.getName().equals( name ) ) return p; throw new AssertionFailedError( "No property '" + name + "' found" ); } public void testSupportsMethodsStartingWithIs() throws Exception { assertEquals( "methodProperty", getConcreteInstance().getName() ); } @Override protected XProperty getConcreteInstance() { XClass xClass = ReflectionManager.INSTANCE.toXClass( Dad.class ); List<XProperty> properties = xClass.getDeclaredProperties( "property" ); for ( XProperty p : properties ) if ( p.getName().equals( "methodProperty" ) ) return p; throw new AssertionFailedError( "Cannot find Foo.getMethodProperty()" ); } } Index: JavaReflectionManagerTest.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/JavaReflectionManagerTest.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- JavaReflectionManagerTest.java 24 Jan 2006 16:01:03 -0000 1.1 +++ JavaReflectionManagerTest.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -5,23 +5,39 @@ import org.hibernate.reflection.ReflectionManager; import org.hibernate.reflection.XClass; +import com.sun.org.apache.xpath.internal.operations.Number; + /** * @author Paolo Perrotta */ public class JavaReflectionManagerTest extends TestCase { - public void testReturnsAnXClassThatWrapsTheGivenClass() { - XClass<Integer> xc = ReflectionManager.INSTANCE.toXClass(Integer.class); - assertEquals("java.lang.Integer", xc.getName()); - } + private ReflectionManager rm = ReflectionManager.INSTANCE; - public void testReturnsSameXClassForSameClass() { - XClass<?> xc1 = ReflectionManager.INSTANCE.toXClass(void.class); - XClass<?> xc2 = ReflectionManager.INSTANCE.toXClass(void.class); - assertSame(xc2, xc1); - } - - public void testReturnsNullForANullClass() { - assertNull(ReflectionManager.INSTANCE.toXClass(null)); - } + public void testReturnsAnXClassThatWrapsTheGivenClass() { + XClass xc = rm.toXClass( Integer.class ); + assertEquals( "java.lang.Integer", xc.getName() ); + } + + public void testReturnsSameXClassForSameClass() { + XClass xc1 = rm.toXClass( void.class ); + XClass xc2 = rm.toXClass( void.class ); + assertSame( xc2, xc1 ); + } + + public void testReturnsNullForANullClass() { + assertNull( rm.toXClass( null ) ); + } + + public void testComparesXClassesWithClasses() { + XClass xc = rm.toXClass( Integer.class ); + assertTrue( rm.equals( xc, Integer.class ) ); + } + + public void testSupportsNullsInComparisons() { + XClass xc = rm.toXClass( Integer.class ); + assertFalse( rm.equals( null, Number.class ) ); + assertFalse( rm.equals( xc, null ) ); + assertTrue( rm.equals( null, null ) ); + } } Index: Foo.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/Foo.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- Foo.java 24 Jan 2006 16:01:03 -0000 1.1 +++ Foo.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -2,32 +2,30 @@ import java.util.List; -import javax.persistence.Entity; - - /** * @author Paolo Perrotta */ -@Entity(name="xyz") +@TestAnnotation(name = "xyz") public class Foo extends FooFather { - public static Integer staticField; - - public Integer fieldProperty; + public static Integer staticField; - public List<String> getCollectionProperty() { - return null; - } - - public Integer getMethodProperty() { - return null; - } + Integer fieldProperty; - public int getPrimitiveProperty() { - return 0; - } + public List<String> getCollectionProperty() { + return null; + } - public static Integer getStaticThing() { - return null; - } + @TestAnnotation(name = "xyz") + public Integer getMethodProperty() { + return null; + } + + public int getPrimitiveProperty() { + return 0; + } + + public static Integer getStaticThing() { + return null; + } } Index: FooFather.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/FooFather.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- FooFather.java 24 Jan 2006 16:01:03 -0000 1.1 +++ FooFather.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -7,17 +7,17 @@ */ public abstract class FooFather<T> { - public Integer fatherField; + public Integer fatherField; - public Boolean isFatherMethod() { - return null; - } - - public T getParameterizedProperty() { - return null; - } - - public List<T> getParameterizedCollectionProperty() { - return null; - } + public Boolean isFatherMethod() { + return null; + } + + public T getParameterizedProperty() { + return null; + } + + public List<T> getParameterizedCollectionProperty() { + return null; + } } Index: JavaXClassTest.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/JavaXClassTest.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- JavaXClassTest.java 24 Jan 2006 16:01:03 -0000 1.1 +++ JavaXClassTest.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -2,64 +2,79 @@ import java.util.List; -import junit.framework.TestCase; - import org.hibernate.annotations.CacheModeType; import org.hibernate.reflection.ReflectionManager; +import org.hibernate.reflection.XAnnotatedElement; import org.hibernate.reflection.XClass; import org.hibernate.reflection.XProperty; +import org.hibernate.test.reflection.java.generics.Dad; +import org.hibernate.test.reflection.java.generics.Grandpa; +import org.hibernate.test.reflection.java.generics.Son; /** * @author Paolo Perrotta */ -public class JavaXClassTest extends TestCase { +public class JavaXClassTest extends XAnnotatedElementTest { - XClass<Foo> clazz = ReflectionManager.INSTANCE.toXClass(Foo.class); - XClass<FooFather> fatherClazz = ReflectionManager.INSTANCE.toXClass(FooFather.class); + XClass clazz; - public void testHasAName() throws Exception { - assertSame("org.hibernate.test.reflection.java.Foo", clazz.getName()); - } + XClass fatherClazz = ReflectionManager.INSTANCE.toXClass( Grandpa.class ); - public void testHasASuperclass() throws Exception { - assertSame(fatherClazz, clazz.getSuperclass()); - } + @Override + protected void setUp() { + clazz = ReflectionManager.INSTANCE.toXClass( Son.class ).getSuperclass(); + } - public void testHasAPackage() throws Exception { - assertEquals("org.hibernate.test.reflection.java", clazz.getPackage().getName()); - } + public void testHasAnOwnerClass() { + // The "owner" is the "point of view" through which we see a class. + // Since Dad is an Entity, getting it through Son.getSuperclass() gives + // us a view of Dad with Son as an owner. + XClass sameView = ReflectionManager.INSTANCE.toXClass( Son.class ).getSuperclass(); + XClass differentView = ReflectionManager.INSTANCE.toXClass( Dad.class ); + assertSame( sameView, clazz ); + assertNotSame( differentView, clazz ); + } - public void testCanBeAssignableFromAnotherXClass() throws Exception { - assertFalse(clazz.isAssignableFrom(fatherClazz)); - assertTrue(fatherClazz.isAssignableFrom(clazz)); - } - - public void testCanBeConvertedToAJavaClass() throws Exception { - assertSame(Foo.class, clazz.toClass()); - } - - public void testExtractsPublicFieldsAsProperties() { - List<XProperty> fieldProperties = clazz.getDeclaredProperties("field"); - assertEquals(1, fieldProperties.size()); - } + public void testHasAName() { + assertSame( "org.hibernate.test.reflection.java.generics.Dad", clazz.getName() ); + } - public void testExtractsPublicMethodsAsProperties() { - List<XProperty> methodProperties = clazz.getDeclaredProperties("property"); - assertEquals(3, methodProperties.size()); - } - - public void testCanBeAbstract() { - assertFalse(clazz.isAbstract()); - assertTrue(ReflectionManager.INSTANCE.toXClass(FooFather.class).isAbstract()); - } - - public void testCanBeAPrimitive() throws Exception { - assertFalse(clazz.isPrimitive()); - assertTrue(ReflectionManager.INSTANCE.toXClass(int.class).isPrimitive()); - } - - public void testCanBeAnEnum() throws Exception { - assertFalse(clazz.isEnum()); - assertTrue(ReflectionManager.INSTANCE.toXClass(CacheModeType.class).isEnum()); - } + public void testHasASuperclass() { + assertEquals( fatherClazz, clazz.getSuperclass() ); + } + + public void testCanBeAssignableFromAnotherXClass() { + assertFalse( clazz.isAssignableFrom( fatherClazz ) ); + assertTrue( fatherClazz.isAssignableFrom( clazz ) ); + } + + public void testExtractsPublicFieldsAsProperties() { + List<XProperty> fieldProperties = clazz.getDeclaredProperties( "field" ); + assertEquals( 1, fieldProperties.size() ); + } + + public void testExtractsPublicMethodsAsProperties() { + List<XProperty> methodProperties = clazz.getDeclaredProperties( "property" ); + assertEquals( 6, methodProperties.size() ); + } + + public void testCanBeAbstract() { + assertFalse( clazz.isAbstract() ); + assertTrue( ReflectionManager.INSTANCE.toXClass( Grandpa.class ).isAbstract() ); + } + + public void testCanBeAPrimitive() { + assertFalse( clazz.isPrimitive() ); + assertTrue( ReflectionManager.INSTANCE.toXClass( int.class ).isPrimitive() ); + } + + public void testCanBeAnEnum() { + assertFalse( clazz.isEnum() ); + assertTrue( ReflectionManager.INSTANCE.toXClass( CacheModeType.class ).isEnum() ); + } + + @Override + protected XAnnotatedElement getConcreteInstance() { + return ReflectionManager.INSTANCE.toXClass( Dad.class ); + } } --- JavaXAnnotatedElementTest.java DELETED --- --- JavaXMemberTest.java DELETED --- |
Update of /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21308/metadata/src/java/org/hibernate/reflection Modified Files: XClass.java XAnnotatedElement.java XProperty.java ReflectionManager.java XPackage.java Log Message: Support for generics in reflection layer Index: XClass.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/XClass.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- XClass.java 26 Jan 2006 15:02:55 -0000 1.3 +++ XClass.java 13 Feb 2006 19:14:35 -0000 1.4 @@ -1,32 +1,31 @@ package org.hibernate.reflection; +import java.lang.reflect.Method; import java.util.List; /** * @author Paolo Perrotta * @author Davide Marchignoli */ -public interface XClass<T> extends XAnnotatedElement { +public interface XClass extends XAnnotatedElement { - String getName(); + String getName(); - XPackage getPackage(); - - XClass getSuperclass(); + XClass getSuperclass(); - boolean isAbstract(); + boolean isAbstract(); - boolean isPrimitive(); + boolean isPrimitive(); - boolean isEnum(); + boolean isEnum(); - boolean isAssignableFrom(XClass c); + boolean isAssignableFrom(XClass c); - // TODO: remove the parameter by pushing the access type guessing down here? emmanuel: I'm -1 List<XProperty> getDeclaredProperties(String accessType); - //TODO emmanuel: we need to add a getDeclaredMethods for EntityManager and possibly Validator - - // TODO: this one must die - Class<T> toClass(); + /** + * Returns the Java <tt>Method</tt>s defined by this class. + */ + // TODO: not called right now. is it still useful? if so, is there any way to avoid it? + Method[] getDeclaredMethods(); } Index: XAnnotatedElement.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/XAnnotatedElement.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- XAnnotatedElement.java 24 Jan 2006 16:01:02 -0000 1.1 +++ XAnnotatedElement.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -8,9 +8,9 @@ */ public interface XAnnotatedElement { - <T extends Annotation> T getAnnotation(Class<T> annotationType); + <T extends Annotation> T getAnnotation(Class<T> annotationType); - <T extends Annotation> boolean isAnnotationPresent(Class<T> annotationType); - - Annotation[] getAnnotations(); + <T extends Annotation> boolean isAnnotationPresent(Class<T> annotationType); + + Annotation[] getAnnotations(); } Index: XProperty.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/XProperty.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- XProperty.java 26 Jan 2006 15:02:55 -0000 1.3 +++ XProperty.java 13 Feb 2006 19:14:35 -0000 1.4 @@ -2,40 +2,38 @@ import java.util.Collection; - /** * @author Paolo Perrotta * @author Davide Marchignoli */ public interface XProperty extends XAnnotatedElement { - String getName(); + String getName(); - boolean isCollection(); + boolean isCollection(); - boolean isArray(); + boolean isArray(); - /** - * Returns either the type of this property (for single values), or - * the type of this property's elements (for Collections and arrays). - * @return The type of this property or its elements, or null if it cannot guess it. - */ - // TODO: the idea is to refactor the binding layer enough that we can uniformily deal with - // "single values" and "multiple values" (collections and arrays) in most situations. - // We hope it can be done. Right now, this method might as well be two separate methods - // getClass() and getElementClass(). - // emmanuel: I don't understand the idea - XClass getClassOrElementClass(); + // TODO We should probably try to reduce the following four methods to two or three at most. + // the last one is particularly offensive - /** - * @return the raw class of this property, assuming that this property is a Collection (List.class, etc.). - * - * @throws RuntimeException if !isCollection() - */ - Class<? extends Collection> getCollectionClass(); - - // TODO: this stuff is temporary - the root entity should be guessed within this layer - // remove after the refactoring to the X layer is done, and just use getClassOrElementClass() - XClass getType(XClass rootEntity); - XClass getClassOrElement(XClass rootEntity); + /** + * The collection class for collections, null for others. + */ + Class<? extends Collection> getCollectionClass(); + + /** + * This property's XClass. + */ + XClass getType(); + + /** + * This property's type for simple properties, the type of its elements for arrays and collections. + */ + XClass getElementClass(); + + /** + * The type of this property's elements for arrays, the type of the property itself for everything else. + */ + XClass getClassOrElementClass(); } Index: ReflectionManager.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/ReflectionManager.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- ReflectionManager.java 25 Jan 2006 21:48:21 -0000 1.2 +++ ReflectionManager.java 13 Feb 2006 19:14:35 -0000 1.3 @@ -1,6 +1,6 @@ package org.hibernate.reflection; -import org.hibernate.reflection.java.JavaReflectionManager; +import org.hibernate.reflection.java.JavaXFactory; /** * The entry point to the reflection layer (a.k.a. the X* layer). @@ -10,12 +10,14 @@ */ public interface ReflectionManager { - // TODO: turn this Singleton into a plug-in - public static final JavaReflectionManager INSTANCE = new JavaReflectionManager(); + // TODO: turn this Singleton into a plug-in + public static final JavaXFactory INSTANCE = new JavaXFactory(); - public <T> XClass<T> toXClass(Class<T> clazz); - - public <T> XClass<T> classForName(String name, Class<T> caller) throws ClassNotFoundException; - - public XPackage packageForName(String packageName) throws ClassNotFoundException; + public <T> XClass toXClass(Class<T> clazz); + + public <T> XClass classForName(String name, Class<T> caller) throws ClassNotFoundException; + + public XPackage packageForName(String packageName) throws ClassNotFoundException; + + public <T> boolean equals(XClass class1, Class<T> class2); } Index: XPackage.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/reflection/XPackage.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- XPackage.java 24 Jan 2006 16:01:02 -0000 1.1 +++ XPackage.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -6,5 +6,5 @@ */ public interface XPackage extends XAnnotatedElement { - String getName(); + String getName(); } |
From: <pao...@us...> - 2006-02-13 19:14:43
|
Update of /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/generics In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21308/metadata/src/test/org/hibernate/test/reflection/java/generics Modified Files: Dad.java Son.java Grandpa.java Added Files: TestAnnotation.java TypeEnvironmentFactoryTest.java Neighbour.java Removed Files: GenericsEnvironmentTest.java Log Message: Support for generics in reflection layer --- NEW FILE: TestAnnotation.java --- package org.hibernate.test.reflection.java.generics; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * @author Davide Marchignoli * @author Paolo Perrotta */ @Target( { TYPE, METHOD, FIELD }) @Retention(RUNTIME) public @interface TestAnnotation { String name() default "abc"; } --- NEW FILE: TypeEnvironmentFactoryTest.java --- package org.hibernate.test.reflection.java.generics; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.List; import java.util.Set; import junit.framework.TestCase; import org.hibernate.reflection.java.generics.TypeEnvironmentFactory; /** * @author Davide Marchignoli * @author Paolo Perrotta */ public class TypeEnvironmentFactoryTest extends TestCase { public void testBindsGenericsToSuperclassEnvironment() throws SecurityException, NoSuchMethodException { TypeEnvironmentFactory env = new TypeEnvironmentFactory(); Type type = Grandpa.class.getMethod( "returnsGeneric", new Class[0] ).getGenericReturnType(); Type asSeenFromGrandpa = env.getEnvironment( Grandpa.class ).bind( type ); assertTrue( asSeenFromGrandpa instanceof TypeVariable ); assertEquals( "T", asSeenFromGrandpa.toString() ); Type asSeenFromDad = env.getEnvironment( Dad.class ).bind( type ); assertTrue( asSeenFromDad instanceof ParameterizedType ); assertEquals( "java.util.List<T>", asSeenFromDad.toString() ); ParameterizedType asSeenFromSon = (ParameterizedType) env.getEnvironment( Son.class ).bind( type ); assertType_isCollectionOfClass_withElementsOfClass( asSeenFromSon, List.class, String.class ); } public void testBindsGenericsToOwnerEnvironment() throws SecurityException, NoSuchMethodException { TypeEnvironmentFactory env = new TypeEnvironmentFactory(); Type friendType = Dad.class.getMethod( "getFriend", new Class[0] ).getGenericReturnType(); ParameterizedType friendTypeAsSeenFromDad = (ParameterizedType) env.getEnvironment( Dad.class ).bind( friendType ); Class friendClass = (Class) friendTypeAsSeenFromDad.getRawType(); Type returnType = friendClass.getMethod( "embeddedProperty", new Class[0] ).getGenericReturnType(); ParameterizedType boundType = (ParameterizedType) env.getEnvironment( friendTypeAsSeenFromDad ).bind( returnType ); assertType_isCollectionOfClass_withElementsOfClass( boundType, Set.class, Integer.class ); } private void assertType_isCollectionOfClass_withElementsOfClass(ParameterizedType t, Class collectionClass, Class elementClass) { assertEquals( collectionClass, t.getRawType() ); assertEquals( 1, t.getActualTypeArguments().length ); assertEquals( elementClass, t.getActualTypeArguments()[0] ); } } --- NEW FILE: Neighbour.java --- package org.hibernate.test.reflection.java.generics; import java.util.Set; /** * @author Davide Marchignoli * @author Paolo Perrotta */ public class Neighbour<T> { public Set<T> embeddedProperty() { return null; } } Index: Dad.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/generics/Dad.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- Dad.java 1 Feb 2006 13:43:33 -0000 1.1 +++ Dad.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -1,11 +1,48 @@ package org.hibernate.test.reflection.java.generics; import java.util.List; +import java.util.Map; +import javax.persistence.Entity; /** * @author Davide Marchignoli * @author Paolo Perrotta */ -public class Dad<T> extends Grandpa<List<T>>{ +@TestAnnotation(name = "xyz") +@Entity +public class Dad<T> extends Grandpa<List<T>, Integer> { + + static Integer staticField; + + T fieldProperty; + + public Map<Double, T> getCollectionProperty() { + return null; + } + + @TestAnnotation(name = "xyz") + public Integer getMethodProperty() { + return null; + } + + public int getPrimitiveProperty() { + return 0; + } + + public boolean isPropertyStartingWithIs() { + return false; + } + + public int[] getPrimitiveArrayProperty() { + return null; + } + + public T[] getArrayProperty() { + return null; + } + + public static Integer getStaticThing() { + return null; + } } Index: Son.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/generics/Son.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- Son.java 1 Feb 2006 13:43:33 -0000 1.1 +++ Son.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -1,6 +1,5 @@ package org.hibernate.test.reflection.java.generics; - /** * @author Davide Marchignoli * @author Paolo Perrotta Index: Grandpa.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/reflection/java/generics/Grandpa.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- Grandpa.java 1 Feb 2006 13:43:33 -0000 1.1 +++ Grandpa.java 13 Feb 2006 19:14:35 -0000 1.2 @@ -4,9 +4,16 @@ * @author Davide Marchignoli * @author Paolo Perrotta */ -public class Grandpa<T> { +public abstract class Grandpa<T, U> { - public T genericMethod() { - return null; - } + Integer grandpaField; + + public T returnsGeneric() { + return null; + } + + // generic embedded value + public Neighbour<U> getFriend() { + return null; + } } --- GenericsEnvironmentTest.java DELETED --- |
From: <epb...@us...> - 2006-02-13 18:18:38
|
Update of /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32558/metadata/src/test/org/hibernate/test/annotations/inheritance Modified Files: SubclassTest.java Log Message: ANN-223 generate disc value even for integers and raise an exception for chars ANN-240 inital work, need test and refinement for @Embeddable Index: SubclassTest.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/SubclassTest.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- SubclassTest.java 12 Feb 2006 11:37:55 -0000 1.9 +++ SubclassTest.java 13 Feb 2006 18:18:25 -0000 1.10 @@ -100,32 +100,6 @@ s.close(); } - public void testDefault() throws Exception { - Session s; - Transaction tx; - s = openSession(); - tx = s.beginTransaction(); - Fruit f = new Fruit(); - Apple a = new Apple(); - s.persist(f); - s.persist(a); - tx.commit(); - s.close(); - - s = openSession(); - tx = s.beginTransaction(); - assertEquals( 1, s.createQuery( "select count(*) from Fruit f where f.class = 'Apple'").uniqueResult() ); - List result = s.createCriteria(Fruit.class).list(); - assertNotNull(result); - assertEquals( 2, result.size() ); - Fruit f2 = (Fruit) result.get(0); - checkClassType(f2, f, a); - f2 = (Fruit) result.get(1); - checkClassType(f2, f, a); - tx.commit(); - s.close(); - } - public void testFormula() throws Exception { Session s; Transaction tx; |
From: <epb...@us...> - 2006-02-13 18:18:38
|
Update of /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32558/metadata/src/java/org/hibernate/cfg Modified Files: AnnotationBinder.java PropertyHolderBuilder.java Log Message: ANN-223 generate disc value even for integers and raise an exception for chars ANN-240 inital work, need test and refinement for @Embeddable Index: AnnotationBinder.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java,v retrieving revision 1.173 retrieving revision 1.174 diff -u -d -r1.173 -r1.174 --- AnnotationBinder.java 11 Feb 2006 02:50:57 -0000 1.173 +++ AnnotationBinder.java 13 Feb 2006 18:18:25 -0000 1.174 @@ -469,11 +469,12 @@ constraints, inheritanceState.hasDenormalizedTable() ? superEntity.getTable() : null ); } - Map<String, Column[]> columnOverride = PropertyHolderBuilder.buildColumnOverride( - annotatedClass, + Map<String, Column[]> columnOverride = PropertyHolderBuilder.buildHierarchyColumnOverride( + clazzToProcess, persistentClass.getClassName() ); PropertyHolder propertyHolder = PropertyHolderBuilder.buildPropertyHolder( + //clazzToProcess, persistentClass, columnOverride, entityBinder.getSecondaryTables() @@ -525,6 +526,7 @@ entityBinder.getSecondaryTables(), propertyHolder ); + entityBinder.bindDiscriminatorValue();//bind it again since the type might have changed } } } @@ -1476,6 +1478,7 @@ String subpath = StringHelper.qualify( propertyHolder.getPath(), inferredData.getPropertyName() ); log.debug( "Binding component with path: " + subpath ); Map<String, Column[]> localColumnOverride = propertyHolder.mergeOverridenColumns( columnOverride ); + //TODO work on it PropertyHolder subHolder = PropertyHolderBuilder.buildPropertyHolder( comp, subpath, localColumnOverride ); List<PropertyAnnotatedElement> classElements = new ArrayList<PropertyAnnotatedElement>(); XClass returnedClassOrElement = inferredData.getReturnedClassOrElement(); @@ -1514,7 +1517,9 @@ String generatorType, String generatorName, PropertyData inferredData, Ejb3Column[] columns, PropertyHolder propertyHolder, Map<String, IdGenerator> localGenerators, - boolean isComposite, Map<String, Column[]> columnOverride, boolean isPropertyAnnotated, + boolean isComposite, + Map<String, Column[]> columnOverride, + boolean isPropertyAnnotated, String propertyAccessor, EntityBinder entityBinder, Type typeAnn, boolean isEmbedded, ExtendedMappings mappings ) { Index: PropertyHolderBuilder.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/PropertyHolderBuilder.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- PropertyHolderBuilder.java 25 Jan 2006 21:48:21 -0000 1.9 +++ PropertyHolderBuilder.java 13 Feb 2006 18:18:25 -0000 1.10 @@ -6,12 +6,17 @@ import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.MappedSuperclass; +import javax.persistence.Embeddable; import org.hibernate.mapping.Collection; import org.hibernate.mapping.Component; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Join; import org.hibernate.reflection.XAnnotatedElement; +import org.hibernate.reflection.XClass; +import org.hibernate.reflection.ReflectionManager; import org.hibernate.util.StringHelper; /** @@ -24,8 +29,13 @@ } public static PropertyHolder buildPropertyHolder( + //XClass clazzToProcess, PersistentClass persistentClass, Map<String, Column[]> columnOverride, Map<String, Join> joins ) { +// Map<String, Column[]> columnOverride = PropertyHolderBuilder.buildHierarchyColumnOverride( +// clazzToProcess, +// persistentClass.getClassName() +// ); return (PropertyHolder) new ClassPropertyHolder( persistentClass, columnOverride, joins ); } @@ -53,6 +63,23 @@ return buildPropertyHolder( persistentClass, new HashMap<String, Column[]>(), joins ); } + public static Map<String, Column[]> buildHierarchyColumnOverride(XClass element, String path) { + XClass current = element; + Map<String, Column[]> columnOverride = new HashMap<String, Column[]>(); + while ( ! ReflectionManager.INSTANCE.toXClass( Object.class ).equals( current ) ) { + if ( current.isAnnotationPresent(Entity.class) || current.isAnnotationPresent(MappedSuperclass.class) + || current.isAnnotationPresent(Embeddable.class) ) { + //FIXME is embeddable override? + Map<String, Column[]> currentOverride = buildColumnOverride( element, path ); + currentOverride.putAll(columnOverride); //subclasses have precedence over superclasses + columnOverride = currentOverride; + } + current = current.getSuperclass(); + } + + return columnOverride; + } + public static Map<String, Column[]> buildColumnOverride(XAnnotatedElement element, String path) { AttributeOverride singleOverride = element.getAnnotation( AttributeOverride.class ); AttributeOverrides multipleOverrides = element.getAnnotation( AttributeOverrides.class ); |
Update of /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32558/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable Modified Files: SingleTableTest.java Added Files: PaperTrash.java Trash.java Log Message: ANN-223 generate disc value even for integers and raise an exception for chars ANN-240 inital work, need test and refinement for @Embeddable --- NEW FILE: PaperTrash.java --- //$Id: PaperTrash.java,v 1.1 2006/02/13 18:18:25 epbernard Exp $ package org.hibernate.test.annotations.inheritance.singletable; import javax.persistence.Entity; /** * @author Emmanuel Bernard */ @Entity public class PaperTrash extends Trash { } --- NEW FILE: Trash.java --- //$Id: Trash.java,v 1.1 2006/02/13 18:18:25 epbernard Exp $ package org.hibernate.test.annotations.inheritance.singletable; import javax.persistence.Entity; import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorType; import javax.persistence.Id; import javax.persistence.GeneratedValue; /** * @author Emmanuel Bernard */ @Entity @DiscriminatorColumn(discriminatorType= DiscriminatorType.INTEGER) public class Trash { @Id @GeneratedValue private Integer id; } Index: SingleTableTest.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/SingleTableTest.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- SingleTableTest.java 4 Nov 2005 19:25:44 -0000 1.1 +++ SingleTableTest.java 13 Feb 2006 18:18:25 -0000 1.2 @@ -1,7 +1,11 @@ //$Id$ package org.hibernate.test.annotations.inheritance.singletable; +import java.util.List; + import org.hibernate.test.annotations.TestCase; +import org.hibernate.test.annotations.inheritance.Fruit; +import org.hibernate.test.annotations.inheritance.Apple; import org.hibernate.Session; import org.hibernate.Transaction; @@ -23,10 +27,77 @@ s.close(); } + public void testDefault() throws Exception { + Session s; + Transaction tx; + s = openSession(); + tx = s.beginTransaction(); + Fruit f = new Fruit(); + Apple a = new Apple(); + s.persist(f); + s.persist(a); + tx.commit(); + s.close(); + + s = openSession(); + tx = s.beginTransaction(); + assertEquals( 1, s.createQuery( "select count(*) from Fruit f where f.class = 'Apple'").uniqueResult() ); + List result = s.createCriteria(Fruit.class).list(); + assertNotNull(result); + assertEquals( 2, result.size() ); + Fruit f2 = (Fruit) result.get(0); + checkClassType(f2, f, a); + f2 = (Fruit) result.get(1); + checkClassType(f2, f, a); + s.delete( result.get(0) ); + s.delete( result.get(1) ); + tx.commit(); + s.close(); + } + + public void testDefaultIntegerDiscriminator() throws Exception { + Session s; + Transaction tx; + s = openSession(); + tx = s.beginTransaction(); + Trash t = new Trash(); + PaperTrash pt = new PaperTrash(); + s.persist(t); + s.persist(pt); + tx.commit(); + s.close(); + + s = openSession(); + tx = s.beginTransaction(); + assertEquals( 1, s.createQuery( "select count(*) from Trash f where f.class = :disc") + .setString( "disc", String.valueOf( "PaperTrash".hashCode() ) ).uniqueResult() ); + List result = s.createCriteria(Trash.class).list(); + assertNotNull(result); + s.delete( result.get(0) ); + s.delete( result.get(1) ); + tx.commit(); + s.close(); + } + + private void checkClassType(Fruit fruitToTest, Fruit f, Apple a) { + if ( fruitToTest.getId().equals( f.getId() ) ) { + assertFalse(fruitToTest instanceof Apple); + } else if ( fruitToTest.getId().equals( a.getId() ) ) { + assertTrue(fruitToTest instanceof Apple); + } else { + fail("Result does not contains the previously inserted elements"); + } + } + + protected Class[] getMappings() { return new Class[] { Building.class, - House.class + House.class, + Fruit.class, + Apple.class, + Trash.class, + PaperTrash.class }; } } |
From: <epb...@us...> - 2006-02-13 18:18:38
|
Update of /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32558/metadata/src/java/org/hibernate/cfg/annotations Modified Files: EntityBinder.java Log Message: ANN-223 generate disc value even for integers and raise an exception for chars ANN-240 inital work, need test and refinement for @Embeddable Index: EntityBinder.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/EntityBinder.java,v retrieving revision 1.40 retrieving revision 1.41 diff -u -d -r1.40 -r1.41 --- EntityBinder.java 12 Feb 2006 11:37:54 -0000 1.40 +++ EntityBinder.java 13 Feb 2006 18:18:25 -0000 1.41 @@ -43,6 +43,7 @@ import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Table; import org.hibernate.mapping.TableOwner; +import org.hibernate.mapping.Value; import org.hibernate.reflection.ReflectionManager; import org.hibernate.reflection.XAnnotatedElement; import org.hibernate.reflection.XClass; @@ -146,12 +147,7 @@ persistentClass.setClassName( annotatedClass.getName() ); //persistentClass.setDynamic(false); //no longer needed with the Entity name refactoring? persistentClass.setEntityName( annotatedClass.getName() ); - if ( StringHelper.isEmpty( discriminatorValue ) ) { - persistentClass.setDiscriminatorValue( name ); - } - else { - persistentClass.setDiscriminatorValue( discriminatorValue ); - } + bindDiscriminatorValue(); persistentClass.setLazy( lazy ); if ( proxyClass != null ) { @@ -211,6 +207,28 @@ } } + public void bindDiscriminatorValue() { + if ( StringHelper.isEmpty( discriminatorValue ) ) { + Value discriminator = persistentClass.getDiscriminator(); + if ( discriminator == null ) { + persistentClass.setDiscriminatorValue( name ); + } + else if ( "character".equals( discriminator.getType().getName() ) ) { + throw new AnnotationException("Using default @DiscriminatorValue for a discriminator of type CHAR is not safe"); + } + else if ( "integer".equals( discriminator.getType().getName() ) ) { + persistentClass.setDiscriminatorValue( String.valueOf( name.hashCode() ) ); + } + else { + persistentClass.setDiscriminatorValue( name ); //Spec compliant + } + } + else { + //persistentClass.getDiscriminator() + persistentClass.setDiscriminatorValue( discriminatorValue ); + } + } + int getVersioning(OptimisticLockType type) { switch ( type ) { case VERSION: |
From: <epb...@us...> - 2006-02-13 18:18:36
|
Update of /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/annotations/join In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32558/metadata/src/test/org/hibernate/test/annotations/join Modified Files: Cat.java Log Message: ANN-223 generate disc value even for integers and raise an exception for chars ANN-240 inital work, need test and refinement for @Embeddable Index: Cat.java =================================================================== RCS file: /cvsroot/hibernate/HibernateExt/metadata/src/test/org/hibernate/test/annotations/join/Cat.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- Cat.java 13 Jan 2006 01:58:40 -0000 1.7 +++ Cat.java 13 Feb 2006 18:18:26 -0000 1.8 @@ -18,7 +18,7 @@ */ @Entity @SecondaryTables({ - @SecondaryTable(name="Cat1"), + @SecondaryTable(name="`Cat nbr1`"), @SecondaryTable(name="Cat2", uniqueConstraints={@UniqueConstraint(columnNames={"storyPart2"})}) }) @Table(name="Cat", indexes = @Index(name="secondname", columnNames="secondName")) @@ -67,7 +67,7 @@ // lifes = collection; // } - @Column(table ="Cat1") + @Column(table ="`Cat nbr1`") @Index(name="story1index") public String getStoryPart1() { return storyPart1; |