package solutions.digamma.damas.logging;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
import java.util.logging.Level;

/**
 * @author Ahmad Shahwan
 */
@Logged
@Interceptor
public class LoggedInterceptor {

    @Inject
    private Logbook log;

    /**
     * No-args constructor.
     */
    public LoggedInterceptor() {
    }

    /**
     * Intercept and log a method invocation.
     *
     * @param context
     * @return
     * @throws Exception
     */
    @AroundInvoke
    public Object invoke(InvocationContext context) throws Exception {
        String name = "%s::%s".format(
                context.getClass().getName(),
                context.getMethod().getName());
        try {
            this.log.info(() -> String.format(
                    "Calling %s.", name));
            Object object = context.proceed();
            this.log.info(() -> String.format(
                    "Method %s returned successfully.", name));
            return object;
        } catch (RuntimeException e) {
            this.log.log(Level.SEVERE, e, () -> String.format(
                    "Unchecked exception @%s.", name));
            throw e;
        } catch (Exception e) {
            this.log.info(() -> String.format(
                    "Checked exception: \"%s\" @%s.", e.getMessage(), name));
            throw e;
        }
    }

    /**
     * Intercept and log bean initialization.
     *
     * @param context
     * @return
     * @throws Exception
     */
    @PostConstruct
    public Object initialize(InvocationContext context) throws Exception {
        String name = context.getMethod().getName();
        try {
            this.log.info(() -> String.format(
                    "Initializing bean of type %s.", name));
            Object object = context.proceed();
            this.log.info(() -> String.format(
                    "Bean of type %s initialized successfully.", name));
            return object;
        } catch (RuntimeException e) {
            this.log.log(Level.SEVERE, e, () -> String.format(
                    "Unchecked exception @%s.", name));
            throw e;
        } catch (Exception e) {
            this.log.info(() -> String.format(
                    "Checked exception: \"%s\" @%s.", e.getMessage(), name));
            throw e;
        }
    }

    /**
     * Intercept and log bean disposal.
     *
     * @param context
     * @return
     * @throws Exception
     */
    @PreDestroy
    public Object dispose(InvocationContext context) throws Exception {
        String name = context.getMethod().getName();
        try {
            this.log.info(() -> String.format(
                    "Disposing bean of type %s.", name));
            Object object = context.proceed();
            this.log.info(() -> String.format(
                    "Bean of type %s disposed successfully.", name));
            return object;
        } catch (RuntimeException e) {
            this.log.log(Level.SEVERE, e, () -> String.format(
                    "Unchecked exception @%s.", name));
            throw e;
        } catch (Exception e) {
            this.log.info(() -> String.format(
                    "Checked exception: \"%s\" @%s.", e.getMessage(), name));
            throw e;
        }
    }
}

@@ -259,16 +259,52 @@
 ontext;%0A
+import java.util.function.Supplier;%0A
 import j
@@ -1237,310 +1237,91 @@
   th
-is.log.log(Level.SEVERE, e, () -%3E String.format(%0A                    %22Unchecked exception @%25s.%22, name));%0A            throw e;%0A        %7D catch (Exception e) %7B%0A            this.log.info(() -%3E String.format(%0A                    %22Checked exception: %5C%22%25s%5C%22 @%25s.%22, e.getMessage(), name));%0A            throw e
+row sever(name, e);%0A        %7D catch (Exception e) %7B%0A            throw info(name, e)
 ;%0A  
@@ -1986,310 +1986,91 @@
   th
-is.log.log(Level.SEVERE, e, () -%3E String.format(%0A                    %22Unchecked exception @%25s.%22, name));%0A            throw e;%0A        %7D catch (Exception e) %7B%0A            this.log.info(() -%3E String.format(%0A                    %22Checked exception: %5C%22%25s%5C%22 @%25s.%22, e.getMessage(), name));%0A            throw e
+row sever(name, e);%0A        %7D catch (Exception e) %7B%0A            throw info(name, e)
 ;%0A  
@@ -2695,32 +2695,200 @@
 eption e) %7B%0A    
+        throw sever(name, e);%0A        %7D catch (Exception e) %7B%0A            throw info(name, e);%0A        %7D%0A    %7D%0A%0A    private Exception sever(String name, Exception e) %7B%0A
         this.log
@@ -2946,20 +2946,16 @@
         
-    
 %22Uncheck
@@ -2990,33 +2990,30 @@
         
-    throw
+return
  e;%0A    
     %7D ca
@@ -3000,37 +3000,67 @@
 turn e;%0A    
+%7D%0A%0A
     
-%7D catch (
+private Exception info(String name, 
 Exception e)
@@ -3054,36 +3054,32 @@
  Exception e) %7B%0A
-    
         this.log
@@ -3097,36 +3097,32 @@
  String.format(%0A
-    
                 
@@ -3191,30 +3191,17 @@
     
-    throw e;%0A        %7D
+return e;
 %0A   

Refactor log interceptor