You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by Howard Lewis Ship <hl...@gmail.com> on 2008/03/08 17:48:34 UTC

Re: 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/o

Looks awesome!

On Sat, Mar 8, 2008 at 7:23 AM,  <da...@apache.org> wrote:
> 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>
>
>
>



-- 
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: 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/o

Posted by Howard Lewis Ship <hl...@gmail.com>.
If an entity id isn't int or long I find it suspect.

On Sat, Mar 8, 2008 at 12:42 PM, Dan Adams <da...@ifactory.com> wrote:
> Feels good to do some commits. I'm almost done with the @Once annotation.
>
>  I encountered an interesting situation when doing this; handling
>  composite id's. But the type coercion was the perfect solution to it. If
>  you have an entity with a composite id (some other custom object) just
>  add a coercion for it and it will get handled perfectly. But I'm not
>  terribly concerned about supporting composite id's anyway since it
>  doesn't seem like a major use case.
>
>
>
>  Howard Lewis Ship wrote:
>  > Looks awesome!
>  >
>  > On Sat, Mar 8, 2008 at 7:23 AM,  <da...@apache.org> wrote:
>  >
>  >> 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>
>  >>
>  >>
>  >>
>  >>
>  >
>  >
>  >
>  >
>
>
>  ---------------------------------------------------------------------
>  To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
>  For additional commands, e-mail: dev-help@tapestry.apache.org
>
>



-- 
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org


Re: 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/o

Posted by Dan Adams <da...@ifactory.com>.
Feels good to do some commits. I'm almost done with the @Once annotation.

I encountered an interesting situation when doing this; handling 
composite id's. But the type coercion was the perfect solution to it. If 
you have an entity with a composite id (some other custom object) just 
add a coercion for it and it will get handled perfectly. But I'm not 
terribly concerned about supporting composite id's anyway since it 
doesn't seem like a major use case.

Howard Lewis Ship wrote:
> Looks awesome!
>
> On Sat, Mar 8, 2008 at 7:23 AM,  <da...@apache.org> wrote:
>   
>> 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>
>>
>>
>>
>>     
>
>
>
>   


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org