/* * JBoss, Home of Professional Open Source. * Copyright 2011, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.as.jpa.injectors; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.persistence.EntityManagerFactory; import org.jboss.as.ee.component.InjectionSource; import org.jboss.as.jpa.messages.JpaLogger; import org.jboss.as.jpa.service.PersistenceUnitServiceImpl; import org.jboss.as.naming.ManagedReference; import org.jboss.as.naming.ManagedReferenceFactory; import org.jboss.as.naming.ValueManagedReference; import org.jboss.as.server.deployment.DeploymentPhaseContext; import org.jboss.as.server.deployment.DeploymentUnitProcessingException; import org.jboss.msc.inject.Injector; import org.jboss.msc.service.ServiceBuilder; import org.jboss.msc.service.ServiceName; import org.jboss.msc.service.ServiceRegistry; import org.jboss.msc.value.ImmediateValue; import org.jipijapa.plugin.spi.PersistenceUnitMetadata; /** * Represents the PersistenceUnit injected into a component. * TODO: support injecting into a HibernateSessionFactory. Initially, hack it by checking injectionTypeName parameter * for HibernateSessionFactory. If/when JPA supports unwrap on the EMF, switch to that. * * @author Scott Marlow */ public class PersistenceUnitInjectionSource extends InjectionSource { private final PersistenceUnitJndiInjectable injectable; private final ServiceName puServiceName; public PersistenceUnitInjectionSource(final ServiceName puServiceName, final ServiceRegistry serviceRegistry, final String injectionTypeName, final PersistenceUnitMetadata pu) { injectable = new PersistenceUnitJndiInjectable(puServiceName, serviceRegistry, injectionTypeName, pu); this.puServiceName = puServiceName; } public void getResourceValue(final ResolutionContext resolutionContext, final ServiceBuilder<?> serviceBuilder, final DeploymentPhaseContext phaseContext, final Injector<ManagedReferenceFactory> injector) throws DeploymentUnitProcessingException { serviceBuilder.addDependencies(puServiceName); injector.inject(injectable); } public boolean equals(final Object other) { if (other instanceof PersistenceUnitInjectionSource) { PersistenceUnitInjectionSource source = (PersistenceUnitInjectionSource) other; return (source.puServiceName.equals(puServiceName)); } return false; } public int hashCode() { return puServiceName.hashCode(); } private static final class PersistenceUnitJndiInjectable implements ManagedReferenceFactory { final ServiceName puServiceName; final ServiceRegistry serviceRegistry; final String injectionTypeName; final PersistenceUnitMetadata pu; private static final String ENTITY_MANAGER_FACTORY_CLASS = "javax.persistence.EntityManagerFactory"; public PersistenceUnitJndiInjectable( final ServiceName puServiceName, final ServiceRegistry serviceRegistry, final String injectionTypeName, final PersistenceUnitMetadata pu) { this.puServiceName = puServiceName; this.serviceRegistry = serviceRegistry; this.injectionTypeName = injectionTypeName; this.pu = pu; } @Override public ManagedReference getReference() { PersistenceUnitServiceImpl service = (PersistenceUnitServiceImpl) serviceRegistry.getRequiredService(puServiceName).getValue(); EntityManagerFactory emf = service.getEntityManagerFactory(); if (!ENTITY_MANAGER_FACTORY_CLASS.equals(injectionTypeName)) { // inject non-standard wrapped class (e.g. org.hibernate.SessionFactory) Class<?> extensionClass; try { // make sure we can access the target class type extensionClass = pu.getClassLoader().loadClass(injectionTypeName); } catch (ClassNotFoundException e) { throw JpaLogger.ROOT_LOGGER.cannotLoadFromJpa(e, injectionTypeName); } // TODO: when/if jpa supports unwrap, change to // Object targetValueToInject = emf.unwrap(extensionClass); // Until jpa supports unwrap on sessionfactory, only support hibernate Method getSessionFactory; try { getSessionFactory = emf.getClass().getMethod("getSessionFactory"); } catch (NoSuchMethodException e) { throw JpaLogger.ROOT_LOGGER.hibernateOnlyEntityManagerFactory(); } Object targetValueToInject = null; try { targetValueToInject = getSessionFactory.invoke(emf, new Object[0]); } catch (IllegalAccessException e) { throw JpaLogger.ROOT_LOGGER.cannotGetSessionFactory(e); } catch (InvocationTargetException e) { throw JpaLogger.ROOT_LOGGER.cannotGetSessionFactory(e); } return new ValueManagedReference(new ImmediateValue<Object>(targetValueToInject)); } return new ValueManagedReference(new ImmediateValue<Object>(emf)); } } }