/*
* ============================================================================
* GNU Lesser General Public License
* ============================================================================
*
* Beanlet - JSE Application Container.
* Copyright (C) 2006 Leon van Zantvoort
*
* This library 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 library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Leon van Zantvoort
* 243 Acalanes Drive #11
* Sunnyvale, CA 94086
* USA
*
* zantvoort@users.sourceforge.net
* http://beanlet.org
*/
package org.beanlet.persistence.impl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.PersistenceProvider;
import javax.persistence.spi.PersistenceUnitInfo;
/**
* Bootstrap class that is used to obtain a container managed
* {@code EntityManagerFactory}.
*
* @author Leon van Zantvoort
*/
public final class PersistenceHelper {
private static final Logger logger = Logger.getLogger(
PersistenceHelper.class.getName());
static final String PERSISTENCE_PROVIDER_PROPERTY = "javax.persistence.provider";
static final String PERSISTENCE_PROVIDER_SERVICE = "META-INF/services/"
+ PersistenceProvider.class.getName();
/**
* Create and return an EntityManagerFactory for the specified persistence unit.
*
* @param unitInfo persistence unit info object.
* @return The factory that creates EntityManagers configured according to the
* specified persistence unit/
*/
public static EntityManagerFactory createContainerEntityManagerFactory(
PersistenceUnitInfo unitInfo) {
return createContainerEntityManagerFactory(unitInfo,
Collections.EMPTY_MAP);
}
/**
* Create and return an EntityManagerFactory for the specified persistence unit
* using the given properties.
*
* @param unitInfo persistence unit info object.
* @param map Additional properties to use when creating the factory. The values of
* these properties override any values that may have been configured
* elsewhere.
* @return The factory that creates EntityManagers configured according to the
* specified persistence unit.
*/
public static EntityManagerFactory createContainerEntityManagerFactory(
PersistenceUnitInfo unitInfo, Map<?, ?> map) {
Map<Object, Object> properties = new HashMap<Object, Object>();
properties.putAll(PersistencePropertiesFactory.getInstance().getProperties());
properties.putAll(map);
// start by loading a provider explicitly specified in properties. The spec
// doesn't seem to forbid providers that are not deployed as a service
Object providerName = properties.get(PERSISTENCE_PROVIDER_PROPERTY);
if (providerName instanceof String && !((String) providerName).equals("")) {
EntityManagerFactory factory = createContainerFactory(
providerName.toString(),
unitInfo,
properties);
if (factory != null) {
return factory;
}
}
if (unitInfo.getPersistenceProviderClassName() != null &&
!unitInfo.getPersistenceProviderClassName().equals("")) {
EntityManagerFactory factory = createContainerFactory(
unitInfo.getPersistenceProviderClassName(),
unitInfo,
properties);
if (factory != null) {
return factory;
}
}
// load correctly deployed providers
ClassLoader loader = unitInfo.getClassLoader();
try {
Enumeration<URL> providers = loader
.getResources(PERSISTENCE_PROVIDER_SERVICE);
while (providers.hasMoreElements()) {
String name = getProviderName(providers.nextElement());
if (name != null && !name.equals("")) {
EntityManagerFactory factory = createContainerFactory(
name,
unitInfo,
properties);
if (factory != null) {
return factory;
}
}
}
} catch (IOException e) {
// spec doesn't mention any exceptions thrown by this method
}
return null;
}
static String getProviderName(URL url) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(
url.openStream(),
"UTF-8"));
String providerName = null;
try {
providerName = in.readLine();
} finally {
in.close();
}
if (providerName != null) {
providerName = providerName.trim();
}
return providerName;
}
static EntityManagerFactory createContainerFactory(
String providerName, PersistenceUnitInfo unitInfo, Map properties) {
try {
Class providerClass = Class.forName(providerName, true,
unitInfo.getClassLoader());
PersistenceProvider provider = (PersistenceProvider) providerClass
.newInstance();
return provider.createContainerEntityManagerFactory(unitInfo,
properties);
} catch (Exception e) {
logger.log(Level.WARNING, "THROW", e);
return null;
}
}
}