/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE file at the root of the source * tree and available online at * * https://github.com/keeps/roda */ package org.roda.wui.common.client; import java.util.logging.Level; import java.util.logging.Logger; import org.roda.core.data.exceptions.AuthorizationDeniedException; import org.roda.wui.client.common.UserLogin; import org.roda.wui.common.client.widgets.Toast; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT.UncaughtExceptionHandler; import com.google.gwt.logging.client.DevelopmentModeLogHandler; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.rpc.IsSerializable; /** * @author Luis Faria * */ public class ClientLogger implements IsSerializable { // log levels /** * Trace level */ public static final int TRACE = 0; /** * Debug level */ public static final int DEBUG = 1; /** * Information level */ public static final int INFO = 2; /** * Warning level */ public static final int WARN = 3; /** * Error level */ public static final int ERROR = 4; /** * Fatal error level */ public static final int FATAL = 5; private static final int CURRENT_LOG_LEVEL = TRACE; private static final boolean SHOW_ERROR_MESSAGES = false; private static final String LOGGING_ERROR = "Error while logging another error"; private String classname; private Logger logger; /** * Create a new client logger */ public ClientLogger() { logger = Logger.getLogger(""); logger.addHandler(new DevelopmentModeLogHandler()); } /** * Create a new client logger * * @param classname */ public ClientLogger(String classname) { this.classname = classname; logger = Logger.getLogger(classname); logger.addHandler(new DevelopmentModeLogHandler()); } /** * Set the uncaught exception handler */ public static void setUncaughtExceptionHandler() { GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { ClientLogger clientlogger = new ClientLogger("Uncaught"); @Override public void onUncaughtException(Throwable e) { clientlogger.fatal("Uncaught Exception: [" + e.getClass().getName() + "] " + e.getMessage(), e); } }); } /** * Log a trace message * * @param message */ public void trace(final String message) { if (CURRENT_LOG_LEVEL <= TRACE) { AsyncCallback<Void> errorcallback = new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { GWT.log(message, null); GWT.log(LOGGING_ERROR, caught); } @Override public void onSuccess(Void result) { // do nothing } }; ClientLoggerService.Util.getInstance().trace(classname, message, errorcallback); } } /** * Log a trace message and error * * @param message * @param error */ public void trace(final String message, final Throwable error) { if (CURRENT_LOG_LEVEL <= TRACE) { AsyncCallback<Void> errorcallback = new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { GWT.log(message, error); GWT.log(LOGGING_ERROR, caught); } @Override public void onSuccess(Void result) { GWT.log(message, error); } }; ClientLoggerService.Util.getInstance().trace(classname, message, errorcallback); } } /** * Log a debug message * * @param message */ public void debug(final String message) { GWT.log(message); if (CURRENT_LOG_LEVEL <= DEBUG) { AsyncCallback<Void> errorcallback = new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { GWT.log(message, null); GWT.log(LOGGING_ERROR, caught); } @Override public void onSuccess(Void result) { // do nothing } }; ClientLoggerService.Util.getInstance().debug(classname, message, errorcallback); } } /** * Log a debug message and error * * @param object * @param error */ public void debug(final String object, final Throwable error) { if (CURRENT_LOG_LEVEL <= DEBUG) { AsyncCallback<Void> errorcallback = new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { GWT.log(object, error); GWT.log(LOGGING_ERROR, caught); } @Override public void onSuccess(Void result) { // do nothing GWT.log(object, error); } }; ClientLoggerService.Util.getInstance().debug(classname, object, errorcallback); } } /** * Log a information message * * @param message */ public void info(final String message) { if (CURRENT_LOG_LEVEL <= INFO) { AsyncCallback<Void> errorcallback = new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { GWT.log(message, null); GWT.log(LOGGING_ERROR, caught); } @Override public void onSuccess(Void result) { // do nothing } }; ClientLoggerService.Util.getInstance().info(classname, message, errorcallback); } } /** * Log an information message and error * * @param message * @param error */ public void info(final String message, final Throwable error) { if (CURRENT_LOG_LEVEL <= INFO) { AsyncCallback<Void> errorcallback = new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { GWT.log(message, error); GWT.log(LOGGING_ERROR, caught); } @Override public void onSuccess(Void result) { // do nothing GWT.log(message, error); } }; ClientLoggerService.Util.getInstance().info(classname, message, errorcallback); } } /** * Log a warning message * * @param message */ public void warn(final String message) { if (CURRENT_LOG_LEVEL <= WARN) { AsyncCallback<Void> errorcallback = new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { GWT.log(message, null); GWT.log(LOGGING_ERROR, caught); } @Override public void onSuccess(Void result) { // do nothing } }; ClientLoggerService.Util.getInstance().warn(classname, message, errorcallback); } } /** * Log a warning message and error * * @param message * @param error */ public void warn(final String message, final Throwable error) { if (CURRENT_LOG_LEVEL <= WARN) { AsyncCallback<Void> errorcallback = new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { GWT.log(message, error); GWT.log(LOGGING_ERROR, caught); } @Override public void onSuccess(Void result) { GWT.log(message, error); } }; ClientLoggerService.Util.getInstance().warn(classname, message, errorcallback); } } /** * Log an error message * * @param message */ public void error(final String message) { if (CURRENT_LOG_LEVEL <= ERROR) { AsyncCallback<Void> errorcallback = new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { GWT.log(message, null); GWT.log(LOGGING_ERROR, caught); } @Override public void onSuccess(Void result) { // do nothing } }; GWT.log(message, null); ClientLoggerService.Util.getInstance().error(classname, message, errorcallback); if (SHOW_ERROR_MESSAGES) { Toast.showError(message); } } } /** * Log an error message and error * * @param message * @param error */ public void error(final String message, final Throwable error) { // FIXME should this be done if internal authentication is being used? I // don't think so if (error instanceof AuthorizationDeniedException) { UserLogin.getInstance().showSuggestLoginDialog(); } else if (CURRENT_LOG_LEVEL <= ERROR && error != null) { AsyncCallback<Void> errorcallback = new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { logger.log(Level.SEVERE, message, error); logger.log(Level.SEVERE, LOGGING_ERROR, caught); } @Override public void onSuccess(Void result) { logger.log(Level.SEVERE, message, error); } }; String errorDetails = extractErrorDetails(error); ClientLoggerService.Util.getInstance().error(classname, message + ", error: " + errorDetails, errorcallback); if (SHOW_ERROR_MESSAGES) { Toast.showError(message, error.getMessage() + (error.getCause() != null ? "\nCause: " + error.getCause().getMessage() : "")); } } } private String extractErrorDetails(final Throwable error) { StringBuilder b = new StringBuilder(); Throwable e = error; while (e != null) { b.append("[").append(e.getClass().getName()).append("] ").append(e.getMessage()); StackTraceElement[] stackTrace = e.getStackTrace(); if (stackTrace != null) { for (StackTraceElement stackTraceElement : stackTrace) { b.append("\n").append(stackTraceElement.toString()); } } e = e.getCause(); } return b.toString(); } /** * Log a fatal message * * @param message */ public void fatal(final String message) { if (CURRENT_LOG_LEVEL <= FATAL) { AsyncCallback<Void> errorcallback = new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { GWT.log(message, null); GWT.log(LOGGING_ERROR, caught); } @Override public void onSuccess(Void result) { // do nothing } }; GWT.log(message); logger.log(Level.SEVERE, message); ClientLoggerService.Util.getInstance().fatal(classname, message, errorcallback); if (SHOW_ERROR_MESSAGES) { Toast.showError(message); } } } /** * Log a fatal message and error * * @param message * @param error */ public void fatal(final String message, final Throwable error) { if (CURRENT_LOG_LEVEL <= FATAL) { AsyncCallback<Void> errorcallback = new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { GWT.log(message, error); GWT.log(LOGGING_ERROR, caught); logger.log(Level.SEVERE, message, error); } @Override public void onSuccess(Void result) { GWT.log(message, error); logger.log(Level.SEVERE, message, error); } }; ClientLoggerService.Util.getInstance().fatal(classname, message, errorcallback); if (SHOW_ERROR_MESSAGES) { Toast.showError(message, error.getMessage() + (error.getCause() != null ? "\nCause: " + error.getCause().getMessage() : "")); } } } /** * Get logging class name * * @return the name of the class being logged */ public String getClassname() { return classname; } /** * Set class name * * @param classname * the name of class being logged */ public void setClassname(String classname) { this.classname = classname; } }