001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.abstractstore;
020:
021: import java.security.AccessController;
022: import java.util.Map;
023: import java.util.Properties;
024:
025: import org.apache.openjpa.conf.OpenJPAConfiguration;
026: import org.apache.openjpa.kernel.AbstractBrokerFactory;
027: import org.apache.openjpa.kernel.Bootstrap;
028: import org.apache.openjpa.kernel.BrokerFactory;
029: import org.apache.openjpa.kernel.StoreManager;
030: import org.apache.openjpa.lib.conf.ConfigurationProvider;
031: import org.apache.openjpa.lib.conf.Configurations;
032: import org.apache.openjpa.lib.conf.ProductDerivations;
033: import org.apache.openjpa.lib.util.J2DoPrivHelper;
034: import org.apache.openjpa.lib.util.Localizer;
035: import org.apache.openjpa.util.UserException;
036:
037: /**
038: * {@link BrokerFactory} implementation for use with the
039: * {@link AbstractStoreManager}. This provides integration into the
040: * {@link Bootstrap#getBrokerFactory()} bootstrapping mechanism, to facilitate
041: * the process of creating a subclass of {@link AbstractStoreManager}. New
042: * store manager implementations need not extend this class. Instead, set the
043: * <code>org.apache.openjpa.BrokerFactory</code> configuration property to
044: * <code>abstractstore</code>,
045: * and set the <code>org.apache.openjpa.abstractstore.AbstractStoreManager</code>
046: * configuration property to the full class name of your implementation.
047: * Additionally, you can optionally create your own
048: * <code>BrokerFactory</code> implementation. However, we recommend that you
049: * use the <code>AbstractStoreBrokerFactory</code>, as it deals with pooling
050: * and bootstrapping from a {@link Map} object (the strategy used by
051: * {@link Bootstrap} to create a factory in a vendor-neutral manner).
052: */
053: public class AbstractStoreBrokerFactory extends AbstractBrokerFactory {
054:
055: /**
056: * The property name under which to name the concrete store manager
057: * class for this runtime.
058: */
059: private static final String PROP_ABSTRACT_STORE = "abstractstore.AbstractStoreManager";
060:
061: private static final Localizer s_loc = Localizer
062: .forPackage(AbstractStoreBrokerFactory.class);
063:
064: private String _storeCls = null;
065: private String _storeProps = null;
066: private String _platform = null;
067:
068: /**
069: * Factory method for obtaining a possibly-pooled {@link BrokerFactory}
070: * from properties. Invoked from {@link Bootstrap#getBrokerFactory()}.
071: */
072: public static AbstractStoreBrokerFactory getInstance(
073: ConfigurationProvider cp) {
074: Object key = toPoolKey(cp.getProperties());
075: AbstractStoreBrokerFactory factory = (AbstractStoreBrokerFactory) getPooledFactoryForKey(key);
076: if (factory != null)
077: return factory;
078:
079: factory = newInstance(cp);
080: factory.pool(key, factory);
081: return factory;
082: }
083:
084: /**
085: * Factory method for constructing a {@link BrokerFactory}
086: * from properties. Invoked from {@link Bootstrap#newBrokerFactory()}.
087: */
088: public static AbstractStoreBrokerFactory newInstance(
089: ConfigurationProvider cp) {
090: // use a tmp store manager to get metadata about the capabilities of
091: // this runtime
092: Map map = cp.getProperties();
093: String storePlugin = (String) map.get(ProductDerivations
094: .getConfigurationKey(PROP_ABSTRACT_STORE, map));
095: String storeCls = Configurations.getClassName(storePlugin);
096: String storeProps = Configurations.getProperties(storePlugin);
097: AbstractStoreManager store = createStoreManager(storeCls,
098: storeProps);
099:
100: // populate configuration
101: OpenJPAConfiguration conf = store.newConfiguration();
102: cp.setInto(conf);
103: conf.supportedOptions()
104: .removeAll(store.getUnsupportedOptions());
105:
106: // create and pool a new factory
107: return new AbstractStoreBrokerFactory(conf, storeCls,
108: storeProps, store.getPlatform());
109: }
110:
111: /**
112: * Construct the factory with the given settings.
113: */
114: protected AbstractStoreBrokerFactory(OpenJPAConfiguration conf,
115: String storeCls, String storeProps, String platform) {
116: super (conf);
117: _storeCls = storeCls;
118: _storeProps = storeProps;
119: _platform = platform;
120: }
121:
122: public Properties getProperties() {
123: Properties props = super .getProperties();
124: props.setProperty("Platform", _platform);
125: return props;
126: }
127:
128: protected StoreManager newStoreManager() {
129: return createStoreManager(_storeCls, _storeProps);
130: }
131:
132: private static AbstractStoreManager createStoreManager(String cls,
133: String props) {
134: AbstractStoreManager store = (AbstractStoreManager) Configurations
135: .newInstance(
136: cls,
137: (ClassLoader) AccessController
138: .doPrivileged(J2DoPrivHelper
139: .getClassLoaderAction(AbstractStoreManager.class)));
140: Configurations.configureInstance(store, null, props,
141: PROP_ABSTRACT_STORE);
142: if (store == null)
143: throw new UserException(s_loc.get("no-store-manager",
144: PROP_ABSTRACT_STORE)).setFatal(true);
145:
146: return store;
147: }
148: }
|