org.javabeanstack.data.DBManager.java Source code

Java tutorial

Introduction

Here is the source code for org.javabeanstack.data.DBManager.java

Source

/*
* JavaBeanStack FrameWork
*
* Copyright (C) 2017 Jorge Enciso
* Email: jorge.enciso.r@gmail.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301  USA
*/

package org.javabeanstack.data;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.annotation.Resource;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.SessionContext;
import javax.ejb.Startup;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.log4j.Logger;

import org.javabeanstack.error.ErrorManager;
import org.javabeanstack.util.Dates;

/**
 * Contiene metodos para gestionar el acceso a los datos, es utilizado
 *  por GenericDAO 
 * 
 * @author Jorge Enciso
 */
@Startup
@Lock(LockType.READ)
public class DBManager implements IDBManager {
    private static final Logger LOGGER = Logger.getLogger(DBManager.class);
    private int entityIdStrategic = IDBManager.PERSESSION;
    private Date lastPurge = new Date();

    private final Map<String, Data> entityManagers = new HashMap<>();

    @Resource
    SessionContext context;

    /**
     * Devuelve la estrategia de acceso/creacin de los entityManagers.
     * Los valores posibles son: un entityManager por Thread o un entityManager 
     * por sesin del usuario.
     * @return estrategia de acceso/creacin de los entityManagers.
     */
    @Override
    public int getEntityIdStrategic() {
        return entityIdStrategic;
    }

    /**
     * Devuelve un entityManager, lo crea si no existe en la unidad de persistencia solicitada
     * @param key  id thread
     * @return Devuelve un entityManager
     */
    @Override
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    public EntityManager getEntityManager(String key) {
        try {
            if (key == null || "".equals(key)) {
                return null;
            }
            EntityManager em;
            if (entityManagers.containsKey(key)) {
                em = entityManagers.get(key).em;
                entityManagers.get(key).lastRef = Dates.now();
                LOGGER.debug("EntityManager ya existe: " + key);
            } else {
                em = this.createEntityManager(key);
            }
            purgeEntityManager();
            return em;
        } catch (Exception ex) {
            ErrorManager.showError(ex, LOGGER);
        }
        return null;
    }

    /**
     * Crea un entitymanager dentro de un Map utiliza la unidad de persistencia 
     * y el threadid o sessionid del usuario como clave
     * 
     * @param key  id thread o sessionid del usuario
     * @return el entity manager creado.
     */
    @Override
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    @Lock(LockType.WRITE)
    public EntityManager createEntityManager(String key) {
        EntityManager em;
        try {
            String persistentUnit = key.substring(0, key.indexOf(':')).toLowerCase();
            em = (EntityManager) context.lookup("java:comp/env/persistence/" + persistentUnit);
            Data data = new Data();
            data.em = em;
            entityManagers.put(key, data);
            LOGGER.debug("--------- Se ha creado un nuevo EntityManager --------- " + key);
            return em;
        } catch (Exception ex) {
            ErrorManager.showError(ex, LOGGER);
        }
        return null;
    }

    /**
     * Elimina los entityManagers del map, a aquellos que no se esta utilizando
     * en un periodo dado.
     */
    protected void purgeEntityManager() {
        LOGGER.debug("purgeEntityManager() " + lastPurge);
        Date now = new Date();
        //Solo procesar si la ultima purga fue hace 5 minutos.
        if (!lastPurge.before(DateUtils.addMinutes(now, -5))) {
            return;
        }
        //Purgar aquellos entityManagers que no fueron referenciados hace 5 minutos
        now = DateUtils.addMinutes(Dates.now(), -5);
        for (Iterator<Map.Entry<String, Data>> it = entityManagers.entrySet().iterator(); it.hasNext();) {
            Map.Entry<String, Data> entry = it.next();
            if (entry.getValue().lastRef.before(now)) {
                LOGGER.debug("Se elimino entityManager: " + entry.getKey());
                it.remove();
            }
        }
        lastPurge = new Date();
        LOGGER.debug("Se proceso purgeEntityManager " + lastPurge);
    }

    /**
     *  Ejecuta rollback de una transaccin 
     */
    @Override
    @Lock(LockType.WRITE)
    public void rollBack() {
        context.setRollbackOnly();
    }

    class Data {
        EntityManager em;
        Date lastRef = Dates.now();
    }
}