net.innig.util
Class DelegatingProxy

java.lang.Object
  extended by net.innig.util.DelegatingProxy
All Implemented Interfaces:
java.lang.reflect.InvocationHandler
Direct Known Subclasses:
LoggingProxy

public class DelegatingProxy
extends java.lang.Object
implements java.lang.reflect.InvocationHandler

Creates dynamic proxy objects which pass the methods of an interface through to a collection of delegate objects. This lets you glue together several objects into a complete implementation of an interface, or override one method of a complex object without subclassing it.

The static methods in this class take a set of interfaces and a set of delegate objects, and return a new delegating proxy object which implements all of the interfaces you passed in. When you call a particular method on the proxy object, it walks through the each of delegate objects in turn until it finds a method with an identical signature.

For example, suppose we have the following three classes:

  public interface WackyInterface
      {
      public void someMethod();
      public void anotherMethod();
      }

  public class ClassOne
      {
      public void someMethod()
          { System.out.println("called ClassOne.someMethod()"); }
      }

  public class ClassTwo
      {
      public void someMethod()
          { System.out.println("called ClassTwo.someMethod()"); }
      public void anotherMethod()
          { System.out.println("called ClassTwo.anotherMethod()"); }
      }
    
The following code...
ClassOne thingOne = new ClassOne();
  ClassTwo thingTwo = new ClassTwo();

  WackyInterface wacky = (WackyInterface) Proxy.newProxyInstance(
      WackyInterface.class,
      new Object[] { thingOne, thingTwo } );

  wacky.someMethod();
  wacky.anotherMethod();
    
...will product the output:
  called ClassOne.someMethod()
  called ClassTwo.anotherMethod()
    
The object wacky implements WackyInterface. Internally, it holds on to thingOne and thingTwo. The first call, wacky.someMethod(), gets delegated to thingOne.someMethod(). However, since thingOne doesn't have anotherMethod(), the second call passes through to thingTwo.anotherMethod().

If a method in the interface does not appear in any of the delegate objects, then by default, calling that method results in an UnsupportedOperationException. Alternatively, you can specify a final handler which takes care of calls that none of the delegates handled.

See Also:
Proxy

Field Summary
static java.lang.reflect.InvocationHandler UNSUPPORTED_OPERATION_HANDLER
           
 
Constructor Summary
DelegatingProxy(java.lang.Object[] delegates)
           
DelegatingProxy(java.lang.Object[] delegates, java.lang.reflect.InvocationHandler finalHandler)
           
 
Method Summary
 java.lang.Object invoke(java.lang.Object proxy, java.lang.reflect.Method method, java.lang.Object[] args)
           
static
<T> T
newProxyInstance(java.lang.Class<T> iface, java.lang.Object[] delegates)
           
static
<T> T
newProxyInstance(java.lang.Class<T> iface, java.lang.Object[] delegates, java.lang.reflect.InvocationHandler finalHandler)
           
static java.lang.Object newProxyInstance(java.lang.ClassLoader classLoader, java.lang.Class[] interfaces, java.lang.Object[] delegates)
           
static java.lang.Object newProxyInstance(java.lang.ClassLoader classLoader, java.lang.Class[] interfaces, java.lang.Object[] delegates, java.lang.reflect.InvocationHandler finalHandler)
           
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

UNSUPPORTED_OPERATION_HANDLER

public static final java.lang.reflect.InvocationHandler UNSUPPORTED_OPERATION_HANDLER
Constructor Detail

DelegatingProxy

public DelegatingProxy(java.lang.Object[] delegates)

DelegatingProxy

public DelegatingProxy(java.lang.Object[] delegates,
                       java.lang.reflect.InvocationHandler finalHandler)
Method Detail

newProxyInstance

public static <T> T newProxyInstance(java.lang.Class<T> iface,
                                     java.lang.Object[] delegates)

newProxyInstance

public static <T> T newProxyInstance(java.lang.Class<T> iface,
                                     java.lang.Object[] delegates,
                                     java.lang.reflect.InvocationHandler finalHandler)

newProxyInstance

public static java.lang.Object newProxyInstance(java.lang.ClassLoader classLoader,
                                                java.lang.Class[] interfaces,
                                                java.lang.Object[] delegates)

newProxyInstance

public static java.lang.Object newProxyInstance(java.lang.ClassLoader classLoader,
                                                java.lang.Class[] interfaces,
                                                java.lang.Object[] delegates,
                                                java.lang.reflect.InvocationHandler finalHandler)

invoke

public java.lang.Object invoke(java.lang.Object proxy,
                               java.lang.reflect.Method method,
                               java.lang.Object[] args)
                        throws java.lang.Throwable
Specified by:
invoke in interface java.lang.reflect.InvocationHandler
Throws:
java.lang.Throwable