You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by da...@apache.org on 2008/03/08 16:23:23 UTC
svn commit: r634989 - in /tapestry/tapestry5/trunk/tapestry-hibernate/src:
main/java/org/apache/tapestry/hibernate/
main/java/org/apache/tapestry/internal/hibernate/ site/ site/apt/
test/java/org/apache/tapestry/hibernate/integration/ test/java/org/exa...
Author: dadams
Date: Sat Mar 8 07:23:21 2008
New Revision: 634989
URL: http://svn.apache.org/viewvc?rev=634989&view=rev
Log:
TAPESTRY-1653: Provide automatic ValueEncoders for Hibernate entities
Added:
tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java
tapestry/tapestry5/trunk/tapestry-hibernate/src/site/apt/userguide.apt
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/EncodeEntities.java
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/EncodeEntities.tml
Modified:
tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateModule.java
tapestry/tapestry5/trunk/tapestry-hibernate/src/site/site.xml
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/apache/tapestry/hibernate/integration/TapestryHibernateIntegrationTests.java
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/entities/User.java
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/Start.java
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/resources/hibernate.cfg.xml
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/Start.tml
Modified: tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateModule.java?rev=634989&r1=634988&r2=634989&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateModule.java Sat Mar 8 07:23:21 2008
@@ -14,12 +14,17 @@
package org.apache.tapestry.hibernate;
+import org.apache.tapestry.ValueEncoder;
import org.apache.tapestry.internal.InternalConstants;
import org.apache.tapestry.internal.hibernate.DefaultHibernateConfigurer;
+import org.apache.tapestry.internal.hibernate.HibernateEntityValueEncoder;
import org.apache.tapestry.internal.hibernate.HibernateSessionManagerImpl;
import org.apache.tapestry.internal.hibernate.HibernateSessionSourceImpl;
import org.apache.tapestry.internal.hibernate.PackageNameHibernateConfigurer;
import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.ObjectLocator;
+
import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
import org.apache.tapestry.ioc.OrderedConfiguration;
import org.apache.tapestry.ioc.annotations.Inject;
@@ -30,11 +35,15 @@
import org.apache.tapestry.ioc.services.PerthreadManager;
import org.apache.tapestry.ioc.services.PropertyShadowBuilder;
import org.apache.tapestry.ioc.services.RegistryShutdownHub;
+import org.apache.tapestry.ioc.services.TypeCoercer;
import org.apache.tapestry.services.AliasContribution;
+import org.apache.tapestry.services.ValueEncoderFactory;
import org.hibernate.Session;
+import org.hibernate.mapping.PersistentClass;
import org.slf4j.Logger;
import java.util.Collection;
+import java.util.Iterator;
import java.util.List;
public class HibernateModule
@@ -129,4 +138,30 @@
config.add("PackageName", new PackageNameHibernateConfigurer(packageManager, classNameLocator));
}
+ /**
+ * Contributes {@link ValueEncoderFactory}s for all registered Hibernate entity classes. Encoding and decoding are based
+ * on the id property value of the entity using type coercion. Hence, if the id can be coerced to a String and back then
+ * the entity can be coerced.
+ */
+ @SuppressWarnings("unchecked")
+ public static void contributeValueEncoderSource(MappedConfiguration<Class, ValueEncoderFactory> configuration,
+ final HibernateSessionSource sessionSource,
+ final Session session,
+ final TypeCoercer typeCoercer)
+ {
+ org.hibernate.cfg.Configuration config = sessionSource.getConfiguration();
+ Iterator<PersistentClass> mappings = config.getClassMappings();
+ while(mappings.hasNext()) {
+ final PersistentClass persistentClass = mappings.next();
+ final Class entityClass = persistentClass.getMappedClass();
+
+ ValueEncoderFactory factory = new ValueEncoderFactory() {
+ public ValueEncoder create(Class type) {
+ return new HibernateEntityValueEncoder(entityClass, persistentClass, session, typeCoercer);
+ }
+ };
+
+ configuration.add(entityClass, factory);
+ }
+ }
}
Added: tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java?rev=634989&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java (added)
+++ tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java Sat Mar 8 07:23:21 2008
@@ -0,0 +1,59 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.hibernate;
+
+import java.io.Serializable;
+
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.hibernate.Session;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.property.Getter;
+
+public final class HibernateEntityValueEncoder<E> implements ValueEncoder<E> {
+ private final Class<E> _entityClass;
+ private final PersistentClass _persistentClass;
+ private final Session _session;
+ private final TypeCoercer _typeCoercer;
+ private final Getter _idGetter;
+
+ public HibernateEntityValueEncoder(Class<E> entityClass, PersistentClass persistentClass, Session session, TypeCoercer typeCoercer) {
+ super();
+ _entityClass = entityClass;
+ _persistentClass = persistentClass;
+ _session = session;
+ _typeCoercer = typeCoercer;
+
+ Property property = _persistentClass.getIdentifierProperty();
+ _idGetter = property.getPropertyAccessor(_entityClass).getGetter(_entityClass, property.getName());
+ }
+
+ public String toClient(E value) {
+ Object id = _idGetter.get(value);
+ return _typeCoercer.coerce(id, String.class);
+ }
+
+ @SuppressWarnings("unchecked")
+ public E toValue(String clientValue) {
+ Class<?> idType = _idGetter.getReturnType();
+
+ Object id = _typeCoercer.coerce(clientValue, idType);
+ Serializable ser = Defense.cast(id, Serializable.class, "id");
+ return (E)_session.get(_entityClass, ser);
+ }
+
+}
Added: tapestry/tapestry5/trunk/tapestry-hibernate/src/site/apt/userguide.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/site/apt/userguide.apt?rev=634989&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-hibernate/src/site/apt/userguide.apt (added)
+++ tapestry/tapestry5/trunk/tapestry-hibernate/src/site/apt/userguide.apt Sat Mar 8 07:23:21 2008
@@ -0,0 +1,31 @@
+ ----
+ User Guide
+ ----
+
+Entity value encoding
+
+ Value encoders are automatically created for all mapped Hibernate entity types. This is done by encoding the entity as it's
+ id (coerced to a String) and decoding the entity by looking it up in the Hibernate Session using the encoded id. Consider
+ the following:
+
++----+
+public class ViewPerson {
+ @Property
+ private Person _person;
+
+ void onActivate(Person person)
+ {
+ _person = person;
+ }
+}
++----+
+
++----+
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+<body>
+ The person's name is: ${person.name}
+</body>
+</html>
++----+
+
+ Accessing the page as <</viewperson/152>> would load the Person entity with id 152 and use that as the page context.
Modified: tapestry/tapestry5/trunk/tapestry-hibernate/src/site/site.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/site/site.xml?rev=634989&r1=634988&r2=634989&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-hibernate/src/site/site.xml (original)
+++ tapestry/tapestry5/trunk/tapestry-hibernate/src/site/site.xml Sat Mar 8 07:23:21 2008
@@ -40,6 +40,7 @@
<menu name="Quick Links">
<item name="About" href="index.html"/>
<item name="Configuration" href="conf.html"/>
+ <item name="User guide" href="userguide.html" />
<item name="Download" href="http://tapestry.apache.org/download.html"/>
</menu>
Modified: tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/apache/tapestry/hibernate/integration/TapestryHibernateIntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/apache/tapestry/hibernate/integration/TapestryHibernateIntegrationTests.java?rev=634989&r1=634988&r2=634989&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/apache/tapestry/hibernate/integration/TapestryHibernateIntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/apache/tapestry/hibernate/integration/TapestryHibernateIntegrationTests.java Sat Mar 8 07:23:21 2008
@@ -25,12 +25,18 @@
super("src/test/webapp");
}
- /** Only needed until actual integration tests are put in. Just proves the integration
- * tests are set up correctly.
- */
- public void test_placeholder() throws Exception {
- open("/");
- // just make sure we can get the hibernate Session
- assertTrue(getText("//span[@id='session']").length() > 0);
+ public void test_valueencode_all_entity_types() throws Exception {
+ open("/encodeentities");
+
+ assertEquals(0, getText("//span[@id='name']").length());
+
+ // need to create an entity in order to link with one
+ clickAndWait("//a[@id='createentity']");
+ assertEquals("name", getText("//span[@id='name']"));
+
+ // should return null for missing objects
+ open("/encodeentities/9999");
+ assertEquals(0, getText("//span[@id='name']").length());
}
+
}
Modified: tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/entities/User.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/entities/User.java?rev=634989&r1=634988&r2=634989&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/entities/User.java (original)
+++ tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/entities/User.java Sat Mar 8 07:23:21 2008
@@ -22,67 +22,68 @@
@Entity
public class User
{
+ // NOTE: Hibernate doesn't understand the '_' syntax. It will end up putting underscores on all the properties
@Id @GeneratedValue
- private Long _id;
+ private Long id;
- private String _firstName;
+ private String firstName;
- private String _lastName;
+ private String lastName;
- private String _email;
+ private String email;
- private String _encodedPassword;
+ private String encodedPassword;
@Version
- private int _version;
+ private int version;
public String getEmail()
{
- return _email;
+ return email;
}
public String getEncodedPassword()
{
- return _encodedPassword;
+ return encodedPassword;
}
public String getFirstName()
{
- return _firstName;
+ return firstName;
}
public Long getId()
{
- return _id;
+ return id;
}
public String getLastName()
{
- return _lastName;
+ return lastName;
}
public int getVersion()
{
- return _version;
+ return version;
}
public void setEmail(String email)
{
- _email = email;
+ this.email = email;
}
public void setEncodedPassword(String encodedPassword)
{
- _encodedPassword = encodedPassword;
+ this.encodedPassword = encodedPassword;
}
public void setFirstName(String firstName)
{
- _firstName = firstName;
+ this.firstName = firstName;
}
public void setLastName(String lastName)
{
- _lastName = lastName;
+ this.lastName = lastName;
}
}
Added: tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/EncodeEntities.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/EncodeEntities.java?rev=634989&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/EncodeEntities.java (added)
+++ tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/EncodeEntities.java Sat Mar 8 07:23:21 2008
@@ -0,0 +1,37 @@
+package org.example.app0.pages;
+
+import java.util.List;
+
+import org.apache.tapestry.annotations.Property;
+import org.apache.tapestry.ioc.annotations.Inject;
+import org.example.app0.entities.User;
+import org.hibernate.Session;
+
+public class EncodeEntities {
+ @Inject
+ @Property
+ private Session _session;
+
+ @SuppressWarnings("unused")
+ @Property
+ private User _user;
+
+ void onCreate() {
+ User user = new User();
+ user.setFirstName("name");
+ _session.save(user);
+ }
+
+ @SuppressWarnings("unchecked")
+ User onPassivate() {
+ List<User> users = _session.createQuery("from User").list();
+ if (users.isEmpty())
+ return null;
+
+ return users.get(0);
+ }
+
+ void onActivate(User user) {
+ _user = user;
+ }
+}
Modified: tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/Start.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/Start.java?rev=634989&r1=634988&r2=634989&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/Start.java (original)
+++ tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/Start.java Sat Mar 8 07:23:21 2008
@@ -14,13 +14,6 @@
package org.example.app0.pages;
-import org.apache.tapestry.annotations.Property;
-import org.apache.tapestry.ioc.annotations.Inject;
-import org.hibernate.Session;
-
public class Start {
- @Property
- @Inject
- private Session _session;
}
Modified: tapestry/tapestry5/trunk/tapestry-hibernate/src/test/resources/hibernate.cfg.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/test/resources/hibernate.cfg.xml?rev=634989&r1=634988&r2=634989&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-hibernate/src/test/resources/hibernate.cfg.xml (original)
+++ tapestry/tapestry5/trunk/tapestry-hibernate/src/test/resources/hibernate.cfg.xml Sat Mar 8 07:23:21 2008
@@ -23,20 +23,19 @@
<session-factory>
<property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
- <property name="hibernate.connection.url">jdbc:hsqldb:file:target/unit-testdb</property>
+ <property name="hibernate.connection.url">jdbc:hsqldb:mem:test</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
- <property name="hbm2ddl.auto">create-drop</property>
-
+ <property name="hbm2ddl.auto">update</property>
+
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
-
</session-factory>
Added: tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/EncodeEntities.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/EncodeEntities.tml?rev=634989&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/EncodeEntities.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/EncodeEntities.tml Sat Mar 8 07:23:21 2008
@@ -0,0 +1,6 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+<body>
+ <p>entity name: <span id="name"><t:if test="user">${user.firstName}</t:if></span></p>
+ <p>create entity: <t:eventlink event="create" t:id="createentity">create an entity</t:eventlink></p>
+</body>
+</html>
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/Start.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/Start.tml?rev=634989&r1=634988&r2=634989&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/Start.tml (original)
+++ tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/Start.tml Sat Mar 8 07:23:21 2008
@@ -4,6 +4,5 @@
</head>
<body>
<h2>Test application for tapestry-hibernate integration tests</h2>
- The Hibernate session: <span id="session">${session}</span>
</body>
</html>