@@ -87,6 +87,7 @@ cdef class JavaClass(object):
8787 # the goal is to found the class constructor, and call it with the
8888 # correct arguments.
8989 cdef jvalue * j_args = NULL
90+ cdef jmethodID constructor = NULL
9091
9192 # get the constructor definition if exist
9293 definition = ' ()V'
@@ -107,7 +108,7 @@ cdef class JavaClass(object):
107108 self .populate_args(d_args, j_args, args)
108109
109110 # get the java constructor
110- cdef jmethodID constructor = self .j_env[0 ].GetMethodID(
111+ constructor = self .j_env[0 ].GetMethodID(
111112 self .j_env, self .j_cls, ' <init>' , < char * >< bytes> definition)
112113 if constructor == NULL :
113114 raise JavaException(' Unable to found the constructor'
@@ -195,7 +196,7 @@ cdef class JavaMethod(object):
195196 cdef JNIEnv * j_env
196197 cdef jclass j_cls
197198 cdef jobject j_self
198- cdef char * definition
199+ cdef bytes definition
199200 cdef object is_static
200201 cdef object definition_return
201202 cdef object definition_args
@@ -207,8 +208,9 @@ cdef class JavaMethod(object):
207208
208209 def __init__ (self , definition , **kwargs ):
209210 super (JavaMethod, self ).__init__()
210- self .definition = < char * >< bytes> definition
211- self .definition_return, self .definition_args = parse_definition(definition)
211+ self .definition = < bytes> definition
212+ self .definition_return, self .definition_args = \
213+ parse_definition(definition)
212214 self .is_static = kwargs.get(' static' , False )
213215
214216 cdef resolve_method(self , JavaClass jc, bytes name):
@@ -219,11 +221,16 @@ cdef class JavaMethod(object):
219221 self .j_self = jc.j_self
220222 if self .is_static:
221223 self .j_method = self .j_env[0 ].GetStaticMethodID(
222- self .j_env, self .j_cls, < char * > name, self .definition)
224+ self .j_env, self .j_cls, < char * > name,
225+ < char * > self .definition)
223226 else :
224227 self .j_method = self .j_env[0 ].GetMethodID(
225- self .j_env, self .j_cls, < char * > name, self .definition)
226- assert (self .j_method != NULL )
228+ self .j_env, self .j_cls, < char * > name,
229+ < char * > self .definition)
230+
231+ if self .j_method == NULL :
232+ raise JavaException(' Unable to found the method'
233+ ' {0} in {1}' .format(name, jc.__javaclass__))
227234
228235 def __call__ (self , *args ):
229236 # argument array to pass to the method
@@ -304,9 +311,10 @@ cdef class JavaMethod(object):
304311 self .j_env, self .j_self, self .j_method, j_args)
305312 ret = < double > j_double
306313 elif r == ' L' :
307- # accept only string for the moment
308314 j_object = self .j_env[0 ].CallObjectMethodA(
309315 self .j_env, self .j_self, self .j_method, j_args)
316+ if j_object == NULL :
317+ return None
310318 if r == ' Ljava/lang/String;' :
311319 c_str = < char * > self .j_env[0 ].GetStringUTFChars(
312320 self .j_env, j_object, NULL )
@@ -319,8 +327,10 @@ cdef class JavaMethod(object):
319327 ret_jobject.obj = j_object
320328 ret = ret_jobject
321329 elif r == ' [' :
322- # TODO array support
323- raise NotImplementedError (" Array arguments not implemented" )
330+ r = self .definition_return[1 :]
331+ j_object = self .j_env[0 ].CallObjectMethodA(
332+ self .j_env, self .j_self, self .j_method, j_args)
333+ ret = self .convert_return_array(j_object)
324334 else :
325335 raise Exception (' Invalid return definition?' )
326336
@@ -361,8 +371,8 @@ cdef class JavaMethod(object):
361371 self .j_env, self .j_cls, self .j_method, j_args)
362372 ret = True if j_boolean else False
363373 elif r == ' B' :
364- j_byte = self .j_env[0 ].CallStaticByteMethodA
365- ( self .j_env, self .j_cls, self .j_method, j_args)
374+ j_byte = self .j_env[0 ].CallStaticByteMethodA(
375+ self .j_env, self .j_cls, self .j_method, j_args)
366376 ret = < char > j_byte
367377 elif r == ' C' :
368378 j_char = self .j_env[0 ].CallStaticCharMethodA(
@@ -381,8 +391,8 @@ cdef class JavaMethod(object):
381391 self .j_env, self .j_cls, self .j_method, j_args)
382392 ret = < long > j_long
383393 elif r == ' F' :
384- j_float = self .j_env[0 ].CallStaticFloatMethodA
385- ( self .j_env, self .j_cls, self .j_method, j_args)
394+ j_float = self .j_env[0 ].CallStaticFloatMethodA(
395+ self .j_env, self .j_cls, self .j_method, j_args)
386396 ret = < float > j_float
387397 elif r == ' D' :
388398 j_double = self .j_env[0 ].CallStaticDoubleMethodA(
@@ -404,13 +414,109 @@ cdef class JavaMethod(object):
404414 ret_jobject.obj = j_object
405415 ret = ret_jobject
406416 elif r == ' [' :
407- # TODO array support
408- raise NotImplementedError (" Array arguments not implemented" )
417+ r = self .definition_return[1 :]
418+ j_object = self .j_env[0 ].CallStaticObjectMethodA(
419+ self .j_env, self .j_cls, self .j_method, j_args)
420+ ret = self .convert_return_array(j_object)
409421 else :
410422 raise Exception (' Invalid return definition?' )
411423
412424 return ret
413425
426+ cdef convert_return_array(self , jobject j_object):
427+ cdef jboolean iscopy
428+ cdef jboolean * j_booleans
429+ cdef jbyte * j_bytes
430+ cdef jchar * j_chars
431+ cdef jshort * j_shorts
432+ cdef jint * j_ints
433+ cdef jlong * j_longs
434+ cdef jfloat * j_float
435+ cdef jdouble * j_double
436+ cdef object ret = None
437+ cdef jsize array_size
438+ cdef int i
439+
440+ if j_object == NULL :
441+ return None
442+
443+ array_size = self .j_env[0 ].GetArrayLength(self .j_env, j_object)
444+
445+ r = self .definition_return[1 ]
446+ if r == ' Z' :
447+ j_booleans = self .j_env[0 ].GetBooleanArrayElements(
448+ self .j_env, j_object, & iscopy)
449+ ret = [(True if j_booleans[i] else False )
450+ for i in range (array_size)]
451+ if iscopy:
452+ self .j_env[0 ].ReleaseBooleanArrayElements(
453+ self .j_env, j_object, j_booleans, 0 )
454+
455+ elif r == ' B' :
456+ j_bytes = self .j_env[0 ].GetByteArrayElements(
457+ self .j_env, j_object, & iscopy)
458+ ret = [(< char > j_bytes[i]) for i in range (array_size)]
459+ if iscopy:
460+ self .j_env[0 ].ReleaseByteArrayElements(
461+ self .j_env, j_object, j_bytes, 0 )
462+
463+ elif r == ' C' :
464+ j_chars = self .j_env[0 ].GetCharArrayElements(
465+ self .j_env, j_object, & iscopy)
466+ ret = [(< char > j_chars[i]) for i in range (array_size)]
467+ if iscopy:
468+ self .j_env[0 ].ReleaseCharArrayElements(
469+ self .j_env, j_object, j_chars, 0 )
470+
471+ elif r == ' S' :
472+ j_shorts = self .j_env[0 ].GetShortArrayElements(
473+ self .j_env, j_object, & iscopy)
474+ ret = [(< short > j_shorts[i]) for i in range (array_size)]
475+ if iscopy:
476+ self .j_env[0 ].ReleaseShortArrayElements(
477+ self .j_env, j_object, j_shorts, 0 )
478+
479+ elif r == ' I' :
480+ j_ints = self .j_env[0 ].GetIntArrayElements(
481+ self .j_env, j_object, & iscopy)
482+ ret = [(< int > j_ints[i]) for i in range (array_size)]
483+ if iscopy:
484+ self .j_env[0 ].ReleaseIntArrayElements(
485+ self .j_env, j_object, j_ints, 0 )
486+
487+ elif r == ' J' :
488+ j_longs = self .j_env[0 ].GetLongArrayElements(
489+ self .j_env, j_object, & iscopy)
490+ ret = [(< long > j_longs[i]) for i in range (array_size)]
491+ if iscopy:
492+ self .j_env[0 ].ReleaseLongArrayElements(
493+ self .j_env, j_object, j_longs, 0 )
494+
495+ elif r == ' F' :
496+ j_floats = self .j_env[0 ].GetFloatArrayElements(
497+ self .j_env, j_object, & iscopy)
498+ ret = [(< float > j_floats[i]) for i in range (array_size)]
499+ if iscopy:
500+ self .j_env[0 ].ReleaseFloatArrayElements(
501+ self .j_env, j_object, j_floats, 0 )
502+
503+ elif r == ' D' :
504+ j_doubles = self .j_env[0 ].GetDoubleArrayElements(
505+ self .j_env, j_object, & iscopy)
506+ ret = [(< double > j_doubles[i]) for i in range (array_size)]
507+ if iscopy:
508+ self .j_env[0 ].ReleaseDoubleArrayElements(
509+ self .j_env, j_object, j_doubles, 0 )
510+
511+ elif r == ' L' :
512+ # TODO support list of strings etc...
513+ raise NotImplementedError (' Array of Java object not done yet' )
514+
515+ else :
516+ raise JavaException(' Invalid return definition for array' )
517+
518+ return ret
519+
414520class JavaStaticMethod (JavaMethod ):
415521 def __init__ (self , definition , **kwargs ):
416522 kwargs[' static' ] = True
0 commit comments