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

br.gov.frameworkdemoiselle.internal.producer.EntityManagerFactoryProducer Maven / Gradle / Ivy

/*
 * Demoiselle Framework
 * Copyright (C) 2010 SERPRO
 * ----------------------------------------------------------------------------
 * This file is part of Demoiselle Framework.
 * 
 * Demoiselle Framework is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License version 3
 * as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License version 3
 * along with this program; if not,  see 
 * or write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA  02110-1301, USA.
 * ----------------------------------------------------------------------------
 * Este arquivo é parte do Framework Demoiselle.
 * 
 * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou
 * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
 * do Software Livre (FSF).
 * 
 * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
 * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
 * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
 * para maiores detalhes.
 * 
 * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
 * "LICENCA.txt", junto com esse programa. Se não, acesse 
 * ou escreva para a Fundação do Software Livre (FSF) Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
 */
package br.gov.frameworkdemoiselle.internal.producer;

import static java.util.logging.Level.SEVERE;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Default;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.inject.Inject;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import br.gov.frameworkdemoiselle.DemoiselleException;
import br.gov.frameworkdemoiselle.annotation.Name;
import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig;
import br.gov.frameworkdemoiselle.util.Beans;
import br.gov.frameworkdemoiselle.util.NameQualifier;
import br.gov.frameworkdemoiselle.util.ResourceBundle;

@ApplicationScoped
public class EntityManagerFactoryProducer implements Serializable {

	private static final long serialVersionUID = 1L;

	private static final String ENTITY_MANAGER_RESOURCE = "META-INF/persistence.xml";

	private transient Logger logger;

	private transient ResourceBundle bundle;

	@Inject
	private Persistences persistenceUnitReader;

	private final Map> factoryCache = Collections
			.synchronizedMap(new HashMap>());

	@Default
	@Produces
	protected EntityManagerFactory createDefault(EntityManagerConfig config) {
		String persistenceUnit = persistenceUnitReader.getFromProperties(config);

		if (persistenceUnit == null) {
			persistenceUnit = persistenceUnitReader.getFromXML();
		}

		return create(persistenceUnit);
	}

	@Name("")
	@Produces
	protected EntityManagerFactory createNamed(InjectionPoint ip) {
		String persistenceUnit = ip.getAnnotated().getAnnotation(Name.class).value();
		return create(persistenceUnit);
	}

	public EntityManagerFactory create(String persistenceUnit) {
		EntityManagerFactory factory;

		ClassLoader c = Thread.currentThread().getContextClassLoader();

		if (factoryCache.containsKey(c)) {
			Map localCache = factoryCache.get(c);
			if (localCache.containsKey(persistenceUnit)) {
				factory = localCache.get(persistenceUnit);
			} else {
				factory = Persistence.createEntityManagerFactory(persistenceUnit);
				localCache.put(persistenceUnit, factory);
			}
		} else {
			Map localCache = new HashMap();
			factory = Persistence.createEntityManagerFactory(persistenceUnit);
			localCache.put(persistenceUnit, factory);
			factoryCache.put(c, localCache);
		}

		return factory;
	}

	private String[] loadPersistenceUnitFromClassloader(ClassLoader classLoader) {
		try {
			ArrayList persistenceUnits = new ArrayList();
			DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			Document document = documentBuilder.parse(classLoader.getResourceAsStream(ENTITY_MANAGER_RESOURCE));
			NodeList nodes = document.getElementsByTagName("persistence-unit");

			String persistenceUnit = "";
			for (int index = 0; index < nodes.getLength(); index++) {
				Node node = nodes.item(index);
				persistenceUnit = ((Element) node).getAttribute("name");

				if ("".equals(persistenceUnit)) {
					throw new DemoiselleException(getBundle()
							.getString("can-not-get-persistence-unit-from-persistence"));
				} else {
					persistenceUnits.add(persistenceUnit);
				}
			}

			return persistenceUnits.toArray(new String[0]);

		} catch (Exception cause) {
			String message = getBundle().getString("can-not-get-persistence-unit-from-persistence");
			getLogger().log(SEVERE, message, cause);

			throw new DemoiselleException(message, cause);
		}

	}

	@PostConstruct
	public void loadPersistenceUnits() {
		ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
		for (String persistenceUnit : loadPersistenceUnitFromClassloader(contextClassLoader)) {

			try {
				create(persistenceUnit);
			} catch (Exception cause) {
				throw new DemoiselleException(cause);
			}

			getLogger().fine(getBundle().getString("persistence-unit-name-found", persistenceUnit));
		}
	}

	@PreDestroy
	public void close() {
		for (Map factories : factoryCache.values()) {
			for (EntityManagerFactory factory : factories.values()) {
				factory.close();
			}
		}
		factoryCache.clear();
	}

	public Map getCache() {
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		Map result = factoryCache.get(classLoader);

		if (result == null || result.isEmpty()) {
			getLogger().fine(getBundle().getString("entity-manager-factory-not-found-in-cache"));
			for (String persistenceUnit : loadPersistenceUnitFromClassloader(classLoader)) {
				create(persistenceUnit);
				result = factoryCache.get(classLoader);
			}
		}

		return result;
	}

	private ResourceBundle getBundle() {
		if (bundle == null) {
			bundle = Beans.getReference(ResourceBundle.class, new NameQualifier("demoiselle-jpa-bundle"));
		}

		return bundle;
	}

	private Logger getLogger() {
		if (logger == null) {
			logger = Beans.getReference(Logger.class, new NameQualifier("br.gov.frameworkdemoiselle.util"));

		}

		return logger;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy