src/JavaMirror.st
author vranyj1
Thu, 16 Aug 2012 11:52:58 +0000
branchjk_new_structure
changeset 1609 7a2627788ad7
parent 1581 70fbc03d2d82
child 1648 ba54c818827d
permissions -rw-r--r--
- JavaMirror: fixed method/constructor reflection for classes loaded by other than system/primordial classloader. - JavaMethodDescriptor added: #parameterClassesUsingClassLoader: #returnClassUsingClassLoader: - JavaFieldDescriptor added: #javaClassUsingClassLoader: ...

"
 COPYRIGHT (c) 1996-2011 by Claus Gittinger

 New code and modifications done at SWING Research Group [1]:

 COPYRIGHT (c) 2010-2011 by Jan Vrany, Jan Kurs and Marcel Hlopko
                            SWING Research Group, Czech Technical University in Prague

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.

 [1] Code written at SWING Research Group contains a signature
     of one of the above copright owners. For exact set of such code,
     see the differences between this version and version stx:libjava
     as of 1.9.2010
"
"{ Package: 'stx:libjava' }"

Object subclass:#JavaMirror
	instanceVariableNames:'klass reflection'
	classVariableNames:''
	poolDictionaries:''
	category:'Languages-Java-Classes'
!

JavaMirror subclass:#AlienClassMirror
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	privateIn:JavaMirror
!

JavaMirror subclass:#JavaArrayMirror
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	privateIn:JavaMirror
!

JavaMirror subclass:#JavaClassMirror
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	privateIn:JavaMirror
!

JavaMirror subclass:#JavaPrimitiveMirror
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	privateIn:JavaMirror
!

!JavaMirror class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1996-2011 by Claus Gittinger

 New code and modifications done at SWING Research Group [1]:

 COPYRIGHT (c) 2010-2011 by Jan Vrany, Jan Kurs and Marcel Hlopko
                            SWING Research Group, Czech Technical University in Prague

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.

 [1] Code written at SWING Research Group contains a signature
     of one of the above copright owners. For exact set of such code,
     see the differences between this version and version stx:libjava
     as of 1.9.2010

"
!

documentation
"
    Instances of a JavaCassMirror provide unified access to
    Java reflective data (expeccially to methods, constructors and
    fields) as required by Java reflection API.

    Different classes may use different mirrors - for example,
    Smalltalk classes use a special mirror so non-Smalltalk classes
    and instances could be introspected and manipulated by standard 
    Java code.

    [author:]
        Jan Vrany <jan.vrany@fit.cvut.cz>

    [instance variables:]
        klass ........ the real class on which receiver reflects
        reflection ... now always a JavaVM reflection.

    [class variables:]

    [see also:]

"
! !

!JavaMirror class methodsFor:'instance creation'!

forClass: aClass
    ^self new setKlass: aClass.

    "Created: / 31-07-2012 / 17:54:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!JavaMirror class methodsFor:'accessing'!

mirrorClassForAlienClass
    ^ AlienClassMirror

    "Created: / 31-07-2012 / 17:36:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

mirrorClassForJavaArray
    ^ JavaArrayMirror

    "Created: / 31-07-2012 / 18:26:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

mirrorClassForJavaClass
    ^ JavaClassMirror

    "Created: / 31-07-2012 / 17:36:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

mirrorClassForJavaPrimitive
    ^ JavaPrimitiveMirror

    "Created: / 31-07-2012 / 18:27:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!JavaMirror methodsFor:'accessing'!

getClassLoader
    "Returns a class loader that loaded this class"
    ^self subclassResponsibility

    "Created: / 31-07-2012 / 18:25:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

getDeclaredConstructors: publicOnly
    "Returns an java.lang.reflect.Constructor[] with all constructors 
     declared by this class"

    ^self subclassResponsibility

    "Created: / 31-07-2012 / 18:39:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

getDeclaredMethods:publicOnly 
    "Returns an java.lang.reflect.Method[] with all methods 
     declared by this class"
    
    ^ self subclassResponsibility

    "Created: / 01-08-2012 / 11:07:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!JavaMirror methodsFor:'initialization'!

setKlass: aClass
    klass := aClass.
    reflection := JavaVM reflection

    "Created: / 31-07-2012 / 17:40:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!JavaMirror methodsFor:'instance creation-java.lang.reflect.*'!

create: ctorOrMethodClass for: class method: method signature: signature modifiers: modifiers parameterTyoes: parameterClasses exceptionTypes: exceptionClasses annotations: annotations
    "Creates a new java.lang.Constructor. Arguments:

        ctorOrMethodClass <java.lang.reflect.Constructor|java.lang.reflect.Method>
        class <Class>
        method <Method>
        signature <String>
        modifiers <SmallInteger>
        parameterClasses <Collection of Class>
        exceptionClasses <Collection of Class>
        annotations <JavaAnnotationContainer>
    "

    | ctorOrMethod |

    ctorOrMethod := ctorOrMethodClass new.

    ctorOrMethod
        instVarNamed: #clazz put: (reflection javaClassObjectForClass: method javaClass);
        instVarNamed: #slot put: method;
        instVarNamed: #modifiers put: modifiers;
        instVarNamed: #parameterTypes
            put: (reflection javaClassObjectArrayForClasses: parameterClasses);
        instVarNamed: #exceptionTypes
            put: (reflection javaClassObjectArrayForClasses: exceptionClasses);
        instVarNamed: #annotations put: annotations runtimeVisible bytes;
        breakPoint: #mh info: 'Please, replace ??? by code that accesses parameterAnnotations byte array'.
        "/ Look at java.lang.reflect.Method/Constructor to figure out what value is needed here."
        "/ Also, make sure there is a test in libjava tests (stx.libjava.tests.lang.XXXX, if not,
        "/ add some!!!!!!
        "/instVarNamed: #parameterAnnotations put: annotations ???;


    method signature notNil ifTrue:[
        ctorOrMethod                 
            instVarNamed: #signature
            put: (reflection javaStringObjectForString: method signature interned: true)
    ].

    ^ ctorOrMethod

    "Created: / 01-08-2012 / 10:24:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createConstructorFor: class method: method signature: signature modifiers: modifiers parameterTyoes: parameterClasses exceptionTypes: exceptionClasses annotations: annotations
    "Creates a new java.lang.Constructor. Arguments:

        class <Class>
        method <Method>
        signature <String>
        modifiers <SmallInteger>
        parameterClasses <Collection of Class>
        exceptionClasses <Collection of Class>
        annotations <JavaAnnotationContainer>
    "

    | ctor |
    ctor := self create: (JavaVM classForName:'java.lang.reflect.Constructor')
                    for: class
                 method: method
              signature: signature 
              modifiers: modifiers 
         parameterTyoes: parameterClasses 
         exceptionTypes: exceptionClasses 
            annotations: annotations.
    ^ctor

    "Created: / 01-08-2012 / 10:20:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

createMethodFor: class method: method name: name signature: signature modifiers: modifiers parameterTyoes: parameterClasses returnType: returnClass exceptionTypes: exceptionClasses annotations: annotations
    "Creates a new java.lang.Constructor. Arguments:

        class <Class>
        method <Method>
        name <String>
        signature <String>
        modifiers <SmallInteger>
        parameterClasses <Collection of Class>
        returnClass <Class>
        exceptionClasses <Collection of Class>
        annotations <JavaAnnotationContainer>
    "

    | mthd |
    mthd := self create: (JavaVM classForName:'java.lang.reflect.Method')
                    for: class
                 method: method
              signature: signature 
              modifiers: modifiers 
         parameterTyoes: parameterClasses 
         exceptionTypes: exceptionClasses 
            annotations: annotations.

    mthd
        instVarNamed: #name       put: (reflection javaStringObjectForString: (method selector upTo:$() interned: true);
        instVarNamed: #returnType put: (reflection javaClassObjectForClass: returnClass);
        instVarNamed: #annotationDefault put: (annotations default bytes).

    ^mthd

    "Created: / 01-08-2012 / 10:46:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!JavaMirror::AlienClassMirror class methodsFor:'documentation'!

documentation
"
    Specialized mirror for Smalltalk (and all other 
    non-Java classes)

    [author:]
        Jan Vrany <jan.vrany@fit.cvut.cz>

    [instance variables:]

    [class variables:]

    [see also:]

"
! !

!JavaMirror::AlienClassMirror methodsFor:'accessing'!

getClassLoader
    "Returns a class loader that loaded this class"

    ^ (Java classForName:'stx.libjava.ClassLoader') instVarNamed: #scl.

    "Modified: / 31-07-2012 / 18:34:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

getDeclaredConstructors:publicOnly
    "Returns an java.lang.reflect.Constructor[] with all constructors 
     declared by this class"

    ^ self shouldImplement
!

getDeclaredMethods:publicOnly 
    "Returns an java.lang.reflect.Method[] with all methods 
     declared by this class"
    
    ^ self shouldImplement
! !

!JavaMirror::JavaArrayMirror methodsFor:'accessing'!

getClassLoader
    "Returns a class loader that loaded this class"

    ^ klass javaComponentClass javaMirror getClassLoader

    "Modified: / 31-07-2012 / 18:35:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

getDeclaredConstructors:publicOnly
    "Returns an java.lang.reflect.Constructor[] with all constructors 
     declared by this class"

    ^ (JavaVM classForName:'java.lang.reflect.Constructor') javaArrayClass new:0.

    "Modified: / 31-07-2012 / 18:41:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

getDeclaredMethods:publicOnly 
    "Returns an java.lang.reflect.Method[] with all methods 
     declared by this class"
    
    ^ (JavaVM classForName:'java.lang.reflect.Method') javaArrayClass new:0.

    "Modified: / 01-08-2012 / 11:08:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!JavaMirror::JavaClassMirror class methodsFor:'documentation'!

documentation
"
    A specialized mirror for all Java classes

    [author:]
        Jan Vrany <jan.vrany@fit.cvut.cz>

    [instance variables:]

    [class variables:]

    [see also:]

"
! !

!JavaMirror::JavaClassMirror methodsFor:'accessing'!

getClassLoader
    "Returns a class loader that loaded this class"

    ^ klass classLoader

    "Modified: / 31-07-2012 / 18:26:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

getDeclaredConstructors:publicOnly
    "Returns an java.lang.reflect.Constructor[] with all constructors 
     declared by this class"

    | ctors |

    ctors := OrderedCollection new.
    klass selectorsAndMethodsDo:[:sel :mthd|
        (mthd isJavaConstructor and:[publicOnly not or:[mthd isPublic]]) ifTrue:[
            ctors add: (self getDeclaredConstructorFor: mthd).
        ].
    ].
    ^(JavaVM classForName:'java.lang.reflect.Constructor') javaArrayClass withAll: ctors

    "Modified: / 01-08-2012 / 11:04:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

getDeclaredMethods:publicOnly
    "Returns an java.lang.reflect.Constructor[] with all constructors 
     declared by this class"

    | ctors |

    ctors := OrderedCollection new.
    klass selectorsAndMethodsDo:[:sel :mthd|
        (mthd isJavaConstructor not and:[publicOnly not or:[mthd isPublic]]) ifTrue:[
            ctors add: (self getDeclaredMethodFor: mthd).
        ].
    ].
    ^(JavaVM classForName:'java.lang.reflect.Method') javaArrayClass withAll: ctors

    "Modified: / 01-08-2012 / 11:10:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!JavaMirror::JavaClassMirror methodsFor:'accessing-private'!

getDeclaredConstructorFor: method

    ^self createConstructorFor: method javaClass
                        method: method
                     signature: method signature
                     modifiers: method accessFlags
                parameterTyoes: (method descriptor parameterClassesUsingClassLoader: method javaClass classLoader)
                exceptionTypes: method exceptionClasses
                   annotations: method method annotations.

    "Created: / 01-08-2012 / 00:46:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

getDeclaredMethodFor: method

    ^self      createMethodFor: method javaClass
                        method: method
                          name: (method selector upTo: $()
                     signature: method signature
                     modifiers: method accessFlags
                parameterTyoes: (method descriptor parameterClassesUsingClassLoader: method javaClass classLoader)
                    returnType: (method descriptor returnClassUsingClassLoader: method javaClass classLoader)
                exceptionTypes: method exceptionClasses
                   annotations: method method annotations.

    "Created: / 01-08-2012 / 11:11:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!JavaMirror::JavaPrimitiveMirror methodsFor:'accessing'!

getClassLoader
    "Returns a class loader that loaded this class"

    ^ nil

    "Modified: / 31-07-2012 / 18:35:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

getDeclaredConstructors:publicOnly
    "Returns an java.lang.reflect.Constructor[] with all constructors 
     declared by this class"

    ^ (JavaVM classForName:'java.lang.reflect.Constructor') javaArrayClass new:0.

    "Modified: / 31-07-2012 / 18:41:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

getDeclaredMethods:publicOnly 
    "Returns an java.lang.reflect.Method[] with all methods 
     declared by this class"
    
    ^ (JavaVM classForName:'java.lang.reflect.Method') javaArrayClass new:0.

    "Modified: / 01-08-2012 / 11:08:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!JavaMirror class methodsFor:'documentation'!

version_SVN
    ^ '$Id::                                                                                                                        $'
! !