

package gov.va.med.cds.persistence.hibernate;


import gov.va.med.cds.exception.ErrorCodeEnum;
import gov.va.med.cds.persistence.PersistenceException;

import org.hibernate.exception.ConstraintViolationException;


/**
 * Handles exceptions thrown by hibernate persistence requests.
 * 
 */
public class HibernateConstraintViolationException
    extends
        PersistenceException
{

    private static final long serialVersionUID = 4371553944863577184L;


    /**
     * Parent constructor for hibernate persistence exception
     * 
     * @param errorCodeName - enum to populate and return to caller.
     */
    public HibernateConstraintViolationException( ErrorCodeEnum errorCodeName )
    {
        super( errorCodeName );
    }


    /**
     * Parent constructor for hibernate persistence exception
     * 
     * @param errorCodeName - enum to populate and return to caller.
     * @param messages - list of messages to be integrated into exception message.
     */
    public HibernateConstraintViolationException( ErrorCodeEnum errorCodeName, String... messages )
    {
        super( errorCodeName, messages );
    }


    /**
     * Parent constructor for hibernate persistence exception
     * 
     * @param errorCode - enum to populate and return to caller.
     * @param cause - exception thrown in hibernate persistence module.
     * @param customMsg - list of messages to be integrated into exception message.
     */
    public HibernateConstraintViolationException( ErrorCodeEnum errorCode, Throwable cause, String... customMsg )
    {
        super( errorCode, cause, customMsg );
    }


    /**
     * Parent constructor for hibernate persistence exception
     * 
     * @param cause - exception thrown in hibernate persistence module.
     */
    public HibernateConstraintViolationException( ConstraintViolationException cause )

    {
    	/*
    	 * 
    	 * TODO: Narasa - ExceptionUtils.getRootCauseMessage result is InvocationTargetException
    	 * Hence replace the following constructor with one that does not call the above method and try
    	 */
        // super( parseRootExceptionCauseMessage( cause ), cause, ExceptionUtils.getRootCauseMessage( cause ) );
        super( parseRootExceptionCauseMessage( cause ), cause, cause.getCause().getMessage() );
    	
    }


    /**
     * Determines the appropriate enum based on key words in exception message. Note: This method is static because
     * constructors cannot contain an instance method.
     * 
     * @param exception - exception thrown by hibernate.
     * @return Enum to be used by exception message.
     */
    private static ErrorCodeEnum parseRootExceptionCauseMessage( ConstraintViolationException exception )

    {
        // try to figure out the main cause of this persistence problem

        String violation = exception.getConstraintName();

        if ( violation != null )
        {
            return ErrorCodeEnum.HDRII_CONSTRAINT_VIOLATED;
        }

        return ErrorCodeEnum.ROOT_CAUSE_MSG;

    }

}
