Package org.paquitosoft.lml.model.dao

Source Code of org.paquitosoft.lml.model.dao.IdentifierDAOImpl

package org.paquitosoft.lml.model.dao;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.paquitosoft.lml.model.exception.InternalErrorException;
import org.paquitosoft.lml.model.exception.ReflectionException;
import org.paquitosoft.lml.model.util.ModelUtilities;

/**
*  This is the DAO used to deal with entity identifiers generation.
*
* @author paquitosoft
*/
public class IdentifierDAOImpl extends DefaultDAOImpl implements IIdentifierDAO {

//    private static Logger logger = Logger.getLogger(IdentifierDAOImpl.class.getName());
   
    private static final int MAX_CHAR_VALUE = 255;

    private static final String CHECK_TABLE_EXISTS_QUERY = "SELECT * FROM ENTITY_KEYS";
    private static final String CREATE_TABLE_QUERY = "CREATE TABLE ENTITY_KEYS ( TABLE_NAME VARCHAR(45) NOT NULL, NEXT_VALUE VARCHAR(75) NOT NULL, PRIMARY KEY (TABLE_NAME))";
    private static final String READ_COUNTER_QUERY = "SELECT NEXT_VALUE FROM ENTITY_KEYS WHERE TABLE_NAME = ?";
    private static final String INSERT_COUNTER_QUERY = "INSERT INTO ENTITY_KEYS (TABLE_NAME, NEXT_VALUE) VALUES (?, ?)";
    private static final String UPDATE_COUNTER_QUERY = "UPDATE ENTITY_KEYS SET NEXT_VALUE = ? WHERE TABLE_NAME = ?";
   
    public IdentifierDAOImpl(Connection connection) {
        super(connection);
    }
   
    public Object generateIdentifier(Class entityType) throws InternalErrorException {
       
        Object result = null;
        PreparedStatement stm = null;
        ResultSet rs = null;
       
        // Get table name
        String tableName = ModelUtilities.getTableName(entityType);
       
        try {
           
            // Get identifier type
            Class pkType = ModelUtilities.getEntityIdType(entityType);
           
            // First we need to ensure the existence of the table
            try {               
                stm = conn.prepareStatement(CHECK_TABLE_EXISTS_QUERY);
                stm.executeQuery();
            } catch (SQLException e) {
                // An exception here means the table does not exists. Let's create it
                stm = conn.prepareStatement(CREATE_TABLE_QUERY);
                stm.executeUpdate();
            }

            // Now we get next available value
            stm = conn.prepareStatement(READ_COUNTER_QUERY);
            stm.setString(1, tableName);
            rs = stm.executeQuery();
            if (rs.next()) {
                result = ModelUtilities.getValueFromQuery(pkType, rs, "NEXT_VALUE");
            } else {
                // This means there is no row for this entity. Let's create it               
                result = getNextIdValue(getLastEntityIdentifier(entityType, conn), pkType); // We need to search entity's table because of the chance the table is not emtpy.
                stm = conn.prepareStatement(INSERT_COUNTER_QUERY);
                stm.setString(1, tableName);               
                ModelUtilities.insertValueInQuery(result, stm, 2);
                if (stm.executeUpdate() != 1) {
                    throw new InternalErrorException("IdentifierDAOImpl::generateIdentifier -> Insert new row failed!");
                }
            }
           
            // Update next available value
            stm = conn.prepareStatement(UPDATE_COUNTER_QUERY);
            ModelUtilities.insertValueInQuery(getNextIdValue(result, pkType), stm, 1);
            stm.setString(2, tableName);           
            if (stm.executeUpdate() != 1) {
                throw new InternalErrorException("IdentifierDAOImpl::generateIdentifier -> Update next available value failed!");
            }
           
        } catch (SQLException e) {
            throw new InternalErrorException("IdentifierDAOImpl::generateIdentifier", e);
        } catch (Exception e) {
            throw new InternalErrorException("IdentifierDAOImpl::generateIdentifier", e);
        } finally {
            closeResouces(stm, rs);
        }
       
        return result;
    }
   
    /**
     * This method is used to generate the next value for the identifier.
     *
     * @param id
     * @return next identifier value
     */
    private Object getNextIdValue(Object id, Class idType) {
       
        Object result = null;
       
        if (Double.class.isAssignableFrom(idType)) {
            result = (id != null) ? ((Double) id).doubleValue() + 1 : 1;
        } else if (Float.class.isAssignableFrom(idType)) {
            result = (id != null) ? ((Float) id).floatValue() + 1 : 1;
        } else if (Long.class.isAssignableFrom(idType)) {
            result = (id != null) ? ((Long) id).longValue() + 1 : 1;
        } else if (Integer.class.isAssignableFrom(idType)) {
            result = (id != null) ? ((Integer) id).intValue() + 1 : 1;
        } else if (Short.class.isAssignableFrom(idType)) {
            result = (id != null) ? ((Short) id).shortValue() + 1 : 1;
        } else if (Byte.class.isAssignableFrom(idType)) {
            result = (id != null) ? ((Byte) id).byteValue() + 1 : 1;
        } else if (BigDecimal.class.isAssignableFrom(idType)) {
            result = (id != null) ? ((BigDecimal) id).add(BigDecimal.ONE) : 1;
        } else if (String.class.isAssignableFrom(idType)) {
            if (id != null) {
                StringBuilder currentId = new StringBuilder((String) id);
                char lastChar = currentId.charAt(currentId.length() - 1);
                if (lastChar >= MAX_CHAR_VALUE) {
                    currentId.append(1);
                } else {
                    currentId.replace(currentId.length() - 1, currentId.length(), String.valueOf(1));
                }
                result = currentId;
            } else {
                result = new String(new char[] {1});
            }
        } else if (Character.class.isAssignableFrom(idType)) {
            char charId = 1;
            if (id != null) {
                charId = ((Character) id).charValue();
                if (charId >= MAX_CHAR_VALUE) {
                    charId = 1; // TODO Ojito con esto. Al finalizar con los caracteres disponibles, se inicia desde el principio (puede haber sido previamente utilizado)
                } else {
                    charId += 1;
                }               
            }
            result = new Character(charId);
        }
       
        return result;
    }
    /**
     * This method is used to get the last used identifier for this entity from its
     * corresponding table. <br/>
     * Used to initialize identifiers table.
     *
     * @param entityType
     * @return query
     * @throws org.paquitosoft.lml.model.exception.InternalErrorException
     */
    protected Object getLastEntityIdentifier(Class entityType, Connection connection) throws InternalErrorException {
   
        Object result = null;
       
        StringBuilder sb = new StringBuilder("SELECT ");
        List<Field> pkFields = ModelUtilities.getEntityIdentifierFields(entityType);
        String idColumnName = "";
        if (pkFields.size() == 1) {
            idColumnName = ModelUtilities.getColumnName(pkFields.get(0));
        } else {
            throw new ReflectionException("IdentifierDAOImpl::getFirsAvailableIdentifier -> Cannot generate coumpund keys");
        }
        sb.append(idColumnName);
        sb.append(" FROM ");
        sb.append(ModelUtilities.getTableName(entityType));
        sb.append(" ORDER BY ");
        sb.append(idColumnName);
        sb.append(" DESC");
       
        try {
            PreparedStatement stm = connection.prepareStatement(sb.toString());
            ResultSet rs = stm.executeQuery();
            if (rs.next()) {
                result = ModelUtilities.getValueFromQuery(pkFields.get(0).getType(), rs, idColumnName);
            }
        } catch (SQLException e) {
            throw new InternalErrorException("IdentiiferDAOImpl::getLastEntityIdentifier -> Error while looking for the last used entity " +
                    "identifier in its table.", e);
        }
       
        return result;
    }

}
TOP

Related Classes of org.paquitosoft.lml.model.dao.IdentifierDAOImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.