edu.vub.at.objects.symbiosis
Class Symbiosis

java.lang.Object
  extended byedu.vub.at.objects.symbiosis.Symbiosis

public final class Symbiosis
extends java.lang.Object

The Symbiosis class is a container for auxiliary methods pertaining to making symbiotic reflective Java invocations.

Author:
tvcutsem

Constructor Summary
Symbiosis()
           
 
Method Summary
static java.lang.Object ambientTalkToJava(ATObject atObj, java.lang.Class targetType)
          Convert an AmbientTalk object into an equivalent Java object.
private static java.lang.Object[] atArgsToJavaArgs(ATObject[] args, java.lang.Class[] types)
           
static JavaField[] getAllFields(java.lang.Object ofObject, java.lang.Class fromClass)
          Retrieve all public static or non-static fields from a given Java class (this includes fields defined in superclasses, but excludes shadowed superclass fields).
static JavaMethod[] getAllMethods(java.lang.Class fromClass, boolean isStatic)
          Retrieve all public static or non-static methods from a given Java class (this includes methods defined in superclasses).
static java.lang.reflect.Field getField(java.lang.Class fromClass, java.lang.String fieldName, boolean isStatic)
          Retrieve a field from a Java object.
static JavaMethod getMethods(java.lang.Class fromClass, java.lang.String selector, boolean isStatic)
          Retrieve all methods of a given name from a Java object.
static boolean hasField(java.lang.Class c, java.lang.String selector, boolean isStatic)
          Query whether the given Java Class contains a (non-)static field with the given selector
static boolean hasMethod(java.lang.Class c, java.lang.String selector, boolean isStatic)
          Query whether the given Java Class contains a (non-)static method with the given selector
private static ATObject invokeUniqueSymbioticConstructor(java.lang.reflect.Constructor ctor, java.lang.Object[] jArgs)
           
private static ATObject invokeUniqueSymbioticMethod(java.lang.Object symbiont, java.lang.reflect.Method javaMethod, java.lang.Object[] jArgs)
           
static ATObject javaToAmbientTalk(java.lang.Object jObj)
          Convert a Java object into an AmbientTalk object.
static ATObject readField(java.lang.Object fromObject, java.lang.Class ofClass, java.lang.String fieldName)
          Read a field from the given Java object reflectively.
static ATObject readField(java.lang.Object fromObject, java.lang.reflect.Field f)
          Read a field from the given Java object reflectively.
static ATObject symbioticInstanceCreation(java.lang.Class ofClass, ATObject[] atArgs)
          Creates a new instance of a Java class.
static ATObject symbioticInvocation(ATObject wrapper, java.lang.Object symbiont, java.lang.Class ofClass, java.lang.String selector, ATObject[] atArgs)
           
static ATObject symbioticInvocation(ATObject wrapper, java.lang.Object symbiont, java.lang.String selector, JavaMethod jMethod, ATObject[] atArgs)
          The Java method invocation algorithm is as follows: case of # of methods matching selector: 0 => XSelectorNotFound 1 => invoke the method OR XIllegalArgument, XArityMismatch, XReflectionFailure * => (case of # of methods with matching arity OR taking varargs: 0 => XSymbiosisFailure 1 => invoke the method OR XIllegalArgument, XReflectionFailure * => (case of # of methods matching 'default type' of the actual arguments: 0 => XSymbiosisFailure 1 => invoke OR XReflectionFailure * => XSymbiosisFailure)) A Java method takes a variable number of AT arguments <=> it has one formal parameter of type ATObject[]
private static java.lang.reflect.Method toInterfaceMethod(java.lang.reflect.Method m)
          Extremely vague and dirty feature of Java reflection: it can sometimes happen that a method is invoked on a private inner class via a publicly accessible interface method.
static void writeField(java.lang.Object toObject, java.lang.Class ofClass, java.lang.String fieldName, ATObject value)
          Write a field in the given Java object reflectively.
static void writeField(java.lang.Object toObject, java.lang.reflect.Field f, ATObject value)
          Write a field in the given Java object reflectively.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Symbiosis

public Symbiosis()
Method Detail

symbioticInvocation

public static ATObject symbioticInvocation(ATObject wrapper,
                                           java.lang.Object symbiont,
                                           java.lang.Class ofClass,
                                           java.lang.String selector,
                                           ATObject[] atArgs)
                                    throws InterpreterException
Throws:
InterpreterException

symbioticInvocation

public static ATObject symbioticInvocation(ATObject wrapper,
                                           java.lang.Object symbiont,
                                           java.lang.String selector,
                                           JavaMethod jMethod,
                                           ATObject[] atArgs)
                                    throws InterpreterException
The Java method invocation algorithm is as follows: case of # of methods matching selector: 0 => XSelectorNotFound 1 => invoke the method OR XIllegalArgument, XArityMismatch, XReflectionFailure * => (case of # of methods with matching arity OR taking varargs: 0 => XSymbiosisFailure 1 => invoke the method OR XIllegalArgument, XReflectionFailure * => (case of # of methods matching 'default type' of the actual arguments: 0 => XSymbiosisFailure 1 => invoke OR XReflectionFailure * => XSymbiosisFailure)) A Java method takes a variable number of AT arguments <=> it has one formal parameter of type ATObject[]

Parameters:
wrapper - the ATObject wrapper for the symbiont
symbiont - the Java object being accessed from within AmbientTalk
selector - the Java selector corresponding to the method invocation
jMethod - a JavaMethod encapsulating all applicable Java methods that correspond to the selector
atArgs - the AT args to the symbiotic invocation
Returns:
the wrapped result of the Java method invocation
Throws:
XArityMismatch - if the wrong number of arguments were supplied
XSelectorNotFound - if no methods correspond to the given selector (i.e. jMethod is null)
XTypeMismatch - if one of the arguments cannot be converted into the static type expected by the Java method
XSymbiosisFailure - if the method is overloaded and cannot be unambiguously resolved given the actual arguments
XReflectionFailure - if the invoked method is not accessible from within AmbientTalk
XJavaException - if the invoked Java method throws a Java exception
InterpreterException

symbioticInstanceCreation

public static ATObject symbioticInstanceCreation(java.lang.Class ofClass,
                                                 ATObject[] atArgs)
                                          throws InterpreterException
Creates a new instance of a Java class.

Parameters:
ofClass - the Java class of which to create an instance
atArgs - the AmbientTalk arguments to the constructor, to be converted to Java arguments
Returns:
an unitialized JavaObject wrapper around a newly created instance of the class
Throws:
XArityMismatch - if the wrong number of arguments were supplied
XNotInstantiatable - if no public constructors are available or if the class is abstract
XTypeMismatch - if one of the arguments cannot be converted into the static type expected by the constructor
XSymbiosisFailure - if the constructor is overloaded and cannot be unambiguously resolved given the actual arguments
XReflectionFailure - if the invoked constructor is not accessible from within AmbientTalk
XJavaException - if the invoked Java constructor throws a Java exception
InterpreterException

readField

public static ATObject readField(java.lang.Object fromObject,
                                 java.lang.Class ofClass,
                                 java.lang.String fieldName)
                          throws InterpreterException
Read a field from the given Java object reflectively.

Returns:
the contents of the Java field, converted into its AmbientTalk equivalent
Throws:
InterpreterException

readField

public static ATObject readField(java.lang.Object fromObject,
                                 java.lang.reflect.Field f)
                          throws InterpreterException
Read a field from the given Java object reflectively.

Returns:
the contents of the Java field, converted into its AmbientTalk equivalent
Throws:
InterpreterException

writeField

public static void writeField(java.lang.Object toObject,
                              java.lang.Class ofClass,
                              java.lang.String fieldName,
                              ATObject value)
                       throws InterpreterException
Write a field in the given Java object reflectively.

Parameters:
toObject - if null, the field is assumed to be static
value - the AmbientTalk value which will be converted into its Java equivalent to be written int he field
Throws:
InterpreterException

writeField

public static void writeField(java.lang.Object toObject,
                              java.lang.reflect.Field f,
                              ATObject value)
                       throws InterpreterException
Write a field in the given Java object reflectively.

Parameters:
value - the AmbientTalk value which will be converted into its Java equivalent to be written int he field
Throws:
InterpreterException

hasMethod

public static boolean hasMethod(java.lang.Class c,
                                java.lang.String selector,
                                boolean isStatic)
Query whether the given Java Class contains a (non-)static method with the given selector


hasField

public static boolean hasField(java.lang.Class c,
                               java.lang.String selector,
                               boolean isStatic)
Query whether the given Java Class contains a (non-)static field with the given selector


getField

public static java.lang.reflect.Field getField(java.lang.Class fromClass,
                                               java.lang.String fieldName,
                                               boolean isStatic)
                                        throws XUndefinedField
Retrieve a field from a Java object.

Throws:
XUndefinedField - if the field does not exist or its static property does not match

getMethods

public static JavaMethod getMethods(java.lang.Class fromClass,
                                    java.lang.String selector,
                                    boolean isStatic)
Retrieve all methods of a given name from a Java object. These are bundled together in a first-class JavaMethod object, which is cached for later reference. A null return value indicates no matches.


getAllMethods

public static JavaMethod[] getAllMethods(java.lang.Class fromClass,
                                         boolean isStatic)
Retrieve all public static or non-static methods from a given Java class (this includes methods defined in superclasses). All methods are properly wrapped in a JavaMethod wrapper, taking care to wrap a set of overloaded methods using the same wrapper.

Parameters:
isStatic - if true, all static methods of fromClass are returned, otherwise the instance methods are returned

getAllFields

public static JavaField[] getAllFields(java.lang.Object ofObject,
                                       java.lang.Class fromClass)
Retrieve all public static or non-static fields from a given Java class (this includes fields defined in superclasses, but excludes shadowed superclass fields). All fields are properly wrapped in a JavaField wrapper.

Parameters:
ofObject - if null, all static fields of fromClass are returned, otherwise the instance fields are returned

javaToAmbientTalk

public static final ATObject javaToAmbientTalk(java.lang.Object jObj)
                                        throws InterpreterException
Convert a Java object into an AmbientTalk object.

Parameters:
jObj - the Java object representing a mirror or a native type
Returns:
the same object if it implements the ATObject interface
Throws:
InterpreterException

ambientTalkToJava

public static final java.lang.Object ambientTalkToJava(ATObject atObj,
                                                       java.lang.Class targetType)
                                                throws InterpreterException
Convert an AmbientTalk object into an equivalent Java object.

Parameters:
atObj - the AmbientTalk object to convert to a Java value
targetType - the known static type of the Java object that should be attained
Returns:
a Java object o where (o instanceof targetType) should yield true
Throws:
XTypeMismatch - if the object cannot be converted into the correct Java targetType
InterpreterException

invokeUniqueSymbioticMethod

private static ATObject invokeUniqueSymbioticMethod(java.lang.Object symbiont,
                                                    java.lang.reflect.Method javaMethod,
                                                    java.lang.Object[] jArgs)
                                             throws InterpreterException
Throws:
InterpreterException

invokeUniqueSymbioticConstructor

private static ATObject invokeUniqueSymbioticConstructor(java.lang.reflect.Constructor ctor,
                                                         java.lang.Object[] jArgs)
                                                  throws InterpreterException
Throws:
InterpreterException

atArgsToJavaArgs

private static java.lang.Object[] atArgsToJavaArgs(ATObject[] args,
                                                   java.lang.Class[] types)
                                            throws InterpreterException
Throws:
InterpreterException

toInterfaceMethod

private static java.lang.reflect.Method toInterfaceMethod(java.lang.reflect.Method m)
Extremely vague and dirty feature of Java reflection: it can sometimes happen that a method is invoked on a private inner class via a publicly accessible interface method. In those cases, invoking that method results in an IllegalAccessException. One example is invoking aVector.iterator().hasNext() The problem is that aVector.iterator() returns an instance of java.util.AbstractList$Itr which is probably private. Selecting that class's hasNext method and invoking it results in an IllegalAccessException. This can be circumvented by invoking the hasNext method through the java.util.Iterator interface class.