package org.jblooming.waf.settings;
import net.sf.ehcache.hibernate.SingletonEhCacheProvider;
import org.apache.log4j.Logger;
import org.hibernate.ConnectionReleaseMode;
import org.hibernate.SessionFactory;
import org.hibernate.cache.HashtableCacheProvider;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.connection.C3P0ConnectionProvider;
import org.hibernate.connection.ProxoolConnectionProvider;
import org.hibernate.dialect.Dialect;
import org.hibernate.impl.SessionFactoryImpl;
import org.jblooming.PlatformRuntimeException;
import org.jblooming.ontology.IdentifiableSupport;
import org.jblooming.persistence.ThreadLocalPersistenceContextCarrier;
import org.jblooming.persistence.hibernate.OLNamingStrategy;
import org.jblooming.persistence.hibernate.PersistenceContext;
import org.jblooming.persistence.hibernate.PlatformAnnotationConfiguration;
import org.jblooming.tracer.Tracer;
import org.jblooming.utilities.JSP;
import org.jblooming.utilities.StringUtilities;
import org.jblooming.waf.configuration.LoaderSupport;
import org.jblooming.waf.constants.Fields;
import org.logicalcobwebs.proxool.ProxoolConstants;
import org.logicalcobwebs.proxool.ProxoolException;
import org.logicalcobwebs.proxool.ProxoolFacade;
import java.io.File;
import java.util.LinkedHashMap;
import java.util.Properties;
/**
* @author Roberto Bicchierai rbicchierai@open-lab.com
* Date: 8-lug-2008 : 12.54.02
*/
public class PersistenceConfiguration {
public String name;
public String driver_class;
public String driver_url;
public Class dialect;
public String db_user_name;
public String db_user_psw;
public String dataSource;
public boolean useProxool = true;
public boolean useC3P0 = false;
public boolean useEHCache = false;
public boolean useHibStats = false;
public String poolAlias;
public PlatformConfiguration.StringConversionType stringPrimitiveFieldsConversion = PlatformConfiguration.StringConversionType.NONE;
public PlatformConfiguration.StringConversionType searchStringParametersConversion = PlatformConfiguration.StringConversionType.NONE;
Properties hibInfo = new Properties();
public boolean loaded = false;
public boolean poolLoaded = false;
public boolean hibernateLoaded;
/**
* This should be specified as tablespace name in oracle when the user has sufficient rights to access different schemas
*/
public String schemaName;
public String namingStrategy;
private PlatformAnnotationConfiguration hibernateConfiguration;
private SessionFactory sessionFactory;
public static LinkedHashMap<String, PersistenceConfiguration> persistenceConfigurations = new LinkedHashMap();
public static String POOL_ACQUIRE_INCREMENT = "2";
public static String POOL_IDLE_TEST_PERIOD = "300";
public static String POOL_MAX_SIZE = "30";
public static String POOL_MAX_STATEMENTS = "0";
public static String POOL_MIN_SIZE = "1";
public static String POOL_TIMEOUT = "300";
public PersistenceConfiguration(String name) {
this.name = name;
hibernateConfiguration = new PlatformAnnotationConfiguration(this);
poolAlias = "pool." + name;
}
public static PersistenceConfiguration getInstance(String persistenceConfigurationName, Properties p) {
String oscvt = getSafelyTrimmedPropertyValue("onSaveConvertValuesTo", p);
String path = ApplicationState.webAppFileSystemRootPath + File.separator + "WEB-INF" + File.separator + "tmpIndex";
new File(path).mkdirs();
PersistenceConfiguration persistenceConfiguration = new PersistenceConfiguration(persistenceConfigurationName);
persistenceConfiguration.hibernateConfiguration.getProperties().put("hibernate.search.default.indexBase", path);
if (PlatformConfiguration.StringConversionType.LOWER.toString().equalsIgnoreCase(oscvt)) {
persistenceConfiguration.stringPrimitiveFieldsConversion = PlatformConfiguration.StringConversionType.LOWER;
} else if (PlatformConfiguration.StringConversionType.UPPER.toString().equalsIgnoreCase(oscvt)) {
persistenceConfiguration.stringPrimitiveFieldsConversion = PlatformConfiguration.StringConversionType.UPPER;
} else
persistenceConfiguration.stringPrimitiveFieldsConversion = PlatformConfiguration.StringConversionType.NONE;
String osearchcvt = getSafelyTrimmedPropertyValue("onSearchConvertValuesTo", p);
if (PlatformConfiguration.StringConversionType.LOWER.toString().equalsIgnoreCase(osearchcvt)) {
persistenceConfiguration.searchStringParametersConversion = PlatformConfiguration.StringConversionType.LOWER;
} else if (PlatformConfiguration.StringConversionType.UPPER.toString().equalsIgnoreCase(osearchcvt)) {
persistenceConfiguration.searchStringParametersConversion = PlatformConfiguration.StringConversionType.UPPER;
} else
persistenceConfiguration.searchStringParametersConversion = PlatformConfiguration.StringConversionType.NONE;
boolean encriptDbAccount = Fields.TRUE.equalsIgnoreCase(getSafelyTrimmedPropertyValue("encriptDbAccount", p));
String datasource = getSafelyTrimmedPropertyValue("dataSource", p);
if (JSP.ex(datasource))
persistenceConfiguration.dataSource = datasource;
//persistenceConfiguration.dataSource = (!datasource.startsWith("java:comp/env/") ? "java:/comp/env/" : "") + datasource;
persistenceConfiguration.driver_class = getSafelyTrimmedPropertyValue("driver", p);
persistenceConfiguration.driver_url = getSafelyTrimmedPropertyValue("url", p);
try {
persistenceConfiguration.dialect = Class.forName(getSafelyTrimmedPropertyValue("dialect", p));
} catch (ClassNotFoundException e) {
throw new PlatformRuntimeException(e);
}
String user = getSafelyTrimmedPropertyValue("user", p);
if (encriptDbAccount)
user = StringUtilities.decrypt(user);
persistenceConfiguration.db_user_name = user;
String password = getSafelyTrimmedPropertyValue("password", p);
if (encriptDbAccount)
password = StringUtilities.decrypt(password);
persistenceConfiguration.db_user_psw = password;
String schemaName = getSafelyTrimmedPropertyValue("schemaName", p);
if (JSP.ex(schemaName))
persistenceConfiguration.schemaName = schemaName;
persistenceConfiguration.namingStrategy = getSafelyTrimmedPropertyValue("namingStrategy", p);
String value = getSafelyTrimmedPropertyValue("poolMaxSize", p);
if (JSP.ex(value))
PersistenceConfiguration.POOL_MAX_SIZE = value;
persistenceConfiguration.useC3P0 = Fields.TRUE.equalsIgnoreCase(getSafelyTrimmedPropertyValue("useC3P0", p));
persistenceConfiguration.useProxool = Fields.TRUE.equalsIgnoreCase(getSafelyTrimmedPropertyValue("useProxool", p));
persistenceConfiguration.useEHCache = Fields.TRUE.equalsIgnoreCase(getSafelyTrimmedPropertyValue("useEHCache", p));
persistenceConfiguration.useHibStats = Fields.TRUE.equalsIgnoreCase(getSafelyTrimmedPropertyValue("useHibStats", p));
NamingStrategy ns = new OLNamingStrategy();
if (JSP.ex(persistenceConfiguration.namingStrategy)) {
try {
ns = (NamingStrategy) (Class.forName(persistenceConfiguration.namingStrategy.trim()).newInstance());
} catch (Exception e) {
throw new PlatformRuntimeException(e);
}
}
persistenceConfiguration.hibernateConfiguration.setNamingStrategy(ns);
persistenceConfiguration.configPoolAndHibernateProperties();
PersistenceConfiguration.persistenceConfigurations.put(persistenceConfigurationName, persistenceConfiguration);
return persistenceConfiguration;
}
private void configPoolAndHibernateProperties() {
loaded = false;
if (poolLoaded) {
if (useProxool)
ProxoolFacade.shutdown(0);
poolLoaded = false;
}
if (useProxool || useC3P0) {
configPool();
} else {
configNoPool();
}
poolLoaded = true;
configHibernateProperties();
}
private void configNoPool() {
if (JSP.ex(dataSource)) {
hibInfo.setProperty(Environment.DATASOURCE, dataSource);
} else {
hibInfo.setProperty(Environment.DRIVER, driver_class);
hibInfo.setProperty(Environment.URL, driver_url);
hibInfo.setProperty(Environment.USER, db_user_name);
hibInfo.setProperty(Environment.PASS, db_user_psw);
}
hibInfo.setProperty(Environment.POOL_SIZE, "1");
Tracer.platformLogger.info("open lab platform - not using connection pooling");
}
private void configPool() {
if (useProxool) {
String url = "proxool." + poolAlias + ":" + driver_class + ":" + driver_url;
Properties proxoolInfo = new Properties();
proxoolInfo.setProperty(ProxoolConstants.STATISTICS_PROPERTY, "5m,1d");
proxoolInfo.setProperty(ProxoolConstants.USER_PROPERTY, db_user_name);
proxoolInfo.setProperty(ProxoolConstants.PASSWORD_PROPERTY, db_user_psw);
proxoolInfo.setProperty(ProxoolConstants.MAXIMUM_CONNECTION_COUNT_PROPERTY, POOL_MAX_SIZE);
//five minutes default is fine
//proxoolInfo.setProperty(ProxoolConstants.MAXIMUM_ACTIVE_TIME_PROPERTY, "30000");
try {
ProxoolFacade.registerConnectionPool(url, proxoolInfo);
// beautiful hack: proxool re-enables it !
Logger.getRootLogger().removeAllAppenders();
Logger proxoolLogger = Logger.getLogger("org.logicalcobwebs.proxool.pool");
proxoolLogger.setLevel(Tracer.hibernateLogger.getLevel());
LoaderSupport.createLogger(PlatformConfiguration.logOnConsole, PlatformConfiguration.logOnFile, PlatformConfiguration.logPattern, PlatformConfiguration.logFilesRoot, proxoolLogger, "proxoolConsoleAppender", "proxool.log", "proxoolFileAppender");
Tracer.platformLogger.info("open lab platform - using Proxool connection pooling");
} catch (ProxoolException e) {
throw new RuntimeException(e);
}
} else {
if (JSP.ex(dataSource)) {
hibInfo.setProperty(Environment.DATASOURCE, dataSource);
} else {
//com.mchange.v2.log.MLog
hibInfo.setProperty(Environment.DRIVER, driver_class);
hibInfo.setProperty(Environment.URL, driver_url);
hibInfo.setProperty(Environment.USER, db_user_name);
hibInfo.setProperty(Environment.PASS, db_user_psw);
}
hibInfo.setProperty(Environment.POOL_SIZE, "1");
hibInfo.setProperty(Environment.C3P0_ACQUIRE_INCREMENT, POOL_ACQUIRE_INCREMENT);
hibInfo.setProperty(Environment.C3P0_IDLE_TEST_PERIOD, POOL_IDLE_TEST_PERIOD);
hibInfo.setProperty(Environment.C3P0_MAX_SIZE, POOL_MAX_SIZE);
hibInfo.setProperty(Environment.C3P0_MAX_STATEMENTS, POOL_MAX_STATEMENTS);
hibInfo.setProperty(Environment.C3P0_MIN_SIZE, POOL_MIN_SIZE);
hibInfo.setProperty(Environment.C3P0_TIMEOUT, POOL_TIMEOUT);
Logger c3p0Logger = Logger.getLogger("com.mchange.v2");
c3p0Logger.setLevel(Tracer.hibernateLogger.getLevel());
LoaderSupport.createLogger(PlatformConfiguration.logOnConsole, PlatformConfiguration.logOnFile, PlatformConfiguration.logPattern, PlatformConfiguration.logFilesRoot, c3p0Logger, "c3p0ConsoleAppender", "c3p0.log", "c3p0FileAppender");
/*Logger C3P0Registry = Logger.getLogger("com.mchange.v2.c3p0.C3P0Registry");
C3P0Registry.setLevel(Tracer.hibernateLogger.getLevel());
createLogger(logOnConsole, logOnFile, logPattern, logFilesRoot, C3P0Registry, "c3p0ConsoleAppender", "c3p0.log", "c3p0FileAppender");
Logger DynamicPooledDataSourceManagerMBean = Logger.getLogger("com.mchange.v2.c3p0.management.DynamicPooledDataSourceManagerMBean");
DynamicPooledDataSourceManagerMBean.setLevel(Tracer.hibernateLogger.getLevel());
createLogger(logOnConsole, logOnFile, logPattern, logFilesRoot, DynamicPooledDataSourceManagerMBean, "c3p0ConsoleAppender", "c3p0.log", "c3p0FileAppender");*/
Tracer.platformLogger.info("open lab platform - using C3P0 connection pooling");
}
}
public void configHibernateProperties() {
try {
if (!(dialect.newInstance() instanceof Dialect))
throw new PlatformRuntimeException("Must configure dialect with a class extending org.hibernate.dialect.Dialect");
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
//hibernate
// hibInfo.setProperty(Environment.QUERY_SUBSTITUTIONS, "true 'Y', false 'N'"); // this is dialect sensitive
hibInfo.setProperty(Environment.QUERY_SUBSTITUTIONS, "true 1, false 0"); // this is dialect sensitive
hibInfo.setProperty(Environment.DIALECT, dialect.getName());
hibInfo.setProperty(Environment.MAX_FETCH_DEPTH, "2");
hibInfo.setProperty(Environment.USE_STREAMS_FOR_BINARY, "true");
hibInfo.setProperty(Environment.STATEMENT_BATCH_SIZE, "15");
//statistics
if (useHibStats)
hibInfo.setProperty(Environment.GENERATE_STATISTICS, "true");
if (useProxool) {
// in case of datasource it must be bypassed
hibInfo.setProperty(Environment.PROXOOL_POOL_ALIAS, poolAlias);
hibInfo.setProperty(Environment.PROXOOL_EXISTING_POOL, "true");
hibInfo.setProperty(Environment.CONNECTION_PROVIDER, ProxoolConnectionProvider.class.getName());
hibInfo.setProperty(Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.ON_CLOSE.toString());
} else if (useC3P0) {
hibInfo.setProperty(Environment.CONNECTION_PROVIDER, C3P0ConnectionProvider.class.getName());
hibInfo.setProperty(Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.ON_CLOSE.toString());
}
if (useEHCache) {
hibInfo.setProperty(Environment.CACHE_PROVIDER, SingletonEhCacheProvider.class.getName());
Tracer.platformLogger.info("open lab platform - using EHCache");
} else
hibInfo.setProperty(Environment.CACHE_PROVIDER, HashtableCacheProvider.class.getName());
hibInfo.setProperty(Environment.USE_REFLECTION_OPTIMIZER, (ApplicationState.platformConfiguration.development ? "false" : "true"));
hibInfo.setProperty(Environment.USE_QUERY_CACHE, "true");
//no connection isolation with hsqldb
if (dialect.getName().indexOf("HSQL") == -1)
hibInfo.setProperty(Environment.ISOLATION, "2");
hibernateConfiguration.addProperties(hibInfo);
}
public void configAndBuildHibSessionFactory() {
if (!loaded) {
try {
sessionFactory = hibernateConfiguration.buildSessionFactory();
} catch (Throwable throwable) {
throwable.printStackTrace();
throw new RuntimeException(throwable);
}
//restart case
} else
((SessionFactoryImpl) sessionFactory).getConnectionProvider().close();
hibernateLoaded = true;
Tracer.platformLogger.info("open lab platform - config:" + name + " hibernate factory ok");
}
private static String getSafelyTrimmedPropertyValue(String name, Properties p) {
String s = p.getProperty(name);
return s != null ? s.trim() : null;
}
/**
* @return first loaded PersistenceConfiguration
*/
public static PersistenceConfiguration getFirstPersistenceConfiguration() {
return PersistenceConfiguration.persistenceConfigurations.values().iterator().next();
}
/**
* @return PersistenceConfiguration in threadLocal if existing else first one
*/
public static PersistenceConfiguration getDefaultPersistenceConfiguration() {
ThreadLocalPersistenceContextCarrier carrier = PersistenceContext.threadLocalPersistenceContextCarrier.get();
if (carrier != null && carrier.currentPC != null)
return carrier.currentPC.persistenceConfiguration;
else
return getFirstPersistenceConfiguration();
}
public PlatformAnnotationConfiguration getHibernateConfiguration() {
return hibernateConfiguration;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public static PersistenceConfiguration getInstance(Class<? extends IdentifiableSupport> persistentClass) {
PersistenceConfiguration conf = null;
for (String confName : PersistenceConfiguration.persistenceConfigurations.keySet()) {
PersistenceConfiguration pcf = PersistenceConfiguration.persistenceConfigurations.get(confName);
if (pcf.getHibernateConfiguration().getClassMapping(persistentClass.getName()) != null) {
conf = pcf;
break;
}
}
return conf;
}
}