Home » tapestry-src-5.0.19 » org.apache.tapestry5.hibernate » [javadoc | source]

    1   // Copyright 2007, 2008 The Apache Software Foundation
    2   //
    3   // Licensed under the Apache License, Version 2.0 (the "License");
    4   // you may not use this file except in compliance with the License.
    5   // You may obtain a copy of the License at
    6   //
    7   //     http://www.apache.org/licenses/LICENSE-2.0
    8   //
    9   // Unless required by applicable law or agreed to in writing, software
   10   // distributed under the License is distributed on an "AS IS" BASIS,
   11   // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12   // See the License for the specific language governing permissions and
   13   // limitations under the License.
   14   
   15   package org.apache.tapestry5.hibernate;
   16   
   17   import org.apache.tapestry5.ValueEncoder;
   18   import org.apache.tapestry5.internal.InternalConstants;
   19   import org.apache.tapestry5.internal.hibernate;
   20   import org.apache.tapestry5.ioc;
   21   import org.apache.tapestry5.ioc.annotations.Inject;
   22   import org.apache.tapestry5.ioc.annotations.Local;
   23   import org.apache.tapestry5.ioc.annotations.Scope;
   24   import org.apache.tapestry5.ioc.annotations.Symbol;
   25   import org.apache.tapestry5.ioc.services;
   26   import org.apache.tapestry5.services.AliasContribution;
   27   import org.apache.tapestry5.services.ComponentClassTransformWorker;
   28   import org.apache.tapestry5.services.PersistentFieldStrategy;
   29   import org.apache.tapestry5.services.ValueEncoderFactory;
   30   import org.hibernate.Session;
   31   import org.hibernate.mapping.PersistentClass;
   32   import org.slf4j.Logger;
   33   
   34   import java.util.Collection;
   35   import java.util.Iterator;
   36   import java.util.List;
   37   
   38   @SuppressWarnings({"JavaDoc"})
   39   public class HibernateModule
   40   {
   41   
   42       public static void bind(ServiceBinder binder)
   43       {
   44           binder.bind(HibernateTransactionDecorator.class, HibernateTransactionDecoratorImpl.class);
   45           binder.bind(HibernateConfigurer.class, DefaultHibernateConfigurer.class).withId("DefaultHibernateConfigurer");
   46       }
   47   
   48       public static void contributeFactoryDefaults(MappedConfiguration<String, String> configuration)
   49       {
   50           configuration.add(HibernateConstants.PROVIDE_ENTITY_VALUE_ENCODERS_SYMBOL, "true");
   51           configuration.add(HibernateConstants.DEFAULT_CONFIGURATION, "true");
   52       }
   53   
   54       public static HibernateEntityPackageManager buildHibernateEntityPackageManager(
   55               final Collection<String> packageNames)
   56       {
   57           return new HibernateEntityPackageManager()
   58           {
   59               public Collection<String> getPackageNames()
   60               {
   61                   return packageNames;
   62               }
   63           };
   64       }
   65   
   66       /**
   67        * Contributes the package "&lt;root&gt;.entities" to the configuration, so that it will be scanned for annotated
   68        * entity classes.
   69        */
   70       public static void contributeHibernateEntityPackageManager(Configuration<String> configuration,
   71   
   72                                                                  @Inject
   73                                                                  @Symbol(InternalConstants.TAPESTRY_APP_PACKAGE_PARAM)
   74                                                                  String appRootPackage)
   75       {
   76           configuration.add(appRootPackage + ".entities");
   77       }
   78   
   79       /**
   80        * The session manager manages sessions on a per-thread/per-request basis. A {@link org.hibernate.Transaction} is
   81        * created initially, and is committed at the end of the request.
   82        */
   83       @Scope(ScopeConstants.PERTHREAD)
   84       public static HibernateSessionManager buildHibernateSessionManager(HibernateSessionSource sessionSource,
   85                                                                          PerthreadManager perthreadManager)
   86       {
   87           HibernateSessionManagerImpl service = new HibernateSessionManagerImpl(sessionSource);
   88   
   89           perthreadManager.addThreadCleanupListener(service);
   90   
   91           return service;
   92       }
   93   
   94       public static Session buildSession(HibernateSessionManager sessionManager,
   95                                          PropertyShadowBuilder propertyShadowBuilder)
   96       {
   97           // Here's the thing: the tapestry.hibernate.Session class doesn't have to be per-thread,
   98           // since
   99           // it will invoke getSession() on the HibernateSessionManager service (which is per-thread).
  100           // On
  101           // first invocation per request,
  102           // this forces the HSM into existence (which creates the session and begins the
  103           // transaction).
  104           // Thus we don't actually create
  105           // a session until we first try to access it, then the session continues to exist for the
  106           // rest
  107           // of the request.
  108   
  109           return propertyShadowBuilder.build(sessionManager, "session", Session.class);
  110       }
  111   
  112       public static void contributeAlias(Configuration<AliasContribution> configuration, @Local Session session)
  113       {
  114           configuration.add(AliasContribution.create(Session.class, session));
  115       }
  116   
  117       public static HibernateSessionSource buildHibernateSessionSource(Logger logger, List<HibernateConfigurer> config,
  118                                                                        RegistryShutdownHub hub)
  119       {
  120           HibernateSessionSourceImpl hss = new HibernateSessionSourceImpl(logger, config);
  121   
  122           hub.addRegistryShutdownListener(hss);
  123   
  124           return hss;
  125       }
  126   
  127       /**
  128        * Adds the following configurers: <dl> <dt>Default <dd> performs default hibernate configuration <dt>PackageName
  129        * <dd> loads entities by package name</dl>
  130        */
  131       public static void contributeHibernateSessionSource(OrderedConfiguration<HibernateConfigurer> config,
  132   
  133                                                           @Local HibernateConfigurer defaultHibernateConfigurer,
  134   
  135                                                           ObjectLocator locator)
  136       {
  137           config.add("Default", defaultHibernateConfigurer);
  138           config.add("PackageName", locator.autobuild(PackageNameHibernateConfigurer.class));
  139       }
  140   
  141       /**
  142        * Contributes {@link ValueEncoderFactory}s for all registered Hibernate entity classes. Encoding and decoding are
  143        * based on the id property value of the entity using type coercion. Hence, if the id can be coerced to a String and
  144        * back then the entity can be coerced.
  145        */
  146       @SuppressWarnings("unchecked")
  147       public static void contributeValueEncoderSource(MappedConfiguration<Class, ValueEncoderFactory> configuration,
  148                                                       @Symbol(HibernateConstants.PROVIDE_ENTITY_VALUE_ENCODERS_SYMBOL)
  149                                                       boolean provideEncoders,
  150                                                       final HibernateSessionSource sessionSource,
  151                                                       final Session session,
  152                                                       final TypeCoercer typeCoercer,
  153                                                       final PropertyAccess propertyAccess,
  154                                                       final LoggerSource loggerSource)
  155       {
  156           if (!provideEncoders) return;
  157   
  158           org.hibernate.cfg.Configuration config = sessionSource.getConfiguration();
  159           Iterator<PersistentClass> mappings = config.getClassMappings();
  160           while (mappings.hasNext())
  161           {
  162               final PersistentClass persistentClass = mappings.next();
  163               final Class entityClass = persistentClass.getMappedClass();
  164   
  165               ValueEncoderFactory factory = new ValueEncoderFactory()
  166               {
  167                   public ValueEncoder create(Class type)
  168                   {
  169                       return new HibernateEntityValueEncoder(entityClass, persistentClass, session, propertyAccess,
  170                                                              typeCoercer, loggerSource.getLogger(entityClass));
  171                   }
  172               };
  173   
  174               configuration.add(entityClass, factory);
  175           }
  176       }
  177   
  178       /**
  179        * Contributes the following: <dl> <dt>entity</dt> <dd>Stores the id of the entity and reloads from the {@link
  180        * Session}</dd> </dl>
  181        */
  182       public static void contributePersistentFieldManager(
  183               MappedConfiguration<String, PersistentFieldStrategy> configuration,
  184               ObjectLocator locator)
  185       {
  186           configuration.add("entity", locator.autobuild(EntityPersistentFieldStrategy.class));
  187       }
  188   
  189       /**
  190        * Adds the CommitAfter annotation work, to process the {@link org.apache.tapestry5.hibernate.annotations.CommitAfter}
  191        * annotation.
  192        */
  193       public static void contributeComponentClassTransformWorker(
  194               OrderedConfiguration<ComponentClassTransformWorker> configuration,
  195               ObjectLocator locator)
  196       {
  197           // If logging is enabled, we want logging to be the first advice, wrapping around the commit advice.
  198   
  199           configuration.add("CommitAfter", locator.autobuild(CommitAfterWorker.class), "after:Log");
  200       }
  201   }

Home » tapestry-src-5.0.19 » org.apache.tapestry5.hibernate » [javadoc | source]