mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#476 - ENH: Enable ServiceConfig to use alternate ClassLoader - was ServiceConfig add setClassloader api --- part 3: Refactor with ClassLoadConfig
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
package com.avaje.ebean.config;
|
||||
|
||||
|
||||
/**
|
||||
* Helper to find classes taking into account the context class loader.
|
||||
*/
|
||||
public class ClassLoadConfig {
|
||||
|
||||
protected final ClassLoaderContext context;
|
||||
|
||||
/**
|
||||
* Construct with the default classLoader search with context classLoader first.
|
||||
*/
|
||||
public ClassLoadConfig() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the classLoader to use for class detection and new instance creation.
|
||||
*/
|
||||
public ClassLoadConfig(ClassLoader classLoader) {
|
||||
this.context = new ClassLoaderContext(classLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the Java.time types are available and should be supported.
|
||||
*/
|
||||
public boolean isJavaTimePresent() {
|
||||
return isPresent("java.time.LocalDate");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the Joda types are available and should be supported.
|
||||
*/
|
||||
public boolean isJodaTimePresent() {
|
||||
return isPresent("org.joda.time.LocalDateTime");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if javax validation annotations like Size and NotNull are present.
|
||||
*/
|
||||
public boolean isJavaxValidationAnnotationsPresent() {
|
||||
return isPresent("javax.validation.constraints.NotNull");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if Jackson annotations like JsonIgnore are present.
|
||||
*/
|
||||
public boolean isJacksonAnnotationsPresent() {
|
||||
return isPresent("com.fasterxml.jackson.annotation.JsonIgnore");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if Jackson ObjectMapper is present.
|
||||
*/
|
||||
public boolean isJacksonObjectMapperPresent() {
|
||||
return isPresent("com.fasterxml.jackson.databind.ObjectMapper");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new instance of the class using the default constructor.
|
||||
*/
|
||||
public Object newInstance(String className) {
|
||||
|
||||
try {
|
||||
Class<?> cls = forName(className);
|
||||
return cls.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("Error constructing " + className, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given class is present.
|
||||
*/
|
||||
protected boolean isPresent(String className) {
|
||||
try {
|
||||
forName(className);
|
||||
return true;
|
||||
} catch (Throwable ex) {
|
||||
// Class or one of its dependencies is not present...
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a class taking into account a context class loader (if present).
|
||||
*/
|
||||
protected Class<?> forName(String name) throws ClassNotFoundException {
|
||||
return context.forName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the preferred, caller and context class loaders.
|
||||
*/
|
||||
protected class ClassLoaderContext {
|
||||
|
||||
/**
|
||||
* Optional - if set only use this classLoader (no fallback).
|
||||
*/
|
||||
protected final ClassLoader preferredLoader;
|
||||
|
||||
protected final ClassLoader contextLoader;
|
||||
|
||||
protected final ClassLoader callerLoader;
|
||||
|
||||
ClassLoaderContext(ClassLoader preferredLoader) {
|
||||
this.preferredLoader = preferredLoader;
|
||||
this.callerLoader = ServerConfig.class.getClassLoader();
|
||||
this.contextLoader = contextLoader();
|
||||
}
|
||||
|
||||
ClassLoader contextLoader() {
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
return (loader != null) ? loader: callerLoader;
|
||||
}
|
||||
|
||||
Class<?> forName(String name) throws ClassNotFoundException {
|
||||
|
||||
if (preferredLoader != null) {
|
||||
// only use the explicitly set classLoader
|
||||
return classForName(name, preferredLoader);
|
||||
}
|
||||
try {
|
||||
// try the context loader first
|
||||
return classForName(name, contextLoader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
if (callerLoader == contextLoader) {
|
||||
throw e;
|
||||
} else {
|
||||
// fallback to the caller classLoader
|
||||
return classForName(name, callerLoader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Class<?> classForName(String name, ClassLoader classLoader) throws ClassNotFoundException {
|
||||
return Class.forName(name, true, classLoader);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.avaje.ebean.event.changelog.ChangeLogRegister;
|
||||
import com.avaje.ebean.event.readaudit.ReadAuditLogger;
|
||||
import com.avaje.ebean.event.readaudit.ReadAuditPrepare;
|
||||
import com.avaje.ebean.meta.MetaInfoManager;
|
||||
import com.avaje.ebeaninternal.api.ClassUtil;
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
@@ -235,6 +234,11 @@ public class ServerConfig {
|
||||
*/
|
||||
private DbMigrationConfig migrationConfig = new DbMigrationConfig();
|
||||
|
||||
/**
|
||||
* The ClassLoadConfig used to detect Joda, Java8, Jackson etc and create plugin instances given a className.
|
||||
*/
|
||||
private ClassLoadConfig classLoadConfig = new ClassLoadConfig();
|
||||
|
||||
/**
|
||||
* Set to true if the DataSource uses autoCommit.
|
||||
* <p>
|
||||
@@ -2030,6 +2034,22 @@ public class ServerConfig {
|
||||
this.persistenceContextScope = persistenceContextScope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ClassLoadConfig which is used to detect Joda, Java8 types etc and also
|
||||
* create new instances of plugins given a className.
|
||||
*/
|
||||
public ClassLoadConfig getClassLoadConfig() {
|
||||
return classLoadConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ClassLoadConfig which is used to detect Joda, Java8 types etc and also
|
||||
* create new instances of plugins given a className.
|
||||
*/
|
||||
public void setClassLoadConfig(ClassLoadConfig classLoadConfig) {
|
||||
this.classLoadConfig = classLoadConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load settings from ebean.properties.
|
||||
*/
|
||||
@@ -2093,7 +2113,7 @@ public class ServerConfig {
|
||||
* @param classname the implementation class as per properties
|
||||
*/
|
||||
protected <T> T createInstance(Class<T> pluginType, String classname) {
|
||||
return classname == null ? null : (T) ClassUtil.newInstance(classname);
|
||||
return classname == null ? null : (T) classLoadConfig.newInstance(classname);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
package com.avaje.ebeaninternal.api;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Wraps the caller and context class loaders.
|
||||
* <p>
|
||||
* Helper for ClassUtil.
|
||||
* </p>
|
||||
*
|
||||
* @author rbygrave
|
||||
*/
|
||||
class ClassLoadContext {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ClassLoadContext.class);
|
||||
|
||||
private final ClassLoader callerLoader;
|
||||
|
||||
private final ClassLoader contextLoader;
|
||||
|
||||
private final boolean preferContext;
|
||||
|
||||
private boolean ambiguous;
|
||||
|
||||
public static ClassLoadContext of(Class<?> caller, boolean preferContext) {
|
||||
return new ClassLoadContext(caller, preferContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor is package-private to restrict instantiation to
|
||||
*/
|
||||
ClassLoadContext(final Class<?> caller, boolean preferContext) {
|
||||
if (caller == null) {
|
||||
throw new IllegalArgumentException("caller is null");
|
||||
}
|
||||
this.callerLoader = caller.getClassLoader();
|
||||
this.contextLoader = Thread.currentThread().getContextClassLoader();
|
||||
this.preferContext = preferContext;
|
||||
}
|
||||
|
||||
public Class<?> forName(String name) throws ClassNotFoundException {
|
||||
|
||||
ClassLoader defaultLoader = getDefault(preferContext);
|
||||
|
||||
try {
|
||||
return Class.forName(name, true, defaultLoader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
if (callerLoader == defaultLoader) {
|
||||
throw e;
|
||||
} else {
|
||||
return Class.forName(name, true, callerLoader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the expected class loader to use.
|
||||
* <p>
|
||||
* Works on the assumption that the child of the caller or context class
|
||||
* loader is preferred.
|
||||
* </p>
|
||||
*/
|
||||
public ClassLoader getDefault(boolean preferContext) {
|
||||
|
||||
if (contextLoader == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No Context ClassLoader, using " + callerLoader.getClass().getName());
|
||||
}
|
||||
return callerLoader;
|
||||
}
|
||||
if (contextLoader == callerLoader) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Context and Caller ClassLoader's same instance of " + contextLoader.getClass().getName());
|
||||
}
|
||||
return callerLoader;
|
||||
}
|
||||
|
||||
if (isChild(contextLoader, callerLoader)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Caller ClassLoader " + callerLoader.getClass().getName()
|
||||
+ " child of ContextLoader " + contextLoader.getClass().getName());
|
||||
}
|
||||
return callerLoader;
|
||||
|
||||
} else if (isChild(callerLoader, contextLoader)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Context ClassLoader " + contextLoader.getClass().getName()
|
||||
+ " child of Caller ClassLoader " + callerLoader.getClass().getName());
|
||||
}
|
||||
return contextLoader;
|
||||
|
||||
} else {
|
||||
// ambiguous case, perhaps both null
|
||||
logger.debug("Ambiguous ClassLoader choice preferContext:" + preferContext
|
||||
+ " Context:" + contextLoader.getClass().getName() + " Caller:" + callerLoader.getClass().getName());
|
||||
ambiguous = true;
|
||||
return preferContext ? contextLoader : callerLoader;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the 'default' class loader is ambiguous.
|
||||
*/
|
||||
public boolean isAmbiguous() {
|
||||
return ambiguous;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ClassLoader of the caller.
|
||||
*/
|
||||
public ClassLoader getCallerLoader() {
|
||||
return callerLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Thread Context ClassLoader.
|
||||
*/
|
||||
public ClassLoader getContextLoader() {
|
||||
return contextLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ClassLoader for this class.
|
||||
*/
|
||||
public ClassLoader getThisLoader() {
|
||||
return this.getClass().getClassLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 'true' if 'loader2' is a delegation child of 'loader1' [or if
|
||||
* 'loader1'=='loader2'].
|
||||
*/
|
||||
private boolean isChild(final ClassLoader loader1, ClassLoader loader2) {
|
||||
|
||||
for (; loader2 != null; loader2 = loader2.getParent()) {
|
||||
if (loader2 == loader1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,79 +6,60 @@ package com.avaje.ebeaninternal.api;
|
||||
*/
|
||||
public class ClassUtil {
|
||||
|
||||
/**
|
||||
* Load a class taking into account a context class loader (if present).
|
||||
*/
|
||||
public static Class<?> forName(String name, Class<?> caller) throws ClassNotFoundException {
|
||||
|
||||
if (caller == null) {
|
||||
caller = ClassUtil.class;
|
||||
}
|
||||
ClassLoadContext ctx = ClassLoadContext.of(caller, true);
|
||||
return ctx.forName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if javax validation annotations like Size and NotNull are present.
|
||||
*/
|
||||
public static boolean isJavaxValidationAnnotationsPresent() {
|
||||
return isPresent("javax.validation.constraints.NotNull", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if Jackson annotations like JsonIgnore are present.
|
||||
*/
|
||||
public static boolean isJacksonAnnotationsPresent() {
|
||||
return isPresent("com.fasterxml.jackson.annotation.JsonIgnore", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if Jackson ObjectMapper is present.
|
||||
*/
|
||||
public static boolean isJacksonObjectMapperPresent() {
|
||||
return isPresent("com.fasterxml.jackson.databind.ObjectMapper", null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if the given class is present.
|
||||
*/
|
||||
public static boolean isPresent(String className) {
|
||||
return isPresent(className, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given class is present.
|
||||
*/
|
||||
public static boolean isPresent(String className, Class<?> caller) {
|
||||
try {
|
||||
forName(className, caller);
|
||||
return true;
|
||||
} catch (Throwable ex) {
|
||||
// Class or one of its dependencies is not present...
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new instance of the class using the default constructor.
|
||||
*/
|
||||
public static Object newInstance(String className) {
|
||||
return newInstance(className, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new instance of the class using the default constructor.
|
||||
*/
|
||||
public static Object newInstance(String className, Class<?> caller) {
|
||||
|
||||
try {
|
||||
Class<?> cls = forName(className, caller);
|
||||
Class<?> cls = forName(className);
|
||||
return cls.newInstance();
|
||||
} catch (Exception e) {
|
||||
String msg = "Error constructing " + className;
|
||||
throw new IllegalArgumentException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a class taking into account a context class loader (if present).
|
||||
*/
|
||||
private static Class<?> forName(String name) throws ClassNotFoundException {
|
||||
return new ClassLoadContext().forName(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to wrap the context and caller classLoaders (to use/try both).
|
||||
*/
|
||||
static class ClassLoadContext {
|
||||
|
||||
private final ClassLoader contextLoader;
|
||||
|
||||
private final ClassLoader callerLoader;
|
||||
|
||||
ClassLoadContext() {
|
||||
this.callerLoader = ClassUtil.class.getClassLoader();
|
||||
this.contextLoader = contextLoader();
|
||||
}
|
||||
|
||||
ClassLoader contextLoader() {
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
return (loader != null) ? loader: callerLoader;
|
||||
}
|
||||
|
||||
public Class<?> forName(String name) throws ClassNotFoundException {
|
||||
|
||||
try {
|
||||
return Class.forName(name, true, contextLoader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
if (callerLoader == contextLoader) {
|
||||
throw e;
|
||||
} else {
|
||||
return Class.forName(name, true, callerLoader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.avaje.ebeaninternal.server.cluster.ClusterManager;
|
||||
import com.avaje.ebeaninternal.server.lib.ShutdownManager;
|
||||
import com.avaje.ebeaninternal.server.lib.sql.DataSourceAlert;
|
||||
import com.avaje.ebeaninternal.server.lib.sql.DataSourcePool;
|
||||
import com.avaje.ebeaninternal.server.lib.sql.DataSourcePoolListener;
|
||||
import com.avaje.ebeaninternal.server.lib.sql.SimpleDataSourceAlert;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -311,7 +312,17 @@ public class DefaultContainer implements SpiContainer {
|
||||
}
|
||||
|
||||
DataSourceAlert notify = new SimpleDataSourceAlert();
|
||||
return new DataSourcePool(notify, config.getName(), dsConfig);
|
||||
DataSourcePoolListener listener = createListener(config, dsConfig);
|
||||
|
||||
return new DataSourcePool(notify, config.getName(), dsConfig, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a DataSourcePoolListener if it has been specified.
|
||||
*/
|
||||
private DataSourcePoolListener createListener(ServerConfig config, DataSourceConfig dsConfig) {
|
||||
String poolListener = dsConfig.getPoolListener();
|
||||
return poolListener != null ? (DataSourcePoolListener) config.getClassLoadConfig().newInstance(poolListener) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -357,6 +357,6 @@ public class InternalConfiguration {
|
||||
}
|
||||
|
||||
public GeneratedPropertyFactory getGeneratedPropertyFactory() {
|
||||
return new GeneratedPropertyFactory(serverConfig.getCurrentUserProvider());
|
||||
return new GeneratedPropertyFactory(serverConfig);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-4
@@ -31,7 +31,7 @@ public class BeanPropertyAssocManyJsonHelp {
|
||||
*/
|
||||
public BeanPropertyAssocManyJsonHelp(BeanPropertyAssocMany<?> many) {
|
||||
this.many = many;
|
||||
this.jsonTransient = !ClassUtil.isJacksonObjectMapperPresent() ? null : new BeanPropertyAssocManyJsonTransient();
|
||||
this.jsonTransient = new BeanPropertyAssocManyJsonTransient();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,9 +81,6 @@ public class BeanPropertyAssocManyJsonHelp {
|
||||
*/
|
||||
private void jsonReadTransientUsingObjectMapper(ReadJson readJson, EntityBean parentBean) throws IOException {
|
||||
|
||||
if (jsonTransient == null) {
|
||||
throw new IllegalStateException("Jackson ObjectMapper is required to read this Transient property "+many.getFullBeanName());
|
||||
}
|
||||
jsonTransient.jsonReadUsingObjectMapper(many, readJson, parentBean);
|
||||
}
|
||||
}
|
||||
|
||||
+17
-4
@@ -3,7 +3,9 @@ package com.avaje.ebeaninternal.server.deploy.generatedproperty;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashSet;
|
||||
|
||||
import com.avaje.ebean.config.ClassLoadConfig;
|
||||
import com.avaje.ebean.config.CurrentUserProvider;
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||
|
||||
/**
|
||||
@@ -13,9 +15,9 @@ public class GeneratedPropertyFactory {
|
||||
|
||||
private final CounterFactory counterFactory = new CounterFactory();
|
||||
|
||||
private final InsertTimestampFactory insertFactory = new InsertTimestampFactory();
|
||||
private final InsertTimestampFactory insertFactory;
|
||||
|
||||
private final UpdateTimestampFactory updateFactory = new UpdateTimestampFactory();
|
||||
private final UpdateTimestampFactory updateFactory;
|
||||
|
||||
private final HashSet<String> numberTypes = new HashSet<String>();
|
||||
|
||||
@@ -23,8 +25,15 @@ public class GeneratedPropertyFactory {
|
||||
|
||||
private final GeneratedWhoCreated generatedWhoCreated;
|
||||
|
||||
public GeneratedPropertyFactory(CurrentUserProvider currentUserProvider) {
|
||||
private final ClassLoadConfig classLoadConfig;
|
||||
|
||||
public GeneratedPropertyFactory(ServerConfig serverConfig) {
|
||||
|
||||
this.classLoadConfig = serverConfig.getClassLoadConfig();
|
||||
this.insertFactory = new InsertTimestampFactory(classLoadConfig);
|
||||
this.updateFactory = new UpdateTimestampFactory(classLoadConfig);
|
||||
|
||||
CurrentUserProvider currentUserProvider = serverConfig.getCurrentUserProvider();
|
||||
if (currentUserProvider != null) {
|
||||
generatedWhoCreated = new GeneratedWhoCreated(currentUserProvider);
|
||||
generatedWhoModified = new GeneratedWhoModified(currentUserProvider);
|
||||
@@ -44,7 +53,11 @@ public class GeneratedPropertyFactory {
|
||||
numberTypes.add(BigDecimal.class.getName());
|
||||
}
|
||||
|
||||
private boolean isNumberType(String typeClassName) {
|
||||
public ClassLoadConfig getClassLoadConfig() {
|
||||
return classLoadConfig;
|
||||
}
|
||||
|
||||
private boolean isNumberType(String typeClassName) {
|
||||
return numberTypes.contains(typeClassName);
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -9,7 +9,7 @@ import java.util.Map;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebeaninternal.api.ClassUtil;
|
||||
import com.avaje.ebean.config.ClassLoadConfig;
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||
|
||||
/**
|
||||
@@ -21,25 +21,25 @@ public class InsertTimestampFactory {
|
||||
|
||||
final Map<Class<?>, GeneratedProperty> map = new HashMap<Class<?>, GeneratedProperty>();
|
||||
|
||||
public InsertTimestampFactory() {
|
||||
public InsertTimestampFactory(ClassLoadConfig classLoadConfig) {
|
||||
map.put(Timestamp.class, new GeneratedInsertTimestamp());
|
||||
map.put(java.util.Date.class, new GeneratedInsertDate());
|
||||
map.put(Long.class, longTime);
|
||||
map.put(long.class, longTime);
|
||||
|
||||
if (ClassUtil.isPresent("java.time.LocalDate", this.getClass())) {
|
||||
if (classLoadConfig.isJavaTimePresent()) {
|
||||
map.put(LocalDateTime.class, new GeneratedInsertJavaTime.LocalDT());
|
||||
map.put(OffsetDateTime.class, new GeneratedInsertJavaTime.OffsetDT());
|
||||
map.put(ZonedDateTime.class, new GeneratedInsertJavaTime.ZonedDT());
|
||||
}
|
||||
if (ClassUtil.isPresent("org.joda.time.LocalDateTime", this.getClass())) {
|
||||
if (classLoadConfig.isJodaTimePresent()) {
|
||||
map.put(org.joda.time.LocalDateTime.class, new GeneratedInsertJodaTime.LocalDT());
|
||||
map.put(org.joda.time.DateTime.class, new GeneratedInsertJodaTime.DateTimeDT());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setInsertTimestamp(DeployBeanProperty property) {
|
||||
public void setInsertTimestamp(DeployBeanProperty property) {
|
||||
|
||||
property.setGeneratedProperty(createInsertTimestamp(property));
|
||||
}
|
||||
|
||||
+4
-4
@@ -9,7 +9,7 @@ import java.util.Map;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebeaninternal.api.ClassUtil;
|
||||
import com.avaje.ebean.config.ClassLoadConfig;
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||
|
||||
/**
|
||||
@@ -21,18 +21,18 @@ public class UpdateTimestampFactory {
|
||||
|
||||
final Map<Class<?>, GeneratedProperty> map = new HashMap<Class<?>, GeneratedProperty>();
|
||||
|
||||
public UpdateTimestampFactory() {
|
||||
public UpdateTimestampFactory(ClassLoadConfig classLoadConfig) {
|
||||
map.put(Timestamp.class, new GeneratedUpdateTimestamp());
|
||||
map.put(java.util.Date.class, new GeneratedUpdateDate());
|
||||
map.put(Long.class, longTime);
|
||||
map.put(long.class, longTime);
|
||||
|
||||
if (ClassUtil.isPresent("java.time.LocalDate", this.getClass())) {
|
||||
if (classLoadConfig.isJavaTimePresent()) {
|
||||
map.put(LocalDateTime.class, new GeneratedUpdateJavaTime.LocalDT());
|
||||
map.put(OffsetDateTime.class, new GeneratedUpdateJavaTime.OffsetDT());
|
||||
map.put(ZonedDateTime.class, new GeneratedUpdateJavaTime.ZonedDT());
|
||||
}
|
||||
if (ClassUtil.isPresent("org.joda.time.LocalDateTime", this.getClass())) {
|
||||
if (classLoadConfig.isJodaTimePresent()) {
|
||||
map.put(org.joda.time.LocalDateTime.class, new GeneratedUpdateJodaTime.LocalDT());
|
||||
map.put(org.joda.time.DateTime.class, new GeneratedUpdateJodaTime.DateTimeDT());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.avaje.ebeaninternal.server.deploy.parse;
|
||||
|
||||
import com.avaje.ebeaninternal.api.ClassUtil;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager;
|
||||
import com.avaje.ebeaninternal.server.deploy.generatedproperty.GeneratedPropertyFactory;
|
||||
|
||||
@@ -37,8 +36,8 @@ public class ReadAnnotations {
|
||||
this.generatedPropFactory = generatedPropFactory;
|
||||
this.asOfViewSuffix = asOfViewSuffix;
|
||||
this.versionsBetweenSuffix = versionsBetweenSuffix;
|
||||
this.javaxValidationAnnotations = ClassUtil.isJavaxValidationAnnotationsPresent();
|
||||
this.jacksonAnnotations = ClassUtil.isJacksonAnnotationsPresent();
|
||||
this.javaxValidationAnnotations = generatedPropFactory.getClassLoadConfig().isJavaxValidationAnnotationsPresent();
|
||||
this.jacksonAnnotations = generatedPropFactory.getClassLoadConfig().isJacksonAnnotationsPresent();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -171,10 +171,14 @@ public class DataSourcePool implements DataSource {
|
||||
private final Runnable heartbeatRunnable = new HeartBeatRunnable();
|
||||
|
||||
public DataSourcePool(DataSourceAlert notify, String name, DataSourceConfig params) {
|
||||
this(notify, name, params, null);
|
||||
}
|
||||
|
||||
public DataSourcePool(DataSourceAlert notify, String name, DataSourceConfig params, DataSourcePoolListener listener) {
|
||||
|
||||
this.notify = notify;
|
||||
this.name = name;
|
||||
this.poolListener = createPoolListener(params.getPoolListener());
|
||||
this.poolListener = listener;
|
||||
|
||||
this.autoCommit = params.isAutoCommit();
|
||||
this.transactionIsolation = params.getIsolationLevel();
|
||||
@@ -238,20 +242,6 @@ public class DataSourcePool implements DataSource {
|
||||
throw new SQLFeatureNotSupportedException("We do not support java.util.logging");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the DataSourcePoolListener if there is one.
|
||||
*/
|
||||
private DataSourcePoolListener createPoolListener(String cn) {
|
||||
if (cn == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return (DataSourcePoolListener) ClassUtil.newInstance(cn, this.getClass());
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void initialise() throws SQLException {
|
||||
|
||||
String transIsolation = TransactionIsolation.getLevelDescription(transactionIsolation);
|
||||
|
||||
@@ -162,13 +162,13 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
this.typeMap = new ConcurrentHashMap<Class<?>, ScalarType<?>>();
|
||||
this.nativeMap = new ConcurrentHashMap<Integer, ScalarType<?>>();
|
||||
|
||||
this.objectMapperPresent = ClassUtil.isJacksonObjectMapperPresent();
|
||||
this.objectMapperPresent = config.getClassLoadConfig().isJacksonObjectMapperPresent();
|
||||
|
||||
this.extraTypeFactory = new DefaultTypeFactory(config);
|
||||
|
||||
initialiseStandard(jsonDateTime, config);
|
||||
initialiseJavaTimeTypes(jsonDateTime, config);
|
||||
initialiseJodaTypes(jsonDateTime);
|
||||
initialiseJodaTypes(jsonDateTime, config);
|
||||
initialiseJacksonTypes(config);
|
||||
|
||||
if (isPostgres(config.getDatabasePlatform())) {
|
||||
@@ -738,7 +738,7 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
*/
|
||||
protected void initialiseJacksonTypes(ServerConfig config) {
|
||||
|
||||
if (ClassUtil.isPresent("com.fasterxml.jackson.databind.ObjectMapper", this.getClass())) {
|
||||
if (config.getClassLoadConfig().isJacksonObjectMapperPresent()) {
|
||||
|
||||
logger.trace("Registering JsonNode type support");
|
||||
|
||||
@@ -765,7 +765,7 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
}
|
||||
|
||||
protected void initialiseJavaTimeTypes(JsonConfig.DateTime mode, ServerConfig config) {
|
||||
if (ClassUtil.isPresent("java.time.LocalDate", this.getClass())) {
|
||||
if (config.getClassLoadConfig().isJavaTimePresent()) {
|
||||
logger.debug("Registering java.time data types");
|
||||
typeMap.put(java.time.LocalDate.class, new ScalarTypeLocalDate());
|
||||
typeMap.put(java.time.LocalDateTime.class, new ScalarTypeLocalDateTime(mode));
|
||||
@@ -796,10 +796,10 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable {
|
||||
* Detect if Joda classes are in the classpath and if so register the Joda
|
||||
* data types.
|
||||
*/
|
||||
protected void initialiseJodaTypes(JsonConfig.DateTime mode) {
|
||||
protected void initialiseJodaTypes(JsonConfig.DateTime mode, ServerConfig config) {
|
||||
|
||||
// detect if Joda classes are in the classpath
|
||||
if (ClassUtil.isPresent("org.joda.time.LocalDateTime", this.getClass())) {
|
||||
if (config.getClassLoadConfig().isJodaTimePresent()) {
|
||||
// Joda classes are in the classpath so register the types
|
||||
logger.debug("Registering Joda data types");
|
||||
typeMap.put(LocalDateTime.class, new ScalarTypeJodaLocalDateTime(mode));
|
||||
|
||||
@@ -75,7 +75,7 @@ public class ClassPathSearch implements ClassPathSearchService {
|
||||
if (classPathReaderCN != null) {
|
||||
// use a user defined classPathReader
|
||||
logger.info("Using [" + classPathReaderCN + "] to read the searchable class path");
|
||||
classPathReader = (ClassPathReader) ClassUtil.newInstance(classPathReaderCN, this.getClass());
|
||||
classPathReader = (ClassPathReader) ClassUtil.newInstance(classPathReaderCN);
|
||||
}
|
||||
|
||||
Object[] rawClassPaths = classPathReader.readPath(classLoader);
|
||||
|
||||
Reference in New Issue
Block a user