[jboss-cvs] jboss-seam/src/main/org/jboss/seam/persistence ...

Gavin King gavin.king at jboss.com
Tue Jun 19 15:02:36 EDT 2007


  User: gavin   
  Date: 07/06/19 15:02:36

  Modified:    src/main/org/jboss/seam/persistence          
                        HibernatePersistenceProvider.java
                        PersistenceProvider.java
  Added:       src/main/org/jboss/seam/persistence          
                        EntityManagerFactory.java Filter.java
                        HibernateSessionFactory.java
                        ManagedHibernateSession.java
                        ManagedPersistenceContext.java
                        PersistenceContextManager.java
                        PersistenceContexts.java package-info.java
  Log:
  repackaged built-in components
  sorry for breakage, but it had to happen eventually :-(
  
  Revision  Changes    Path
  1.13      +1 -3      jboss-seam/src/main/org/jboss/seam/persistence/HibernatePersistenceProvider.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: HibernatePersistenceProvider.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/persistence/HibernatePersistenceProvider.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -b -r1.12 -r1.13
  --- HibernatePersistenceProvider.java	18 Jun 2007 20:38:22 -0000	1.12
  +++ HibernatePersistenceProvider.java	19 Jun 2007 19:02:36 -0000	1.13
  @@ -21,8 +21,6 @@
   import org.jboss.seam.annotations.Intercept;
   import org.jboss.seam.annotations.Name;
   import org.jboss.seam.annotations.Scope;
  -import org.jboss.seam.core.Filter;
  -import org.jboss.seam.core.ManagedPersistenceContext;
   import org.jboss.seam.core.Expressions.ValueExpression;
   
   /**
  @@ -42,7 +40,7 @@
      @Override
      public void setFlushModeManual(EntityManager entityManager)
      {
  -      getSession(entityManager).setFlushMode(FlushMode.NEVER);
  +      getSession(entityManager).setFlushMode(FlushMode.MANUAL);
      }
   
      @Override
  
  
  
  1.14      +0 -2      jboss-seam/src/main/org/jboss/seam/persistence/PersistenceProvider.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: PersistenceProvider.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/persistence/PersistenceProvider.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -b -r1.13 -r1.14
  --- PersistenceProvider.java	18 Jun 2007 20:38:22 -0000	1.13
  +++ PersistenceProvider.java	19 Jun 2007 19:02:36 -0000	1.14
  @@ -17,8 +17,6 @@
   import org.jboss.seam.annotations.Intercept;
   import org.jboss.seam.annotations.Name;
   import org.jboss.seam.annotations.Scope;
  -import org.jboss.seam.core.Filter;
  -import org.jboss.seam.core.ManagedPersistenceContext;
   
   /**
    * Abstraction layer for persistence providers (JPA implementations).
  
  
  
  1.1      date: 2007/06/19 19:02:36;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/persistence/EntityManagerFactory.java
  
  Index: EntityManagerFactory.java
  ===================================================================
  //$Id: EntityManagerFactory.java,v 1.1 2007/06/19 19:02:36 gavin Exp $
  package org.jboss.seam.persistence;
  
  import static org.jboss.seam.InterceptionType.NEVER;
  
  import java.util.HashMap;
  import java.util.Hashtable;
  import java.util.Map;
  
  import javax.persistence.Persistence;
  
  import org.hibernate.cfg.Environment;
  import org.jboss.seam.Component;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Create;
  import org.jboss.seam.annotations.Destroy;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Startup;
  import org.jboss.seam.annotations.Unwrap;
  import org.jboss.seam.util.Naming;
  
  /**
   * A Seam component that boostraps an EntityManagerFactory,
   * for use of JPA outside of Java EE 5 / Embeddable EJB3.
   * 
   * @author Gavin King
   */
  @Scope(ScopeType.APPLICATION)
  @Intercept(NEVER)
  @Startup
  public class EntityManagerFactory
  {
  
     private String persistenceUnitName;
     private Map persistenceUnitProperties;
     private javax.persistence.EntityManagerFactory entityManagerFactory;
     
     @Unwrap
     public javax.persistence.EntityManagerFactory getEntityManagerFactory()
     {
        return entityManagerFactory;
     }
     
     @Create
     public void startup(Component component) throws Exception
     {
        if (persistenceUnitName==null)
        {
           persistenceUnitName = component.getName();
        }
        
        Map properties = new HashMap();
        Hashtable<String, String> jndiProperties = Naming.getInitialContextProperties();
        if ( jndiProperties!=null )
        {
           // Prefix regular JNDI properties for Hibernate
           for (Map.Entry<String, String> entry : jndiProperties.entrySet())
           {
              properties.put( Environment.JNDI_PREFIX + "." + entry.getKey(), entry.getValue() );
           }
        }
        if (persistenceUnitProperties!=null)
        {
           properties.putAll(persistenceUnitProperties);
        }
  
        if ( properties.isEmpty() )
        {
           entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnitName);
        }
        else
        {
           entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnitName, properties);
        }
     }
     
     @Destroy
     public void shutdown()
     {
        if (entityManagerFactory!=null)
        {
           entityManagerFactory.close();
        }
     }
     
     /**
      * The persistence unit name
      */
     public String getPersistenceUnitName()
     {
        return persistenceUnitName;
     }
  
     public void setPersistenceUnitName(String persistenceUnitName)
     {
        this.persistenceUnitName = persistenceUnitName;
     }
  
     /**
      * Properties to pass to Persistence.createEntityManagerFactory()
      */
     public Map getPersistenceUnitProperties()
     {
        return persistenceUnitProperties;
     }
  
     public void setPersistenceUnitProperties(Map persistenceUnitProperties)
     {
        this.persistenceUnitProperties = persistenceUnitProperties;
     }
  
  }
  
  
  
  1.1      date: 2007/06/19 19:02:36;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/persistence/Filter.java
  
  Index: Filter.java
  ===================================================================
  package org.jboss.seam.persistence;
  
  import java.util.Map;
  
  import org.jboss.seam.Component;
  import org.jboss.seam.InterceptionType;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Create;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.core.Expressions.ValueExpression;
  
  /**
   * Support for declarative application of
   * Hibernate filters to persistence contexts.
   * 
   * @see org.hibernate.Filter
   * @see ManagedHibernateSession
   * @see ManagedPersistenceContext
   * @author Gavin King
   */
  @Intercept(InterceptionType.NEVER)
  @Scope(ScopeType.APPLICATION)
  public class Filter
  {
     private String name;
     private Map<String, ValueExpression> parameters;
     private ValueExpression enabled;
     
     @Create
     public void create(Component component)
     {
        //default the filter name to the component name
        if (name==null)
        {
           name = component.getName();
        }
     }
     
     /**
      * The filter parameters.
      * 
      * @see org.hibernate.Filter#setParameter(String, Object)
      */
     public Map<String, ValueExpression> getParameters()
     {
        return parameters;
     }
     public void setParameters(Map<String, ValueExpression> parameters)
     {
        this.parameters = parameters;
     }
     
     /**
      * The Hibernate filter name.
      * 
      * @see org.hibernate.Session#enableFilter(String)
      */
     public String getName()
     {
        return name;
     }
     
     public void setName(String name)
     {
        this.name = name;
     }
     
     public boolean isFilterEnabled()
     {
        ValueExpression enabledValueBinding = getEnabled();
        if (enabledValueBinding==null)
        {
           return true;
        }
        else
        {
           Boolean enabled = (Boolean) enabledValueBinding.getValue();
           return enabled!=null && enabled;
        }
     }
  
     @Override
     public String toString()
     {
        return "Filter(" + name + ")";
     }
  
     public ValueExpression getEnabled()
     {
        return enabled;
     }
  
     public void setEnabled(ValueExpression enabled)
     {
        this.enabled = enabled;
     }
  }
  
  
  
  1.1      date: 2007/06/19 19:02:36;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/persistence/HibernateSessionFactory.java
  
  Index: HibernateSessionFactory.java
  ===================================================================
  //$Id: HibernateSessionFactory.java,v 1.1 2007/06/19 19:02:36 gavin Exp $
  package org.jboss.seam.persistence;
  
  import static org.jboss.seam.InterceptionType.NEVER;
  
  import java.io.File;
  import java.util.Hashtable;
  import java.util.List;
  import java.util.Map;
  import java.util.Properties;
  
  import org.hibernate.SessionFactory;
  import org.hibernate.cfg.AnnotationConfiguration;
  import org.hibernate.cfg.Environment;
  import org.hibernate.cfg.NamingStrategy;
  import org.hibernate.util.ReflectHelper;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Create;
  import org.jboss.seam.annotations.Destroy;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Startup;
  import org.jboss.seam.annotations.Unwrap;
  import org.jboss.seam.security.HibernateSecurityInterceptor;
  import org.jboss.seam.util.Naming;
  
  /**
   * A Seam component that boostraps a Hibernate SessionFactory
   * 
   * <p>
   * Loads Hibernate configuration options by checking:
   * <li>hibernate.properties in root of the classpath
   * <li>hibernate.cfg.xml in root of the classpath
   * <li>cfgResourceName as location of a cfg.xml file
   * <li>factory-suplied cfgProperties options
   * <p>
   * Note that this factory only supports cfg.xml files <b>or</b> programmatic
   * <tt>cfgProperties</tt> supplied to the factory. Any
   * <tt>hibernate.properties</tt> are always loaded from the classpath.
   * <p>
   * Mapping metadata can be supplied through:
   * <li>mappingClasses: equivalent to &lt;mapping class="..."/>
   * <li>mappingFiles: equivalent to &lt;mapping file="..."/>
   * <li>mappingJars: equivalent to &lt;mapping jar="..."/>
   * <li>mappingPackages: equivalent to &lt;mapping package="..."/>
   * <li>mappingResources: equivalent to &lt;mapping resource="..."/>
   * <p>
   * or through cfg.xml files.
   * <p>
   * The <tt>jndiProperties</tt> are convenience, the factory will automatically
   * prefix regular JNDI properties for use as Hibernate configuration properties.
   * 
   * @author Gavin King
   * @author Christian Bauer
   */
  @Scope(ScopeType.APPLICATION)
  @Intercept(NEVER)
  @Startup
  public class HibernateSessionFactory
  {
     private SessionFactory sessionFactory;
  
     private String cfgResourceName;
     private Map<String, String> cfgProperties;
     private List<String> mappingClasses;
     private List<String> mappingFiles;
     private List<String> mappingJars;
     private List<String> mappingPackages;
     private List<String> mappingResources;
     private NamingStrategy namingStrategy;
     
     @Unwrap
     public SessionFactory getSessionFactory() throws Exception
     {
        return createSessionFactory();
     }
     
     protected SessionFactory createSessionFactory() throws ClassNotFoundException
     {
        AnnotationConfiguration configuration = new AnnotationConfiguration();
        
        // setup non-default naming strategy
        if (namingStrategy != null)
        {
           configuration.setNamingStrategy(namingStrategy);
        }
        
        // Programmatic configuration
        if (cfgProperties != null)
        {
           Properties props = new Properties();
           props.putAll(cfgProperties);
           configuration.setProperties(props);
        }
        Hashtable<String, String> jndiProperties = Naming.getInitialContextProperties();
        if ( jndiProperties!=null )
        {
           // Prefix regular JNDI properties for Hibernate
           for (Map.Entry<String, String> entry : jndiProperties.entrySet())
           {
              configuration.setProperty( Environment.JNDI_PREFIX + "." + entry.getKey(), entry.getValue() );
           }
        }
        // hibernate.cfg.xml configuration
        if (cfgProperties==null && cfgResourceName==null)
        {
           configuration.configure();
        } 
        else if (cfgProperties==null && cfgResourceName!=null)
        {
           configuration.configure(cfgResourceName);
        }
        // Mapping metadata
        if (mappingClasses!=null)
        {
           for (String className: mappingClasses) 
           {
              configuration.addAnnotatedClass(ReflectHelper.classForName(className));
           }
        }
        if (mappingFiles!=null)
        {
           for (String fileName: mappingFiles) 
           {
              configuration.addFile(fileName);
           }
        }
        if (mappingJars!=null)
        {
           for (String jarName: mappingJars) 
           {
              configuration.addJar(new File(jarName));
           }
        }
        if (mappingPackages!= null)
        {
           for (String packageName: mappingPackages) 
           {
              configuration.addPackage(packageName);
           }
        }
        if (mappingResources!= null)
        {
           for (String resourceName : mappingResources) 
           {
              configuration.addResource(resourceName);
           }
        }
        
        configuration.setInterceptor(new HibernateSecurityInterceptor(configuration.getInterceptor()));
        
        return configuration.buildSessionFactory();
     }
     
     @Create
     public void startup() throws Exception
     {
        sessionFactory = createSessionFactory();
     }
     
     @Destroy
     public void shutdown()
     {
        sessionFactory.close();
     }
  
     public String getCfgResourceName()
     {
        return cfgResourceName;
     }
     
     public void setCfgResourceName(String cfgFileName)
     {
        this.cfgResourceName = cfgFileName;
     }
     
     public NamingStrategy getNamingStrategy()
     {
        return namingStrategy;
     }
     
     public void setNamingStrategy(NamingStrategy namingStrategy)
     {
        this.namingStrategy = namingStrategy;
     }
     
     public Map<String, String> getCfgProperties()
     {
        return cfgProperties;
     }
     public void setCfgProperties(Map<String, String> cfgProperties)
     {
        this.cfgProperties = cfgProperties;
     }
     public List<String> getMappingClasses()
     {
        return mappingClasses;
     }
     public void setMappingClasses(List<String> mappingClasses)
     {
        this.mappingClasses = mappingClasses;
     }
     public List<String> getMappingFiles()
     {
        return mappingFiles;
     }
     public void setMappingFiles(List<String> mappingFiles)
     {
        this.mappingFiles = mappingFiles;
     }
     public List<String> getMappingJars()
     {
        return mappingJars;
     }
     public void setMappingJars(List<String> mappingJars)
     {
        this.mappingJars = mappingJars;
     }
     public List<String> getMappingPackages()
     {
        return mappingPackages;
     }
     public void setMappingPackages(List<String> mappingPackages)
     {
        this.mappingPackages = mappingPackages;
     }
     public List<String> getMappingResources()
     {
        return mappingResources;
     }
     public void setMappingResources(List<String> mappingResources)
     {
        this.mappingResources = mappingResources;
     }
     
  }
  
  
  
  1.1      date: 2007/06/19 19:02:36;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/persistence/ManagedHibernateSession.java
  
  Index: ManagedHibernateSession.java
  ===================================================================
  //$Id: ManagedHibernateSession.java,v 1.1 2007/06/19 19:02:36 gavin Exp $
  package org.jboss.seam.persistence;
  
  import static org.jboss.seam.InterceptionType.NEVER;
  
  import java.io.Serializable;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Map;
  
  import javax.naming.NamingException;
  import javax.servlet.http.HttpSessionActivationListener;
  import javax.servlet.http.HttpSessionEvent;
  import javax.transaction.Synchronization;
  import javax.transaction.SystemException;
  
  import org.hibernate.FlushMode;
  import org.hibernate.Session;
  import org.hibernate.SessionFactory;
  import org.jboss.seam.Component;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Create;
  import org.jboss.seam.annotations.Destroy;
  import org.jboss.seam.annotations.FlushModeType;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Unwrap;
  import org.jboss.seam.async.LocalTransactionListener;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.contexts.Lifecycle;
  import org.jboss.seam.core.Mutable;
  import org.jboss.seam.core.TransactionListener;
  import org.jboss.seam.core.Expressions.ValueExpression;
  import org.jboss.seam.log.LogProvider;
  import org.jboss.seam.log.Logging;
  import org.jboss.seam.transaction.Transaction;
  import org.jboss.seam.util.Naming;
  
  /**
   * A Seam component that manages a conversation-scoped extended
   * persistence context that can be shared by arbitrary other
   * components.
   * 
   * @author Gavin King
   */
  @Scope(ScopeType.CONVERSATION)
  @Intercept(NEVER)
  public class ManagedHibernateSession 
     implements Serializable, HttpSessionActivationListener, Mutable, PersistenceContextManager, Synchronization
  {
     
     /** The serialVersionUID */
     private static final long serialVersionUID = 3130309555079841107L;
  
     private static final LogProvider log = Logging.getLogProvider(ManagedHibernateSession.class);
     
     private Session session;
     private String sessionFactoryJndiName;
     private String componentName;
     private ValueExpression<SessionFactory> sessionFactory;
     private List<Filter> filters = new ArrayList<Filter>(0);
     
     private transient boolean synchronizationRegistered;
     
     public boolean clearDirty()
     {
        return true;
     }
  
     @Create
     public void create(Component component)
     {
        this.componentName = component.getName();
        if (sessionFactoryJndiName==null)
        {
           sessionFactoryJndiName = "java:/" + componentName;
        }
              
        PersistenceContexts.instance().touch(componentName);
     }
  
     private void initSession()
     {
        session = getSessionFactoryFromJndiOrValueBinding().openSession();
        session = new HibernateSessionProxy(session);
        setSessionFlushMode( PersistenceContexts.instance().getFlushMode() );
        for (Filter f: filters)
        {
           if ( f.isFilterEnabled() )
           {
              enableFilter(f);
           }
        }
  
        if ( log.isDebugEnabled() )
        {
           log.debug("created seam managed session for session factory: "+ sessionFactoryJndiName);
        }
     }
  
     private void enableFilter(Filter f)
     {
        org.hibernate.Filter filter = session.enableFilter( f.getName() );
        for ( Map.Entry<String, ValueExpression> me: f.getParameters().entrySet() )
        {
           filter.setParameter( me.getKey(), me.getValue().getValue() );
        }
        filter.validate();
     }
     
     @Unwrap
     public Session getSession() throws SystemException
     {
        if (session==null) initSession();
        
        //join the transaction
        if ( !synchronizationRegistered && !Lifecycle.isDestroying() && Transaction.instance().isActive() )
        {
           session.isOpen();
           LocalTransactionListener transactionListener = TransactionListener.instance();
           if (transactionListener!=null)
           {
              transactionListener.registerSynchronization(this);
           }
           else
           {
              session.getTransaction().registerSynchronization(this);
           }
           synchronizationRegistered = true;
        }
        
        return session;
     }
     
     //we can't use @PrePassivate because it is intercept NEVER
     public void sessionWillPassivate(HttpSessionEvent event)
     {
        if ( session!=null && !session.isDirty() )
        {
           session.close();
           session = null;
        }
     }
     
     //we can't use @PostActivate because it is intercept NEVER
     public void sessionDidActivate(HttpSessionEvent event) {}
     
     @Destroy
     public void destroy()
     {
        if ( !synchronizationRegistered )
        {
           //in requests that come through SeamPhaseListener,
           //there can be multiple transactions per request,
           //but they are all completed by the time contexts
           //are destroyed
           //so wait until the end of the request to close
           //the session
           //on the other hand, if we are still waiting for
           //the transaction to commit, leave it open
           close();
        }
        PersistenceContexts.instance().untouch(componentName);
     }
  
     public void afterCompletion(int status)
     {
        synchronizationRegistered = false;
        if ( !Contexts.isConversationContextActive() )
        {
           //in calls to MDBs and remote calls to SBs, the 
           //transaction doesn't commit until after contexts
           //are destroyed, so wait until the transaction
           //completes before closing the session
           //on the other hand, if we still have an active
           //conversation context, leave it open
           close();
        }
     }
     
     public void beforeCompletion() {}
     
     private void close()
     {
        if ( log.isDebugEnabled() )
        {
           log.debug("destroying seam managed session for session factory: " + sessionFactoryJndiName);
        }
        if (session!=null)
        {
           session.close();
        }
     }
     
     private SessionFactory getSessionFactoryFromJndiOrValueBinding()
     {
        SessionFactory result = null;
        //first try to find it via the value binding
        if (sessionFactory!=null)
        {
           result = sessionFactory.getValue();
        }
        //if its not there, try JNDI
        if (result==null)
        {
           try
           {
              result = (SessionFactory) Naming.getInitialContext().lookup(sessionFactoryJndiName);
           }
           catch (NamingException ne)
           {
              throw new IllegalArgumentException("SessionFactory not found in JNDI", ne);
           }
        }
        return result;
     }
     
     public String getComponentName() {
        return componentName;
     }
     
     public void changeFlushMode(FlushModeType flushMode)
     {
        if (session!=null)
        {
           setSessionFlushMode(flushMode);
        }
     }
  
     protected void setSessionFlushMode(FlushModeType flushMode)
     {
        switch (flushMode)
        {
           case AUTO:
              session.setFlushMode(FlushMode.AUTO);
              break;
           case MANUAL:
              session.setFlushMode(FlushMode.MANUAL);
              break;
           case COMMIT:
              session.setFlushMode(FlushMode.COMMIT);
              break;
        }
     }
     
     /**
      * The JNDI name of the Hibernate SessionFactory, if it is
      * to be obtained from JNDI
      */
     public String getSessionFactoryJndiName()
     {
        return sessionFactoryJndiName;
     }
  
     public void setSessionFactoryJndiName(String sessionFactoryName)
     {
        this.sessionFactoryJndiName = sessionFactoryName;
     }
  
     /**
      * A value binding expression that returns a SessionFactory,
      * if it is to be obtained as a Seam component reference
      */
     public void setSessionFactory(ValueExpression<SessionFactory> sessionFactory)
     {
        this.sessionFactory = sessionFactory;
     }
  
     public ValueExpression<SessionFactory> getSessionFactory()
     {
        return sessionFactory;
     }
  
     /**
      * Hibernate filters to enable automatically
      */
     public List<Filter> getFilters()
     {
        return filters;
     }
  
     public void setFilters(List<Filter> filters)
     {
        this.filters = filters;
     }
  
     @Override
     public String toString()
     {
        return "ManagedHibernateSession(" + sessionFactoryJndiName + ")";
     }
  
  }
  
  
  
  1.1      date: 2007/06/19 19:02:36;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/persistence/ManagedPersistenceContext.java
  
  Index: ManagedPersistenceContext.java
  ===================================================================
  //$Id: ManagedPersistenceContext.java,v 1.1 2007/06/19 19:02:36 gavin Exp $
  package org.jboss.seam.persistence;
  
  import static org.jboss.seam.InterceptionType.NEVER;
  
  import java.io.Serializable;
  import java.util.ArrayList;
  import java.util.List;
  
  import javax.naming.NamingException;
  import javax.persistence.EntityManager;
  import javax.persistence.EntityManagerFactory;
  import javax.servlet.http.HttpSessionActivationListener;
  import javax.servlet.http.HttpSessionEvent;
  import javax.transaction.Synchronization;
  import javax.transaction.SystemException;
  
  import org.jboss.seam.Component;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Create;
  import org.jboss.seam.annotations.Destroy;
  import org.jboss.seam.annotations.FlushModeType;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Unwrap;
  import org.jboss.seam.async.LocalTransactionListener;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.contexts.Lifecycle;
  import org.jboss.seam.core.Mutable;
  import org.jboss.seam.core.TransactionListener;
  import org.jboss.seam.core.Expressions.ValueExpression;
  import org.jboss.seam.log.LogProvider;
  import org.jboss.seam.log.Logging;
  import org.jboss.seam.transaction.Transaction;
  import org.jboss.seam.util.Naming;
  
  /**
   * A Seam component that manages a conversation-scoped extended
   * persistence context that can be shared by arbitrary other
   * components.
   * 
   * @author Gavin King
   */
  @Scope(ScopeType.CONVERSATION)
  @Intercept(NEVER)
  @Install(false)
  public class ManagedPersistenceContext 
     implements Serializable, HttpSessionActivationListener, Mutable, PersistenceContextManager, Synchronization
  {
     private static final long serialVersionUID = -4972387440275848126L;
     private static final LogProvider log = Logging.getLogProvider(ManagedPersistenceContext.class);
     
     private EntityManager entityManager;
     private String persistenceUnitJndiName;
     private String componentName;
     private ValueExpression<EntityManagerFactory> entityManagerFactory;
     private List<Filter> filters = new ArrayList<Filter>(0);
     
     private transient boolean synchronizationRegistered;
    
     public boolean clearDirty()
     {
        return true;
     }
     
     @Create
     public void create(Component component)
     {
        this.componentName = component.getName();
        if (persistenceUnitJndiName==null)
        {
           persistenceUnitJndiName = "java:/" + componentName;
        }
        
        PersistenceContexts.instance().touch(componentName);      
     }
     
     private void initEntityManager()
     {
        entityManager = getEntityManagerFactoryFromJndiOrValueBinding().createEntityManager();
        entityManager = new EntityManagerProxy(entityManager);
        setEntityManagerFlushMode( PersistenceContexts.instance().getFlushMode() );
  
        for (Filter f: filters)
        {
           if ( f.isFilterEnabled() )
           {
              PersistenceProvider.instance().enableFilter(f, entityManager);
           }
        }
  
        if ( log.isDebugEnabled() )
        {
           if (entityManagerFactory==null)
           {
              log.debug("created seam managed persistence context for persistence unit: "+ persistenceUnitJndiName);
           }
           else 
           {
              log.debug("created seam managed persistence context from EntityManagerFactory");
           }
        }
     }
     
     @Unwrap
     public EntityManager getEntityManager() throws NamingException, SystemException
     {
        if (entityManager==null) initEntityManager();
        
        //join the transaction
        if ( !synchronizationRegistered && !Lifecycle.isDestroying() && Transaction.instance().isActive() )
        {
           entityManager.joinTransaction();
           LocalTransactionListener transactionListener = TransactionListener.instance();
           if (transactionListener!=null)
           {
              transactionListener.registerSynchronization(this);
              synchronizationRegistered = true;
           }
           else
           {
              synchronizationRegistered = PersistenceProvider.instance().registerSynchronization(this, entityManager);
           }
        }
        
        return entityManager;
     }
     
     //we can't use @PrePassivate because it is intercept NEVER
     public void sessionWillPassivate(HttpSessionEvent event)
     {
        //need to create a context, because this can get called
        //outside the JSF request, and we want to use the
        //PersistenceProvider object
        boolean createContext = !Contexts.isApplicationContextActive();
        if (createContext) Lifecycle.beginCall();
        try
        {
           if ( entityManager!=null && !PersistenceProvider.instance().isDirty(entityManager) )
           {
              entityManager.close();
              entityManager = null;
           }
        }
        finally
        {
           if (createContext) Lifecycle.endCall();
        }
     }
     
     //we can't use @PostActivate because it is intercept NEVER
     public void sessionDidActivate(HttpSessionEvent event) {}
     
     @Destroy
     public void destroy()
     {
        if ( !synchronizationRegistered )
        {
           //in requests that come through SeamPhaseListener,
           //there can be multiple transactions per request,
           //but they are all completed by the time contexts
           //are destroyed
           //so wait until the end of the request to close
           //the session
           //on the other hand, if we are still waiting for
           //the transaction to commit, leave it open
           close();
        }
        PersistenceContexts.instance().untouch(componentName);
     }
  
     public void afterCompletion(int status)
     {
        synchronizationRegistered = false;
        if ( !Contexts.isConversationContextActive() )
        {
           //in calls to MDBs and remote calls to SBs, the 
           //transaction doesn't commit until after contexts
           //are destroyed, so wait until the transaction
           //completes before closing the session
           //on the other hand, if we still have an active
           //conversation context, leave it open
           close();
        }
     }
     
     public void beforeCompletion() {}
     
     private void close()
     {
        if ( log.isDebugEnabled() )
        {
           log.debug("destroying seam managed persistence context for persistence unit: " + persistenceUnitJndiName);
        }
        
        if (entityManager!=null)
        {
           entityManager.close();
        }
     }
     
     public EntityManagerFactory getEntityManagerFactoryFromJndiOrValueBinding()
     {
        EntityManagerFactory result = null;
        //first try to find it via the value binding
        if (entityManagerFactory!=null)
        {
           result = entityManagerFactory.getValue();
        }
        //if its not there, try JNDI
        if (result==null)
        {
           try
           {
              result = (EntityManagerFactory) Naming.getInitialContext().lookup(persistenceUnitJndiName);
           }
           catch (NamingException ne)
           {
              throw new IllegalArgumentException("EntityManagerFactory not found in JNDI", ne);
           }
        }
        return result;
     }
     
     /**
      * A value binding expression that returns an EntityManagerFactory,
      * for use of JPA outside of Java EE 5 / Embeddable EJB3.
      */
     public ValueExpression<EntityManagerFactory> getEntityManagerFactory()
     {
        return entityManagerFactory;
     }
     
     public void setEntityManagerFactory(ValueExpression<EntityManagerFactory> entityManagerFactory)
     {
        this.entityManagerFactory = entityManagerFactory;
     }
     
     /**
      * The JNDI name of the EntityManagerFactory, for 
      * use of JPA in Java EE 5 / Embeddable EJB3.
      */
     public String getPersistenceUnitJndiName()
     {
        return persistenceUnitJndiName;
     }
     
     public void setPersistenceUnitJndiName(String persistenceUnitName)
     {
        this.persistenceUnitJndiName = persistenceUnitName;
     }
     
     public String getComponentName() 
     {
        return componentName;
     }
     
     /**
      * Hibernate filters to enable automatically
      */
     public List<Filter> getFilters()
     {
        return filters;
     }
     
     public void setFilters(List<Filter> filters)
     {
        this.filters = filters;
     }
     
     public void changeFlushMode(FlushModeType flushMode)
     {
        if (entityManager!=null)
        {
           setEntityManagerFlushMode(flushMode);
        }
     }
     
     protected void setEntityManagerFlushMode(FlushModeType flushMode)
     {
        switch (flushMode)
        {
           case AUTO:
              entityManager.setFlushMode(javax.persistence.FlushModeType.AUTO);
              break;
           case COMMIT:
              entityManager.setFlushMode(javax.persistence.FlushModeType.COMMIT);
              break;
           case MANUAL:
              PersistenceProvider.instance().setFlushModeManual(entityManager);
              break;
        }
     }
     @Override
     public String toString()
     {
        return "ManagedPersistenceContext(" + persistenceUnitJndiName + ")";
     }
  }
  
  
  
  1.1      date: 2007/06/19 19:02:36;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/persistence/PersistenceContextManager.java
  
  Index: PersistenceContextManager.java
  ===================================================================
  package org.jboss.seam.persistence;
  
  import org.jboss.seam.annotations.FlushModeType;
  
  public interface PersistenceContextManager
  {
     public void changeFlushMode(FlushModeType flushMode);
  }
  
  
  
  1.1      date: 2007/06/19 19:02:36;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/persistence/PersistenceContexts.java
  
  Index: PersistenceContexts.java
  ===================================================================
  package org.jboss.seam.persistence;
  
  import static org.jboss.seam.InterceptionType.NEVER;
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import java.io.Serializable;
  import java.util.Collections;
  import java.util.HashSet;
  import java.util.Set;
  
  import org.jboss.seam.Component;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.FlushModeType;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.core.AbstractMutable;
  
  @Name("org.jboss.seam.persistence.persistenceContexts")
  @Scope(ScopeType.CONVERSATION)
  @Intercept(NEVER)
  @Install(precedence=BUILT_IN)
  public class PersistenceContexts extends AbstractMutable implements Serializable
  {
     private static final long serialVersionUID = -4897350516435283182L;
     private Set<String> set = new HashSet<String>();
     private FlushModeType flushMode = FlushModeType.AUTO;
     private FlushModeType actualFlushMode = FlushModeType.AUTO;
   
     public FlushModeType getFlushMode()
     {
        return flushMode;
     }
     
     public Set<String> getTouchedContexts()
     {
        return Collections.unmodifiableSet(set);
     }
     
     public void touch(String context)
     {
        if ( set.add(context) ) setDirty();
     }
     
     public void untouch(String context)
     {
        if ( set.remove(context) ) setDirty();
     }
     
     public static PersistenceContexts instance()
     {
        if ( Contexts.isConversationContextActive() )
        {
           return (PersistenceContexts) Component.getInstance(PersistenceContexts.class);
        }
        else
        {
           return null;
        }
     }
     
     public void changeFlushMode(FlushModeType flushMode)
     {
        this.flushMode = flushMode;
        this.actualFlushMode = flushMode;
        changeFlushModes();   
     }
  
     private void changeFlushModes()
     {
        for (String name: set)
        {
           PersistenceContextManager pcm = (PersistenceContextManager) Contexts.getConversationContext().get(name);
           if (pcm!=null)
           {
              pcm.changeFlushMode(flushMode);
           }
        }
     }
     
     public void beforeRender()
     {
        PersistenceProvider pp = PersistenceProvider.instance();
        flushMode = pp==null ? FlushModeType.MANUAL : pp.getRenderFlushMode();
        changeFlushModes();
     }
     
     public void afterRender()
     {
        flushMode = actualFlushMode;
        changeFlushModes();
     }
     
  }
  
  
  
  1.1      date: 2007/06/19 19:02:36;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/persistence/package-info.java
  
  Index: package-info.java
  ===================================================================
  @Namespace(value="http://jboss.com/products/seam/persistence", prefix="org.jboss.seam.persistence")
  package org.jboss.seam.persistence;
  
  import org.jboss.seam.annotations.Namespace;
  
  
  



More information about the jboss-cvs-commits mailing list