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.reflect.Constructor;
   22   import java.lang.reflect.InvocationTargetException;
   23   import java.lang.reflect.Method;
   24   import java.util.Collections;
   25   import java.util.HashMap;
   26   import java.util.LinkedList;
   27   import java.util.List;
   28   import java.util.Map;
   29   import java.util.Properties;
   30   import java.util.Set;
   31   import javax.persistence.EntityManagerFactory;
   32   
   33   import org.apache.openjpa.conf.OpenJPAConfiguration;
   34   import org.apache.openjpa.enhance.Reflection;
   35   import org.apache.openjpa.kernel.AutoDetach;
   36   import org.apache.openjpa.kernel.Broker;
   37   import org.apache.openjpa.kernel.BrokerFactory;
   38   import org.apache.openjpa.kernel.DelegatingBrokerFactory;
   39   import org.apache.openjpa.kernel.DelegatingFetchConfiguration;
   40   import org.apache.openjpa.kernel.FetchConfiguration;
   41   import org.apache.openjpa.lib.conf.Configurations;
   42   import org.apache.openjpa.lib.conf.ProductDerivations;
   43   import org.apache.openjpa.lib.conf.Value;
   44   import org.apache.openjpa.lib.util.Localizer;
   45   import org.apache.openjpa.lib.util.Closeable;
   46   import org.apache.openjpa.util.OpenJPAException;
   47   import serp.util.Strings;
   48   
   49   /**
   50    * Implementation of {@link EntityManagerFactory} that acts as a
   51    * facade to a {@link BrokerFactory}.
   52    *
   53    * @author Marc Prud'hommeaux
   54    * @nojavadoc
   55    */
   56   public class EntityManagerFactoryImpl
   57       implements OpenJPAEntityManagerFactory, OpenJPAEntityManagerFactorySPI,
   58       Closeable {
   59   
   60       private static final Localizer _loc = Localizer.forPackage
   61           (EntityManagerFactoryImpl.class);
   62   
   63       private DelegatingBrokerFactory _factory = null;
   64       private transient Constructor<FetchPlan> _plan = null;
   65       private transient StoreCache _cache = null;
   66       private transient QueryResultCache _queryCache = null;
   67   
   68       /**
   69        * Default constructor provided for auto-instantiation.
   70        */
   71       public EntityManagerFactoryImpl() {
   72       }
   73   
   74       /**
   75        * Supply delegate on construction.
   76        */
   77       public EntityManagerFactoryImpl(BrokerFactory factory) {
   78           setBrokerFactory(factory);
   79       }
   80   
   81       /**
   82        * Delegate.
   83        */
   84       public BrokerFactory getBrokerFactory() {
   85           return _factory.getDelegate();
   86       }
   87   
   88       /**
   89        * Delegate must be provided before use.
   90        */
   91       public void setBrokerFactory(BrokerFactory factory) {
   92           _factory = new DelegatingBrokerFactory(factory,
   93               PersistenceExceptions.TRANSLATOR);
   94       }
   95   
   96       public OpenJPAConfiguration getConfiguration() {
   97           return _factory.getConfiguration();
   98       }
   99   
  100       public Properties getProperties() {
  101           return _factory.getProperties();
  102       }
  103   
  104       public Object putUserObject(Object key, Object val) {
  105           return _factory.putUserObject(key, val);
  106       }
  107   
  108       public Object getUserObject(Object key) {
  109           return _factory.getUserObject(key);
  110       }
  111   
  112       public StoreCache getStoreCache() {
  113           _factory.lock();
  114           try {
  115               if (_cache == null) {
  116                   OpenJPAConfiguration conf = _factory.getConfiguration();
  117                   _cache = new StoreCacheImpl(this,
  118                       conf.getDataCacheManagerInstance().getSystemDataCache());
  119               }
  120               return _cache;
  121           } finally {
  122               _factory.unlock();
  123           }
  124       }
  125   
  126       public StoreCache getStoreCache(String cacheName) {
  127           return new StoreCacheImpl(this, _factory.getConfiguration().
  128               getDataCacheManagerInstance().getDataCache(cacheName, true));
  129       }
  130   
  131       public QueryResultCache getQueryResultCache() {
  132           _factory.lock();
  133           try {
  134               if (_queryCache == null)
  135                   _queryCache = new QueryResultCacheImpl(_factory.
  136                       getConfiguration().getDataCacheManagerInstance().
  137                       getSystemQueryCache());
  138               return _queryCache;
  139           } finally {
  140               _factory.unlock();
  141           }
  142       }
  143   
  144       public OpenJPAEntityManagerSPI createEntityManager() {
  145           return createEntityManager(null);
  146       }
  147   
  148       public OpenJPAEntityManagerSPI createEntityManager(Map props) {
  149           if (props == null)
  150               props = Collections.EMPTY_MAP;
  151           else if (!props.isEmpty())
  152               props = new HashMap(props);
  153   
  154           OpenJPAConfiguration conf = getConfiguration();
  155           String user = (String) Configurations.removeProperty
  156               ("ConnectionUserName", props);
  157           if (user == null)
  158               user = conf.getConnectionUserName();
  159           String pass = (String) Configurations.removeProperty
  160               ("ConnectionPassword", props);
  161           if (pass == null)
  162               pass = conf.getConnectionPassword();
  163   
  164           String str = (String) Configurations.removeProperty
  165               ("TransactionMode", props);
  166           boolean managed;
  167           if (str == null)
  168               managed = conf.isTransactionModeManaged();
  169           else {
  170               Value val = conf.getValue("TransactionMode");
  171               managed = Boolean.parseBoolean(val.unalias(str));
  172           }
  173   
  174           Object obj = Configurations.removeProperty("ConnectionRetainMode", 
  175               props);
  176           int retainMode;
  177           if (obj instanceof Number)
  178               retainMode = ((Number) obj).intValue();
  179           else if (obj == null)
  180               retainMode = conf.getConnectionRetainModeConstant();
  181           else {
  182               Value val = conf.getValue("ConnectionRetainMode");
  183               try {
  184                   retainMode = Integer.parseInt(val.unalias((String) obj));
  185               } catch (Exception e) {
  186                   throw new ArgumentException(_loc.get("bad-em-prop",
  187                       "openjpa.ConnectionRetainMode", obj),
  188                       new Throwable[]{ e }, obj, true);
  189               }
  190           }
  191   
  192           Broker broker = _factory.newBroker(user, pass, managed, retainMode,
  193               false);
  194               
  195           // add autodetach for close and rollback conditions to the configuration
  196           broker.setAutoDetach(AutoDetach.DETACH_CLOSE, true);
  197           broker.setAutoDetach(AutoDetach.DETACH_ROLLBACK, true);
  198           
  199           broker.setDetachedNew(false);
  200           OpenJPAEntityManagerSPI em = newEntityManagerImpl(broker);
  201   
  202           // allow setting of other bean properties of EM
  203           String[] prefixes = ProductDerivations.getConfigurationPrefixes();
  204           List<RuntimeException> errs = null;
  205           Method setter;
  206           String prop, prefix;
  207           Object val;
  208           for (Map.Entry entry : (Set<Map.Entry>) props.entrySet()) {
  209               prop = (String) entry.getKey();
  210               prefix = null;
  211               for (int i = 0; i < prefixes.length; i++) {
  212                   prefix = prefixes[i] + ".";
  213                   if (prop.startsWith(prefix))
  214                       break;
  215                   prefix = null; 
  216               } 
  217               if (prefix == null)
  218                   continue; 
  219               prop = prop.substring(prefix.length());
  220               try {
  221                   setter = Reflection.findSetter(em.getClass(), prop, true);
  222               } catch (OpenJPAException ke) {
  223                   if (errs == null)
  224                       errs = new LinkedList<RuntimeException>();
  225                   errs.add(PersistenceExceptions.toPersistenceException(ke));
  226                   continue;
  227               }
  228   
  229               val = entry.getValue();
  230               try {
  231                   if (val instanceof String) {
  232                       if ("null".equals(val))
  233                           val = null;
  234                       else
  235                           val = Strings.parse((String) val,
  236                               setter.getParameterTypes()[0]);
  237                   }
  238                   Reflection.set(em, setter, val);
  239               } catch (Throwable t) {
  240                   while (t.getCause() != null)
  241                       t = t.getCause();
  242                   ArgumentException err = new ArgumentException(_loc.get
  243                       ("bad-em-prop", prop, entry.getValue()),
  244                       new Throwable[]{ t }, null, true);
  245                   if (errs == null)
  246                       errs = new LinkedList<RuntimeException>();
  247                   errs.add(err);
  248               }
  249           }
  250   
  251           if (errs != null) {
  252               em.close();
  253               if (errs.size() == 1)
  254                   throw errs.get(0);
  255               throw new ArgumentException(_loc.get("bad-em-props"),
  256                   errs.toArray(new Throwable[errs.size()]),
  257                   null, true);
  258           }
  259           return em;
  260       }
  261   
  262       /**
  263        * Create a new entity manager around the given broker.
  264        */
  265       protected EntityManagerImpl newEntityManagerImpl(Broker broker) {
  266           return new EntityManagerImpl(this, broker);
  267       }
  268   
  269       public void addLifecycleListener(Object listener, Class... classes) {
  270           _factory.addLifecycleListener(listener, classes);
  271       }
  272   
  273       public void removeLifecycleListener(Object listener) {
  274           _factory.removeLifecycleListener(listener);
  275       }
  276   
  277       public void addTransactionListener(Object listener) {
  278           _factory.addTransactionListener(listener);
  279       }
  280   
  281       public void removeTransactionListener(Object listener) {
  282           _factory.removeTransactionListener(listener);
  283       }
  284   
  285       public void close() {
  286           _factory.close();
  287       }
  288   
  289       public boolean isOpen() {
  290           return !_factory.isClosed();
  291       }
  292   
  293       public int hashCode() {
  294           return _factory.hashCode();
  295       }
  296   
  297       public boolean equals(Object other) {
  298           if (other == this)
  299               return true;
  300           if (!(other instanceof EntityManagerFactoryImpl))
  301               return false;
  302           return _factory.equals(((EntityManagerFactoryImpl) other)._factory);
  303       }
  304   
  305       /**
  306        * Create a store-specific facade for the given fetch configuration.
  307   	 * If no facade class exists, we use the default {@link FetchPlan}.
  308        */
  309       FetchPlan toFetchPlan(Broker broker, FetchConfiguration fetch) {
  310           if (fetch == null)
  311               return null;
  312   
  313           if (fetch instanceof DelegatingFetchConfiguration)
  314               fetch = ((DelegatingFetchConfiguration) fetch).
  315                   getInnermostDelegate();
  316   
  317           try {
  318               if (_plan == null) {
  319                   Class storeType = (broker == null) ? null : broker.
  320                       getStoreManager().getInnermostDelegate().getClass();
  321                   Class cls = _factory.getConfiguration().
  322                       getStoreFacadeTypeRegistry().
  323                       getImplementation(FetchPlan.class, storeType, 
  324                       		FetchPlanImpl.class);
  325                   _plan = cls.getConstructor(FetchConfiguration.class);
  326               }
  327               return _plan.newInstance(fetch);
  328           } catch (InvocationTargetException ite) {
  329               throw PersistenceExceptions.toPersistenceException
  330                   (ite.getTargetException());
  331           } catch (Exception e) {
  332               throw PersistenceExceptions.toPersistenceException(e);
  333           }
  334   	}
  335   }

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