org.jpu.patterns.proxy
Class JPUInvocationHandler

java.lang.Object
  extended byorg.jpu.patterns.proxy.JPUInvocationHandler
All Implemented Interfaces:
java.lang.reflect.InvocationHandler, java.io.Serializable
Direct Known Subclasses:
DelegatingProxy, JPUProxyAccountImpl, ProxyBean

public class JPUInvocationHandler
extends java.lang.Object
implements java.lang.reflect.InvocationHandler, java.io.Serializable

This class is designed to make writing InvocationHandler's easier and less error-prone, as well as to facilitate more efficient delegation and a more natural inheritance-based delegation model. Its features are summarized below:

The ProxyBean class extends JPUInvocationHandler and adds support for automatic implementation of simple getter and setter methods along with change tracking.

See Also:
Serialized Form

Nested Class Summary
protected static class JPUInvocationHandler.DelegationCacheValue
          Defines entries in the self-delegation cache.
protected static class JPUInvocationHandler.DelegationState
           
 
Constructor Summary
JPUInvocationHandler()
           
 
Method Summary
protected  boolean autoDelegateToSelf(java.lang.Object proxy, java.lang.reflect.Method interfaceMethod, java.lang.Object[] args)
          Returns whether self delegation is performed automatically for any matching method invocations.
protected  boolean delegate(java.lang.Object proxy, java.lang.Object target, java.lang.reflect.Method interfaceMethod, java.lang.Object[] args, java.lang.Object[] result)
          Attempts to delegate the given method invocation to "target".
protected  void doGetImplementedInterfaces(java.util.Collection dest)
          Default implementation does nothing, but subclasses can override to add to dest the Class instances of any interfaces the generated proxy should implement, in addition to those explicitly passed via the first parameter to newProxy(Class[], ClassLoader).
protected  boolean doInvoke(java.lang.Object proxy, java.lang.reflect.Method method, java.lang.Object[] args, java.lang.Object[] result)
          Overrides the method of JPUInvocationHandler.
static long getCacheHits()
          Returns the number of cache hits registered for the self-delegation cache since resetCacheCounters() was last called.
static long getCacheMisses()
          Returns the number of cache misses registered for the self-delegation cache since resetCacheCounters() was last called.
protected  java.lang.reflect.Method getCurrentInterfaceMethod()
          Returns the interface method through which the current invocation was called.
protected  java.lang.ClassLoader getDefaultClassLoader()
          Returns the ClassLoader to pass to the first parameter of Proxy.newInstance() if null is passed as the second parameter to newProxy(Class[], ClassLoader).
protected  java.lang.reflect.Method getDelegationMethod(java.lang.reflect.Method interfaceMethod)
          Alias for "getDelegationTargetMethod( interfaceMethod, getClass() )".
protected  JPUInvocationHandler.DelegationState getDelegationState()
          Returns the state of the self-delegation action that is currently in progress, or null if no self-delegation is in progress.
protected  java.lang.reflect.Method getDelegationTargetMethod(java.lang.reflect.Method interfaceMethod, java.lang.Class targetClass)
          Returns the method on the invocation handler to which invocations on the given interface method should be delegated, or null if no such method exists.
 java.lang.Class[] getInterfaces(java.lang.Class[] moreClasses)
          Returns all interfaces that this invocation handler's proxy implements.
protected  java.lang.Object getProxy()
          Returns the proxy for which this invocation handler is currently handling an invocation.
 void initializeProxy(java.lang.Object newProxy)
          Default implementation does nothing, but subclasses can override to perform any sort of initialization on a newly-generated proxy instance.
 java.lang.Object invoke(java.lang.Object proxy, java.lang.reflect.Method interfaceMethod, java.lang.Object[] args)
          Method required by the InvocationHandler interface.
 java.lang.Object newProxy()
          Convenience alias for "newProxy(null)".
 java.lang.Object newProxy(java.lang.Class[] moreClasses)
          Convenience alias for "newProxy(moreClasses, null)".
 java.lang.Object newProxy(java.lang.Class[] moreClasses, java.lang.ClassLoader loader)
          Uses Proxy.newProxyInstance() to generate a proxy instance backed by this invocation handler.
static void resetCacheCounters()
          Resets the counters used to measure the hit and miss rate of the self-delegation cache.
protected  void rethrow(java.lang.Object proxy, java.lang.reflect.Method interfaceMethod, java.lang.Object[] args, java.lang.Throwable t)
          Rethrows exceptions thrown from doInvoke(Object,Method,Object[],Object[]).
protected  void setDelegationState(JPUInvocationHandler.DelegationState delegationState)
          Sets the current self-delegation state to the given value.
protected  void throwUnhandledException(java.lang.reflect.Method method)
          Throws an unchecked exception indiciating that the given method was not handled by the invocation handler.
protected  void throwUnlistedException(java.lang.Object proxy, java.lang.reflect.Method interfaceMethod, java.lang.Object[] args, java.lang.Throwable t)
          This method is called when an exception is thrown from doInvoke(Object,Method,Object[],Object[]) that is an illegal checked exception for the interface method that was invoked; that is, the exception is not assignment compatible with any exception class listed in the interface method's throws clause.
protected  boolean wouldDelegationInfinitelyRecurse(JPUInvocationHandler.DelegationState state, java.lang.Object target, java.lang.reflect.Method interfaceMethod)
          Internal method used to ensure that a delegation call would not result in infinite recursion.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

JPUInvocationHandler

public JPUInvocationHandler()
Method Detail

throwUnhandledException

protected void throwUnhandledException(java.lang.reflect.Method method)
Throws an unchecked exception indiciating that the given method was not handled by the invocation handler. The default implementation throws UnhandledMethodCallException, but subclasses are free to override.


invoke

public java.lang.Object invoke(java.lang.Object proxy,
                               java.lang.reflect.Method interfaceMethod,
                               java.lang.Object[] args)
                        throws java.lang.Throwable
Method required by the InvocationHandler interface. Calls doInvoke(Object,Method,Object[],Object[]), catching any exceptions thrown from it and rethrowing them using the rethrow(Object,Method,Object[],Throwable) method (which subclasses can override). If doInvoke() returns false (meaning the invocation was not handled), throws an exception by calling throwUnhandledException(Method), which subclasses can override.

Specified by:
invoke in interface java.lang.reflect.InvocationHandler
Throws:
java.lang.Throwable

rethrow

protected void rethrow(java.lang.Object proxy,
                       java.lang.reflect.Method interfaceMethod,
                       java.lang.Object[] args,
                       java.lang.Throwable t)
                throws java.lang.Throwable
Rethrows exceptions thrown from doInvoke(Object,Method,Object[],Object[]). If the given Throwable is an Error or RuntimeException, it is rethrown as is. Else if the exception is of a type that is compatible with the interface method's throws clause, it is rethrown as is. Else throwUnhandledException(Method) is called, which subclasses can override.

Throws:
java.lang.Throwable

throwUnlistedException

protected void throwUnlistedException(java.lang.Object proxy,
                                      java.lang.reflect.Method interfaceMethod,
                                      java.lang.Object[] args,
                                      java.lang.Throwable t)
                               throws java.lang.Throwable
This method is called when an exception is thrown from doInvoke(Object,Method,Object[],Object[]) that is an illegal checked exception for the interface method that was invoked; that is, the exception is not assignment compatible with any exception class listed in the interface method's throws clause. This method must throw either an unchecked exception or a checked exception appearing in the throws clause of the method.

The default implementation throws a NestableRuntimeException wrapping the given Throwable, but subclasses are free to override.

Throws:
java.lang.Throwable

wouldDelegationInfinitelyRecurse

protected boolean wouldDelegationInfinitelyRecurse(JPUInvocationHandler.DelegationState state,
                                                   java.lang.Object target,
                                                   java.lang.reflect.Method interfaceMethod)
Internal method used to ensure that a delegation call would not result in infinite recursion.


autoDelegateToSelf

protected boolean autoDelegateToSelf(java.lang.Object proxy,
                                     java.lang.reflect.Method interfaceMethod,
                                     java.lang.Object[] args)
Returns whether self delegation is performed automatically for any matching method invocations. Default is true, but subclasses are free to override.


getDelegationTargetMethod

protected java.lang.reflect.Method getDelegationTargetMethod(java.lang.reflect.Method interfaceMethod,
                                                             java.lang.Class targetClass)
                                                      throws java.lang.Throwable
Returns the method on the invocation handler to which invocations on the given interface method should be delegated, or null if no such method exists. Uses caching to ensure that this lookup incurs minimal overhead.

Throws:
java.lang.Throwable

getDelegationMethod

protected java.lang.reflect.Method getDelegationMethod(java.lang.reflect.Method interfaceMethod)
                                                throws java.lang.Throwable
Alias for "getDelegationTargetMethod( interfaceMethod, getClass() )".

Throws:
java.lang.Throwable

getCacheMisses

public static long getCacheMisses()
Returns the number of cache misses registered for the self-delegation cache since resetCacheCounters() was last called.


getCacheHits

public static long getCacheHits()
Returns the number of cache hits registered for the self-delegation cache since resetCacheCounters() was last called.


resetCacheCounters

public static void resetCacheCounters()
Resets the counters used to measure the hit and miss rate of the self-delegation cache.


delegate

protected boolean delegate(java.lang.Object proxy,
                           java.lang.Object target,
                           java.lang.reflect.Method interfaceMethod,
                           java.lang.Object[] args,
                           java.lang.Object[] result)
                    throws java.lang.Throwable
Attempts to delegate the given method invocation to "target". If no matching method could be found (as determined by a call to getDelegationTargetMethod(Method,Class)), this method returns false. Else it invokes the method, setting result[0] to its return value, and returns true. Any exception thrown by the invoked method will be allowed to propagate up.

Throws:
java.lang.Throwable

getDelegationState

protected JPUInvocationHandler.DelegationState getDelegationState()
Returns the state of the self-delegation action that is currently in progress, or null if no self-delegation is in progress.


setDelegationState

protected void setDelegationState(JPUInvocationHandler.DelegationState delegationState)
Sets the current self-delegation state to the given value.


getProxy

protected java.lang.Object getProxy()
Returns the proxy for which this invocation handler is currently handling an invocation. If no invocation is in progress, this method returns null.


getCurrentInterfaceMethod

protected java.lang.reflect.Method getCurrentInterfaceMethod()
Returns the interface method through which the current invocation was called. If no invocation is in progress, this method returns null.


newProxy

public java.lang.Object newProxy()
Convenience alias for "newProxy(null)".


newProxy

public java.lang.Object newProxy(java.lang.Class[] moreClasses)
Convenience alias for "newProxy(moreClasses, null)".


getInterfaces

public java.lang.Class[] getInterfaces(java.lang.Class[] moreClasses)
Returns all interfaces that this invocation handler's proxy implements. This is a list consisting of all interfaces returned by doGetImplementedInterfaces(Collection), plus those passed via the moreClasses parameter.


newProxy

public java.lang.Object newProxy(java.lang.Class[] moreClasses,
                                 java.lang.ClassLoader loader)
Uses Proxy.newProxyInstance() to generate a proxy instance backed by this invocation handler. The generated proxy will implement all interfaces returned by getInterfaces(Class[]). Once the proxy is generated, this method calls initializeProxy(Object), which subclasses can override.

Parameters:
moreClasses - Interfaces to implement in addition to those returned by doGetImplementedInterfaces(Collection). Can be null.
loader - The ClassLoader to pass as the first parameter to Proxy.newProxyInstance(). If null, getDefaultClassLoader() is called and its return value is used as the ClassLoader.
Returns:
The generated proxy instance.

getDefaultClassLoader

protected java.lang.ClassLoader getDefaultClassLoader()
Returns the ClassLoader to pass to the first parameter of Proxy.newInstance() if null is passed as the second parameter to newProxy(Class[], ClassLoader). This methods default implementation returns "getClass().getClassLoader()", but subclasses are free to override.


initializeProxy

public void initializeProxy(java.lang.Object newProxy)
Default implementation does nothing, but subclasses can override to perform any sort of initialization on a newly-generated proxy instance.


doInvoke

protected boolean doInvoke(java.lang.Object proxy,
                           java.lang.reflect.Method method,
                           java.lang.Object[] args,
                           java.lang.Object[] result)
                    throws java.lang.Throwable
Overrides the method of JPUInvocationHandler. If autoDelegateToSelf() returns true, calls delegate(Object,Object,Method,Object[],Object[]). Returns whether the invocation was handled or not.

Throws:
java.lang.Throwable

doGetImplementedInterfaces

protected void doGetImplementedInterfaces(java.util.Collection dest)
Default implementation does nothing, but subclasses can override to add to dest the Class instances of any interfaces the generated proxy should implement, in addition to those explicitly passed via the first parameter to newProxy(Class[], ClassLoader).



Copyright (c) 2001-2003 - Apache Software Foundation