/*
 * Copyright (C) 2017 Alex Stockinger
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package fi.testee.interceptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.EJBContext;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import static fi.testee.interceptor.TestInterceptor.Type.AROUND_INVOKE;
import static fi.testee.interceptor.TestInterceptor.Type.POST_CONSTRUCT;
import static fi.testee.interceptor.TestInterceptor.Type.PRE_DESTROY;
import static org.junit.Assert.assertNotNull;

@UseInterceptor
@Interceptor
public class TestInterceptor {
    private static final Logger LOG = LoggerFactory.getLogger(TestInterceptor.class);

    public enum Type {
        AROUND_INVOKE,
        POST_CONSTRUCT,
        PRE_DESTROY
    }

    public static class Invocation {
        public final Object target;
        public final Method method;
        public final Type type;

        public Invocation(final Object target, final Method method, final Type type) {
            this.target = target;
            this.method = method;
            this.type = type;
        }
    }

    public static final List<Invocation> INVOCATIONS = new ArrayList<>();

    @PostConstruct
    public Object logPostConstruct(final InvocationContext invocationContext) throws Exception {
        LOG.info("PostConstruct: {} {}", invocationContext.getTarget(), invocationContext.getMethod());
        INVOCATIONS.add(new Invocation(invocationContext.getTarget(), invocationContext.getMethod(), POST_CONSTRUCT));
        return invocationContext.proceed();
    }

    @PreDestroy
    public Object logPreDestroy(final InvocationContext invocationContext) throws Exception {
        LOG.info("PreDestroy: {} {}", invocationContext.getTarget(), invocationContext.getMethod());
        INVOCATIONS.add(new Invocation(invocationContext.getTarget(), invocationContext.getMethod(), PRE_DESTROY));
        return invocationContext.proceed();
    }

    @AroundInvoke
    public Object logMethodEntry(final InvocationContext invocationContext) throws Exception {
        LOG.info("AroundInvoke: {} {}", invocationContext.getTarget(), invocationContext.getMethod());
        INVOCATIONS.add(new Invocation(invocationContext.getTarget(), invocationContext.getMethod(), AROUND_INVOKE));
        return invocationContext.proceed();
    }
}

@@ -761,71 +761,8 @@
 oy;%0A
-import javax.annotation.Resource;%0Aimport javax.ejb.EJBContext;%0A
 impo
@@ -796,16 +796,16 @@
 Invoke;%0A
+
 import j
@@ -1181,54 +1181,8 @@
 ROY;
-%0Aimport static org.junit.Assert.assertNotNull;
 %0A%0A@U
@@ -1563,16 +1563,69 @@
 pe type;
+%0A        public final StackTraceElement%5B%5D stacktrace;
 %0A%0A      
@@ -1799,24 +1799,89 @@
 ype = type;%0A
+            stacktrace = Thread.currentThread().getStackTrace();%0A
         %7D%0A  
@@ -2068,32 +2068,33 @@
 ows Exception %7B%0A
+%0A
         LOG.info
@@ -2937,32 +2937,117 @@
 t.getMethod());%0A
+        if (invocationContext.getMethod().getDeclaringClass() != Object.class) %7B%0A    
         INVOCATI
@@ -3144,24 +3144,34 @@
 D_INVOKE));%0A
+        %7D%0A
         retu

Test now resistant against changes in loglevel (toString could have been called in higher log levels causing tests to fail)