001 /* 002 // This software is subject to the terms of the Common Public License 003 // Agreement, available at the following URL: 004 // http://www.opensource.org/licenses/cpl.html. 005 // Copyright (C) 2007-2007 Julian Hyde 006 // All Rights Reserved. 007 // You must accept the terms of that agreement to use this software. 008 */ 009 package mondrian.util; 010 011 import java.lang.reflect.*; 012 013 /** 014 * A class derived from <code>DelegatingInvocationHandler</code> handles a 015 * method call by looking for a method in itself with identical parameters. If 016 * no such method is found, it forwards the call to a fallback object, which 017 * must implement all of the interfaces which this proxy implements. 018 * 019 * <p>It is useful in creating a wrapper class around an interface which may 020 * change over time.</p> 021 * 022 * <p>Example: 023 * 024 * <blockquote> 025 * <pre>import java.sql.Connection; 026 * Connection connection = ...; 027 * Connection tracingConnection = (Connection) Proxy.newProxyInstance( 028 * null, 029 * new Class[] {Connection.class}, 030 * new DelegatingInvocationHandler() { 031 * protected Object getTarget() { 032 * return connection; 033 * } 034 * Statement createStatement() { 035 * System.out.println("statement created"); 036 * return connection.createStatement(); 037 * } 038 * });</pre> 039 * </blockquote> 040 * </p> 041 * 042 * @author jhyde 043 * @version $Id: //open/mondrian/src/main/mondrian/util/DelegatingInvocationHandler.java#6 $ 044 */ 045 public abstract class DelegatingInvocationHandler 046 implements InvocationHandler 047 { 048 public Object invoke( 049 Object proxy, 050 Method method, 051 Object [] args) 052 throws Throwable 053 { 054 Class clazz = getClass(); 055 Method matchingMethod; 056 try { 057 matchingMethod = 058 clazz.getMethod( 059 method.getName(), 060 method.getParameterTypes()); 061 } catch (NoSuchMethodException e) { 062 matchingMethod = null; 063 } catch (SecurityException e) { 064 matchingMethod = null; 065 } 066 try { 067 if (matchingMethod != null) { 068 // Invoke the method in the derived class. 069 return matchingMethod.invoke(this, args); 070 } 071 final Object target = getTarget(); 072 if (target == null) { 073 throw new UnsupportedOperationException( 074 "method: " + method); 075 } 076 return method.invoke( 077 target, 078 args); 079 } catch (InvocationTargetException e) { 080 throw e.getTargetException(); 081 } 082 } 083 084 /** 085 * Returns the object to forward method calls to, should the derived class 086 * not implement the method. Generally, this object will be a member of the 087 * derived class, supplied as a parameter to its constructor. 088 * 089 * <p>The default implementation returns null, which will cause the 090 * {@link #invoke(Object, java.lang.reflect.Method, Object[])} method 091 * to throw an {@link UnsupportedOperationException} if the derived class 092 * does not have the required method. 093 * 094 * @return object to forward method calls to 095 */ 096 protected Object getTarget() { 097 return null; 098 } 099 } 100 101 // End DelegatingInvocationHandler.java