001package org.javasimon.proxy;
002
003import org.javasimon.Split;
004import org.javasimon.source.StopwatchSource;
005
006/**
007 * Stopwatch proxy factory can generate a proxy to wrap an existing class and monitor its performance.
008 * Sample usage:
009 * <pre>
010 * MonitoredInterface monitoredProxy=new StopwatchProxyFactory(monitoredImplementation).newProxy(MonitoredInterface.class);</pre>
011 * or
012 * <pre>
013 * MonitoredInterface monitoredProxy=new StopwatchProxyFactory(monitoredImplementation, new CustomProxyStopwatchSource<MonitoredInterface>()).newProxy(MonitoredInterface.class);</pre>
014 */
015public final class StopwatchProxyFactory<T> extends DelegatingProxyFactory<T> {
016        /**
017         * Stopwatch template.
018         */
019        private final StopwatchSource<DelegatingMethodInvocation<T>> stopwatchSource;
020
021        /**
022         * Constructor
023         *
024         * @param delegate Wrapped object
025         * @param stopwatchSource Stopwatch source (to configure Stopwatch naming)
026         */
027        public StopwatchProxyFactory(T delegate, StopwatchSource<DelegatingMethodInvocation<T>> stopwatchSource) {
028                super(delegate);
029                this.stopwatchSource = stopwatchSource;
030        }
031
032        /**
033         * Constructor.
034         *
035         * @param delegate Wrapped object
036         */
037        public StopwatchProxyFactory(T delegate) {
038                this(delegate, new ProxyStopwatchSource<T>());
039        }
040
041        /**
042         * Invocation handler main method.
043         */
044        @Override
045        protected Object invoke(DelegatingMethodInvocation<T> methodInvocation) throws Throwable {
046                final Split split = stopwatchSource.start(methodInvocation);
047                try {
048                        return methodInvocation.proceed();
049                } finally {
050                        split.stop();
051                }
052        }
053}