Mega Code Archive

 
Categories / Java / Reflection
 

A dynamic proxy adapter which allows overriding several methods of a target proxy

/*  * Copyright 2006-2007 The Scriptella Project Team.  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */ import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /**  * A dynamic proxy adapter which allows overriding several  * methods of a target proxy.  * <p>To create a proxy adapter for Interface, create subclass of  * ProxyAdapter and define methods from Interface you want to handle,  * other methods invocations will be failed.  *  * @author Fyodor Kupolov  * @version 1.0  */ public class ProxyAdapter<T> {     private final T proxy;     @SuppressWarnings("unchecked")     public ProxyAdapter(Class... interfaces) {         proxy = (T) Proxy.newProxyInstance(getClass().getClassLoader(), interfaces, new InvocationHandler() {             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                 Method m;                 try {                     //Determine if the method has been defined in a subclass                     m = ProxyAdapter.this.getClass().getMethod(method.getName(), method.getParameterTypes());                     m.setAccessible(true);                 } catch (Exception e) { //if not found                     throw new UnsupportedOperationException(method.toString(), e);                 }                 //Invoke the method found and return the result                 try {                     return m.invoke(ProxyAdapter.this, args);                 } catch (InvocationTargetException e) {                     throw e.getCause();                 }             }         });     }     /**      * @return proxy instance implementing T.      */     public T getProxy() {         return proxy;     }     /**      * Usage example      */     public static void main(String[] args) throws Exception {         //Create adapter for Appendable         ProxyAdapter<Appendable> pa = new ProxyAdapter(Appendable.class) {             private StringBuilder sb = new StringBuilder();             //Override only 2 methods: append and toString             public Appendable append(char c) {                 System.out.println("Proxy append(char c) method. Append "+c);                 sb.append(c);                 return (Appendable) getProxy();             }             public String toString() {                 return "Proxy toString method: "+sb;             }         };         final Appendable a = pa.getProxy();         a.append('1').append('2');         System.out.println("a.toString() = " + a.toString());         //this invocation fails because no method has been created         a.append("Not implemented");     } }