/* * Copyright (c) OSGi Alliance (2013). All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package osgi.jpa.managed.support; import java.util.HashSet; import java.util.Hashtable; import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import org.osgi.framework.Bundle; import org.osgi.framework.ServiceRegistration; import v2_0.Persistence; /** * This class represents a bundle with one or more valid Persistence Units. It * maintains a the service registrations for the TransactionalEntityManager for * each persistence units and closes them when applicable. */ class PersistentBundle { private static final String OSGI_UNIT_PROVIDER = "osgi.unit.provider"; private static final String OSGI_UNIT_VERSION = "osgi.unit.version"; private static final String OSGI_UNIT_NAME = "osgi.unit.name"; private final Set<ServiceRegistration<? extends EntityManager>> units = new HashSet<ServiceRegistration<? extends EntityManager>>(); final JPAManager bridge; final Bundle bundle; /** * We found some persistence units for this bridge so create this manager. * * @param bridge the bridge we work for * @param bundle the actual bundle for the persistence units * @param set a set of persistence units. */ PersistentBundle(JPAManager bridge, Bundle bundle, Set<Persistence.PersistenceUnit> set) throws Exception { this.bridge = bridge; this.bundle = bundle; for (Persistence.PersistenceUnit pu : set) { units.add(createEM(pu)); } } /** * Create an Entity Manager that is configured for a given persistence unit. * * @param pu The persistence unit we want the Entity Manager for. * @return A Service Registration of the Entity Manager */ private ServiceRegistration<EntityManager> createEM(Persistence.PersistenceUnit pu) throws Exception { PersistenceUnitInfoImpl pui = new PersistenceUnitInfoImpl(this, pu); EntityManagerFactory emf = bridge.persistenceProvider.createContainerEntityManagerFactory(pui, bridge.bridgeProperties); Hashtable<String, Object> properties = new Hashtable<String, Object>(bridge.bridgeProperties); properties.put(OSGI_UNIT_NAME, pu.getName()); properties.put(OSGI_UNIT_VERSION, bundle.getVersion()); properties.put(OSGI_UNIT_PROVIDER, bridge.persistenceProvider.getClass().getName()); bridge.log.step("Register Entity Manager for " + emf); return bridge.context.registerService(EntityManager.class, new TransactionalEntityManager( bridge.transactionManager, emf), properties); } /** * Unregister all registrations and close the Entity Manager. */ public void close() { bridge.log.step("closing " + this); for (ServiceRegistration<? extends EntityManager> emi : units) try { EntityManager em = bridge.context.getService(emi.getReference()); emi.unregister(); em.close(); } catch (Exception e) { bridge.log.failed("Closing " + emi, e); } } @Override public String toString() { return "PersistentBundle [bridge=" + bridge.config.name() + ", bundle=" + bundle.getBundleId() + "]"; } }