1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.commons.proxy.interceptor; 19 20 import EDU.oswego.cs.dl.util.concurrent.Executor; 21 import org.apache.commons.proxy.Invocation; 22 import org.apache.commons.proxy.Interceptor; 23 24 /** 25 * A method interceptor that uses an {@link Executor} to execute the method invocation. 26 * <p/> 27 * <b>Note</b>: Only <em>void</em> methods can be intercepted using this class! Any attempts to intercept non-void 28 * methods will result in an {@link IllegalArgumentException}. If the proxy interfaces include non-void methods, try 29 * using a {@link FilteredInterceptor} along with a 30 * {@link org.apache.commons.proxy.interceptor.filter.ReturnTypeFilter} to wrap an instance of this class. 31 * 32 * <p> 33 * <b>Dependencies</b>: 34 * <ul> 35 * <li>Concurrent API version 1.3.4 or greater</li> 36 * </ul> 37 * </p> 38 * @author James Carman 39 * @since 1.0 40 */ 41 public class ExecutorInterceptor implements Interceptor 42 { 43 private final Executor executor; 44 45 public ExecutorInterceptor( Executor executor ) 46 { 47 this.executor = executor; 48 } 49 50 public Object intercept( final Invocation invocation ) throws Throwable 51 { 52 if( Void.TYPE.equals( invocation.getMethod().getReturnType() ) ) 53 { 54 // Special case for finalize() method (should not be run in a different thread)... 55 if( !( invocation.getMethod().getName().equals( "finalize" ) && 56 invocation.getMethod().getParameterTypes().length == 0 ) ) 57 { 58 executor.execute( new Runnable() 59 { 60 public void run() 61 { 62 try 63 { 64 invocation.proceed(); 65 } 66 catch( Throwable t ) 67 { 68 // What to do here? I can't convey the failure back to the caller. 69 } 70 } 71 } ); 72 return null; 73 } 74 else 75 { 76 return invocation.proceed(); 77 } 78 } 79 else 80 { 81 throw new IllegalArgumentException( "Only void methods can be executed in a different thread." ); 82 } 83 } 84 }