package com.fp.common.exception; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; import java.sql.BatchUpdateException; import java.sql.SQLException; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; import javax.persistence.PersistenceException; import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.GenericJDBCException; import com.fp.common.logger.APPLogger; /** * Clase encargada del manejo de excepciones * * @author Jorge Vaca * @version 2.1 */ public class ExceptionHandler { /** * Referencia a la excepcion presentanda. */ private final Throwable exception; /** * Referencia a la causa de la excepcion. */ private Throwable cause; /** * Codigo de lenguage */ private String language = "es"; /** * Indica que es un mensaje aplicativo. */ private boolean appexception = false; /** * Crea una Instancia de ExceptionHandler * * @param pException Excepcion por Manejar */ public ExceptionHandler(Throwable pException, String pLanguage) { APPLogger.getLogger().warn(pException, pException); this.exception = pException; this.cause = this.exception.getCause(); if (pException instanceof APPException) { this.appexception = true; } while ((this.cause != null) && (this.cause.getCause() != null)) { if ((pException instanceof InvocationTargetException) || (pException instanceof PersistenceException) || (this.cause instanceof PersistenceException) || (this.cause instanceof InvocationTargetException) || (pException instanceof RuntimeException)) { if (this.cause instanceof PersistenceException) { this.cause = this.cause.getCause(); } if ((this.cause != null) && (this.cause.getCause() != null)) { this.cause = this.cause.getCause(); } if ((this.cause != null) && (this.cause instanceof ConstraintViolationException)) { this.cause = this.cause.getCause(); } if ((this.cause != null) && (this.cause instanceof GenericJDBCException)) { this.cause = this.cause.getCause(); } } else { break; } if ((this.cause == null) || (this.cause.getCause() == null)) { break; } } if (pLanguage != null) { this.language = pLanguage.toLowerCase(); } } /** * Metodo que entrega un mensaje tecnico. * * @return String */ public String getTechnicalMessage() { if (!(this.exception instanceof APPException)) { return ""; } String message = this.exception.getMessage(); StackTraceElement[] stack = this.exception.getStackTrace(); if (this.cause != null) { message = this.cause.getMessage(); stack = this.cause.getStackTrace(); } for (StackTraceElement element : stack) { if (element.getClassName().indexOf("com.fp") > -1) { message += " " + element.getClassName() + " : " + element.getLineNumber(); break; } } return message; } /** * Metodo que entrega el StackTrace de la Excepcion. * * @return */ public String getStackTrace() { try { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); StackTraceElement[] ele; if (this.cause != null) { // pw.println(this.cause.getMessage()); ele = this.cause.getStackTrace(); // this.cause.printStackTrace(pw); } else { // pw.println(this.exception.getMessage()); ele = this.exception.getStackTrace(); // this.exception.printStackTrace(pw); } String msg = this.getTechnicalMessage(); if (msg.length() > 200) { msg = msg.substring(0, 200); } pw.println(msg); boolean first = true; for (StackTraceElement element : ele) { if (first) { pw.println(element.getClassName() + "." + element.getMethodName() + ":" + element.getLineNumber()); first = false; continue; } if (element.getClassName().indexOf("com.fp") > -1) { pw.println(" " + element.getClassName() + "." + element.getMethodName() + ":" + element.getLineNumber()); } } String data = sw.toString(); pw.close(); return data; } catch (Exception e) { return null; } } /** * Metodo que entrega el mensaje de usuario. * * @return String */ public String getUserMessage() { String message = this.exception.getMessage(); Locale locale = new Locale(this.language, Locale.getDefault().getCountry(), this.getVariant()); boolean exist = false; if (this.exception instanceof APPException) { message = ((APPException) this.exception).getUserMessage(this.language); exist = true; } if (this.cause instanceof APPException) { message = ((APPException) this.cause).getUserMessage(this.language); exist = true; } if (!exist) { ExceptionManager man = this.getExceptionManager(); if (man == null) { try { ResourceBundle bdl = ResourceBundle.getBundle("userMessages", locale); message = bdl.getString(this.exception.getClass().getName()); } catch (MissingResourceException e) { message = this.exception.getMessage(); } } else { man.setLocale(locale); message = man.getUserMessage(this.cause != null ? this.cause : this.exception); } } return message; } /** * Metodo que entrega la clase que se encarga del manejo de la excepcion. * * @return ExceptionManager */ private ExceptionManager getExceptionManager() { try { ExceptionsProperties param = ExceptionsProperties.getInstance(); String className = ""; if (this.cause == null) { className = param.getValue(this.exception.getClass().getName()); } else { className = param.getValue(this.cause.getClass().getName()); } return (ExceptionManager) Class.forName(className).newInstance(); } catch (Exception e) { return null; } } /** * Metodo que entrega el codigo de la excepcion. * * @return String */ public String getCode() { String code = this.exception.getClass().getName(); if (this.cause != null) { code = this.cause.getClass().getName(); if ((this.cause instanceof BatchUpdateException) || (this.cause instanceof SQLException)) { Integer i = ((SQLException) this.cause).getErrorCode(); code = i.toString(); if (code.compareTo("0") == 0) { // Si no puede obtener una coneccion de base devuelve el codigo de error 0 code = "99999"; } } } else if (this.exception instanceof SQLException) { Integer i = ((SQLException) this.exception).getErrorCode(); code = i.toString(); if (code.compareTo("0") == 0) { // Si no puede obtener una coneccion de base devuelve el codigo de error 0 code = "99999"; } } if (this.exception instanceof APPException) { code = ((APPException) this.exception).getCode(); } if (this.cause instanceof APPException) { code = ((APPException) this.cause).getCode(); } return code; } /** * Metodo que entrega la variante del idioma. * * @return String */ private String getVariant() { String code = ""; for (int i = 0; i < this.getCode().length(); i++) { if (Character.isDigit(this.getCode().charAt(i))) { break; } else { code += this.getCode().charAt(i); } } return code; } /** * Entrega el valor de: ExceptionHandler.java * * @return boolean */ public boolean isAppexception() { return this.appexception; } }