001    /** 
002     * 
003     * Copyright 2004 Protique Ltd
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * You may obtain a copy of the License at 
008     * 
009     * http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS, 
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
014     * See the License for the specific language governing permissions and 
015     * limitations under the License. 
016     * 
017     **/
018    
019    package org.activemq.util;
020    
021    import EDU.oswego.cs.dl.util.concurrent.Executor;
022    import org.apache.commons.logging.Log;
023    import org.apache.commons.logging.LogFactory;
024    
025    import java.lang.reflect.InvocationHandler;
026    import java.lang.reflect.Method;
027    import java.lang.reflect.Proxy;
028    
029    /**
030     * A proxy to some service which offers an asynchronous way to invoke methods which
031     * are void and don't throw exceptions. Calling the method results in a command object
032     * being added to a queue for later execution.
033     *
034     * @version $Revision: 1.1.1.1 $
035     */
036    public class AsyncProxy implements InvocationHandler {
037    
038        private Object realObject;
039        private Executor executor;
040        private Log log;
041    
042        public static Object createProxy(Class interfaceType, Object realObject, Executor executor) {
043            return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
044                    new Class[]{interfaceType},
045                    new AsyncProxy(realObject, executor));
046        }
047    
048        public AsyncProxy(Object realObject, Executor executor) {
049            this(realObject, executor, LogFactory.getLog(AsyncProxy.class));
050        }
051    
052        public AsyncProxy(Object realObject, Executor executor, Log log) {
053            this.realObject = realObject;
054            this.executor = executor;
055            this.log = log;
056        }
057    
058        public AsyncProxy(Executor executor, Log log) {
059            this.executor = executor;
060            this.log = log;
061        }
062    
063        public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
064            if (method.getReturnType() == void.class) {
065                executor.execute(new Runnable() {
066                    public void run() {
067                        doAsyncMethodInvoke(method, args);
068                    }
069                });
070                return null;
071            }
072            else {
073                return method.invoke(realObject, args);
074            }
075        }
076    
077        protected void doAsyncMethodInvoke(Method method, Object[] args) {
078            try {
079                method.invoke(realObject, args);
080            }
081            catch (Throwable e) {
082                log.warn("Caught exception: " + e, e);
083            }
084        }
085    }