/*
 * Copyright 2015, Red Hat, Inc. and individual contributors as indicated by the
 * @author tags. See the copyright.txt file in the distribution for a full
 * listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This software is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this software; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
 * site: http://www.fsf.org.
 */

package org.zanata.exception.handler;

import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent;
import org.apache.deltaspike.core.api.scope.WindowScoped;
import org.apache.deltaspike.core.util.ContextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zanata.ui.faces.FacesMessages;
import org.zanata.util.FacesNavigationUtil;
import org.zanata.util.UrlUtil;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;

/**
 * Base handler for all exceptions. N.B. this will handle exceptions from both
 * JSF and REST. For REST exceptions, this happens before REST ExceptionMapper
 * is called so we need to be careful not to use any jsf specific beans. e.g.
 * FacesMessages which is in WindowScoped.
 *
 * @author Patrick Huang <a href="mailto:pahuang@redhat.com">pahuang@redhat.com</a>
 */
public abstract class AbstractExceptionHandler {
    private static final Logger log =
            LoggerFactory.getLogger(AbstractExceptionHandler.class);
    @Inject
    protected FacesMessages messages;
    @Inject
    protected UrlUtil urlUtil;

    protected final <T extends Throwable> void handle(ExceptionEvent<T> event,
            LogLevel logLevel,
            FacesMessage.Severity severity,
            String messageKey,
            Object... messageArgs) {
        handle(event, logLevel, urlUtil.genericErrorPage(), severity,
                messageKey, messageArgs);
    }

    protected final <T extends Throwable> void handle(ExceptionEvent<T> event,
            LogLevel logLevel,
            String redirectUrl, FacesMessage.Severity severity,
            String messageKey,
            Object... messageArgs) {
        logException(logLevel, event.getException());

        if (ContextUtils.isContextActive(WindowScoped.class)) {
            messages.clear();
            messages.addFromResourceBundle(severity, messageKey, messageArgs);
            urlUtil.redirectTo(redirectUrl);

            // required - "stops" the JSF lifecycle
            FacesContext.getCurrentInstance().responseComplete();
        }
        // no other ExceptionHandler should handle this exception...
        event.handled();
    }

    protected static <T extends Throwable> void logException(LogLevel logLevel,
            T exception) {
        String currentViewId = FacesNavigationUtil.getCurrentViewId();

        switch (logLevel) {
            case Trace:
                log.trace("exception happened in view: {}", currentViewId,
                        exception);
                break;
            case Debug:
                log.debug("exception happened in view: {}", currentViewId,
                        exception);
                break;
            case Warn:
                log.warn("exception happened in view: {}", currentViewId,
                        exception);
                break;
            case Error:
                log.error("exception happened in view: {}", currentViewId,
                        exception);
                break;
        }
    }

    static enum LogLevel {
        Trace, Debug, Warn, Error
    }
}

@@ -1376,16 +1376,50 @@
 lUtil;%0A%0A
+import javax.annotation.Nullable;%0A
 import j
@@ -3338,24 +3338,42 @@
 xception) %7B%0A
+        @Nullable%0A
         Stri
@@ -3431,25 +3431,24 @@
 ewId();%0A
-%0A
         
 switch (
@@ -3443,51 +3443,57 @@
     
-switch (logLevel) %7B%0A            case Trace:
+String msg;%0A        msg = currentViewId != null ?
 %0A   
@@ -3509,18 +3509,8 @@
     
-log.trace(
 %22exc
@@ -3526,36 +3526,35 @@
 ppened in view: 
-%7B%7D%22,
+%22 +
  currentViewId,%0A
@@ -3543,39 +3543,35 @@
  + currentViewId
-,%0A     
+ :%0A
                 
@@ -3562,35 +3562,33 @@
                 
-   
+%22
 exception);%0A    
@@ -3572,33 +3572,40 @@
       %22exception
-)
+ caught%22
 ;%0A              
@@ -3594,38 +3594,43 @@
 t%22;%0A        
-        break;
+switch (logLevel) %7B
 %0A           
@@ -3635,21 +3635,21 @@
    case 
-Debug
+Trace
 :%0A      
@@ -3666,86 +3666,108 @@
 log.
-debug(%22exception happened in view: %7B%7D%22, currentViewId,%0A                       
+trace(msg, exception);%0A                break;%0A            case Debug:%0A                log.debug(msg,
  exc
@@ -3850,80 +3850,12 @@
 arn(
-%22exception happened in view: %7B%7D%22, currentViewId,%0A                       
+msg,
  exc
@@ -3940,80 +3940,12 @@
 ror(
-%22exception happened in view: %7B%7D%22, currentViewId,%0A                       
+msg,
  exc
@@ -3997,23 +3997,16 @@
  %7D%0A%0A    
-static 
 enum Log

Modify log message