/*
 * JBoss, the OpenSource J2EE webOS
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.ejb3.injection;

import javax.persistence.PersistenceContextType;
import javax.persistence.EntityManager;
import org.jboss.aop.util.PayloadKey;
import org.jboss.ejb3.BeanContext;
import org.jboss.ejb3.Container;
import org.jboss.ejb3.entity.ExtendedEntityManager;
import org.jboss.ejb3.entity.ExtendedHibernateSession;
import org.jboss.ejb3.entity.ExtendedPersistenceContext;
import org.jboss.ejb3.entity.InjectedEntityManager;
import org.jboss.ejb3.entity.ManagedEntityManagerFactory;
import org.jboss.ejb3.entity.InjectedHibernateSession;
import org.jboss.ejb3.stateful.StatefulContainer;
import org.jboss.logging.Logger;

/**
 * Comment
 *
 * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
 * @version $Revision: 1.1.2.4 $
 */
public abstract class EntityManagerInjector implements Injector
{
   protected static final Logger log = Logger.getLogger(EntityManagerFieldInjector.class);
   protected Container container;
   protected ManagedEntityManagerFactory factory;
   protected PersistenceContextType type;


   protected EntityManagerInjector(Container container, ManagedEntityManagerFactory factory, PersistenceContextType type)
   {
      this.container = container;
      this.factory = factory;
      this.type = type;
   }

   protected Object getEntityManager(BeanContext ctx, boolean isTransient, Class emType)
   {
      Object entityManager;
      if (type == PersistenceContextType.EXTENDED)
      {
         if (!(container instanceof StatefulContainer)) throw new IllegalStateException("EXTENDED persistence contexts can only be used within a Stateful Session bean");
         ExtendedPersistenceContext pc = (ExtendedPersistenceContext) ctx.getMetaData().getMetaData(ManagedEntityManagerFactory.LONG_LIVED_SESSION, factory.getJndiName());
         if (pc == null)
         {
            if (emType.getName().equals(org.hibernate.Session.class.getName()))
            {
               entityManager = new ExtendedHibernateSession(isTransient, factory, container.getInitialContextProperties());
            }
            else
            {
               entityManager = new ExtendedEntityManager(isTransient, factory, container.getInitialContextProperties());
            }
            ctx.getMetaData().addMetaData(ManagedEntityManagerFactory.LONG_LIVED_SESSION, factory.getJndiName(), entityManager, PayloadKey.AS_IS);
         }
         else
         {
            EntityManager realPC = pc.getPersistenceContext();
            if (emType.getName().equals(org.hibernate.Session.class.getName()))
            {
               entityManager = new ExtendedHibernateSession(isTransient, factory, container.getInitialContextProperties(), realPC);
            }
            else
            {
               entityManager = new ExtendedEntityManager(isTransient, factory, container.getInitialContextProperties(), realPC);
            }
         }
      }
      else
      {
         if (emType.getName().equals(org.hibernate.Session.class.getName()))
         {
            entityManager = new InjectedHibernateSession(factory, container.getInitialContextProperties());
         }
         else
         {
            entityManager = new InjectedEntityManager(factory, container.getInitialContextProperties());
         }
      }
      return entityManager;
   }
}
