com.hiperium.bo.manager.exception.ExceptionManager.java Source code

Java tutorial

Introduction

Here is the source code for com.hiperium.bo.manager.exception.ExceptionManager.java

Source

/**
 * Product  : Hiperium Project
 * Architect: Andres Solorzano.
 * Created  : 08-05-2009 - 23:30:00
 * 
 * The contents of this file are copyrighted by Andres Solorzano 
 * and it is protected by the license: "GPL V3." You can find a copy of this 
 * license at: http://www.hiperium.com/about/licence.html
 * 
 * Copyright 2014 Andres Solorzano. All rights reserved.
 * 
 */
package com.hiperium.bo.manager.exception;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.interceptor.ExcludeDefaultInterceptors;
import javax.persistence.NoResultException;
import javax.persistence.OptimisticLockException;
import javax.validation.constraints.NotNull;

import org.apache.commons.lang.text.StrSubstitutor;

import com.hiperium.commons.EnumHiperiumTier;
import com.hiperium.commons.EnumI18N;
import com.hiperium.commons.HiperiumTier;
import com.hiperium.commons.exception.EnumInformationException;
import com.hiperium.commons.exception.InformationException;
import com.hiperium.commons.log.HiperiumLogger;
import com.hiperium.dao.general.EntityLanguageDAO;
import com.hiperium.dao.general.EntityTableDAO;
import com.hiperium.dao.general.ErrorLanguageDAO;
import com.hiperium.dao.general.IntegrityDAO;
import com.hiperium.model.general.EntityLanguage;
import com.hiperium.model.general.EntityLanguagePK;
import com.hiperium.model.general.EntityTable;
import com.hiperium.model.general.ErrorLanguage;
import com.hiperium.model.general.ErrorLanguagePK;
import com.hiperium.model.general.Integrity;

/**
 * Implements the methods declared in the ExceptionHandlerLocal interface.
 * 
 * @author Andres Solorzano.
 * 
 */
@Stateless
@LocalBean
@ExcludeDefaultInterceptors
public class ExceptionManager {

    /** The property ENTITY_FIELD. */
    private static final String ENTITY_FIELD = "entityField";
    /** The property ENTITY_CHILD. */
    private static final String ENTITY_CHILD = "entityChild";

    /** The property log. */
    @Inject
    @HiperiumTier(EnumHiperiumTier.BUSINESS)
    private HiperiumLogger log;

    /** The property errorLanguageDAO. */
    @EJB
    private ErrorLanguageDAO errorLanguageDAO;
    /** The property entityLanguageDAO. */
    @EJB
    private EntityLanguageDAO entityLanguageDAO;
    /** The property entityTableDAO. */
    @EJB
    private EntityTableDAO entityTableDAO;
    /** The property integrityDAO. */
    @EJB
    private IntegrityDAO integrityDAO;

    /**
     * {@inheritDoc}
     */
    public InformationException createMessageException(@NotNull Exception ex, @NotNull Locale locale)
            throws InformationException {
        this.log.debug("createMessageException - START");
        if (ex instanceof InformationException || ex.getCause() instanceof InformationException) {
            return (InformationException) ex;
        }
        if (locale == null) {
            locale = Locale.getDefault();
        }
        InformationException informacionExcepcion = null;
        try {
            informacionExcepcion = this.findErrorCode(ex, locale);
            if (informacionExcepcion == null) {
                return InformationException.generate(EnumI18N.COMMON, EnumInformationException.SYSTEM_EXCEPTION,
                        locale);
            } else if (informacionExcepcion.getErrorCode() == null) {
                return informacionExcepcion;
            }
            ErrorLanguagePK languagePK = new ErrorLanguagePK(informacionExcepcion.getErrorCode().toString(),
                    locale.getLanguage());
            ErrorLanguage errorLenguaje = this.errorLanguageDAO.findById(languagePK, false, true);
            if (errorLenguaje == null) {
                throw new NoResultException(informacionExcepcion.getMessage());
            } else {
                informacionExcepcion = new InformationException(errorLenguaje.getText());
            }
            informacionExcepcion = this.createMessageParameters(informacionExcepcion, locale);
        } catch (NoResultException e) {
            this.log.error("ERROR - MESSAGE NOT FOUND IN DATA BASE: " + e.getMessage());
        }
        this.log.debug("createMessageException - END");
        return informacionExcepcion;
    }

    /**
     * Finds the error code of the exception.
     * 
     * @param t
     *            exception object
     * @throws javax.persistence.NoResultException
     *             if no result exception in the searching
     * @return the information exception object.
     */
    private InformationException findErrorCode(Throwable t, Locale locale) {
        this.log.debug("findErrorCode - START");
        InformationException informationException = null;
        if (t instanceof Throwable) {
            if (t instanceof SQLException) {
                Integer code = ((SQLException) t).getErrorCode();
                String error = t.getMessage();
                if (error.contains("Detail")) {
                    error = error.split(": ")[1].split("Detail")[0];
                } else if (error.contains("ERROR")) {
                    error = error.split(": ")[1];
                }
                informationException = new InformationException(error);
                informationException.setErrorCode(code);
            } else if (t instanceof OptimisticLockException) {
                informationException = InformationException.generate(EnumI18N.COMMON,
                        EnumInformationException.OPTIMISTIC_LOCK, locale);
            } else if (t.getCause() == null) {
                informationException = new InformationException(t.toString());
            } else {
                informationException = this.findErrorCode(t.getCause(), locale);
            }
            this.log.debug("findErrorCode - END");
        }
        return informationException;
    }

    /**
     * Verifies if the error exception ID corresponds to a message that need a
     * parameter exchange.
     *
     * @param infoExcepcion
     *            the information exception
     * @param locale
     *            the locale used to format the message
     * @return the information exception object with the internationalized
     *         message.
     * @throws javax.persistence.NoResultException
     *             if no result exception in the searching
     */
    private InformationException createMessageParameters(InformationException infoExcepcion, Locale locale)
            throws NoResultException, InformationException {
        this.log.debug("createMessageParameters - START");
        Map<String, String> var = new HashMap<String, String>();
        // POSTGRES INTEGRITY CODES: http://www.postgresql.org/docs/9.1/static/errcodes-appendix.html
        switch (infoExcepcion.getErrorCode()) {
        case 23502: // Insert null in a required field
            var.put(ENTITY_FIELD, infoExcepcion.getMessage().split("\"")[1]);
            break;
        case 23503: // Foreign key constraint exception
            var.put(ENTITY_CHILD, this.findEntityTableName(infoExcepcion, locale));
            break;
        case 23514: // Check constraint exception
            var.put(ENTITY_FIELD, infoExcepcion.getMessage().split("chk_")[1].split("\"")[0]);
            break;
        default:
            break;
        }
        if (!var.isEmpty()) {
            StrSubstitutor sub = new StrSubstitutor(var);
            infoExcepcion = new InformationException(sub.replace(infoExcepcion.getMessage()));
        }
        this.log.debug("createMessageParameters - END");
        return infoExcepcion;
    }

    /**
     * This method finds the name of the entity table required for error message
     * generation in the case of Foreign Keys.
     * 
     * @param infoExcepcion
     *            Exception information detail
     * @param locale
     *            user logged locale
     * @return the detail of the referenced table
     * @throws EntidadNoEncontradaException
     *             if the method not found the referenced entity table detail
     */
    private String findEntityTableName(InformationException infoExcepcion, Locale locale)
            throws NoResultException, InformationException {
        this.log.debug("findEntityTableName - START");
        String message = infoExcepcion.getMessage();
        String[] messageSplit = message.split("fk_");
        String key = null;
        if (messageSplit.length > 0) {
            key = "fk_" + messageSplit[1].split("\"")[0];
        }
        Integrity integrity = this.integrityDAO.findByConstraintName(key);
        if (integrity == null) {
            throw new NoResultException(key);
        }
        String tableCode = integrity.getReferencedTableName();
        EntityLanguagePK languagePK = new EntityLanguagePK(tableCode, locale.getLanguage());
        EntityLanguage entityLanguage = this.entityLanguageDAO.findById(languagePK, false, true);
        String entityName = null;
        if (entityLanguage == null) {
            EntityTable entityTable = this.entityTableDAO.findById(tableCode, false, true);
            if (entityTable == null) {
                throw new NoResultException(tableCode);
            }
        } else {
            entityName = entityLanguage.getText();
        }
        this.log.debug("findEntityTableName - END");
        return entityName;
    }
}