Home » apache-openjpa-1.1.0-source » org.apache.openjpa » persistence » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
   10    * http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied.  See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.    
   18    */
   19   package org.apache.openjpa.persistence;
   20   
   21   import java.lang.instrument.ClassFileTransformer;
   22   import java.lang.instrument.IllegalClassFormatException;
   23   import java.security.ProtectionDomain;
   24   import java.util.Map;
   25   import javax.persistence.EntityManager;
   26   import javax.persistence.spi.ClassTransformer;
   27   import javax.persistence.spi.PersistenceProvider;
   28   import javax.persistence.spi.PersistenceUnitInfo;
   29   
   30   import org.apache.openjpa.conf.BrokerValue;
   31   import org.apache.openjpa.conf.OpenJPAConfiguration;
   32   import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
   33   import org.apache.openjpa.enhance.PCClassFileTransformer;
   34   import org.apache.openjpa.kernel.Bootstrap;
   35   import org.apache.openjpa.kernel.BrokerFactory;
   36   import org.apache.openjpa.lib.conf.Configuration;
   37   import org.apache.openjpa.lib.conf.ConfigurationProvider;
   38   import org.apache.openjpa.lib.conf.Configurations;
   39   import org.apache.openjpa.lib.log.Log;
   40   import org.apache.openjpa.lib.util.Localizer;
   41   import org.apache.openjpa.meta.MetaDataModes;
   42   import org.apache.openjpa.meta.MetaDataRepository;
   43   import org.apache.openjpa.util.ClassResolver;
   44   
   45   
   46   /**
   47    * Bootstrapping class that allows the creation of a stand-alone
   48    * {@link EntityManager}.
   49    *
   50    * @see javax.persistence.Persistence#createEntityManagerFactory(String,Map)
   51    * @published
   52    */
   53   public class PersistenceProviderImpl
   54       implements PersistenceProvider {
   55   
   56       static final String CLASS_TRANSFORMER_OPTIONS = "ClassTransformerOptions";
   57       private static final String EMF_POOL = "EntityManagerFactoryPool";
   58   
   59       private static final Localizer _loc = Localizer.forPackage(
   60           PersistenceProviderImpl.class);
   61   
   62       /**
   63        * Loads the entity manager specified by <code>name</code>, applying
   64        * the properties in <code>m</code> as overrides to the properties defined
   65        * in the XML configuration file for <code>name</code>. If <code>name</code>
   66        * is <code>null</code>, this method loads the XML in the resource
   67        * identified by <code>resource</code>, and uses the first resource found
   68        * when doing this lookup, regardless of the name specified in the XML
   69        * resource or the name of the jar that the resource is contained in.
   70        * This does no pooling of EntityManagersFactories.
   71        */
   72       public OpenJPAEntityManagerFactory createEntityManagerFactory(String name,
   73           String resource, Map m) {
   74           PersistenceProductDerivation pd = new PersistenceProductDerivation();
   75           try {
   76               Object poolValue = Configurations.removeProperty(EMF_POOL, m);
   77               ConfigurationProvider cp = pd.load(resource, name, m);
   78               if (cp == null)
   79                   return null;
   80   
   81               BrokerFactory factory = getBrokerFactory(cp, poolValue, null);
   82               return JPAFacadeHelper.toEntityManagerFactory(factory);
   83           } catch (Exception e) {
   84               throw PersistenceExceptions.toPersistenceException(e);
   85           }
   86       }
   87   
   88       private BrokerFactory getBrokerFactory(ConfigurationProvider cp,
   89           Object poolValue, ClassLoader loader) {
   90           // handle "true" and "false"
   91           if (poolValue instanceof String
   92               && ("true".equalsIgnoreCase((String) poolValue)
   93                   || "false".equalsIgnoreCase((String) poolValue)))
   94               poolValue = Boolean.valueOf((String) poolValue);
   95   
   96           if (poolValue != null && !(poolValue instanceof Boolean)) {
   97               // we only support boolean settings for this option currently.
   98               throw new IllegalArgumentException(poolValue.toString());
   99           }
  100           
  101           if (poolValue == null || !((Boolean) poolValue).booleanValue())
  102               return Bootstrap.newBrokerFactory(cp, loader);
  103           else
  104               return Bootstrap.getBrokerFactory(cp, loader);
  105       }
  106   
  107       public OpenJPAEntityManagerFactory createEntityManagerFactory(String name,
  108           Map m) {
  109           return createEntityManagerFactory(name, null, m);
  110       }
  111   
  112       public OpenJPAEntityManagerFactory createContainerEntityManagerFactory(
  113           PersistenceUnitInfo pui, Map m) {
  114           PersistenceProductDerivation pd = new PersistenceProductDerivation();
  115           try {
  116               Object poolValue = Configurations.removeProperty(EMF_POOL, m);
  117               ConfigurationProvider cp = pd.load(pui, m);
  118               if (cp == null)
  119                   return null;
  120   
  121               // add enhancer
  122               Exception transformerException = null;
  123               String ctOpts = (String) Configurations.getProperty
  124                   (CLASS_TRANSFORMER_OPTIONS, pui.getProperties());
  125               try {
  126                   pui.addTransformer(new ClassTransformerImpl(cp, ctOpts,
  127                       pui.getNewTempClassLoader(), newConfigurationImpl()));
  128               } catch (Exception e) {
  129                   // fail gracefully
  130                   transformerException = e;
  131               }
  132   
  133               // if the BrokerImpl hasn't been specified, switch to the
  134               // non-finalizing one, since anything claiming to be a container
  135               // should be doing proper resource management.
  136               if (!Configurations.containsProperty(BrokerValue.KEY,
  137                   cp.getProperties())) {
  138                   cp.addProperty("openjpa." + BrokerValue.KEY, 
  139                       getDefaultBrokerAlias());
  140               }
  141   
  142               BrokerFactory factory = getBrokerFactory(cp, poolValue,
  143                   pui.getClassLoader());
  144               if (transformerException != null) {
  145                   Log log = factory.getConfiguration().getLog(
  146                       OpenJPAConfiguration.LOG_RUNTIME);
  147                   if (log.isTraceEnabled()) {
  148                       log.warn(
  149                           _loc.get("transformer-registration-error-ex", pui),
  150                           transformerException);
  151                   } else {
  152                       log.warn(
  153                           _loc.get("transformer-registration-error", pui));
  154                   }
  155               }
  156               return JPAFacadeHelper.toEntityManagerFactory(factory);
  157           } catch (Exception e) {
  158               throw PersistenceExceptions.toPersistenceException(e);
  159           }
  160       }
  161   
  162       /*
  163        * Returns a default Broker alias to be used when no openjpa.BrokerImpl
  164        *  is specified. This method allows PersistenceProvider subclass to
  165        *  override the default broker alias.
  166        */
  167       protected String getDefaultBrokerAlias() {
  168           return BrokerValue.NON_FINALIZING_ALIAS;
  169       }
  170       
  171       /*
  172        * Return a new instance of Configuration subclass used by entity
  173        * enhancement in ClassTransformerImpl. If OpenJPAConfigurationImpl
  174        * instance is used, configuration options declared in configuration
  175        * sub-class will not be recognized and a warning is posted in the log.
  176        */
  177       protected OpenJPAConfiguration newConfigurationImpl() {
  178           return new OpenJPAConfigurationImpl();
  179       }
  180       
  181       /**
  182        * Java EE 5 class transformer.
  183        */
  184       private static class ClassTransformerImpl
  185           implements ClassTransformer {
  186   
  187           private final ClassFileTransformer _trans;
  188   
  189           private ClassTransformerImpl(ConfigurationProvider cp, String props, 
  190               final ClassLoader tmpLoader, OpenJPAConfiguration conf) {
  191               cp.setInto(conf);
  192               // use the tmp loader for everything
  193               conf.setClassResolver(new ClassResolver() {
  194                   public ClassLoader getClassLoader(Class context, 
  195                       ClassLoader env) {
  196                       return tmpLoader;
  197                   }
  198               });
  199               conf.setReadOnly(Configuration.INIT_STATE_FREEZING);
  200   
  201               MetaDataRepository repos = conf.getMetaDataRepositoryInstance();
  202               repos.setResolve(MetaDataModes.MODE_MAPPING, false);
  203               _trans = new PCClassFileTransformer(repos,
  204                   Configurations.parseProperties(props), tmpLoader);
  205           }
  206   
  207           public byte[] transform(ClassLoader cl, String name,
  208               Class<?> previousVersion, ProtectionDomain pd, byte[] bytes)
  209               throws IllegalClassFormatException {
  210               return _trans.transform(cl, name, previousVersion, pd, bytes);
  211           }
  212   	}
  213   }

Save This Page
Home » apache-openjpa-1.1.0-source » org.apache.openjpa » persistence » [javadoc | source]