/*******************************************************************************
* Copyright (c) 1998, 2008 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.internal.jpa;
import java.io.File;
import java.util.Map;
import java.util.HashMap;
import javax.persistence.spi.PersistenceUnitInfo;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.config.TargetDatabase;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.tools.schemaframework.SchemaManager;
/**
* This is a helper/impl class for the EclipseLink EJB 3.0 provider
* The default constructor can be used to build the provider by reflection, after which it can
* be used to create EntityManagerFactories
*/
public class EntityManagerFactoryProvider {
public static final HashMap<String, EntityManagerSetupImpl> emSetupImpls = new HashMap<String, EntityManagerSetupImpl>();
//Cache the Persistence Units
public static final HashMap<String, PersistenceUnitInfo> persistenceUnits = new HashMap<String, PersistenceUnitInfo>();
public static volatile int PUIUsageCount = 0;
// TEMPORARY - WILL BE REMOVED.
// Used to warn users about deprecated property name and suggest the valid name.
// TEMPORARY the old property names will be translated to the new ones and processed.
protected static final String oldPropertyNames[][] = {
{PersistenceUnitProperties.JDBC_WRITE_CONNECTIONS_MAX, "eclipselink.max-write-connections"},
{PersistenceUnitProperties.JDBC_WRITE_CONNECTIONS_MIN, "eclipselink.min-write-connections"},
{PersistenceUnitProperties.JDBC_READ_CONNECTIONS_MAX, "eclipselink.max-read-connections"},
{PersistenceUnitProperties.JDBC_READ_CONNECTIONS_MIN, "eclipselink.min-read-connections"},
{PersistenceUnitProperties.JDBC_BIND_PARAMETERS, "eclipselink.bind-all-parameters"},
{PersistenceUnitProperties.TARGET_DATABASE, "eclipselink.platform.class.name"},
{PersistenceUnitProperties.TARGET_SERVER, "eclipselink.server.platform.class.name"},
{PersistenceUnitProperties.CACHE_SIZE_DEFAULT, "eclipselink.cache.default-size"}
};
/**
* Add an EntityManagerSetupImpl to the cached list
* These are used to ensure all persistence units that are the same get the same underlying session
* @param name
* @param setup
*/
public static void addEntityManagerSetupImpl(String name, EntityManagerSetupImpl setup){
if (name == null){
emSetupImpls.put("", setup);
}
emSetupImpls.put(name, setup);
}
protected static String addFileSeperator(String appLocation) {
int strLength = appLocation.length();
if (appLocation.substring(strLength -1, strLength).equals(File.separator)) {
return appLocation;
} else {
return appLocation + File.separator;
}
}
protected static void createOrReplaceDefaultTables(SchemaManager mgr, boolean shouldDropFirst) {
if (shouldDropFirst){
mgr.replaceDefaultTables(true, true);
} else {
mgr.createDefaultTables(true);
}
}
protected static void generateDDL(ServerSession session, Map props) {
boolean createTables = false, shouldDropFirst = false;
if(null == props){
return;
}
String ddlGeneration = getConfigPropertyAsString(PersistenceUnitProperties.DDL_GENERATION, props, PersistenceUnitProperties.NONE);
ddlGeneration = ddlGeneration.toLowerCase();
if(ddlGeneration.equals(PersistenceUnitProperties.NONE)) {
return;
}
if(ddlGeneration.equals(PersistenceUnitProperties.CREATE_ONLY) ||
ddlGeneration.equals(PersistenceUnitProperties.DROP_AND_CREATE)) {
createTables = true;
if(ddlGeneration.equals(PersistenceUnitProperties.DROP_AND_CREATE)) {
shouldDropFirst = true;
}
}
if (createTables) {
String ddlGenerationMode = getConfigPropertyAsString(PersistenceUnitProperties.DDL_GENERATION_MODE, props, PersistenceUnitProperties.DEFAULT_DDL_GENERATION_MODE);
// Optimize for cases where the value is explicitly set to NONE
if (ddlGenerationMode.equals(PersistenceUnitProperties.NONE)) {
return;
}
SchemaManager mgr = new SchemaManager(session);
if (ddlGenerationMode.equals(PersistenceUnitProperties.DDL_DATABASE_GENERATION) || ddlGenerationMode.equals(PersistenceUnitProperties.DDL_BOTH_GENERATION)) {
writeDDLToDatabase(mgr, shouldDropFirst);
}
if (ddlGenerationMode.equals(PersistenceUnitProperties.DDL_SQL_SCRIPT_GENERATION)|| ddlGenerationMode.equals(PersistenceUnitProperties.DDL_BOTH_GENERATION)) {
String appLocation = getConfigPropertyAsString(PersistenceUnitProperties.APP_LOCATION, props, PersistenceUnitProperties.DEFAULT_APP_LOCATION);
String createDDLJdbc = getConfigPropertyAsString(PersistenceUnitProperties.CREATE_JDBC_DDL_FILE, props, PersistenceUnitProperties.DEFAULT_CREATE_JDBC_FILE_NAME);
String dropDDLJdbc = getConfigPropertyAsString(PersistenceUnitProperties.DROP_JDBC_DDL_FILE, props, PersistenceUnitProperties.DEFAULT_DROP_JDBC_FILE_NAME);
writeDDLsToFiles(mgr, appLocation, createDDLJdbc, dropDDLJdbc);
}
}
}
public static String getConfigPropertyAsString(String propertyKey, Map overrides){
String value = null;
if (overrides != null){
value = (String)overrides.get(propertyKey);
}
if (value == null){
value = System.getProperty(propertyKey);
}
return value;
}
/**
* Check the provided map for an object with the given key. If that object is not available, check the
* System properties. If it is not available from either location, return the default value.
* @param propertyKey
* @param map
* @param defaultValue
* @return
*/
public static String getConfigPropertyAsString(String propertyKey, Map overrides, String defaultValue){
String value = getConfigPropertyAsString(propertyKey, overrides);
if (value == null){
value = defaultValue;
}
return value;
}
protected static String getConfigPropertyAsStringLogDebug(String propertyKey, Map overrides, AbstractSession session) {
return (String)getConfigPropertyLogDebug(propertyKey, overrides, session);
}
protected static String getConfigPropertyAsStringLogDebug(String propertyKey, Map overrides, AbstractSession session, boolean useSystemAsDefault) {
return (String)getConfigPropertyLogDebug(propertyKey, overrides, session, useSystemAsDefault);
}
protected static String getConfigPropertyAsStringLogDebug(String propertyKey, Map overrides, String defaultValue, AbstractSession session){
String value = getConfigPropertyAsStringLogDebug(propertyKey, overrides, session);
if (value == null){
value = defaultValue;
session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "property_value_default", new Object[]{propertyKey, value});
}
return value;
}
protected static Object getConfigPropertyLogDebug(String propertyKey, Map overrides, AbstractSession session){
return getConfigPropertyLogDebug(propertyKey, overrides, session, true);
}
protected static Object getConfigPropertyLogDebug(String propertyKey, Map overrides, AbstractSession session, boolean useSystemAsDefault){
Object value = null;
if (overrides != null){
value = overrides.get(propertyKey);
}
if ((value == null) && useSystemAsDefault){
value = System.getProperty(propertyKey);
}
if ((value != null) && (session != null)) {
if (session.shouldLog(SessionLog.FINEST, SessionLog.PROPERTIES)) {
String overrideValue = PersistenceUnitProperties.getOverriddenLogStringForProperty(propertyKey);;
Object logValue = (overrideValue == null) ? value : overrideValue;
session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "property_value_specified", new Object[]{propertyKey, logValue});
}
}
return value;
}
/**
* Return the setup class for a given entity manager name
* @param emName
*/
public static EntityManagerSetupImpl getEntityManagerSetupImpl(String emName){
if (emName == null){
return emSetupImpls.get("");
}
return emSetupImpls.get(emName);
}
/**
* Return the setup class for a given entity manager name
* @param emName
*/
public static PersistenceUnitInfo getPersistenceUnitInfo(String puName){
if (puName == null){
return persistenceUnits.get("");
}
return persistenceUnits.get(puName);
}
/**
* Logs in to given session. If user has not specified <codeTARGET_DATABASE</code>
* the platform would be auto detected
* @param session The session to login to.
* @param properties User specified properties for the persistence unit
*/
protected static void login(ServerSession session, Map properties) {
String eclipselinkPlatform = (String)properties.get(PersistenceUnitProperties.TARGET_DATABASE);
if (!session.isConnected()) {
if (eclipselinkPlatform == null || eclipselinkPlatform.equals(TargetDatabase.Auto)) {
// if user has not specified a database platform, try to detect
session.loginAndDetectDatasource();
} else {
session.login();
}
}
}
/**
* Merge the properties from the source object into the target object. If the property
* exists in both objects, use the one from the target
* @param target
* @param source
* @return the target object
*/
public static Map mergeMaps(Map target, Map source){
Map map = new HashMap();
if (source != null){
map.putAll(source);
}
if (target != null){
map.putAll(target);
}
return map;
}
/**
* This is a TEMPORARY method that will be removed.
* DON'T USE THIS METHOD - for internal use only.
* @param Map m
* @param AbstractSession session
*/
protected static void translateOldProperties(Map m, AbstractSession session) {
for(int i=0; i < oldPropertyNames.length; i++) {
Object value = getConfigPropertyAsString(oldPropertyNames[i][1], m);
if(value != null) {
if(session != null){
session.log(SessionLog.INFO, SessionLog.TRANSACTION, "deprecated_property", oldPropertyNames[i]);
}
m.put(oldPropertyNames[i][0], value);
}
}
}
protected static void warnOldProperties(Map m, AbstractSession session) {
for(int i=0; i < oldPropertyNames.length; i++) {
Object value = m.get(oldPropertyNames[i][1]);
if(value != null) {
session.log(SessionLog.INFO, SessionLog.TRANSACTION, "deprecated_property", oldPropertyNames[i]);
}
}
}
protected static void writeDDLToDatabase(SchemaManager mgr, boolean shouldDropFirst) {
String str = getConfigPropertyAsString(PersistenceUnitProperties.JAVASE_DB_INTERACTION, null ,"true");
boolean interactWithDB = Boolean.valueOf(str.toLowerCase()).booleanValue();
if (!interactWithDB){
return;
}
createOrReplaceDefaultTables(mgr, shouldDropFirst);
}
protected static void writeDDLsToFiles(SchemaManager mgr, String appLocation, String createDDLJdbc, String dropDDLJdbc) {
// Ensure that the appLocation string ends with File.separator
appLocation = addFileSeperator(appLocation);
if (null != createDDLJdbc) {
String createJdbcFileName = appLocation + createDDLJdbc;
mgr.outputCreateDDLToFile(createJdbcFileName);
}
if (null != dropDDLJdbc) {
String dropJdbcFileName = appLocation + dropDDLJdbc;
mgr.outputDropDDLToFile(dropJdbcFileName);
}
mgr.setCreateSQLFiles(false);
// When running in the application server environment always ensure that
// we write out both the drop and create table files.
createOrReplaceDefaultTables(mgr, true);
mgr.closeDDLWriter();
}
}