001    package org.shiftone.jrat.core.proxy;
002    
003    
004    import java.lang.reflect.InvocationHandler;
005    import java.lang.reflect.InvocationTargetException;
006    import java.lang.reflect.Method;
007    import java.lang.reflect.Proxy;
008    import java.util.Hashtable;
009    import java.util.Map;
010    
011    
012    /**
013     * @author jeff@shiftone.org (Jeff Drost)
014     * @deprecated Basicly Java 1.4 built in AOP.
015     */
016    public class JRatInvocationHandler implements InvocationHandler {
017    
018        private static long handlers = 0;
019        private final long instance;
020        private boolean infect = true;
021        private Object target = null;
022        private Class iface = null;
023        private String className = null;
024    
025        public JRatInvocationHandler(Object target, Class iface, boolean infect) {
026    
027            Class targetClass = target.getClass();
028    
029            this.infect = infect;
030            this.iface = iface;
031            this.target = target;
032    
033            if (Proxy.isProxyClass(targetClass)) {
034                className = iface.getName();          // log to iface rather than $Proxy
035            } else {
036                className = targetClass.getName();    // non-jdbc class
037            }
038    
039            synchronized (JRatInvocationHandler.class) {
040                handlers++;
041    
042                instance = handlers;
043            }
044        }
045    
046    
047        private static final boolean returnsInterface(Method method) {
048            return (method.getReturnType().isInterface());
049        }
050    
051    
052        private static final boolean returnsVoid(Method method) {
053            return (method.getReturnType().equals(Void.TYPE));
054        }
055    
056    
057        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
058    //
059    //        MethodHandler methodHandler = null;
060    //        Object        result        = null;
061    //        long          start         = 0;
062    //        boolean       success       = false;
063    //
064    //        methodHandler = HandlerFactory.getMethodHandler(className, method);
065    //
066    //        try
067    //        {
068    //            methodHandler.onMethodStart(target);
069    //
070    //            start   = System.currentTimeMillis();
071    //            result  = doInvoke(method, args);
072    //            success = true;
073    //
074    //            methodHandler.onMethodFinish(target, System.currentTimeMillis() - start, null);
075    //
076    //            return result;
077    //        }
078    //        catch (Throwable throwable)
079    //        {
080    //            methodHandler.onMethodFinish(target, System.currentTimeMillis() - start, throwable);
081    //
082    //            throw throwable;
083    //        }
084            return null; ///
085        }
086    
087    
088        public Object doInvoke(Method method, Object[] args) throws Throwable {
089    
090            Object result = null;
091            Throwable toRethrow = null;
092    
093            try {
094                result = method.invoke(target, args);
095            }
096            catch (InvocationTargetException e) {
097                toRethrow = e.getTargetException();
098    
099                if (toRethrow == null)    // unlikely
100                {
101                    toRethrow = e;
102                }
103            }
104            catch (Throwable e) {
105                toRethrow = e;
106            }
107    
108            if (toRethrow != null) {
109                throw toRethrow;
110            }
111    
112            // -------------------------------------------------------------
113            // the result is not null, and the method that was called returns
114            // interface type, then wrap the returned object in a proxy also
115            if ((result != null) && (infect)) {
116                if (returnsInterface(method)) {
117                    result = JRatInvocationHandler.safeGetTracedProxy(result, method.getReturnType());
118                }
119            }
120    
121            return result;
122        }
123    
124    
125        public static Object safeGetTracedProxy(Object target, Class iface) {
126    
127            Object proxy = target;
128    
129            try {
130                proxy = getTracedProxy(target, iface);
131            }
132            catch (Exception e) {
133    
134                // LOG.error("error creating jdbc", e);
135            }
136    
137            return proxy;
138        }
139    
140    
141        public static Object getTracedProxy(Object target, Class iface) {
142    
143            if (target == null) {
144                throw new NullPointerException("target Object is null");
145            }
146    
147            if (iface == null) {
148                throw new NullPointerException("iface Class is null");
149            }
150    
151            if (!iface.isInterface()) {
152                throw new IllegalArgumentException("iface Class is not an interface");
153            }
154    
155            if (!iface.isAssignableFrom(target.getClass())) {
156                throw new IllegalArgumentException("target does not implement supplied interface : " + iface.getName());
157            }
158    
159            InvocationHandler handler = null;
160            Object proxy = null;
161            ClassLoader classLoader = null;
162    
163            classLoader = target.getClass().getClassLoader();
164            handler = new JRatInvocationHandler(target, iface, true);
165            proxy = Proxy.newProxyInstance(classLoader, new Class[]{iface}, handler);
166    
167            return proxy;
168        }
169    
170    
171        public static void main(String[] args) {
172    
173            Map m = new Hashtable();
174            Map m2 = (Map) JRatInvocationHandler.getTracedProxy(m, Map.class);
175            Class mc = Map.class;
176    
177            for (int i = 0; i < 500000; i++) {
178                m.put("n=" + i, "tste");
179            }
180    
181            m2.containsValue("novalue");
182            m2.put(null, null);
183    
184            if (mc.isAssignableFrom(m.getClass())) {
185                System.out.println("Map.class isAssignableFrom HashMap.class");
186            }
187    
188            if (m.getClass().isAssignableFrom(mc)) {
189                System.out.println("HashMap.class isAssignableFrom Map.class");
190            }
191    
192            m2.put("test", "123");
193    
194            Object z = new String[5];
195    
196            System.out.println(z.getClass().getName());
197    
198            z = new Double(1);
199    
200            System.out.println(z.getClass().getName());
201        }
202    }