org.eclipse.persistence.internal.jpa.deployment.JPAInitializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2018 IBM Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// tware, ssmith = 1.0 - Generic JPA deployment (OSGI, EE, SE)
// 11/04/2014 - Rick Curtis
// - 450010 : Add java se test bucket
// 08/29/2016 Jody Grassel
// - 500441: Eclipselink core has System.getProperty() calls that are not potentially executed under doPriv()
package org.eclipse.persistence.internal.jpa.deployment;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import jakarta.persistence.spi.ClassTransformer;
import jakarta.persistence.spi.PersistenceUnitInfo;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider;
import org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.jpa.Archive;
import org.eclipse.persistence.jpa.PersistenceProvider;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
/**
* Base class for all JPA initialization classes. This is an abstract class that provides the framework
* for JPA initialization (finding and initializing persistence units). Subclasses implement the abstract methods
* to provide customized functionality
*
* @see JavaSECMPInitializer
* @author tware
*
*/
public abstract class JPAInitializer {
// The internal loader is used by applications that do weaving to pre load classes
// When this flag is set to false, we will not be able to weave.
protected boolean shouldCreateInternalLoader = true;
protected ClassLoader initializationClassloader = null;
// Cache the initial puInfos - those used by initialEmSetupImpls
protected Map initialPuInfos;
// Cache the initial emSetupImpls - those created and predeployed by JavaSECMPInitializer.initialize method.
protected Map initialEmSetupImpls;
// Initializers keyed by their initializationClassloaders
protected static Map initializers = new Hashtable<>();
protected JPAInitializer() {
}
/**
* Initialize the logging file if it is specified by the system property.
*/
public static void initializeTopLinkLoggingFile() {
String loggingFile = PrivilegedAccessHelper.getSystemProperty(PersistenceUnitProperties.LOGGING_FILE);
try {
if (loggingFile != null) {
AbstractSessionLog.getLog().setWriter(new FileWriter(loggingFile));
}
} catch (IOException e) {
AbstractSessionLog.getLog().log(SessionLog.WARNING, "cmp_init_default_logging_file_is_invalid",loggingFile,e);
}
}
/**
* predeploy (with deploy) is one of the two steps required in deployment of entities
* This method will prepare to call predeploy, call it and finally register the
* transformer returned to be used for weaving.
*/
public EntityManagerSetupImpl callPredeploy(SEPersistenceUnitInfo persistenceUnitInfo, Map m, String persistenceUnitUniqueName, String sessionName) {
AbstractSessionLog.getLog().log(SessionLog.FINER, SessionLog.JPA, "cmp_init_invoke_predeploy", persistenceUnitInfo.getPersistenceUnitName());
Map mergedProperties = EntityManagerFactoryProvider.mergeMaps(m, persistenceUnitInfo.getProperties());
// Bug#4452468 When globalInstrumentation is null, there is no weaving
checkWeaving(mergedProperties);
Set tempLoaderSet = PersistenceUnitProcessor.buildClassSet(persistenceUnitInfo, m);
// Create the temp loader that will not cache classes for entities in our persistence unit
ClassLoader tempLoader = createTempLoader(tempLoaderSet);
persistenceUnitInfo.setNewTempClassLoader(tempLoader);
EntityManagerSetupImpl emSetupImpl = new EntityManagerSetupImpl(persistenceUnitUniqueName, sessionName);
// A call to predeploy will partially build the session we will use
final ClassTransformer transformer = emSetupImpl.predeploy(persistenceUnitInfo, mergedProperties);
// After preDeploy it's impossible to weave again - so may substitute the temporary classloader with the real one.
// The temporary classloader could be garbage collected even if the puInfo is cached for the future use by other emSetupImpls.
persistenceUnitInfo.setNewTempClassLoader(persistenceUnitInfo.getClassLoader());
registerTransformer(transformer, persistenceUnitInfo, m);
return emSetupImpl;
}
/**
* Check whether weaving is possible and update the properties and variable as appropriate
* @param properties The list of properties to check for weaving and update if weaving is not needed
*/
public abstract void checkWeaving(Map properties);
/**
* Create a temporary class loader that can be used to inspect classes and then
* thrown away. This allows classes to be introspected prior to loading them
* with application's main class loader enabling weaving.
*/
protected abstract ClassLoader createTempLoader(Collection col);
protected abstract ClassLoader createTempLoader(Collection col, boolean shouldOverrideLoadClassForCollectionMembers);
/**
* Find PersistenceUnitInfo corresponding to the persistence unit name.
* Returns null if either persistence unit either not found or provider is not supported.
*/
public SEPersistenceUnitInfo findPersistenceUnitInfo(String puName, Map m) {
SEPersistenceUnitInfo persistenceUnitInfo = null;
if(initialPuInfos != null) {
persistenceUnitInfo = initialPuInfos.get(puName);
}
if(persistenceUnitInfo != null) {
return persistenceUnitInfo;
}
persistenceUnitInfo = (SEPersistenceUnitInfo) m.get(PersistenceUnitProperties.ECLIPSELINK_SE_PUINFO);
if (persistenceUnitInfo != null) {
return persistenceUnitInfo;
}
return findPersistenceUnitInfoInArchives(puName, m);
}
/**
* Find PersistenceUnitInfo corresponding to the persistence unit name.
* Returns null if either persistence unit either not found or provider is not supported.
*/
protected SEPersistenceUnitInfo findPersistenceUnitInfoInArchives(String puName, Map m) {
SEPersistenceUnitInfo persistenceUnitInfo = null;
// mkeith - get resource name from prop and include in subsequent call
String descriptorPath = (String) m.get(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML);
final Set pars;
if (descriptorPath != null) {
pars = PersistenceUnitProcessor.findPersistenceArchives(initializationClassloader, descriptorPath);
} else {
pars = PersistenceUnitProcessor.findPersistenceArchives(initializationClassloader);
}
try {
for (Archive archive: pars) {
persistenceUnitInfo = findPersistenceUnitInfoInArchive(puName, archive, m);
if(persistenceUnitInfo != null) {
break;
}
}
} finally {
for (Archive archive: pars) {
archive.close();
}
}
return persistenceUnitInfo;
}
/**
* Find PersistenceUnitInfo corresponding to the persistence unit name in the archive.
* Returns null if either persistence unit either not found or provider is not supported.
*/
protected SEPersistenceUnitInfo findPersistenceUnitInfoInArchive(String puName, Archive archive, Map m){
Iterator persistenceUnits = PersistenceUnitProcessor.getPersistenceUnits(archive, initializationClassloader).iterator();
while (persistenceUnits.hasNext()) {
SEPersistenceUnitInfo persistenceUnitInfo = persistenceUnits.next();
if(isPersistenceProviderSupported(persistenceUnitInfo.getPersistenceProviderClassName()) && persistenceUnitInfo.getPersistenceUnitName().equals(puName)) {
return persistenceUnitInfo;
}
}
return null;
}
/**
* Returns whether the given persistence provider class is supported by this implementation
*/
public boolean isPersistenceProviderSupported(String providerClassName){
return (providerClassName == null) || providerClassName.equals("") || providerClassName.equals(EntityManagerFactoryProvider.class.getName()) || providerClassName.equals(PersistenceProvider.class.getName());
}
/**
* Create a list of java.lang.Class that contains the classes of all the entities
* that we will be deploying.
*/
protected Set loadEntityClasses(Collection entityNames, ClassLoader classLoader) {
Set