buildframework/helium/sf/java/metadata/src/com/nokia/helium/metadata/FactoryManager.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/buildframework/helium/sf/java/metadata/src/com/nokia/helium/metadata/FactoryManager.java Fri Aug 13 14:59:05 2010 +0300
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description:
+ *
+ */
+package com.nokia.helium.metadata;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.Cache;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceUnitUtil;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.metamodel.Metamodel;
+
+/**
+ * This singleton class is the main entry point to the Metadata framework.
+ * Developer must use it to get access to the EntityManagerFactory from the
+ * JPA framework.
+ *
+ */
+public final class FactoryManager {
+ private static FactoryManager self = new FactoryManager();
+ private List<EntityManagerFactoryWrapper> wrappers = new ArrayList<EntityManagerFactoryWrapper>();
+ private EntityManagerFactoryCreator factoryManagerCreator = new DerbyFactoryManagerCreator();
+
+ /**
+ * This class must not be instantiated from outside.
+ */
+ private FactoryManager() {
+ }
+
+ /**
+ * Get the FactoryManager instance.
+ * @return the FactoryManager instance.
+ */
+ public static FactoryManager getFactoryManager() {
+ return self;
+ }
+
+ /**
+ * Get the EntityManagerFactory for the database.
+ * @param database the File object representing the database.
+ * @return an EntityManagerFactory instance.
+ * @throws MetadataException is thrown in case of error.
+ */
+ public synchronized EntityManagerFactory getEntityManagerFactory(File database) throws MetadataException {
+ EntityManagerFactoryWrapper wrapper = null;
+ for (EntityManagerFactoryWrapper wrp : wrappers) {
+ // Found what we wanted so leaving the loop.
+ if (wrp.getDatabase().equals(database)) {
+ wrapper = wrp;
+ break;
+ }
+ }
+ if (wrapper != null) {
+ wrapper.reference();
+ return wrapper;
+ } else {
+ // creating a new one.
+ wrapper =
+ new EntityManagerFactoryWrapper(factoryManagerCreator.create(database), this, database);
+ wrappers.add(wrapper);
+ return wrapper;
+ }
+ }
+
+ /**
+ * Removing the wrapper object from the available database, so no one can
+ * use it anymore. This method is intended to be used by the EntityManagerFactoryWrapper.
+ * @param wrapper
+ */
+ private synchronized void remove(EntityManagerFactoryWrapper wrapper) {
+ wrappers.remove(wrapper);
+ }
+
+ /**
+ * Unload the database when not used anymore.
+ * This method is intended to be used by the EntityManagerFactoryWrapper.
+ * @param database the database to unload.
+ */
+ private void unload(File database) {
+ try {
+ factoryManagerCreator.unload(database);
+ } catch (MetadataException e) {
+ // do nothing in the meantime
+ database = null;
+ }
+ }
+
+ /**
+ * Internal Factory wrapper object which implements a custom
+ * factory lifecycle management.
+ *
+ */
+ class EntityManagerFactoryWrapper implements EntityManagerFactory {
+ private EntityManagerFactory factory;
+ private FactoryManager factoryManager;
+ private int counter = 1;
+ private File database;
+
+ /**
+ * Default constructor.
+ * @param factory the factory to delegate to calls to.
+ * @param factoryManager the factory manager used for the lifecycle management.
+ * @param database the database this object is connected to.
+ */
+ public EntityManagerFactoryWrapper(EntityManagerFactory factory,
+ FactoryManager factoryManager, File database) {
+ this.factory = factory;
+ this.factoryManager = factoryManager;
+ this.database = database;
+ }
+
+ /**
+ * Method used by the factoryManager to reference the usage of the
+ * EntityFactoryManager.
+ */
+ public synchronized void reference() {
+ counter++;
+ }
+
+ /**
+ * {@inheritDoc}
+ * This method overrides the default close implementation, and will
+ * only close the EntityManagerFactory, if all application have stopped
+ * using the EntityManagerFactory.
+ * It interacts with the factoryManager.
+ */
+ public synchronized void close() {
+ counter--;
+ if (counter == 0) {
+ factoryManager.remove(this);
+ factory.close();
+ factoryManager.unload(database);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public EntityManager createEntityManager() {
+ return factory.createEntityManager();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public EntityManager createEntityManager(Map properties) {
+ return factory.createEntityManager(properties);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Cache getCache() {
+ return factory.getCache();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public CriteriaBuilder getCriteriaBuilder() {
+ return factory.getCriteriaBuilder();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Metamodel getMetamodel() {
+ return factory.getMetamodel();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PersistenceUnitUtil getPersistenceUnitUtil() {
+ return factory.getPersistenceUnitUtil();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Map<String, Object> getProperties() {
+ return factory.getProperties();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isOpen() {
+ return factory.isOpen();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public File getDatabase() {
+ return database;
+ }
+ }
+
+}