| /* |
| * 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.abstractstore; |
| |
| import java.security.AccessController; |
| import java.util.Map; |
| |
| import org.apache.openjpa.conf.OpenJPAConfiguration; |
| import org.apache.openjpa.kernel.AbstractBrokerFactory; |
| import org.apache.openjpa.kernel.Bootstrap; |
| import org.apache.openjpa.kernel.BrokerFactory; |
| import org.apache.openjpa.kernel.StoreManager; |
| import org.apache.openjpa.lib.conf.ConfigurationProvider; |
| import org.apache.openjpa.lib.conf.Configurations; |
| 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.UserException; |
| |
| /** |
| * {@link BrokerFactory} implementation for use with the |
| * {@link AbstractStoreManager}. This provides integration into the |
| * {@link Bootstrap#getBrokerFactory()} bootstrapping mechanism, to facilitate |
| * the process of creating a subclass of {@link AbstractStoreManager}. New |
| * store manager implementations need not extend this class. Instead, set the |
| * <code>openjpa.BrokerFactory</code> configuration property to |
| * <code>abstractstore</code>, |
| * and set the <code>openjpa.abstractstore.AbstractStoreManager</code> |
| * configuration property to the full class name of your implementation. |
| * Additionally, you can optionally create your own |
| * <code>BrokerFactory</code> implementation. However, we recommend that you |
| * use the <code>AbstractStoreBrokerFactory</code>, as it deals with pooling |
| * and bootstrapping from a {@link Map} object (the strategy used by |
| * {@link Bootstrap} to create a factory in a vendor-neutral manner). |
| */ |
| public class AbstractStoreBrokerFactory |
| extends AbstractBrokerFactory { |
| |
| |
| private static final long serialVersionUID = 1L; |
| |
| /** |
| * The property name under which to name the concrete store manager |
| * class for this runtime. |
| */ |
| private static final String PROP_ABSTRACT_STORE = |
| "abstractstore.AbstractStoreManager"; |
| |
| private static final Localizer s_loc = Localizer.forPackage |
| (AbstractStoreBrokerFactory.class); |
| |
| private String _storeCls = null; |
| private String _storeProps = null; |
| private String _platform = null; |
| |
| /** |
| * Factory method for obtaining a possibly-pooled {@link BrokerFactory} |
| * from properties. Invoked from {@link Bootstrap#getBrokerFactory()}. |
| */ |
| public static AbstractStoreBrokerFactory getInstance( |
| ConfigurationProvider cp) { |
| Object key = toPoolKey(cp.getProperties()); |
| AbstractStoreBrokerFactory factory = (AbstractStoreBrokerFactory) |
| getPooledFactoryForKey(key); |
| if (factory != null) |
| return factory; |
| |
| factory = newInstance(cp); |
| AbstractBrokerFactory.pool(key, factory); |
| return factory; |
| } |
| |
| /** |
| * Factory method for constructing a {@link BrokerFactory} |
| * from properties. Invoked from {@link Bootstrap#newBrokerFactory()}. |
| */ |
| public static AbstractStoreBrokerFactory newInstance |
| (ConfigurationProvider cp) { |
| // use a tmp store manager to get metadata about the capabilities of |
| // this runtime |
| Map map = cp.getProperties(); |
| String storePlugin = (String) map.get(ProductDerivations |
| .getConfigurationKey(PROP_ABSTRACT_STORE, map)); |
| String storeCls = Configurations.getClassName(storePlugin); |
| String storeProps = Configurations.getProperties(storePlugin); |
| AbstractStoreManager store = createStoreManager(storeCls, |
| storeProps); |
| |
| // populate configuration |
| OpenJPAConfiguration conf = store.newConfiguration(); |
| cp.setInto(conf); |
| conf.supportedOptions().removeAll(store.getUnsupportedOptions()); |
| |
| // create and pool a new factory |
| return new AbstractStoreBrokerFactory(conf, storeCls, storeProps, |
| store.getPlatform()); |
| } |
| |
| /** |
| * Construct the factory with the given settings. |
| */ |
| protected AbstractStoreBrokerFactory(OpenJPAConfiguration conf, |
| String storeCls, String storeProps, String platform) { |
| super(conf); |
| _storeCls = storeCls; |
| _storeProps = storeProps; |
| _platform = platform; |
| } |
| |
| @Override |
| public Map<String,Object> getProperties() { |
| Map<String,Object> props = super.getProperties(); |
| props.put("Platform", _platform); |
| return props; |
| } |
| |
| @Override |
| protected StoreManager newStoreManager() { |
| return createStoreManager(_storeCls, _storeProps); |
| } |
| |
| private static AbstractStoreManager createStoreManager(String cls, |
| String props) { |
| AbstractStoreManager store = |
| (AbstractStoreManager) Configurations.newInstance(cls, |
| AccessController.doPrivileged(J2DoPrivHelper |
| .getClassLoaderAction(AbstractStoreManager.class))); |
| Configurations.configureInstance(store, null, props, |
| PROP_ABSTRACT_STORE); |
| if (store == null) |
| throw new UserException(s_loc.get("no-store-manager", |
| PROP_ABSTRACT_STORE)).setFatal(true); |
| |
| return store; |
| } |
| } |