| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.openjpa.kernel; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.security.AccessController; |
| |
| import org.apache.openjpa.conf.BrokerFactoryValue; |
| import org.apache.openjpa.lib.conf.ConfigurationProvider; |
| import org.apache.openjpa.lib.conf.MapConfigurationProvider; |
| import org.apache.openjpa.lib.conf.ProductDerivations; |
| import org.apache.openjpa.lib.util.J2DoPrivHelper; |
| import org.apache.openjpa.lib.util.Localizer; |
| import org.apache.openjpa.util.InternalException; |
| import org.apache.openjpa.util.OpenJPAException; |
| import org.apache.openjpa.util.UserException; |
| |
| /** |
| * Helper methods for acquiring {@link BrokerFactory} objects |
| * |
| * @since 0.4.0.0 |
| */ |
| public class Bootstrap { |
| |
| private static final Class<?>[] CONFIGURATION_ARG = |
| new Class<?>[]{ ConfigurationProvider.class }; |
| |
| private static final Class<?>[] CONFIGURATION_CLASSLOADER_ARGS = |
| new Class<?>[] { ConfigurationProvider.class, ClassLoader.class }; |
| |
| private static Localizer s_loc = Localizer.forPackage(Bootstrap.class); |
| |
| /** |
| * Return a new factory for the default configuration. |
| */ |
| public static BrokerFactory newBrokerFactory() { |
| return Bootstrap.newBrokerFactory(null, null); |
| } |
| |
| /** |
| * Return a new factory for the given configuration. The classloader |
| * will be used to load the factory class. If no classloader is given, |
| * the thread's context classloader is used. |
| */ |
| public static BrokerFactory newBrokerFactory(ConfigurationProvider conf, |
| ClassLoader loader) { |
| try { |
| BrokerFactory factory = |
| invokeFactory(conf, loader, "newInstance", CONFIGURATION_ARG, new Object[] { conf }); |
| factory.postCreationCallback(); |
| return factory; |
| } catch (InvocationTargetException ite) { |
| Throwable cause = ite.getTargetException(); |
| if (cause instanceof OpenJPAException) |
| throw (OpenJPAException) cause; |
| throw new InternalException(s_loc.get("new-brokerfactory-excep", |
| getFactoryClassName(conf, loader)), cause); |
| } catch (Exception e) { |
| throw new UserException(s_loc.get("bad-new-brokerfactory", |
| getFactoryClassName(conf, loader)), e).setFatal(true); |
| } |
| } |
| |
| /** |
| * Return a pooled factory for the default configuration. |
| */ |
| public static BrokerFactory getBrokerFactory() { |
| return Bootstrap.getBrokerFactory(null, null); |
| } |
| |
| /** |
| * Return a pooled factory for the given configuration. The classloader |
| * will be used to load the factory class. If no classloader is given, |
| * the thread's context classloader is used. |
| */ |
| public static BrokerFactory getBrokerFactory(ConfigurationProvider conf, |
| ClassLoader loader) { |
| try { |
| return invokeFactory(conf, loader, "getInstance", CONFIGURATION_CLASSLOADER_ARGS, new Object[] { conf, |
| loader }); |
| } catch (InvocationTargetException ite) { |
| Throwable cause = ite.getTargetException(); |
| if (cause instanceof OpenJPAException) |
| throw (OpenJPAException) cause; |
| throw new InternalException(s_loc.get("brokerfactory-excep", |
| getFactoryClassName(conf, loader)), cause); |
| } catch (Exception e) { |
| throw new UserException(s_loc.get("bad-brokerfactory", |
| getFactoryClassName(conf, loader)), e).setFatal(true); |
| } |
| } |
| |
| private static BrokerFactory invokeFactory(ConfigurationProvider conf, |
| ClassLoader loader, String methodName, Class<?>[] argTypes, Object[] args) |
| throws InvocationTargetException, NoSuchMethodException, |
| IllegalAccessException { |
| if (conf == null) |
| conf = new MapConfigurationProvider(); |
| ProductDerivations.beforeConfigurationConstruct(conf); |
| |
| Class cls = getFactoryClass(conf, loader); |
| Method meth; |
| try { |
| meth = cls.getMethod(methodName, argTypes); |
| } catch (NoSuchMethodException nsme) { |
| // handle cases where there is a mismatch between loaders by falling |
| // back to the configuration's class loader for broker resolution |
| cls = getFactoryClass(conf, |
| AccessController.doPrivileged( |
| J2DoPrivHelper.getClassLoaderAction(conf.getClass()))); |
| meth = cls.getMethod(methodName, argTypes); |
| } |
| |
| return (BrokerFactory) meth.invoke(null, args); |
| } |
| |
| private static String getFactoryClassName(ConfigurationProvider conf, |
| ClassLoader loader) { |
| try { |
| return getFactoryClass(conf, loader).getName(); |
| } catch (Exception e) { |
| return "<" + e.toString() + ">"; |
| } |
| } |
| |
| /** |
| * Instantiate the factory class designated in properties. |
| */ |
| private static Class getFactoryClass(ConfigurationProvider conf, |
| ClassLoader loader) { |
| if (loader == null) |
| loader = AccessController.doPrivileged( |
| J2DoPrivHelper.getContextClassLoaderAction()); |
| |
| Object cls = BrokerFactoryValue.get(conf); |
| if (cls instanceof Class) |
| return (Class) cls; |
| |
| BrokerFactoryValue value = new BrokerFactoryValue(); |
| value.setString((String) cls); |
| String clsName = value.getClassName(); |
| if (clsName == null) |
| throw new UserException(s_loc.get("no-brokerfactory", |
| conf.getProperties())).setFatal(true); |
| |
| try { |
| return Class.forName(clsName, true, loader); |
| } catch (Exception e) { |
| throw new UserException(s_loc.get("bad-brokerfactory-class", |
| clsName), e).setFatal(true); |
| } |
| } |
| } |