WebJETJavaSECMPInitializer.java
package sk.iway.iwcm.system.jpa;
import static sk.iway.iwcm.Tools.isEmpty;
import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.config.TargetDatabase;
import org.eclipse.persistence.exceptions.PersistenceUnitLoadingException;
import org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl;
import org.eclipse.persistence.internal.jpa.deployment.JavaSECMPInitializer;
import org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor;
import org.eclipse.persistence.internal.jpa.deployment.SEPersistenceUnitInfo;
import org.eclipse.persistence.jpa.Archive;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import sk.iway.iwcm.Constants;
import sk.iway.iwcm.DBPool;
import sk.iway.iwcm.Logger;
import sk.iway.iwcm.Tools;
import sk.iway.iwcm.io.JarPackaging;
/**
* WebJETJavaSECMPInitializer.java
* Subclassed in order to override reading metadata from persistence.xml and use datasources specified in poolman.xml
*
*@Title webjet7
*@Company Interway s.r.o. (www.interway.sk)
*@Copyright Interway s.r.o. (c) 2001-2010
*@author $Author: rusho $
*@version $Revision: 1.3 $
*@created Date: 22.1.2010 11:18:45
*@modified $Date: 2004/08/16 06:26:11 $
*/
@SuppressWarnings("rawtypes")
public class WebJETJavaSECMPInitializer extends JavaSECMPInitializer
{
protected static WebJETJavaSECMPInitializer initializer;
// Used as a lock in getJavaSECMPInitializer.
private static final Object initializationLock = new Object();
/**
* Get the singleton entityContainer.
*/
public static WebJETJavaSECMPInitializer getJavaSECMPInitializer() {
return getJavaSECMPInitializer(Thread.currentThread().getContextClassLoader(), null, false);
}
public static WebJETJavaSECMPInitializer getJavaSECMPInitializer(ClassLoader loader) {
return getJavaSECMPInitializer(loader, null, false);
}
public static WebJETJavaSECMPInitializer getJavaSECMPInitializerFromAgent()
{
return getJavaSECMPInitializer(Thread.currentThread().getContextClassLoader(), null, true);
}
public static WebJETJavaSECMPInitializer getJavaSECMPInitializerFromMain(Map m)
{
return getJavaSECMPInitializer(Thread.currentThread().getContextClassLoader(), m, false);
}
protected WebJETJavaSECMPInitializer()
{
super();
}
protected WebJETJavaSECMPInitializer(ClassLoader loader)
{
super(loader);
}
public static WebJETJavaSECMPInitializer getJavaSECMPInitializer(ClassLoader classLoader, Map m, boolean fromAgent) {
Logger.debug(WebJETJavaSECMPInitializer.class, "getJavaSECMPInitializer start");
if(!isInitialized) {
//if(globalInstrumentation != null) {
synchronized(initializationLock) {
if(!isInitialized) {
Logger.debug(WebJETJavaSECMPInitializer.class, "getJavaSECMPInitializer, initializing");
initializeTopLinkLoggingFile();
if(fromAgent) {
AbstractSessionLog.getLog().log(SessionLog.FINER, SessionLog.WEAVER, "cmp_init_initialize_from_agent", (Object[])null);
}
//usesAgent = true;
initializer = new WebJETJavaSECMPInitializer(classLoader);
initializer.initialize(m != null ? m : new HashMap(0));
// all the transformers have been added to instrumentation, don't need it any more.
globalInstrumentation = null;
}
}
//}
isInitialized = true;
}
if(initializer != null && initializer.getInitializationClassLoader() == classLoader) {
return initializer;
} else {
// when agent is not used initializer does not need to be initialized.
return new WebJETJavaSECMPInitializer(classLoader);
}
}
/**
* This method initializes the container. Essentially, it will try to load the
* class that contains the list of entities and reflectively call the method that
* contains that list. It will then initialize the container with that list.
*/
@SuppressWarnings("unchecked")
@Override
public void initialize(Map m) {
Logger.debug(WebJETJavaSECMPInitializer.class, "JPA: initialize");
//boolean keepInitialMaps = keepAllPredeployedPersistenceUnits();
//if(keepInitialMaps) {
initialPuInfos = new HashMap();
//}
// always create initialEmSetupImpls - it's used to check for puName uniqueness in initPersistenceUnits
initialEmSetupImpls = new HashMap();
// ailitchev - copied from findPersistenceUnitInfoInArchives: mkeith - get resource name from prop and include in subsequent call
//String descriptorPath = (String) m.get(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML);
//WebJET zmena
final Set<Archive> pars = findPersistenceArchives(initializationClassloader);
try {
for (Archive archive: pars) {
AbstractSessionLog.getLog().log(SessionLog.FINER, SessionLog.JPA, "cmp_init_initialize", archive);
initPersistenceUnits(archive, m);
}
} finally {
for (Archive archive: pars) {
archive.close();
}
initialEmSetupImpls = null;
}
}
/**
* WebJET verzia PersistenceUnitPRocessor metody kvoli premenovanemu persistence.xml kvoli jBossu v ING (kde persistence.xml kolidovalo)
* @param loader
* @return
*/
private static Set<Archive> findPersistenceArchives(ClassLoader loader){
Logger.debug(WebJETJavaSECMPInitializer.class, "findPersistenceArchives");
String descriptor = "META-INF/persistence-webjet.xml";
Set<Archive> pars = new HashSet<>();
try {
Enumeration<URL> resources = loader.getResources(descriptor);
while (resources.hasMoreElements()){
URL pxmlURL = resources.nextElement();
URL puRootURL = PersistenceUnitProcessor.computePURootURL(pxmlURL, descriptor);
Archive archive = PersistenceUnitProcessor.getArchiveFactory(loader).createArchive(puRootURL, descriptor, null);
pars.add(archive);
}
} catch (java.io.IOException|URISyntaxException exc){
//clean up first
for (Archive archive : pars) {
archive.close();
}
throw PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(loader, exc);
}
return pars;
}
/**
* Initialize persistence units.
* Initialization is a two phase process. First the predeploy process builds the metadata
* and creates any required transformers. This is WebJET specific version, any metadata from persistence.xml is abandoned.
* Instead, a new SEPersistenceUnitInfo is created from metadata contained in poolman.xml. Only classes in specific packages
* with specific class name patterns are included to be scanned as managedClasses.
* Second the deploy process creates an EclipseLink session based on that metadata.
*/
@Override
protected void initPersistenceUnits(Archive archive, Map m){
/*
* povodny PersistenceUnitsList obsahujuci udaje z persistence.xml nahradime vlastnym, postavenym na zaklade DBPool a poolman.xml
*/
try
{
Logger.debug(WebJETJavaSECMPInitializer.class, "Archive: persistence:" + archive.getEntry("META-INF/persistence.xml")+" root="+archive.getRootURL());
}
catch (Exception e)
{
// handle exception
}
//List<SEPersistenceUnitInfo> persistenceUnitsList = PersistenceUnitProcessor.getPersistenceUnits(archive, initializationClassloader);
List<SEPersistenceUnitInfo> persistenceUnitsList = new ArrayList<>();
persistenceUnitsList.clear();
DBPool dbPool = DBPool.getInstance();
// nacitaj vsetky DataSources z DBPool a vytvor k nim SEPersistenceUnitInfo, nasledne vloz do Listu
for(String dbName:DBPool.getDataSourceNames())
{
if (JpaTools.isJPADatasource(dbName))
{
DataSource ds = dbPool.getWebJETAbandonedDataSource(dbName);
SEPersistenceUnitInfo puInfo = new SEPersistenceUnitInfo();
puInfo.setPersistenceUnitName(dbName);
puInfo.setNonJtaDataSource(ds);
puInfo.setTransactionType(PersistenceUnitTransactionType.RESOURCE_LOCAL);
puInfo.setPersistenceProviderClassName("sk.iway.iwcm.system.jpa.WebJETPersistenceProvider");
puInfo.setPersistenceUnitRootUrl(archive.getRootURL());
String[] packages = {
"sk.iway.iwcm.calendar",
"sk.iway.iwcm.components.banner.model",
"sk.iway.iwcm.components.basket",
"sk.iway.iwcm.components.dictionary.model",
"sk.iway.iwcm.components.domainRedirects",
"sk.iway.iwcm.components.enumerations.model",
"sk.iway.iwcm.components.export",
"sk.iway.iwcm.components.file_archiv",
"sk.iway.iwcm.components.gdpr",
"sk.iway.iwcm.components.insertScript",
"sk.iway.iwcm.components.inquirySimple",
"sk.iway.iwcm.components.quiz.jpa",
"sk.iway.iwcm.components.reservation",
"sk.iway.iwcm.components.todo",
"sk.iway.iwcm.components.users.userdetail",
"sk.iway.iwcm.dmail",
"sk.iway.iwcm.doc",
"sk.iway.iwcm.editor",
"sk.iway.iwcm.io",
"sk.iway.iwcm.system.cache",
"sk.iway.iwcm.system.captcha",
"sk.iway.iwcm.system.jpa",
"sk.iway.iwcm.system.msg",
"sk.iway.iwcm.users",
"sk.iway.spirit.model"
};
List<String> managedClasses = new ArrayList<>();
for (String packageToScan : packages) {
managedClasses.addAll(JpaTools.getJpaClassNames("/WEB-INF/classes/" + packageToScan.replace(".", "/")));
}
managedClasses.add("sk.iway.iwcm.system.UrlRedirectBean");
if (Tools.isNotEmpty(Constants.getString("jpaAddPackages")))
{
for (String packageToScan : Constants.getString("jpaAddPackages").split(","))
{
if (isEmpty(packageToScan)) continue;
String packagePath = "/WEB-INF/classes/"+packageToScan.replace(".", "/");
packagePath = Tools.replace(packagePath, "/*", "");
managedClasses.addAll(JpaTools.getJpaClassNames(packagePath));
}
}
Logger.debug(WebJETJavaSECMPInitializer.class, "initPersistenceUnits["+dbName+"], beans="+managedClasses.size());
puInfo.setManagedClassNames(managedClasses);
puInfo.setExcludeUnlistedClasses(true);
List<URL> libUrlsList = new ArrayList<>();
//pridaj lokacie z JarPackagingu
try
{
List<String> jarLocations = JarPackaging.getJarLocations();
for (String location : jarLocations)
{
if (location == null) continue;
location = Tools.URLDecode(location);
if (location.endsWith("-admin.jar") || location.endsWith("-components.jar")) continue;
Logger.debug(WebJETJavaSECMPInitializer.class, "JPA: Adding "+location);
libUrlsList.add(new File(location).toURI().toURL());
}
}
catch (Exception e)
{
sk.iway.iwcm.Logger.error(e);
}
if (libUrlsList.size()>0) puInfo.setJarFileUrls(libUrlsList);
Properties properties = new Properties();
String driverClassName = "";
try
{
Connection connection = ds.getConnection();
driverClassName = DriverManager.getDriver(connection.getMetaData().getURL()).getClass().getName();
connection.close();
}
catch (SQLException e){sk.iway.iwcm.Logger.error(e);}
String jpaTargetDatabase = TargetDatabase.Auto;
if(driverClassName.contains("com.mysql.jdbc.Driver") || driverClassName.contains("mariadb")) {
jpaTargetDatabase = TargetDatabase.MySQL;
} else if(driverClassName.contains("oracle.jdbc.OracleDriver")) {
jpaTargetDatabase = TargetDatabase.Oracle;
} else if(driverClassName.contains("net.sourceforge.jtds.jdbc.Driver")) {
jpaTargetDatabase = TargetDatabase.SQLServer;
} else if(driverClassName.contains("org.postgresql.Driver")) {
jpaTargetDatabase = TargetDatabase.PostgreSQL;
}
Logger.debug(WebJETJavaSECMPInitializer.class, "JPA: Setting TargetDatabase to " + jpaTargetDatabase + " driverClassName="+driverClassName);
properties.setProperty(PersistenceUnitProperties.TARGET_DATABASE, jpaTargetDatabase);
if (Constants.getBoolean("serverMonitoringEnableJPA")) properties.setProperty(PersistenceUnitProperties.PROFILER, "sk.iway.iwcm.system.jpa.WebJETPerformanceProfiler");
setDefaultProperties(properties);
puInfo.setProperties(properties);
puInfo.setClassLoader(this.initializationClassloader);
persistenceUnitsList.add(puInfo);
}
}
for (SEPersistenceUnitInfo persistenceUnitInfo : persistenceUnitsList)
{
// puName uniquely defines the pu on a class loader
String puName = persistenceUnitInfo.getPersistenceUnitName();
// don't add puInfo that could not be used standalone (only as composite member).
if (EntityManagerSetupImpl.mustBeCompositeMember(persistenceUnitInfo)) {
continue;
}
// If puName is already in the map then there are two jars containing persistence units with the same name.
// Because both are loaded from the same classloader there is no way to distinguish between them - throw exception.
EntityManagerSetupImpl anotherEmSetupImpl = null;
if (initialEmSetupImpls != null){
anotherEmSetupImpl = this.initialEmSetupImpls.get(puName);
}
if(anotherEmSetupImpl != null) {
EntityManagerSetupImpl.throwPersistenceUnitNameAlreadyInUseException(puName, persistenceUnitInfo, anotherEmSetupImpl.getPersistenceUnitInfo());
}
// Note that session name is extracted only from puInfo, the passed properties ignored.
String sessionName = EntityManagerSetupImpl.getOrBuildSessionName(Collections.emptyMap(), persistenceUnitInfo, puName);
EntityManagerSetupImpl emSetupImpl = callPredeploy(persistenceUnitInfo, m, puName, sessionName);
if (initialEmSetupImpls != null){
this.initialEmSetupImpls.put(puName, emSetupImpl);
}
if (initialPuInfos != null){
this.initialPuInfos.put(puName, persistenceUnitInfo);
}
}
}
public static void setDefaultProperties(Properties properties)
{
properties.setProperty(PersistenceUnitProperties.CACHE_TYPE_DEFAULT, "None");
properties.setProperty(PersistenceUnitProperties.CACHE_SIZE_DEFAULT, "0");
properties.setProperty(PersistenceUnitProperties.CACHE_SHARED_DEFAULT, "false");
if (Constants.getBoolean("serverMonitoringEnableJPA"))
{
properties.setProperty("eclipselink.logging.level", "FINE");
properties.setProperty("eclipselink.logging.level.sql", "FINE");
properties.setProperty(PersistenceUnitProperties.LOGGING_PARAMETERS, "true");
properties.setProperty("eclipselink.jdbc.bind-parameters", "true");
}
properties.setProperty("eclipselink.session.customizer", "sk.iway.webjet.v9.JpaSessionCustomizer");
}
}