edu.vub.at.objects.symbiosis
Class JavaClass

java.lang.Object
  extended byedu.vub.at.objects.natives.NATNil
      extended byedu.vub.at.objects.natives.NATByRef
          extended byedu.vub.at.objects.natives.NATCallframe
              extended byedu.vub.at.objects.natives.NATObject
                  extended byedu.vub.at.objects.symbiosis.JavaClass
All Implemented Interfaces:
ATAbstractGrammar, ATConversions, ATExpression, ATNil, ATObject, ATStatement, ATStripe, java.io.Serializable

public final class JavaClass
extends NATObject
implements ATStripe

A JavaClass instance represents a Java Class under symbiosis. Java classes are treated as AmbientTalk 'singleton' objects: - cloning a Java class results in the same Java class instance - sending 'new' to a Java class invokes the constructor and returns a new instance of the class under symbiosis - all static fields and methods of the Java class are reflected under symbiosis as fields and methods of the AT object A Java Class object that represents an interface can furthermore be used as an AmbientTalk stripe. The stripe's name corresponds to the interface's full name. JavaClass instances are pooled (on a per-actor basis): there should exist only one JavaClass instance for each Java class loaded into the JVM. Because the JVM ensures that a Java class can only be loaded once, we can use the Java class wrapped by the JavaClass instance as a unique key to identify its corresponding JavaClass instance.

Author:
tvcutsem
See Also:
Serialized Form

Field Summary
private static java.lang.ThreadLocal _JAVACLASS_POOL_
          A thread-local hashmap pooling all of the JavaClass wrappers for the current actor, referring to them using SOFT references, such that unused wrappers can be GC-ed when running low on memory.
private  java.lang.Class wrappedClass_
           
 
Fields inherited from class edu.vub.at.objects.natives.NATObject
_EQL_NAME_, _INI_NAME_, _IS_A_, _NEW_NAME_, _NO_STRIPES_, _SHARES_A_, _SUPER_NAME_, stripes_
 
Fields inherited from class edu.vub.at.objects.natives.NATCallframe
customFields_, lexicalParent_, stateVector_, variableMap_
 
Fields inherited from class edu.vub.at.objects.natives.NATNil
_INSTANCE_
 
Constructor Summary
private JavaClass(java.lang.Class wrappedClass)
          A JavaClass wrapping a class c is an object that has the lexical scope as its lexical parent and has NIL as its dynamic parent.
 
Method Summary
 JavaClass asJavaClassUnderSymbiosis()
           
 ATTable base_getParentStripes()
          If this class represents an interface type, parentStripes are wrappers for all interfaces extended by this Java interface type
 ATSymbol base_getStripeName()
           
 ATBoolean base_isSubstripeOf(ATStripe other)
          A Java interface type used as a stripe can only be a substripe of another Java interface type used as a stripe, and only if this type is assignable to the other type.
 boolean equals(java.lang.Object other)
          By default, two AmbientTalk objects are equal if they are the same object, or one is a proxy for the same object.
 java.lang.Class getWrappedClass()
           
 ATNil meta_addMethod(ATMethod method)
          Methods can be added to a symbiotic Java class object provided they do not already exist in the Java class.
 ATNil meta_assignField(ATObject receiver, ATSymbol name, ATObject value)
          Fields can be assigned within a symbiotic Java class object if that class has a mutable field with a matching name.
 ATNil meta_assignVariable(ATSymbol name, ATObject value)
          Variables can be assigned within a symbiotic Java class object if that class object has a mutable static field with a matching name.
 ATObject meta_clone()
          Symbiotic Java class objects are singletons.
 ATNil meta_defineField(ATSymbol name, ATObject value)
          Fields can be defined within a symbiotic Java class object.
 ATField meta_grabField(ATSymbol fieldName)
          Fields can be grabbed from a symbiotic Java class object.
 ATMethod meta_grabMethod(ATSymbol methodName)
          Methods can be grabbed from a symbiotic Java class object.
 ATObject meta_invoke(ATObject receiver, ATSymbol atSelector, ATTable arguments)
          When a method is invoked upon a symbiotic Java class object, the underlying static Java method with the same name as the AmbientTalk selector is invoked.
 ATBoolean meta_isCloneOf(ATObject original)
          Detects whether this object an the passed parameter are the result of cloning from a common ancestor (possibly either one of the objects itself).
 ATTable meta_listFields()
          Querying a symbiotic Java class object for its fields results in a table containing both 'native' static Java fields and the fields of its AT symbiont
 ATTable meta_listMethods()
          Querying a symbiotic Java class object for its methods results in a table containing both 'native' static Java methods and the methods of its AT symbiont
 ATObject meta_lookup(ATSymbol selector)
          A variable lookup is resolved by first checking whether the Java object has an appropriate static field with a matching name.
 ATObject meta_newInstance(ATTable initargs)
          aJavaClass.new(@args) == invoke a Java constructor AmbientTalk objects can add a custom new method to the class in order to intercept instance creation.
 NATText meta_print()
          Prints out the object in a human-readable way.
 ATObject meta_resolve()
          A Java Class object remains unique within an actor.
 ATBoolean meta_respondsTo(ATSymbol atSelector)
          A symbiotic Java class object responds to all of the public static selectors of its Java class plus all of the per-instance selectors added to its AmbientTalk symbiont.
 ATObject meta_select(ATObject receiver, ATSymbol selector)
          When selecting a field from a symbiotic Java class object, if the object's class has a static field with a matching selector, it is automatically read; if it has methods corresponding to the selector, they are returned in a JavaMethod wrapper, otherwise, the fields of its AT symbiont are checked.
static JavaClass wrapperFor(java.lang.Class c)
           
 
Methods inherited from class edu.vub.at.objects.natives.NATObject
asAmbientTalkObject, base_asActorMirror, base_asAsyncMessage, base_asBegin, base_asBoolean, base_asClosure, base_asDefinition, base_asExpression, base_asField, base_asHandler, base_asMessage, base_asMessageCreation, base_asMethod, base_asMirror, base_asNumber, base_asSplice, base_asStatement, base_asStripe, base_asSymbol, base_asTable, base_asUnquoteSplice, base_isBoolean, base_isCallFrame, base_isClosure, base_isMethod, base_isMirror, base_isSplice, base_isStripe, base_isSymbol, base_isTable, base_isUnquoteSplice, createChild, createClone, createIsolate, isAmbientTalkObject, isPrimitive, listTransitiveFields, listTransitiveMethods, meta_extend, meta_getStripes, meta_isRelatedTo, meta_isStripedWith, meta_pass, meta_share
 
Methods inherited from class edu.vub.at.objects.natives.NATCallframe
getLocalCustomField, getLocalField, hasLocalCustomField, hasLocalField, hasLocalNativeField, meta_addField, meta_doesNotUnderstand, meta_getDynamicParent, meta_getLexicalParent, setLocalField
 
Methods inherited from class edu.vub.at.objects.natives.NATNil
asJavaObjectUnderSymbiosis, asNativeBoolean, asNativeException, asNativeFarReference, asNativeFraction, asNativeNumber, asNativeNumeric, asNativeTable, asNativeText, base__opeql__opeql_, base_asFarReference, base_asVariableAssignment, base_init, base_isFarReference, base_isMessageCreation, base_isVariableAssignment, base_new, isJavaObjectUnderSymbiosis, isNativeBoolean, isNativeField, isNativeText, meta_eval, meta_quote, meta_receive, meta_send, readResolve, toString, writeReplace
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface edu.vub.at.objects.ATObject
base__opeql__opeql_, base_init, base_new, meta_addField, meta_doesNotUnderstand, meta_eval, meta_extend, meta_getDynamicParent, meta_getLexicalParent, meta_getStripes, meta_isRelatedTo, meta_isStripedWith, meta_pass, meta_quote, meta_receive, meta_send, meta_share
 
Methods inherited from interface edu.vub.at.objects.coercion.ATConversions
asAmbientTalkObject, asJavaObjectUnderSymbiosis, asNativeBoolean, asNativeException, asNativeFarReference, asNativeFraction, asNativeNumber, asNativeNumeric, asNativeTable, asNativeText, base_asActorMirror, base_asAsyncMessage, base_asBegin, base_asBoolean, base_asClosure, base_asDefinition, base_asExpression, base_asFarReference, base_asField, base_asHandler, base_asMessage, base_asMessageCreation, base_asMethod, base_asMirror, base_asNumber, base_asSplice, base_asStatement, base_asStripe, base_asSymbol, base_asTable, base_asUnquoteSplice, base_asVariableAssignment, base_isBoolean, base_isCallFrame, base_isClosure, base_isFarReference, base_isMessageCreation, base_isMethod, base_isMirror, base_isSplice, base_isStripe, base_isSymbol, base_isTable, base_isUnquoteSplice, base_isVariableAssignment, isAmbientTalkObject, isJavaObjectUnderSymbiosis, isNativeBoolean, isNativeField, isNativeText
 

Field Detail

_JAVACLASS_POOL_

private static final java.lang.ThreadLocal _JAVACLASS_POOL_
A thread-local hashmap pooling all of the JavaClass wrappers for the current actor, referring to them using SOFT references, such that unused wrappers can be GC-ed when running low on memory.


wrappedClass_

private final java.lang.Class wrappedClass_
Constructor Detail

JavaClass

private JavaClass(java.lang.Class wrappedClass)
A JavaClass wrapping a class c is an object that has the lexical scope as its lexical parent and has NIL as its dynamic parent. If the JavaClass wraps a Java interface type, JavaClass instances are also stripes.

Method Detail

wrapperFor

public static final JavaClass wrapperFor(java.lang.Class c)

getWrappedClass

public java.lang.Class getWrappedClass()

asJavaClassUnderSymbiosis

public JavaClass asJavaClassUnderSymbiosis()
                                    throws XTypeMismatch
Specified by:
asJavaClassUnderSymbiosis in interface ATConversions
Overrides:
asJavaClassUnderSymbiosis in class NATNil
Throws:
XTypeMismatch

equals

public boolean equals(java.lang.Object other)
Description copied from class: NATNil
By default, two AmbientTalk objects are equal if they are the same object, or one is a proxy for the same object.

Overrides:
equals in class NATNil

meta_invoke

public ATObject meta_invoke(ATObject receiver,
                            ATSymbol atSelector,
                            ATTable arguments)
                     throws InterpreterException
When a method is invoked upon a symbiotic Java class object, the underlying static Java method with the same name as the AmbientTalk selector is invoked. Its arguments are converted into their Java equivalents. Conversely, the result of the method invocation is converted into an AmbientTalk object.

Specified by:
meta_invoke in interface ATObject
Overrides:
meta_invoke in class NATObject
Throws:
InterpreterException

meta_respondsTo

public ATBoolean meta_respondsTo(ATSymbol atSelector)
                          throws InterpreterException
A symbiotic Java class object responds to all of the public static selectors of its Java class plus all of the per-instance selectors added to its AmbientTalk symbiont.

Specified by:
meta_respondsTo in interface ATObject
Overrides:
meta_respondsTo in class NATObject
Throws:
InterpreterException

meta_select

public ATObject meta_select(ATObject receiver,
                            ATSymbol selector)
                     throws InterpreterException
When selecting a field from a symbiotic Java class object, if the object's class has a static field with a matching selector, it is automatically read; if it has methods corresponding to the selector, they are returned in a JavaMethod wrapper, otherwise, the fields of its AT symbiont are checked.

Specified by:
meta_select in interface ATObject
Overrides:
meta_select in class NATObject
Parameters:
receiver - the original receiver of the selection
selector - the selector to look up
Returns:
the value of the found field, or a closure wrapping a found method
Throws:
InterpreterException

meta_lookup

public ATObject meta_lookup(ATSymbol selector)
                     throws InterpreterException
A variable lookup is resolved by first checking whether the Java object has an appropriate static field with a matching name. If so, that field's contents are returned. If not, the AT symbiont's fields are checked.

Specified by:
meta_lookup in interface ATObject
Overrides:
meta_lookup in class NATObject
Throws:
InterpreterException

meta_defineField

public ATNil meta_defineField(ATSymbol name,
                              ATObject value)
                       throws InterpreterException
Fields can be defined within a symbiotic Java class object. They are added to its AmbientTalk symbiont, but only if they do not clash with already existing field names.

Specified by:
meta_defineField in interface ATObject
Overrides:
meta_defineField in class NATObject
Throws:
InterpreterException

meta_assignVariable

public ATNil meta_assignVariable(ATSymbol name,
                                 ATObject value)
                          throws InterpreterException
Variables can be assigned within a symbiotic Java class object if that class object has a mutable static field with a matching name. Variable assignment is first resolved in the Java object and afterwards in the AT symbiont.

Specified by:
meta_assignVariable in interface ATObject
Overrides:
meta_assignVariable in class NATCallframe
Throws:
InterpreterException

meta_assignField

public ATNil meta_assignField(ATObject receiver,
                              ATSymbol name,
                              ATObject value)
                       throws InterpreterException
Fields can be assigned within a symbiotic Java class object if that class has a mutable field with a matching name. Field assignment is first resolved in the Java object and afterwards in the AT symbiont.

Specified by:
meta_assignField in interface ATObject
Overrides:
meta_assignField in class NATObject
Parameters:
value - the value to assign to the field
name - the field to assign
Returns:
NIL
Throws:
InterpreterException

meta_clone

public ATObject meta_clone()
                    throws InterpreterException
Symbiotic Java class objects are singletons.

Specified by:
meta_clone in interface ATObject
Overrides:
meta_clone in class NATObject
Throws:
InterpreterException

meta_newInstance

public ATObject meta_newInstance(ATTable initargs)
                          throws InterpreterException
aJavaClass.new(@args) == invoke a Java constructor AmbientTalk objects can add a custom new method to the class in order to intercept instance creation. The original instance can then be performed by invoking the old new(@args). For example, imagine we want to extend the class java.lang.Point with a 3D coordinate, e.g. a 'z' field: def Point := jlobby.java.awt.Point; def oldnew := Point.new; def Point.new(x,y,z) { // 'override' the new method def point := oldnew(x,y); // invokes the Java constructor def point.z := z; // adds a field dynamically to the new JavaObject wrapper point; // important! new should return the newly created instance } def mypoint := Point.new(1,2,3);

Specified by:
meta_newInstance in interface ATObject
Overrides:
meta_newInstance in class NATObject
Throws:
InterpreterException

meta_addMethod

public ATNil meta_addMethod(ATMethod method)
                     throws InterpreterException
Methods can be added to a symbiotic Java class object provided they do not already exist in the Java class.

Specified by:
meta_addMethod in interface ATObject
Overrides:
meta_addMethod in class NATObject
Throws:
InterpreterException

meta_grabField

public ATField meta_grabField(ATSymbol fieldName)
                       throws InterpreterException
Fields can be grabbed from a symbiotic Java class object. Fields that correspond to static fields in the Java class are returned as JavaField instances.

Specified by:
meta_grabField in interface ATObject
Overrides:
meta_grabField in class NATCallframe
Throws:
InterpreterException

meta_grabMethod

public ATMethod meta_grabMethod(ATSymbol methodName)
                         throws InterpreterException
Methods can be grabbed from a symbiotic Java class object. Methods that correspond to static methods in the Java class are returned as JavaMethod instances.

Specified by:
meta_grabMethod in interface ATObject
Overrides:
meta_grabMethod in class NATObject
Throws:
InterpreterException

meta_listFields

public ATTable meta_listFields()
                        throws InterpreterException
Querying a symbiotic Java class object for its fields results in a table containing both 'native' static Java fields and the fields of its AT symbiont

Specified by:
meta_listFields in interface ATObject
Overrides:
meta_listFields in class NATCallframe
Throws:
InterpreterException

meta_listMethods

public ATTable meta_listMethods()
                         throws InterpreterException
Querying a symbiotic Java class object for its methods results in a table containing both 'native' static Java methods and the methods of its AT symbiont

Specified by:
meta_listMethods in interface ATObject
Overrides:
meta_listMethods in class NATObject
Throws:
InterpreterException

meta_isCloneOf

public ATBoolean meta_isCloneOf(ATObject original)
                         throws InterpreterException
Description copied from interface: ATObject
Detects whether this object an the passed parameter are the result of cloning from a common ancestor (possibly either one of the objects itself).

Specified by:
meta_isCloneOf in interface ATObject
Overrides:
meta_isCloneOf in class NATObject
Throws:
InterpreterException

meta_print

public NATText meta_print()
                   throws InterpreterException
Description copied from interface: ATObject
Prints out the object in a human-readable way.

Specified by:
meta_print in interface ATObject
Overrides:
meta_print in class NATObject
Throws:
InterpreterException

meta_resolve

public ATObject meta_resolve()
                      throws InterpreterException
A Java Class object remains unique within an actor.

Specified by:
meta_resolve in interface ATObject
Overrides:
meta_resolve in class NATObject
Throws:
InterpreterException

base_getParentStripes

public ATTable base_getParentStripes()
                              throws InterpreterException
If this class represents an interface type, parentStripes are wrappers for all interfaces extended by this Java interface type

Specified by:
base_getParentStripes in interface ATStripe
Throws:
InterpreterException

base_getStripeName

public ATSymbol base_getStripeName()
                            throws InterpreterException
Specified by:
base_getStripeName in interface ATStripe
Throws:
InterpreterException

base_isSubstripeOf

public ATBoolean base_isSubstripeOf(ATStripe other)
                             throws InterpreterException
A Java interface type used as a stripe can only be a substripe of another Java interface type used as a stripe, and only if this type is assignable to the other type.

Specified by:
base_isSubstripeOf in interface ATStripe
Throws:
InterpreterException