use of org.apache.xbean.recipe.ObjectRecipe in project tomee by apache.
the class DataSourceFactory method create.
public static CommonDataSource create(final String name, final boolean configuredManaged, final Class impl, final String definition, final Duration maxWaitTime, final Duration timeBetweenEvictionRuns, final Duration minEvictableIdleTime, final boolean useAlternativeDriver) throws IllegalAccessException, InstantiationException, IOException {
final Properties properties = asProperties(definition);
final Set<String> originalKeys = properties.stringPropertyNames();
final String handler = SystemInstance.get().getOptions().get(GLOBAL_HANDLER_PROPERTY, (String) properties.remove(HANDLER_PROPERTY));
boolean flushable = SystemInstance.get().getOptions().get(GLOBAL_FLUSH_PROPERTY, "true".equalsIgnoreCase((String) properties.remove(FLUSHABLE_PROPERTY)));
final String forceDifferent = SystemInstance.get().getOptions().get(XA_GLOBAL_FORCE_DIFFERENT, String.class.cast(properties.remove(XA_FORCE_DIFFERENT)));
convert(properties, maxWaitTime, "maxWaitTime", "maxWait");
convert(properties, timeBetweenEvictionRuns, "timeBetweenEvictionRuns", "timeBetweenEvictionRunsMillis");
convert(properties, minEvictableIdleTime, "minEvictableIdleTime", "minEvictableIdleTimeMillis");
// these can be added and are managed by OpenEJB and not the DataSource itself
properties.remove("Definition");
properties.remove("JtaManaged");
properties.remove("ServiceId");
boolean managed = configuredManaged;
if (properties.containsKey("transactional")) {
managed = Boolean.parseBoolean((String) properties.remove("transactional")) || managed;
}
normalizeJdbcUrl(properties);
final String jdbcUrl = properties.getProperty("JdbcUrl");
final AlternativeDriver driver;
if (Driver.class.isAssignableFrom(impl) && jdbcUrl != null && useAlternativeDriver) {
try {
driver = new AlternativeDriver((Driver) impl.newInstance(), jdbcUrl);
driver.register();
} catch (final SQLException e) {
throw new IllegalStateException(e);
}
} else {
driver = null;
}
final boolean logSql = SystemInstance.get().getOptions().get(GLOBAL_LOG_SQL_PROPERTY, "true".equalsIgnoreCase((String) properties.remove(LOG_SQL_PROPERTY)));
final String logPackages = SystemInstance.get().getProperty(GLOBAL_LOG_SQL_PACKAGE_PROPERTY, (String) properties.remove(LOG_SQL_PACKAGE_PROPERTY));
final DataSourceCreator creator = creator(properties.remove(DATA_SOURCE_CREATOR_PROP), logSql);
final String resetOnError = (String) properties.remove(RESET_PROPERTY);
// before setProperties()
final String resetMethods = (String) properties.remove(RESET_METHODS_PROPERTY);
boolean useContainerLoader = "true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.resources.use-container-loader", "true")) && impl.getClassLoader() == DataSourceFactory.class.getClassLoader();
final ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
if (useContainerLoader) {
final ClassLoader containerLoader = DataSourceFactory.class.getClassLoader();
Thread.currentThread().setContextClassLoader(containerLoader);
try {
useContainerLoader = basicChecksThatDataSourceCanBeCreatedFromContainerLoader(properties, containerLoader);
} finally {
Thread.currentThread().setContextClassLoader(oldLoader);
}
if (useContainerLoader) {
Thread.currentThread().setContextClassLoader(containerLoader);
} else {
LOGGER.info("Can't use container loader to create datasource " + name + " so using application one");
}
}
try {
CommonDataSource ds;
if (createDataSourceFromClass(impl)) {
// opposed to "by driver"
trimNotSupportedDataSourceProperties(properties);
final ObjectRecipe recipe = new ObjectRecipe(impl);
recipe.allow(Option.CASE_INSENSITIVE_PROPERTIES);
recipe.allow(Option.IGNORE_MISSING_PROPERTIES);
recipe.allow(Option.NAMED_PARAMETERS);
recipe.allow(Option.PRIVATE_PROPERTIES);
recipe.setAllProperties(properties);
if (!properties.containsKey("url") && properties.containsKey("JdbcUrl")) {
// depend on the datasource class so add all well known keys
recipe.setProperty("url", properties.getProperty("JdbcUrl"));
}
CommonDataSource dataSource = (CommonDataSource) recipe.create();
final boolean isDs = DataSource.class.isInstance(dataSource);
if (!isDs && XADataSource.class.isInstance(dataSource) && forceDifferent != null) {
try {
dataSource = CommonDataSource.class.cast(Thread.currentThread().getContextClassLoader().loadClass("true".equals(forceDifferent) ? "org.apache.openejb.resource.jdbc.xa.IsDifferentXaDataSourceWrapper" : forceDifferent).getConstructor(XADataSource.class).newInstance(dataSource));
} catch (InvocationTargetException | ClassNotFoundException | NoSuchMethodException e) {
throw new IllegalArgumentException(e);
}
}
if (managed) {
if (isDs && usePool(properties)) {
ds = creator.poolManaged(name, DataSource.class.cast(dataSource), properties);
} else {
ds = creator.managed(name, dataSource);
}
} else {
if (isDs && usePool(properties)) {
ds = creator.pool(name, DataSource.class.cast(dataSource), properties);
} else {
ds = dataSource;
}
}
} else {
// by driver
if (managed) {
final XAResourceWrapper xaResourceWrapper = SystemInstance.get().getComponent(XAResourceWrapper.class);
if (xaResourceWrapper != null) {
ds = creator.poolManagedWithRecovery(name, xaResourceWrapper, impl.getName(), properties);
} else {
ds = creator.poolManaged(name, impl.getName(), properties);
}
} else {
ds = creator.pool(name, impl.getName(), properties);
}
}
// ds and creator are associated here, not after the proxying of the next if if active
setCreatedWith(creator, ds);
if (driver != null) {
driverByDataSource.put(ds, driver);
}
final boolean doResetOnError = resetOnError != null && !"false".equals(resetOnError);
if (doResetOnError || logSql || flushable) {
// will get proxied
ObjectRecipe objectRecipe = null;
ResettableDataSourceHandler existingResettableHandler = null;
FlushableDataSourceHandler flushableDataSourceHandler = null;
if (ExecutionContext.isContextSet()) {
final ExecutionContext context = ExecutionContext.getContext();
final List<Recipe> stack = context.getStack();
if (stack.size() > 0) {
objectRecipe = ObjectRecipe.class.cast(stack.get(0));
existingResettableHandler = ResettableDataSourceHandler.class.cast(objectRecipe.getProperty("resettableHandler"));
flushableDataSourceHandler = FlushableDataSourceHandler.class.cast(objectRecipe.getProperty("flushableHandler"));
final Map<String, Object> props = objectRecipe.getProperties();
for (final String key : originalKeys) {
props.remove(key);
}
// meta properties, not needed here so gain few cycles removing them
props.remove("properties");
props.remove("Definition");
props.remove("ServiceId");
props.remove("resettableHandler");
props.remove("flushableHandler");
// we create a proxy so we cant get txmgr etc in another manner or we cant extend (= break) this method
new ObjectRecipe(ds.getClass()) {
{
allow(Option.CASE_INSENSITIVE_PROPERTIES);
allow(Option.IGNORE_MISSING_PROPERTIES);
allow(Option.NAMED_PARAMETERS);
allow(Option.PRIVATE_PROPERTIES);
setAllProperties(props);
}
}.setProperties(ds);
}
}
ds = wrapIfNeeded(handler, ds);
if (logSql) {
ds = makeItLogging(ds, logPackages);
}
final ResettableDataSourceHandler resettableDataSourceHandler;
if (doResetOnError) {
// needs to be done after flushable
// ensure we reuse the same handle instance otherwise we loose state
resettableDataSourceHandler = existingResettableHandler != null ? existingResettableHandler : new ResettableDataSourceHandler(ds, resetOnError, resetMethods);
} else {
resettableDataSourceHandler = null;
}
if (flushable || doResetOnError) {
if (flushableDataSourceHandler == null) {
final FlushableDataSourceHandler.FlushConfig flushConfig;
// don't let it wrap the delegate again
properties.remove("flushable");
final Map<String, Object> recipeProps = new HashMap<>(objectRecipe == null ? new HashMap<String, Object>() : objectRecipe.getProperties());
recipeProps.remove("properties");
recipeProps.put("OpenEJBResourceClasspath", String.valueOf(useAlternativeDriver));
flushConfig = new FlushableDataSourceHandler.FlushConfig(recipeProps);
flushableDataSourceHandler = new FlushableDataSourceHandler(ds, flushConfig, resettableDataSourceHandler);
} else {
flushableDataSourceHandler.updateDataSource(ds);
}
ds = makeSerializableFlushableDataSourceProxy(ds, flushableDataSourceHandler);
}
if (doResetOnError) {
// needs to be done after flushable
// ensure we reuse the same handle instance otherwise we loose state
resettableDataSourceHandler.updateDelegate(ds);
ds = makeSerializableFlushableDataSourceProxy(ds, resettableDataSourceHandler);
}
} else {
ds = wrapIfNeeded(handler, ds);
}
return ds;
} finally {
if (useContainerLoader) {
Thread.currentThread().setContextClassLoader(oldLoader);
}
}
}
use of org.apache.xbean.recipe.ObjectRecipe in project tomee by apache.
the class DataSourceFactory method forgetRecipe.
// TODO: should we get a get and a clear method instead of a single one?
@SuppressWarnings("SuspiciousMethodCalls")
public static ObjectRecipe forgetRecipe(final Object rawObject, final ObjectRecipe defaultValue) {
final Object object = realInstance(rawObject);
final DataSourceCreator creator = creatorByDataSource.get(object);
ObjectRecipe recipe = null;
if (creator != null) {
recipe = creator.clearRecipe(object);
}
if (recipe == null) {
return defaultValue;
}
return recipe;
}
use of org.apache.xbean.recipe.ObjectRecipe in project tomee by apache.
the class StatefulContainerFactory method buildCache.
private void buildCache() throws Exception {
if (properties == null) {
throw new IllegalArgumentException("No cache defined for StatefulContainer " + id);
}
// get the cache property
Object cache = getProperty("Cache");
if (cache == null) {
throw new IllegalArgumentException("No cache defined for StatefulContainer " + id);
}
// if property contains a live cache instance, just use it
if (cache instanceof Cache) {
this.cache = (Cache<Object, Instance>) cache;
return;
}
// build the object recipe
final ObjectRecipe serviceRecipe = new ObjectRecipe((String) cache);
serviceRecipe.allow(Option.CASE_INSENSITIVE_PROPERTIES);
serviceRecipe.allow(Option.IGNORE_MISSING_PROPERTIES);
serviceRecipe.allow(Option.NAMED_PARAMETERS);
serviceRecipe.setAllProperties(properties);
// invoke recipe
/* the cache should be created with container loader to avoid memory leaks
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) getClass().getClassLoader();
*/
ClassLoader classLoader = StatefulContainerFactory.class.getClassLoader();
if (!((String) cache).startsWith("org.apache.tomee")) {
// user impl?
classLoader = Thread.currentThread().getContextClassLoader();
}
cache = serviceRecipe.create(classLoader);
// assign value
this.cache = (Cache<Object, Instance>) cache;
}
use of org.apache.xbean.recipe.ObjectRecipe in project tomee by apache.
the class PassthroughFactory method recipe.
public static ObjectRecipe recipe(final Object instance) {
final ObjectRecipe recipe = new ObjectRecipe(PassthroughFactory.Create.class);
recipe.setFactoryMethod("create");
final String param = "instance" + recipe.hashCode();
recipe.setConstructorArgNames(new String[] { param });
recipe.setProperty(param, instance);
return recipe;
}
use of org.apache.xbean.recipe.ObjectRecipe in project tomee by apache.
the class CliRunnable method run.
@Override
public void run() {
clean();
try {
final StreamManager streamManager = new StreamManager(out, err, lineSep);
final ConsoleReader reader = new ConsoleReader(sin, streamManager.getSout());
reader.addCompletor(new FileNameCompletor());
reader.addCompletor(new SimpleCompletor(COMMANDS.keySet().toArray(new String[COMMANDS.size()])));
// TODO : add completers
String line;
final StringBuilder builtWelcome = new StringBuilder("Apache OpenEJB ").append(OpenEjbVersion.get().getVersion()).append(" build: ").append(OpenEjbVersion.get().getDate()).append("-").append(OpenEjbVersion.get().getTime()).append(lineSep);
if (tomee) {
builtWelcome.append(OS_LINE_SEP).append(PROPERTIES.getProperty(WELCOME_TOMEE_KEY));
} else {
builtWelcome.append(OS_LINE_SEP).append(PROPERTIES.getProperty(WELCOME_OPENEJB_KEY));
}
builtWelcome.append(lineSep).append(PROPERTIES.getProperty(WELCOME_COMMON_KEY));
streamManager.writeOut(OpenEjbVersion.get().getUrl());
streamManager.writeOut(builtWelcome.toString().replace("$bind", bind).replace("$port", Integer.toString(port)).replace("$name", NAME).replace(OS_LINE_SEP, lineSep));
while ((line = reader.readLine(prompt())) != null) {
// do we need a command for it?
if (EXIT_COMMAND.equals(line)) {
break;
}
Class<?> cmdClass = null;
String key = null;
for (final Map.Entry<String, Class<?>> cmd : COMMANDS.entrySet()) {
if (line.startsWith(cmd.getKey())) {
cmdClass = cmd.getValue();
key = cmd.getKey();
break;
}
}
if (cmdClass != null) {
final ObjectRecipe recipe = new ObjectRecipe(cmdClass);
recipe.setProperty("streamManager", streamManager);
recipe.setProperty("command", line);
recipe.setProperty("scripter", scripter);
recipe.setProperty("commands", COMMANDS);
recipe.allow(Option.CASE_INSENSITIVE_PROPERTIES);
recipe.allow(Option.IGNORE_MISSING_PROPERTIES);
recipe.allow(Option.NAMED_PARAMETERS);
try {
final AbstractCommand cmdInstance = (AbstractCommand) recipe.create();
cmdInstance.execute(trunc(line, key));
} catch (Exception e) {
streamManager.writeErr(e);
}
} else {
streamManager.writeErr("sorry i don't understand '" + line + "'");
}
}
clean();
} catch (IOException e) {
clean();
throw new CliRuntimeException(e);
}
}
Aggregations