buildframework/helium/sf/java/metadata/src/com/nokia/helium/metadata/FactoryManager.java
changeset 628 7c4a911dc066
equal deleted inserted replaced
588:c7c26511138f 628:7c4a911dc066
       
     1 /*
       
     2  * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3  * All rights reserved.
       
     4  * This component and the accompanying materials are made available
       
     5  * under the terms of the License "Eclipse Public License v1.0"
       
     6  * which accompanies this distribution, and is available
       
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8  *
       
     9  * Initial Contributors:
       
    10  * Nokia Corporation - initial contribution.
       
    11  *
       
    12  * Contributors:
       
    13  *
       
    14  * Description:  
       
    15  *
       
    16  */
       
    17 package com.nokia.helium.metadata;
       
    18 
       
    19 import java.io.File;
       
    20 import java.util.ArrayList;
       
    21 import java.util.List;
       
    22 import java.util.Map;
       
    23 
       
    24 import javax.persistence.Cache;
       
    25 import javax.persistence.EntityManager;
       
    26 import javax.persistence.EntityManagerFactory;
       
    27 import javax.persistence.PersistenceUnitUtil;
       
    28 import javax.persistence.criteria.CriteriaBuilder;
       
    29 import javax.persistence.metamodel.Metamodel;
       
    30 
       
    31 /**
       
    32  * This singleton class is the main entry point to the Metadata framework.
       
    33  * Developer must use it to get access to the EntityManagerFactory from the
       
    34  * JPA framework. 
       
    35  *
       
    36  */
       
    37 public final class FactoryManager {
       
    38     private static FactoryManager self = new FactoryManager();
       
    39     private List<EntityManagerFactoryWrapper> wrappers = new ArrayList<EntityManagerFactoryWrapper>();
       
    40     private EntityManagerFactoryCreator factoryManagerCreator = new DerbyFactoryManagerCreator();
       
    41     
       
    42     /**
       
    43      * This class must not be instantiated from outside.
       
    44      */
       
    45     private FactoryManager() {
       
    46     }
       
    47     
       
    48     /**
       
    49      * Get the FactoryManager instance.
       
    50      * @return the FactoryManager instance.
       
    51      */
       
    52     public static FactoryManager getFactoryManager() {
       
    53         return self;
       
    54     }
       
    55     
       
    56     /**
       
    57      * Get the EntityManagerFactory for the database. 
       
    58      * @param database the File object representing the database.
       
    59      * @return an EntityManagerFactory instance.
       
    60      * @throws MetadataException is thrown in case of error.
       
    61      */
       
    62     public synchronized EntityManagerFactory getEntityManagerFactory(File database) throws MetadataException {
       
    63         EntityManagerFactoryWrapper wrapper = null;
       
    64         for (EntityManagerFactoryWrapper wrp : wrappers) {
       
    65             // Found what we wanted so leaving the loop.
       
    66             if (wrp.getDatabase().equals(database)) {
       
    67                 wrapper = wrp;
       
    68                 break;
       
    69             }
       
    70         }
       
    71         if (wrapper != null) {
       
    72             wrapper.reference();
       
    73             return wrapper;
       
    74         } else {
       
    75             // creating a new one.
       
    76             wrapper = 
       
    77                 new EntityManagerFactoryWrapper(factoryManagerCreator.create(database), this, database);
       
    78             wrappers.add(wrapper);
       
    79             return wrapper;
       
    80         }
       
    81     }
       
    82     
       
    83     /**
       
    84      * Removing the wrapper object from the available database, so no one can 
       
    85      * use it anymore. This method is intended to be used by the EntityManagerFactoryWrapper.
       
    86      * @param wrapper
       
    87      */
       
    88     private synchronized void remove(EntityManagerFactoryWrapper wrapper) {
       
    89         wrappers.remove(wrapper);
       
    90     }
       
    91 
       
    92     /**
       
    93      * Unload the database when not used anymore.
       
    94      * This method is intended to be used by the EntityManagerFactoryWrapper.
       
    95      * @param database the database to unload.
       
    96      */
       
    97     private void unload(File database) {
       
    98         try {
       
    99             factoryManagerCreator.unload(database);
       
   100         } catch (MetadataException e) {
       
   101             // do nothing in the meantime
       
   102             database = null;
       
   103         }        
       
   104     }
       
   105     
       
   106     /**
       
   107      * Internal Factory wrapper object which implements a custom 
       
   108      * factory lifecycle management. 
       
   109      *
       
   110      */
       
   111     class EntityManagerFactoryWrapper implements EntityManagerFactory {
       
   112         private EntityManagerFactory factory;
       
   113         private FactoryManager factoryManager;
       
   114         private int counter = 1;
       
   115         private File database;
       
   116         
       
   117         /**
       
   118          * Default constructor.
       
   119          * @param factory the factory to delegate to calls to.
       
   120          * @param factoryManager the factory manager used for the lifecycle management.
       
   121          * @param database the database this object is connected to.
       
   122          */
       
   123         public EntityManagerFactoryWrapper(EntityManagerFactory factory,
       
   124                 FactoryManager factoryManager, File database) {
       
   125             this.factory = factory;
       
   126             this.factoryManager = factoryManager;
       
   127             this.database = database;
       
   128         }
       
   129 
       
   130         /**
       
   131          * Method used by the factoryManager to reference the usage of the 
       
   132          * EntityFactoryManager.
       
   133          */
       
   134         public synchronized void reference() {
       
   135             counter++;
       
   136         }
       
   137 
       
   138         /**
       
   139          * {@inheritDoc}
       
   140          * This method overrides the default close implementation, and will
       
   141          * only close the EntityManagerFactory, if all application have stopped
       
   142          * using the EntityManagerFactory.
       
   143          * It interacts with the factoryManager.
       
   144          */
       
   145         public synchronized void close() {
       
   146             counter--;
       
   147             if (counter == 0) {
       
   148                 factoryManager.remove(this);
       
   149                 factory.close();
       
   150                 factoryManager.unload(database);
       
   151             }
       
   152         }
       
   153 
       
   154         /**
       
   155          * {@inheritDoc}
       
   156          */
       
   157         public EntityManager createEntityManager() {
       
   158             return factory.createEntityManager();
       
   159         }
       
   160 
       
   161         /**
       
   162          * {@inheritDoc}
       
   163          */
       
   164         @SuppressWarnings("unchecked")
       
   165         public EntityManager createEntityManager(Map properties) {
       
   166             return factory.createEntityManager(properties);
       
   167         }
       
   168 
       
   169         /**
       
   170          * {@inheritDoc}
       
   171          */
       
   172         public Cache getCache() {
       
   173             return factory.getCache();
       
   174         }
       
   175 
       
   176         /**
       
   177          * {@inheritDoc}
       
   178          */
       
   179         public CriteriaBuilder getCriteriaBuilder() {
       
   180             return factory.getCriteriaBuilder();
       
   181         }
       
   182 
       
   183         /**
       
   184          * {@inheritDoc}
       
   185          */
       
   186         public Metamodel getMetamodel() {
       
   187             return factory.getMetamodel();
       
   188         }
       
   189 
       
   190         /**
       
   191          * {@inheritDoc}
       
   192          */
       
   193         public PersistenceUnitUtil getPersistenceUnitUtil() {
       
   194             return factory.getPersistenceUnitUtil();
       
   195         }
       
   196 
       
   197         /**
       
   198          * {@inheritDoc}
       
   199          */
       
   200         public Map<String, Object> getProperties() {
       
   201             return factory.getProperties();
       
   202         }
       
   203 
       
   204         /**
       
   205          * {@inheritDoc}
       
   206          */
       
   207         public boolean isOpen() {
       
   208             return factory.isOpen();
       
   209         }
       
   210         
       
   211         /**
       
   212          * {@inheritDoc}
       
   213          */
       
   214         public File getDatabase() {
       
   215             return database;
       
   216         }
       
   217     }
       
   218 
       
   219 }