001    package org.javasimon.javaee;
002    
003    import javax.interceptor.AroundInvoke;
004    import javax.interceptor.InvocationContext;
005    
006    import org.javasimon.Manager;
007    import org.javasimon.SimonManager;
008    import 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")
017    public 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                            Split split = SimonManager.getStopwatch(simonName).start();
067                            try {
068                                    return context.proceed();
069                            } finally {
070                                    split.stop();
071                            }
072                    } else {
073                            return context.proceed();
074                    }
075            }
076    }