[jboss-cvs] jboss-seam/src/ioc/org/jboss/seam/ioc/spring ...

Michael Youngstrom youngm at gmail.com
Wed Jul 11 13:22:52 EDT 2007


  User: myoungstrom
  Date: 07/07/11 13:22:52

  Modified:    src/ioc/org/jboss/seam/ioc/spring  
                        SeamManagedEntityManagerFactory.java
  Added:       src/ioc/org/jboss/seam/ioc/spring  
                        SeamManagedSessionFactoryBean.java
  Log:
  JBSEAM-1346
  
  Revision  Changes    Path
  1.5       +13 -2     jboss-seam/src/ioc/org/jboss/seam/ioc/spring/SeamManagedEntityManagerFactory.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: SeamManagedEntityManagerFactory.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/ioc/org/jboss/seam/ioc/spring/SeamManagedEntityManagerFactory.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -b -r1.4 -r1.5
  --- SeamManagedEntityManagerFactory.java	3 Jul 2007 20:36:29 -0000	1.4
  +++ SeamManagedEntityManagerFactory.java	11 Jul 2007 17:22:52 -0000	1.5
  @@ -56,6 +56,7 @@
         log.debug("Returning a Seam Managed PC from createEntityManager()");
         SeamLifecycleUtils.beginTransactionalSeamCall();
         EntityManager em = (EntityManager) Component.getInstance(persistenceContextName);
  +      //Creating Proxy of EntityManager to ensure we implement all the interfaces 
         return (EntityManager) Proxy.newProxyInstance(getClass().getClassLoader(), ClassUtils
                  .getAllInterfaces(em), new SeamManagedPersistenceContextHandler(em));
      }
  @@ -98,6 +99,16 @@
   
         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
         {
  +         if (method.getName().equals("equals"))
  +         {
  +            // Only consider equal when proxies are identical.
  +            return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE);
  +         }
  +         if (method.getName().equals("hashCode"))
  +         {
  +            // Use hashCode of EntityManager proxy.
  +            return new Integer(hashCode());
  +         }
            if (method.getName().equals("isOpen"))
            {
               return delegate.isOpen() && !closed;
  @@ -116,11 +127,11 @@
            }
            if (closed)
            {
  -            throw new IllegalStateException("This EntityManager is closed.");
  +            throw new IllegalStateException("This PersistenceContext is closed.");
            }
            if (method.getName().equals("close"))
            {
  -            log.debug("Closing EntityManager Proxy.");
  +            log.debug("Closing PersistenceContext Proxy.");
               closed = true;
               return null;
            }
  
  
  
  1.1      date: 2007/07/11 17:22:52;  author: myoungstrom;  state: Exp;jboss-seam/src/ioc/org/jboss/seam/ioc/spring/SeamManagedSessionFactoryBean.java
  
  Index: SeamManagedSessionFactoryBean.java
  ===================================================================
  package org.jboss.seam.ioc.spring;
  
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.lang.reflect.Proxy;
  
  import org.hibernate.HibernateException;
  import org.hibernate.SessionFactory;
  import org.hibernate.classic.Session;
  import org.jboss.seam.Component;
  import org.jboss.seam.log.LogProvider;
  import org.jboss.seam.log.Logging;
  import org.springframework.beans.factory.annotation.Required;
  import org.springframework.beans.factory.config.AbstractFactoryBean;
  import org.springframework.orm.hibernate3.SessionFactoryUtils;
  import org.springframework.util.ClassUtils;
  
  /**
   * A SessionFactory that delegates requests to open a Session to a "managed-hibernate-session". 
   * @author Mike Youngstrom
   */
  public class SeamManagedSessionFactoryBean extends AbstractFactoryBean
  {
     private String sessionName;
     private SessionFactory baseSessionFactory;
     
     @Override
     public void afterPropertiesSet() throws Exception
     {
        super.afterPropertiesSet();
        if(sessionName == null || "".equals(sessionName)) {
           throw new IllegalArgumentException("SesssionName cannot be empty");
        }
     }
  
     @Override
     protected Object createInstance() throws Exception
     {
        Class[] sessionFactoryInterfaces;
        if(baseSessionFactory != null) {
           sessionFactoryInterfaces = ClassUtils.getAllInterfaces(baseSessionFactory);
        } else {
           sessionFactoryInterfaces = new Class[] {SessionFactory.class};
        }
        //Create proxy of SessionFactory to implement all interfaces the baseSessionFactory did.
        return Proxy.newProxyInstance(getClass().getClassLoader(),
                 sessionFactoryInterfaces, new SeamManagedSessionFactoryHandler(sessionName, baseSessionFactory));
     }
  
     @Override
     public Class getObjectType()
     {
        if (baseSessionFactory != null)
        {
           return baseSessionFactory.getClass();
        }
        return SessionFactory.class;
     }
  
     /**
      * Optionally provide an instance of the SessionFactory we are wrapping.  Only necessary if the proxy
      * needs to expose access to any interfaces besides SessionFactory.class.
      * @param baseSessionFactory
      */
     public void setBaseSessionFactory(SessionFactory baseSessionFactory)
     {
        this.baseSessionFactory = baseSessionFactory;
     }
  
     /**
      * The name of the Seam "managed-hibernate-session" component.
      * @param sessionName
      */
     @Required
     public void setSessionName(String sessionName)
     {
        this.sessionName = sessionName;
     }
  
     /**
      * Proxy for a SessionFactory.  Returning a close suppressing proxy on calls to "openSession".
      * @author Mike Youngstrom
      *
      */
     public static class SeamManagedSessionFactoryHandler implements InvocationHandler
     {
  
        private SessionFactory rawSessionFactory;
  
        private String sessionName;
  
        private boolean isClosed = false;
  
        public SeamManagedSessionFactoryHandler(String sessionName, SessionFactory rawSessionFactory)
        {
           this.rawSessionFactory = rawSessionFactory;
           this.sessionName = sessionName;
        }
  
        private synchronized SessionFactory getRawSessionFactory()
        {
           if (rawSessionFactory == null)
           {
              rawSessionFactory = getSession().getSessionFactory();
           }
           return rawSessionFactory;
        }
  
        private Session getSession()
        {
           SeamLifecycleUtils.beginTransactionalSeamCall();
           return (Session) Component.getInstance(sessionName);
        }
  
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
        {
           if (method.getName().equals("equals"))
           {
              // Only consider equal when proxies are identical.
              return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE);
           }
           if (method.getName().equals("hashCode"))
           {
              // Use hashCode of SessionFactory proxy.
              return new Integer(hashCode());
           }
           SessionFactory delegate = getRawSessionFactory();
           if (method.getName().equals("isClosed"))
           {
              return delegate.isClosed() || isClosed;
           }
           if (delegate.isClosed())
           {
              // Defer to delegate error if it's closed.
              try
              {
                 return method.invoke(delegate, args);
              }
              catch (InvocationTargetException ex)
              {
                 throw ex.getTargetException();
              }
           }
           if (isClosed)
           {
              throw new IllegalStateException("This SessionFactory is closed.");
           }
           if (method.getName().equals("close"))
           {
              isClosed = true;
              return null;
           }
  
           if (method.getName().equals("getCurrentSession"))
           {
              try
              {
                 return SessionFactoryUtils.doGetSession((SessionFactory)proxy, false);
              }
              catch (IllegalStateException ex)
              {
                 throw new HibernateException(ex.getMessage());
              }
           }
           if (method.getName().equals("openSession"))
           {
              if (method.getParameterTypes().length == 0)
              {
                 Session session = getSession();
                 // Return close suppressing Session Proxy that implements all interfaces the original did
                 return Proxy.newProxyInstance(this.getClass().getClassLoader(), ClassUtils
                          .getAllInterfaces(session), new SeamManagedSessionHandler((SessionFactory)proxy,
                          session));
              }
              else
              {
                 throw new HibernateException(
                          "This SeamManagedSessionFactory will only return a session from a call to noarg openSession()");
              }
           }
           if (method.getName().equals("openStatelessSession"))
           {
              throw new HibernateException("This SessionFactory does not support StatelessSessions");
           }
           if (method.getName().equals("getReference"))
           {
              throw new HibernateException(
                       "A SeamManagedSessionFactory is not referencable.  If this is a requirement file a feature request.");
           }
           try
           {
              return method.invoke(delegate, args);
           }
           catch (InvocationTargetException ex)
           {
              throw ex.getTargetException();
           }
        }
     }
  
     /**
      * Delegates calls to a hibernate session and suppresses calls to close. 
      * @author Mike Youngstrom
      */
     public static class SeamManagedSessionHandler implements InvocationHandler
     {
        private static final LogProvider log = Logging
                 .getLogProvider(SeamManagedSessionHandler.class);
  
        private Session delegate;
  
        private SessionFactory sessionFactory;
  
        private boolean closed = false;
  
        public SeamManagedSessionHandler(SessionFactory sessionFactory, Session delegate)
        {
           super();
           this.delegate = delegate;
           this.sessionFactory = sessionFactory;
        }
  
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
        {
           if (method.getName().equals("getSessionFactory"))
           {
              return sessionFactory;
           }
           else if (method.getName().equals("equals"))
           {
              // Only consider equal when proxies are identical.
              return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE);
           }
           else if (method.getName().equals("hashCode"))
           {
              // Use hashCode of Session proxy.
              return new Integer(hashCode());
           }
           if (method.getName().equals("isOpen"))
           {
              return delegate.isOpen() && !closed;
           }
           if (!delegate.isOpen())
           {
              // Defer to delegate error if it's closed.
              try
              {
                 return method.invoke(delegate, args);
              }
              catch (InvocationTargetException ex)
              {
                 throw ex.getTargetException();
              }
           }
           if (closed)
           {
              throw new IllegalStateException("This Session is closed.");
           }
           if (method.getName().equals("close"))
           {
              log.debug("Closing Session Proxy.");
              closed = true;
              return null;
           }
  
           try
           {
              return method.invoke(delegate, args);
           }
           catch (InvocationTargetException ex)
           {
              throw ex.getTargetException();
           }
        }
     }
  
  }
  
  
  



More information about the jboss-cvs-commits mailing list