package org.jboss.weld.integration.persistence;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
import org.jboss.deployers.structure.spi.DeploymentUnit;
import org.jboss.ejb3.common.deployers.spi.AttachmentNames;
import org.jboss.jpa.deployment.ManagedEntityManagerFactory;
import org.jboss.jpa.deployment.PersistenceUnitDeployment;
import org.jboss.jpa.injection.InjectedEntityManagerFactory;
import org.jboss.jpa.resolvers.PersistenceUnitDependencyResolver;
import org.jboss.jpa.tx.TransactionScopedEntityManager;
import org.jboss.metadata.ejb.jboss.JBossMetaData;
import org.jboss.metadata.web.jboss.JBossWebMetaData;
import org.jboss.weld.injection.spi.JpaInjectionServices;
import org.jboss.weld.integration.util.AbstractJBossServices;
public class JBossJpaServices extends AbstractJBossServices implements JpaInjectionServices
{
public JBossJpaServices() throws NamingException
{
super();
}
protected PersistenceUnitDependencyResolver persistenceUnitDependencyResolver;
public void setPersistenceUnitDependencyResolver(PersistenceUnitDependencyResolver persistenceUnitDependencyResolver)
{
this.persistenceUnitDependencyResolver = persistenceUnitDependencyResolver;
}
public Collection<Class<?>> discoverEntities()
{
return Collections.emptyList();
}
public EntityManager resolvePersistenceContext(InjectionPoint injectionPoint)
{
if (!injectionPoint.getAnnotated().isAnnotationPresent(PersistenceContext.class))
{
throw new IllegalArgumentException("No @PersistenceContext annotation found on injection point " + injectionPoint);
}
if (injectionPoint.getMember() instanceof Method && ((Method) injectionPoint.getMember()).getParameterTypes().length != 1)
{
throw new IllegalArgumentException("Injection point represents a method which doesn't follow JavaBean conventions (must have exactly one parameter) " + injectionPoint);
}
try
{
String persistenceUnitName = injectionPoint.getAnnotated().getAnnotation(PersistenceContext.class).unitName();
return new TransactionScopedEntityManager(lookupPersistenceUnitDeployment(persistenceUnitName).getManagedFactory());
}
catch (IllegalStateException e)
{
throw new IllegalStateException("Unable to resolve persistence context for " + injectionPoint);
}
}
public EntityManagerFactory resolvePersistenceUnit(InjectionPoint injectionPoint)
{
if (!injectionPoint.getAnnotated().isAnnotationPresent(PersistenceUnit.class))
{
throw new IllegalArgumentException("No @PersistenceUnit annotation found on injection point " + injectionPoint);
}
if (injectionPoint.getMember() instanceof Method && ((Method) injectionPoint.getMember()).getParameterTypes().length != 1)
{
throw new IllegalArgumentException("Injection point represents a method which doesn't follow JavaBean conventions (must have exactly one parameter) " + injectionPoint);
}
try
{
return resolvePersistenceUnit((injectionPoint.getAnnotated().getAnnotation(PersistenceUnit.class).unitName()));
}
catch (IllegalStateException e)
{
throw new IllegalStateException("Unable to resolve persistence context for " + injectionPoint);
}
}
private EntityManagerFactory resolvePersistenceUnit(String unitName)
{
PersistenceUnitDeployment deployment = lookupPersistenceUnitDeployment(unitName);
ManagedEntityManagerFactory managedFactory = deployment.getManagedFactory();
return new InjectedEntityManagerFactory(managedFactory);
}
private PersistenceUnitDeployment lookupPersistenceUnitDeployment(String unitName)
{
if (unitName == null)
{
throw new IllegalArgumentException("unitName is null");
}
String beanName = getPersistenceUnitSupplier(topLevelDeploymentUnit, persistenceUnitDependencyResolver, unitName);
if (beanName == null)
{
throw new IllegalStateException("No persistence unit available for " + unitName);
}
PersistenceUnitDeployment deployment = jbossEjb.lookupPersistenceUnitDeployment(beanName);
return deployment;
}
private static String getPersistenceUnitSupplier(DeploymentUnit deploymentUnit, PersistenceUnitDependencyResolver persistenceUnitDependencyResolver, String persistenceUnitName)
{
if ((deploymentUnit.getAttachment(AttachmentNames.PROCESSED_METADATA, JBossMetaData.class) != null && deploymentUnit.getAttachment(JBossMetaData.class).isEJB3x()) || (deploymentUnit.getAttachment(JBossWebMetaData.class) != null))
{
try
{
return persistenceUnitDependencyResolver.resolvePersistenceUnitSupplier(deploymentUnit, persistenceUnitName);
}
catch (IllegalArgumentException e)
{
// No-op, means we can't find the PU in this DU
}
}
for (DeploymentUnit child : deploymentUnit.getChildren())
{
String beanName = getPersistenceUnitSupplier(child, persistenceUnitDependencyResolver, persistenceUnitName);
if (beanName != null)
{
return beanName;
}
}
return null;
}
}