KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com4j > MethodInfo


1 package com4j;
2
3 import java.lang.annotation.Annotation JavaDoc;
4 import java.lang.reflect.Method JavaDoc;
5 import java.lang.reflect.ParameterizedType JavaDoc;
6 import java.lang.reflect.Type JavaDoc;
7 import java.nio.Buffer JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.Calendar JavaDoc;
10 import java.util.Date JavaDoc;
11 import java.util.Map JavaDoc;
12 import java.util.HashMap JavaDoc;
13
14 /**
15  * @author Kohsuke Kawaguchi (kk@kohsuke.org)
16  */

17 final class MethodInfo {
18
19     final Method JavaDoc method;
20
21     final int vtIndex;
22     // list of params.code
23
final int[] paramConvs;
24     final NativeType[] params;
25     final int returnIndex;
26     final boolean returnIsInOut;
27     final NativeType returnConv;
28     final Class JavaDoc<?>[] paramTypes;
29     final Type JavaDoc[] genericParamTypes;
30
31     MethodInfo( Method JavaDoc m ) {
32         method = m;
33
34         VTID vtid = m.getAnnotation(VTID.class);
35         if(vtid==null)
36             throw new IllegalAnnotationException("@VTID is missing: "+m.toGenericString());
37         vtIndex = vtid.value();
38
39         Annotation JavaDoc[][] pa = m.getParameterAnnotations();
40         int paramLen = pa.length;
41
42
43         ReturnValue rt = m.getAnnotation(ReturnValue.class);
44         if(rt!=null) {
45             if(rt.index()==-1) returnIndex=pa.length;
46             else returnIndex=rt.index();
47             returnIsInOut = rt.inout();
48             returnConv = rt.type();
49         } else {
50             // guess the default
51
if( method.getReturnType()==Void.TYPE ) {
52                 // no return type
53
returnIndex = -1;
54                 returnIsInOut = false;
55                 returnConv = NativeType.Default; // unused
56
} else {
57                 returnIndex = paramLen;
58                 returnIsInOut = false;
59                 returnConv = getDefaultConversion(method.getReturnType());
60             }
61         }
62
63         Type JavaDoc[] javaParamTypes = m.getGenericParameterTypes();
64
65         paramTypes = m.getParameterTypes();
66         genericParamTypes = m.getGenericParameterTypes();
67         paramConvs = new int[paramLen];
68         params = new NativeType[paramLen];
69         for( int i=0; i<paramLen; i++ ) {
70             NativeType n=null;
71             for( Annotation JavaDoc a : pa[i] )
72                 if( a instanceof MarshalAs )
73                     n = ((MarshalAs)a).value();
74             if(n==null) {
75                 // missing annotation
76
n = getDefaultConversion(javaParamTypes[i]);
77             }
78             params[i] = n;
79             paramConvs[i] = n.code;
80         }
81     }
82
83     Object JavaDoc invoke( int ptr, Object JavaDoc[] args ) {
84         for( int i=0; i<args.length; i++ )
85             args[i] = params[i].massage(args[i]);
86
87         try {
88             Object JavaDoc r = Native.invoke( ptr, vtIndex, args, paramConvs,
89                 method.getReturnType(), returnIndex, returnIsInOut, returnConv.code );
90             return returnConv.unmassage(method.getReturnType(), method.getGenericReturnType(), r);
91         } finally {
92             for( int i=0; i<args.length; i++ )
93                 args[i] = params[i].unmassage(paramTypes[i], genericParamTypes[i], args[i]);
94         }
95     }
96
97
98     private static final Map JavaDoc<Class JavaDoc,NativeType> defaultConversions = new HashMap JavaDoc<Class JavaDoc, NativeType>();
99
100     static {
101         defaultConversions.put( Iterator JavaDoc.class, NativeType.ComObject );
102         defaultConversions.put( GUID.class, NativeType.GUID );
103         defaultConversions.put( double.class, NativeType.Double );
104         defaultConversions.put( float.class, NativeType.Float );
105         defaultConversions.put( int.class, NativeType.Int32 );
106         defaultConversions.put( short.class, NativeType.Int16 );
107         defaultConversions.put( byte.class, NativeType.Int8 );
108         defaultConversions.put( boolean.class, NativeType.VariantBool );
109         defaultConversions.put( String JavaDoc.class, NativeType.BSTR );
110         defaultConversions.put( Object JavaDoc.class, NativeType.VARIANT_ByRef );
111         defaultConversions.put( Variant.class, NativeType.VARIANT_ByRef );
112         defaultConversions.put( Date JavaDoc.class, NativeType.Date );
113     }
114
115     /**
116      * Computes the default conversion for the given type.
117      */

118     private static NativeType getDefaultConversion(Type JavaDoc t) {
119         if( t instanceof Class JavaDoc ) {
120             Class JavaDoc<?> c = (Class JavaDoc<?>)t;
121             NativeType r = defaultConversions.get(c);
122             if(r!=null) return r;
123
124             if(Com4jObject.class.isAssignableFrom(c))
125                 return NativeType.ComObject;
126             if(Enum JavaDoc.class.isAssignableFrom(c))
127                 return NativeType.Int32;
128             if(Buffer JavaDoc.class.isAssignableFrom(c))
129                 return NativeType.PVOID;
130             if(Calendar JavaDoc.class.isAssignableFrom(c))
131                 return NativeType.Date;
132         }
133
134         if( t instanceof ParameterizedType JavaDoc ) {
135             ParameterizedType JavaDoc p = (ParameterizedType JavaDoc) t;
136             if( p.getRawType()==Holder.class ) {
137                 // let p=Holder<V>
138
Type JavaDoc v = p.getActualTypeArguments()[0];
139                 if( v instanceof Class JavaDoc && Com4jObject.class.isAssignableFrom((Class JavaDoc<?>)v))
140                     return NativeType.ComObject_ByRef;
141                 if(String JavaDoc.class==v)
142                     return NativeType.BSTR_ByRef;
143                 if(Integer JavaDoc.class==v)
144                     return NativeType.Int32_ByRef;
145             }
146             if( p.getRawType()==Iterator JavaDoc.class ) {
147                 return NativeType.ComObject;
148             }
149         }
150
151         throw new IllegalAnnotationException("no default conversion available for "+t);
152     }
153
154 }
155
Popular Tags