org.erights.e.elib.deflect
Class Deflector

java.lang.Object
  |
  +--org.erights.e.elib.deflect.Deflector
All Implemented Interfaces:
java.lang.reflect.InvocationHandler, Marker, PassByConstruction, Persistent, Selfless, Serializable

public class Deflector
extends Object
implements java.lang.reflect.InvocationHandler, PassByConstruction, Selfless, Persistent

Untamed: Deflectors enable E objects to implement Java interfaces, and thereby to be called by Java callers written without any knowledge of E or ELib.

You deflect an object to an interface by calling the static deflect method below. We say the result is a deflection of the original object. The result is a three layer wrapping: 1) On the outside is the deflection. This wraps 2) a Deflector, which wraps 3) the deflected object.

The deflection is actually a dynamically generated subclass of Proxy which implements both the interface being deflected to as well as Callable. Deflector itself implements PassByConstruction, Selfless, and Persistent just in case the deflected object does. The Deflection of the object implements whichever of these the deflected object does. We say the interface being deflected to is the J-Interface, and we say that Callable, and whatever subset of PassByConstruction, Selfless, and Persistent the deflection implements are the E-Interfaces.

If the J-Interface has any message definitions in common with the E-Interfaces, confusion will result. XXX This case should be automatically detected, preventing such deflections.

When a deflection is E-called (as with "E.call(...)"), the call is simply passed through to the deflected object (but with the vat context restored, in case the call is coming from a non-turn event in our hosting Runner, such as an AWT-initiated callback). To the E programmer (or the ELib programmer using only ELib mechanisms rather than corresponding Java mechanisms), the deflection is identical to the deflected object.

When a deflection is Java-called (as with "."), this is turned into a Method.invoke(java.lang.Object, java.lang.Object[]). The vat context is also restored around this.

Note that you can deflect an eventual reference, but you can't use the deflection until the deflected becomes a near reference.

XXX Deflector does not and cannot implement DeepPassByCopy, etc, since it isn't. Will this cause trouble?

Author:
Mark S. Miller
See Also:
Serialized Form

Field Summary
private static StaticMaker DeflectorMaker
           
private static Class[] EInterfaces
          See the class comment about E-Interfaces
private  Callable myDeflected
           
private  Vat myVat
          XXX Bug: Since this is transient, it must be restored to the containing Vat on revival; or perhaps it shouldn't be transient?
private static long serialVersionUID
           
 
Fields inherited from interface org.erights.e.elib.serial.PassByConstruction
HONORARY, HONORED_NAMES
 
Fields inherited from interface org.erights.e.elib.tables.Selfless
HONORARY, HONORED_NAMES
 
Fields inherited from interface org.erights.e.elib.serial.Persistent
HONORARY, HONORED_NAMES
 
Constructor Summary
private Deflector(Callable target)
          Makes a deflector which will wrap and deflect a Callable.
 
Method Summary
static Object deflect(Object target, Class face)
          Enabled: Deflects target to face by wrapping it in a Deflector, and wrapping that in a deflection (a Proxy).
 Callable getDeflected()
          Enabled: The original deflected target object.
static Callable getOptDeflected(Object proxy)
          Enabled: If proxy is a deflection, then return the deflected object.
 Object[] getSpreadUncall()
          Enabled: Uses 'DeflectorMaker(myDeflected)'
 Object invoke(Object proxy, java.lang.reflect.Method method, Object[] optArgs)
          Enabled: This is the magic method invoked by the Proxy mechanism.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

serialVersionUID

private static final long serialVersionUID

DeflectorMaker

private static final StaticMaker DeflectorMaker

EInterfaces

private static final Class[] EInterfaces
See the class comment about E-Interfaces


myDeflected

private final Callable myDeflected

myVat

private final transient Vat myVat
XXX Bug: Since this is transient, it must be restored to the containing Vat on revival; or perhaps it shouldn't be transient?

Constructor Detail

Deflector

private Deflector(Callable target)
Makes a deflector which will wrap and deflect a Callable.

Method Detail

deflect

public static Object deflect(Object target,
                             Class face)
Enabled: Deflects target to face by wrapping it in a Deflector, and wrapping that in a deflection (a Proxy).

Taming note: To be used only by InterfaceGuardSugar.coerce/2, as that's where the we check whether face is a rubber-stamping (non-Marker) interface.


getSpreadUncall

public Object[] getSpreadUncall()
Enabled: Uses 'DeflectorMaker(myDeflected)'

Specified by:
getSpreadUncall in interface Selfless

getDeflected

public Callable getDeflected()
Enabled: The original deflected target object.

getDeflected/0 must be thread safe, in order for getOptDeflected/1 to be thread safe.


getOptDeflected

public static Callable getOptDeflected(Object proxy)
Enabled: If proxy is a deflection, then return the deflected object.

Else return null.

getOptDeflected/1 must be thread safe, in order for Ref.resolution/1 to be thread safe.


invoke

public Object invoke(Object proxy,
                     java.lang.reflect.Method method,
                     Object[] optArgs)
              throws Throwable
Enabled: This is the magic method invoked by the Proxy mechanism.

If the method is either an Object method or a method declared by one of the EInterfaces, then just invoke this method directly on the deflected target object.

Otherwise, we turn it into a callAll() on the deflected target object.

XXX Currently, we only use the method's simple name, but that's fine for all objects defined in E. The only practical place this fails is remote invocation of overloaded Java methods.

Parameters:
optArgs - may be null, so we replace with an empty list.
Throwable


comments?