All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.emf.teneo.hibernate.HbHelper Maven / Gradle / Ivy

/**
 * 
 *
 * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Martin Taal
 * 
 *
 * $Id: HbHelper.java,v 1.19 2010/04/02 22:28:53 mtaal Exp $
 */

package org.eclipse.emf.teneo.hibernate;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.teneo.PersistenceOptions;
import org.eclipse.emf.teneo.annotations.mapper.PersistenceMappingBuilder;
import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedModel;
import org.eclipse.emf.teneo.ecore.EModelResolver;
import org.eclipse.emf.teneo.extension.ExtensionManager;
import org.eclipse.emf.teneo.extension.ExtensionManagerFactory;
import org.eclipse.emf.teneo.hibernate.mapper.HibernateMappingGenerator;
import org.eclipse.emf.teneo.hibernate.mapper.MappingUtil;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass;

/**
 * Is the main entry point for 'outside' users to create, register and retrieve EMF Data stores.
 * 
 * @author Martin Taal
 * @version $Revision: 1.19 $
 */
public class HbHelper {
	/** The logger */
	private static Log log = LogFactory.getLog(HbHelper.class);

	/** The singleton instance of this class */
	public static final HbHelper INSTANCE = new HbHelper();

	/** The list of EMF Datastores mapped by name */
	private final Hashtable emfDataStores = new Hashtable();

	/** The list of emf datastores mapped by hibernate persistent class */
	private final Hashtable dataStoreByPersistentClass = new Hashtable();

	/** The registered emf data store factory */
	private static HbDataStoreFactory emfDataStoreFactory = new HbDataStoreFactory() {
		public HbDataStore createHbDataStore() {
			return new HbSessionDataStore();
		}
	};

	/**
	 * @param emfDataStoreFactory
	 *          the emfDataStoreFactory to set
	 */
	public static void setHbDataStoreFactory(HbDataStoreFactory hbDataStoreFactory) {
		HbHelper.emfDataStoreFactory = hbDataStoreFactory;
	}

	/** Put a datastore in the dataStoreByPersistentClass */
	void registerDataStoreByPC(HbDataStore ds) {
		for (Iterator it = ds.getClassMappings(); it.hasNext();) {
			final PersistentClass pc = (PersistentClass) it.next();
			if (dataStoreByPersistentClass.get(pc) != null) {
				throw new HbMapperException("There is already a datastore registered for this pc: "
						+ pc.getEntityName() + (dataStoreByPersistentClass.get(pc)).getName() + "/"
						+ ds.getName());
			}
			if (log.isDebugEnabled()) {
				log.debug("Datastore: " + ds.getName() + " registered for pc: " + pc.getEntityName());
			}
			dataStoreByPersistentClass.put(pc, ds);
		}
	}

	/** Register the datastore also for the components */
	void registerDataStoreByComponent(HbDataStore ds, Component component) {
		if (log.isDebugEnabled()) {
			log.debug("Datastore: " + ds.getName() + " registered for component: "
					+ component.getComponentClassName());
		}
		dataStoreByPersistentClass.put(component, ds);
	}

	/** Return the datastore on the basis of the pc */
	public HbDataStore getDataStore(PersistentClass pc) {
		final HbDataStore ds = dataStoreByPersistentClass.get(pc);
		if (ds == null) {
			throw new HbMapperException("No datastore for pc " + pc.getEntityName());
		}
		return ds;
	}

	/** Return the datastore on the basis of the component */
	public HbDataStore getDataStore(Component component) {
		final HbDataStore ds = dataStoreByPersistentClass.get(component);
		if (ds == null) {
			throw new HbMapperException("No datastore for pc " + component.getComponentClassName());
		}
		return ds;
	}

	/** Clears the list of session factories */
	public synchronized void closeAll() {
		final List dataStores = new ArrayList(emfDataStores.values());
		for (HbDataStore emfds : dataStores) {
			emfds.close();
		}
		emfDataStores.clear();
		dataStoreByPersistentClass.clear();
	}

	/** Deregisters a session factory from the registry */
	public synchronized void deRegisterDataStore(String name) {
		if (name == null) {
			throw new HbMapperException(
					"An unique name should be specified when deregistering a session factory");
		}
		final HbDataStore emfds = emfDataStores.get(name);
		if (emfds == null) {
			return;
		}
		deRegisterDataStore(emfds);
	}

	/** Deregisters a datastore from the registry */
	public synchronized void deRegisterDataStore(HbDataStore emfds) {
		// changed for bugzilla 281036
		final List toRemove = new ArrayList();
		for (Object key : dataStoreByPersistentClass.keySet()) {
			if (emfds == dataStoreByPersistentClass.get(key)) {
				toRemove.add(key);
			}
		}
		for (Object key : toRemove) {
			dataStoreByPersistentClass.remove(key);
		}
		if (emfds.getName() != null) {
			emfDataStores.remove(emfds.getName());
		}

		EModelResolver.instance().unregisterOwnerShip(emfds, emfds.getEPackages());

		if (emfds.isInitialized()) {
			emfds.close();
		}
	}

	/**
	 * Creates and register a HibernateEMFDataStore, initialization has to be done by the caller
	 */
	public synchronized HbDataStore createRegisterDataStore(String name) {
		HbDataStore emfds = emfDataStores.get(name);
		if (emfds != null) {
			log.warn("EMF Data Store already registered under name: " + name + ", returning it");
			return emfds;
		}

		log.info("Creating emf data store and registering it under name: " + name);
		emfds = emfDataStoreFactory.createHbDataStore();
		emfds.setName(name);
		// next call is done automatically
		// emfDataStores.put(name, emfds);
		log.info("Returning created emf data store, initialize this newly created data store!");
		return emfds;
	}

	/** Register a datastore */
	public void register(HbDataStore hbDataStore) {
		emfDataStores.put(hbDataStore.getName(), hbDataStore);
	}

	/** Return a emf data store */
	public HbDataStore getDataStore(String name) {
		final HbDataStore hds = emfDataStores.get(name);
		if (hds == null && log.isDebugEnabled()) {
			log.debug("No datastore found using " + name);
		}
		return hds;
	}

	/**
	 * Separate utility method, generates a hibernate mapping for a set of epackages and options. The
	 * hibernate.hbm.xml is returned as a string. The mapping is not registered or used in any other
	 * way by Elver.
	 */
	public String generateMapping(EPackage[] epackages, Properties props) {
		return generateMapping(epackages, props, ExtensionManagerFactory.getInstance().create());
	}

	/**
	 * Separate utility method, generates a hibernate mapping for a set of epackages and options. The
	 * hibernate.hbm.xml is returned as a string. The mapping is not registered or used in any other
	 * way by Elver.
	 */
	public String generateMapping(EPackage[] epackages, Properties props,
			ExtensionManager extensionManager) {
		MappingUtil.registerHbExtensions(extensionManager);

		if (log.isDebugEnabled()) {
			log.debug("Generating mapping file passed epackages");
		}
		// DCB: Use Hibernate-specific annotation processing mechanism. This
		// allows use of
		// Hibernate-specific annotations.
		final PersistenceOptions po = extensionManager.getExtension(PersistenceOptions.class,
				new Object[] { props });
		final PAnnotatedModel paModel = extensionManager.getExtension(PersistenceMappingBuilder.class)
				.buildMapping(epackages, po, extensionManager);
		final HibernateMappingGenerator hmg = extensionManager
				.getExtension(HibernateMappingGenerator.class);
		hmg.setPersistenceOptions(po);

		return hmg.generateToString(paModel);
	}
}