001package org.javasimon.javaee;
002
003import javax.interceptor.AroundInvoke;
004import javax.interceptor.InvocationContext;
005
006import org.javasimon.Manager;
007import org.javasimon.SimonManager;
008import org.javasimon.Split;
009
010/**
011 * Simon Interceptor measuring method execution time - can be used in EJB, or CDI in general.
012 *
013 * @author <a href="mailto:richard.richter@siemens-enterprise.com">Richard "Virgo" Richter</a>
014 * @since 2.3
015 */
016@SuppressWarnings("UnusedParameters")
017public class SimonInterceptor {
018        /**
019         * Default prefix for interceptor Simons if no "prefix" init parameter is used.
020         */
021        public static final String DEFAULT_INTERCEPTOR_PREFIX = "org.javasimon.business";
022
023        /**
024         * Simon name prefix - can be overridden in subclasses.
025         */
026        protected String prefix = DEFAULT_INTERCEPTOR_PREFIX;
027
028        /**
029         * Returns Simon name for the specified Invocation context.
030         * By default it contains the prefix + method name.
031         * This method can be overridden.
032         *
033         * @param context Invocation context
034         * @return fully qualified name of the Simon
035         * @since 3.1
036         */
037        protected String getSimonName(InvocationContext context) {
038                String className = context.getMethod().getDeclaringClass().getSimpleName();
039                String methodName = context.getMethod().getName();
040                return prefix + Manager.HIERARCHY_DELIMITER + className + Manager.HIERARCHY_DELIMITER + methodName;
041        }
042
043        /**
044         * Indicates whether the method invocation should be monitored.
045         * Default behavior always returns true.
046         * This method can be overridden
047         *
048         * @param context Method invocation context
049         * @return true to enable Simon, false either
050         */
051        protected boolean isMonitored(InvocationContext context) {
052                return true;
053        }
054
055        /**
056         * Around invoke method that measures the split for one method invocation.
057         *
058         * @param context invocation context
059         * @return return value from the invocation
060         * @throws Exception exception thrown from the invocation
061         */
062        @AroundInvoke
063        public Object monitor(InvocationContext context) throws Exception {
064                if (isMonitored(context)) {
065                        String simonName = getSimonName(context);
066                        try (Split ignored = SimonManager.getStopwatch(simonName).start()) {
067                                return context.proceed();
068                        }
069                } else {
070                        return context.proceed();
071                }
072        }
073}