001    /*
002     @license.text@
003      */
004    package biz.hammurapi.metrics;
005    
006    import java.lang.reflect.InvocationHandler;
007    import java.lang.reflect.Method;
008    import java.lang.reflect.Proxy;
009    
010    import biz.hammurapi.wrap.WrapperHandler;
011    
012    /**
013     * Wraps objects to measure object method's performance.
014     * 
015     * @author Pavel Vlasov
016     *
017     * @version $Revision: 1.3 $
018     */
019    public class MeasuringWrapper {
020    
021            private MeasurementConsumer consumer;
022    
023            /**
024             * 
025             */
026            public MeasuringWrapper(MeasurementConsumer consumer) {
027                    this.consumer=consumer;
028            }
029            
030            /**
031             * Wraps object to measure methods performance.
032             * @param obj Object to be wrapped.
033             * @return proxy object which implements all interfaces of the original object.
034             */
035            public Object wrap(final Object obj) {
036                    return wrap(obj, consumer);
037            }
038            
039            /**
040             * Wraps object to measure methods performance.
041             * @param obj Object to be wrapped.
042             * @param consumer Metric consumer.
043             * @return proxy object which implements all interfaces of the original object.
044             */
045            public static Object wrap(final Object obj, final MeasurementConsumer consumer) {
046                    return Proxy.newProxyInstance(
047                                    obj.getClass().getClassLoader(),
048                                    WrapperHandler.getClassInterfaces(obj.getClass()),
049                                    new InvocationHandler() {
050    
051                                            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                                             
052                                                    long start=System.currentTimeMillis();
053                                                    try {
054                                                            return method.invoke(obj, args);                                                        
055                                                    } finally {
056                                                            long finish=System.currentTimeMillis();
057                                                            consumer.addMeasurement(obj.getClass().toString()+": "+method, finish-start, finish);
058                                                    }
059                                            }
060                                            
061                                    });
062            }
063    
064    }