[libinline-java-perl] 62/398: *** empty log message ***

Jonas Smedegaard dr at jones.dk
Thu Feb 26 11:42:46 UTC 2015


This is an automated email from the git hooks/post-receive script.

js pushed a commit to tag 0.55
in repository libinline-java-perl.

commit 093858e877813fde0b4a30a8245457b06c4caddc
Author: patrick <>
Date:   Mon Apr 16 16:07:04 2001 +0000

    *** empty log message ***
---
 Java/Array.pm     |   7 +-
 Java/Class.pm     | 362 +++++++++++++++++++++++++++++++++++++++---------------
 Java/Object.pm    | 102 +++++++++------
 Java/Protocol.pm  | 139 +++++++--------------
 MANIFEST          |   2 +
 t/02_primitives.t | 147 ++++++++++++++++++----
 t/03_objects.t    | 157 +++++++++++------------
 t/04_members.t    | 141 ++++++++++++++++-----
 t/05_arrays.t     | 170 +++++++++++++++++++++----
 t/06_static.t     |  43 +++++--
 t/07_polymorph.t  |  82 +++++++++++--
 11 files changed, 940 insertions(+), 412 deletions(-)

diff --git a/Java/Array.pm b/Java/Array.pm
index de3fe76..b7fbcc0 100644
--- a/Java/Array.pm
+++ b/Java/Array.pm
@@ -48,12 +48,7 @@ sub __isa {
 	my $this = shift ;
 	my $proto = shift ;
 
-	eval {
-		my $obj = $this->__get_object() ;
-		$obj->__get_private()->{proto}->ISA($proto) ;
-	} ;
-
-	return $@ ;
+	return $this->__get_object()->__isa($proto) ;
 }
 
 
diff --git a/Java/Class.pm b/Java/Class.pm
index ea27728..b3f037f 100644
--- a/Java/Class.pm
+++ b/Java/Class.pm
@@ -100,8 +100,11 @@ sub CastArguments {
 	my $ret = [] ;
 	my $score = 0 ;
 	for (my $i = 0 ; $i < scalar(@{$args}) ; $i++){
-		my @r = CastArgument($args->[$i], $proto->[$i], $module) ;
+		my $arg = $args->[$i] ;
+		my $pro = $proto->[$i] ;
+		my @r = CastArgument($arg, $pro, $module) ;
 		$ret->[$i] = $r[0] ;
+		
 		$score += $r[1] ;
 	}
 
@@ -116,100 +119,163 @@ sub CastArgument {
 
 	ValidateClass($proto) ;
 
-	if ((ClassIsReference($proto))&&(! UNIVERSAL::isa($arg, "Inline::Java::Object"))){
-		# Here we allow scalars to be passed in place of java.lang.Object
-		# They will wrapped on the Java side.
-		if (defined($arg)){
-			if (UNIVERSAL::isa($arg, "ARRAY")){
-				if (! UNIVERSAL::isa($arg, "Inline::Java::Array")){
-					my $an = new Inline::Java::Array::Normalizer($proto, $arg) ;
-					my $flat = $an->FlattenArray() ; 
-					my $inline = Inline::Java::get_INLINE($module) ;
-					my $obj = Inline::Java::Object->__new($proto, $inline, -1, $flat->[0], $flat->[1]) ;
-
-					# We need to create the array on the Java side, and then grab 
-					# the returned object.
-					$arg = new Inline::Java::Array($obj) ;
-				}
-				else{
-					Inline::Java::debug("argument is already an Inline::Java array") ;
-				}
-			}
-			else{
-				if (ref($arg)){
-					# We got some other type of ref...
-					croak "Can't convert $arg to object $proto" ;
+	my $arg_ori = $arg ;
+	my $proto_ori = $proto ;
+
+	my $sub = sub {
+		my $array_type = undef ;
+		if (UNIVERSAL::isa($arg, "Inline::Java::Class::Cast")){
+			my $v = $arg->get_value() ;
+			$proto = $arg->get_type() ;
+			$array_type = $arg->get_array_type() ;
+			$arg = $v ;
+		}
+
+		if ((ClassIsReference($proto))&&(! UNIVERSAL::isa($arg, "Inline::Java::Object"))){
+			# Here we allow scalars to be passed in place of java.lang.Object
+			# They will wrapped on the Java side.
+			if (defined($arg)){
+				if (UNIVERSAL::isa($arg, "ARRAY")){
+					if (! UNIVERSAL::isa($arg, "Inline::Java::Array")){
+						my $an = new Inline::Java::Array::Normalizer($array_type || $proto, $arg) ;
+						my $flat = $an->FlattenArray() ; 
+						my $inline = Inline::Java::get_INLINE($module) ;
+						my $obj = Inline::Java::Object->__new($array_type || $proto, $inline, -1, $flat->[0], $flat->[1]) ;
+
+						# We need to create the array on the Java side, and then grab 
+						# the returned object.
+						$arg = new Inline::Java::Array($obj) ;
+					}
+					else{
+						Inline::Java::debug("argument is already an Inline::Java array") ;
+					}
 				}
 				else{
-					# Here we got a scalar
-					# Here we allow scalars to be passed in place of java.lang.Object
-					# They will wrapped on the Java side.
-					if ($proto ne "java.lang.Object"){
+					if (ref($arg)){
+						# We got some other type of ref...
 						croak "Can't convert $arg to object $proto" ;
 					}
+					else{
+						# Here we got a scalar
+						# Here we allow scalars to be passed in place of java.lang.Object
+						# They will wrapped on the Java side.
+						if ($proto ne "java.lang.Object"){
+							croak "Can't convert $arg to object $proto" ;
+						}
+					}
 				}
 			}
 		}
-	}
-	if ((ClassIsPrimitive($proto))&&(ref($arg))){
-		croak "Can't convert $arg to primitive $proto" ;
-	}
+		if ((ClassIsPrimitive($proto))&&(ref($arg))){
+			croak "Can't convert $arg to primitive $proto" ;
+		}
 
-	if (ClassIsNumeric($proto)){
-		if (! defined($arg)){
-			return (0, 0) ;
-		}
-		my $re = $RANGE->{$proto}->{REGEXP} ;
-		my $min = $RANGE->{$proto}->{MIN} ;
-		my $max = $RANGE->{$proto}->{MAX} ;
-		Inline::Java::debug("min = $min, max = $max, val = $arg") ;
-		if ($arg =~ /$re/){
-			if (($arg >= $min)&&($arg <= $max)){
-				return ($arg, 0) ;
+		if (ClassIsNumeric($proto)){
+			if (! defined($arg)){
+				# undef gets lowest score since it can be passed
+				# as anything
+				return (0, 1) ;
 			}
-			croak "$arg out of range for type $proto" ;
+			my $re = $RANGE->{$proto}->{REGEXP} ;
+			my $min = $RANGE->{$proto}->{MIN} ;
+			my $max = $RANGE->{$proto}->{MAX} ;
+			Inline::Java::debug("min = $min, max = $max, val = $arg") ;
+			if ($arg =~ /$re/){
+				if (($arg >= $min)&&($arg <= $max)){
+					# number is a pretty precise match, but it's still
+					# guessing amongst the numeric types
+					return ($arg, 5.5) ;
+				}
+				croak "$arg out of range for type $proto" ;
+			}
+			croak "Can't convert $arg to $proto" ;
 		}
-		croak "Can't convert $arg to $proto" ;
-	}
-	elsif (ClassIsChar($proto)){
-		if (! defined($arg)){
-			return ("\0", 0) ;
+		elsif (ClassIsChar($proto)){
+			if (! defined($arg)){
+				# undef gets lowest score since it can be passed
+				# as anything
+				return ("\0", 1) ;
+			}
+			if (length($arg) == 1){
+				# char is a pretty precise match
+				return ($arg, 5) ;
+			}
+			croak "Can't convert $arg to $proto" ;
 		}
-		if (length($arg) == 1){
-			return ($arg, 0) ;
+		elsif (ClassIsBool($proto)){
+			if (! defined($arg)){
+				# undef gets lowest score since it can be passed
+				# as anything
+				return (0, 1) ;
+			}
+			elsif (! $arg){
+				# bool gets lowest score since anything is a bool
+				return (0, 1) ;
+			}
+			else{
+				# bool gets lowest score since anything is a bool
+				return (1, 1) ;
+			}
 		}
-		croak "Can't convert $arg to $proto" ;
-	}
-	elsif (ClassIsBool($proto)){
-		if ((! defined($arg))||(! $arg)){
-			return (0, 0) ;
+		elsif (ClassIsString($proto)){
+			if (! defined($arg)){
+				# undef gets lowest score since it can be passed
+				# as anything
+				return (undef, 1) ;
+			}
+			# string get almost lowest score since anything can match it
+			# except objects
+			if ($proto eq "java.lang.StringBuffer"){
+				# in case we have both protos, we want to give String
+				# the advantage
+				return ($arg, 1.75) ;
+			}
+			return ($arg, 2) ;
 		}
 		else{
-			return (1, 0) ;
-		}
-	}
-	elsif (ClassIsString($proto)){
-		if (! defined($arg)){
-			return (undef, 0) ;
-		}
-		return ($arg, 0) ;
-	}
-	else{
-		if (! defined($arg)){
-			return ($arg, 0) ;
-		}
-		# Here the prototype calls for an object of type $proto
-		# We must ask Java if our object extends $proto		
-		if (ref($arg)){
-			my $msg = $arg->__isa($proto) ;
-			if ($msg){
-				croak $msg ;
+			if (! defined($arg)){
+				# undef gets lowest score since it can be passed
+				# as anything
+				return ($arg, 1) ;
 			}
-			Inline::Java::debug("$arg is a $proto") ;
+
+			# Here the prototype calls for an object of type $proto
+			# We must ask Java if our object extends $proto		
+			if (ref($arg)){
+				my ($msg, $score) = $arg->__isa($proto) ;
+				if ($msg){
+					croak $msg ;
+				}
+				Inline::Java::debug("$arg is a $proto") ;
+
+				# a matching object, pretty good match, except if proto
+				# is java.lang.Object
+				if ($proto eq "java.lang.Object"){	
+					return ($arg, 1) ;
+				}
+				
+				# Here we deduce point the more our argument is "far"
+				# from the prototype.
+				return ($arg, 7 - ($score * 0.01)) ;
+			}
+
+			# Here we are passing a scalar as an object, this is pretty
+			# vague as well
+			return ($arg, 1) ;
 		}
+	} ;
 
-		return ($arg, 0) ;
+	my @ret = $sub->() ;
+	
+	if (UNIVERSAL::isa($arg_ori, "Inline::Java::Class::Cast")){
+		# It seems we had casted the variable to a specific type
+		if ($arg_ori->matches($proto_ori)){
+			Inline::Java::debug("Type cast match!") ;
+			$ret[1] = 10 ;
+		}
 	}
+
+	return @ret ;
 }
 
 
@@ -328,8 +394,66 @@ sub ClassIsArray {
 }
 
 
-1 ;
 
+######################## Inline::Java::Class::Cast ########################
+package Inline::Java::Class::Cast ;
+
+
+use Carp ;
+
+sub new {
+	my $class = shift ;
+	my $type = shift ;
+	my $value = shift ;
+	my $array_type = shift ;
+
+	if (UNIVERSAL::isa($value, "Inline::Java::Class::Cast")){
+		# This allows chaining
+		$value = $value->get_value() ;
+	}
+	
+	my $this = {} ;
+	$this->{cast} = Inline::Java::Class::ValidateClass($type) ;
+	$this->{value} = $value ;
+	$this->{array_type} = $array_type ;
+
+	bless($this, $class) ;
+	return $this ;
+}
+
+
+sub get_value {
+	my $this = shift ;
+
+	return $this->{value} ;
+}
+
+
+sub get_type {
+	my $this = shift ;
+
+	return $this->{cast} ;
+}
+
+sub get_array_type {
+	my $this = shift ;
+
+	return $this->{array_type} ;
+}
+
+
+sub matches {
+	my $this = shift ;
+	my $proto = shift ;
+
+	return ($proto eq $this->{cast}) ;
+}
+
+
+package Inline::Java::Class ;
+
+
+1 ;
 
 
 __DATA__
@@ -337,20 +461,10 @@ __DATA__
 class InlineJavaClass {
 	InlineJavaServer ijs ;
 	InlineJavaProtocol ijp ;
-	HashMap hm = new HashMap() ;
 
 	InlineJavaClass(InlineJavaServer _ijs, InlineJavaProtocol _ijp){
 		ijs = _ijs ;
 		ijp = _ijp ;
-
-		hm.put("B", "byte") ;
-		hm.put("S", "short") ;
-		hm.put("I", "int") ;
-		hm.put("J", "long") ;
-		hm.put("F", "float") ;
-		hm.put("D", "double") ;
-		hm.put("C", "char") ;
-		hm.put("Z", "boolean") ;
 	}
 
 
@@ -358,9 +472,9 @@ class InlineJavaClass {
 		Makes sure a class exists
 	*/
 	Class ValidateClass(String name) throws InlineJavaException {
-		String s = (String)hm.get(name) ;
-		if (s != null){
-			name = s ;
+		Class pc = FindType(name) ;
+		if (pc != null){
+			return pc ;
 		}
 
 		try {
@@ -511,7 +625,7 @@ class InlineJavaClass {
 
 				Class c = ValidateClass(c_name) ;
 
-				if (DoesExtend(c, p)){
+				if (DoesExtend(c, p) > -1){
 					ijs.debug("    " + c.getName() + " is a kind of " + p.getName()) ;
 					// get the object from the hash table
 					Integer oid = new Integer(objid) ;
@@ -531,20 +645,23 @@ class InlineJavaClass {
 	}
 
 
-	boolean DoesExtend(Class a, Class b){
+	/* 
+		Returns the number of levels that separate a from b
+	*/
+	int DoesExtend(Class a, Class b){
 		// We need to check if a extends b
 		Class parent = a ;
-		boolean got_it = false ;
+		int level = 0 ;
 		while (parent != null){
 			ijs.debug("    parent is " + parent.getName()) ;
 			if (parent == b){
-				got_it = true ;
-				break ;
+				return level ;
 			}
+			level++ ;
 			parent = parent.getSuperclass() ;
 		}
 
-		return got_it ;
+		return -1 ;
 	}
 
 
@@ -583,6 +700,57 @@ class InlineJavaClass {
 	}
 
 
+	/*
+		Finds the primitive type class for the passed primitive type name.
+	*/
+	Class FindType (String name){
+		String [] list = {
+			"byte",
+			"short",
+			"int",
+			"long",
+			"float",
+			"double",
+			"boolean",
+			"char",
+			"B",
+			"S",
+			"I",
+			"J",
+			"F",
+			"D",
+			"Z",
+			"C",
+		} ;
+		Class [] listc = {
+			byte.class,
+			short.class,
+			int.class,
+			long.class,
+			float.class,
+			double.class,
+			boolean.class,
+			char.class,
+			byte.class,
+			short.class,
+			int.class,
+			long.class,
+			float.class,
+			double.class,
+			boolean.class,
+			char.class,
+		} ;
+
+		for (int i = 0 ; i < list.length ; i++){
+			if (name.equals(list[i])){
+				return listc[i] ;
+			}
+		}
+
+		return null ;
+	}
+
+
 	boolean ClassIsPrimitive (Class p){
 		String name = p.getName() ;
 
diff --git a/Java/Object.pm b/Java/Object.pm
index 95b8782..6fcf047 100644
--- a/Java/Object.pm
+++ b/Java/Object.pm
@@ -78,25 +78,21 @@ sub __validate_prototype {
 	my $method = shift ;
 	my $args = shift ;
 	my $protos = shift ;
-	my $static = shift ;
 	my $inline = shift ;
 
-	my $matched_protos = [] ;
-	my $new_arguments = [] ;
-	my $scores = [] ;
-
-	my $prototypes = [] ;
-	foreach my $s (values %{$protos}){
-		if ($static == $s->{STATIC}){
-			push @{$prototypes}, $s->{SIGNATURE} ;
-		}
-	}
+	my @matched = () ;
  
-	my $nb_proto = scalar(@{$prototypes}) ;
+	my $nb_proto = scalar(values %{$protos}) ;
 	my @errors = () ;
-	foreach my $proto (@{$prototypes}){
+	foreach my $s (values %{$protos}){
+		my $proto = $s->{SIGNATURE} ;
+		my $stat = $s->{STATIC} ;
 		my $new_args = undef ;
 		my $score = undef ;
+
+		my $s = Inline::Java::Protocol->CreateSignature($proto) ;
+		Inline::Java::debug("Matching arguments to $method$s") ;
+		
 		eval {
 			($new_args, $score) = Inline::Java::Class::CastArguments($args, $proto, $inline->{modfname}) ;
 		} ;
@@ -111,20 +107,29 @@ sub __validate_prototype {
 		}
 
 		# We passed!
-		push @{$matched_protos}, $proto ;
-		push @{$new_arguments}, $new_args ;
-		push @{$scores}, $score ;
+		Inline::Java::debug("Match successful: score is $score") ;
+		my $h = {
+			PROTO =>	$proto,
+			NEW_ARGS =>	$new_args,
+			SCORE =>	$score,
+			STATIC =>	$stat,
+		} ;
+		push @matched, $h ;
 	}
 
-	if (! scalar(@{$matched_protos})){
+	my $nb_matched = scalar(@matched) ;
+	if (! $nb_matched){
 		my $name = $this->__get_private()->{class} ;
 		my $sa = Inline::Java::Protocol->CreateSignature($args) ;
 		my $msg = "In method $method of class $name: Can't find any signature that matches " .
 			"the arguments passed $sa.\nAvailable signatures are:\n"  ;
 		my $i = 0 ;
-		foreach my $proto (@{$prototypes}){
+		foreach my $s (values %{$protos}){
+			my $proto = $s->{SIGNATURE} ;	
+			my $static = ($s->{STATIC} ? "static " : "") ;
+
 			my $s = Inline::Java::Protocol->CreateSignature($proto) ;
-			$msg .= "\t$method$s\n" ;
+			$msg .= "\t$static$method$s\n" ;
 			$msg .= "\t\terror was: $errors[$i]" ;
 			$i++ ;
 		}
@@ -132,23 +137,50 @@ sub __validate_prototype {
 		croak $msg ;
 	}
 
-	# Amongst the ones that matched, we need to select the one with the 
-	# highest score. For now, the last one will do.
-	
-	my $nb = scalar(@{$matched_protos}) ;
-	return ($matched_protos->[$nb - 1], $new_arguments->[$nb - 1]) ;
+	my $chosen = undef ;
+	my $max = 0 ;
+	foreach my $h (@matched){
+		my $s = $h->{SCORE} ;
+		if ($s >= $max){
+			# Here if the scores are equal we take the last one since
+			# we start with inherited methods and move to class mothods
+			$max = $s ;
+			$chosen = $h ;
+		}
+	}
+
+	if ((! $chosen->{STATIC})&&(! ref($this))){
+		# We are trying to call an instance method without an object
+		# reference
+		croak "Method $method of class $inline->{pkg}::$this must be called from an object reference" ;
+	}
+
+	return (
+		$chosen->{PROTO}, 
+		$chosen->{NEW_ARGS}, 
+		$chosen->{STATIC},
+	) ;
 }
 
 
 sub __isa {
 	my $this = shift ;
 	my $proto = shift ;
-
+	
+	my $ret = undef ;
 	eval {
-		$this->__get_private()->{proto}->ISA($proto) ;
+		$ret = $this->__get_private()->{proto}->ISA($proto) ;
 	} ;
+	if ($@){
+		return ($@, 0) ;
+	}
+
+	if ($ret == -1){
+		my $c = $this->__get_private()->{java_class} ;
+		return ("$c is not a kind of $proto", 0) ;
+	}
 
-	return $@ ;
+	return ('', $ret) ;
 }
 
 
@@ -241,15 +273,15 @@ sub DESTROY {
 			} ;
 			my $name = $this->__get_private()->{class} ;
 			croak "In method DESTROY of class $name: $@" if $@ ;
-		}
 		
-		# Here we have a circular reference so we need to break it
-		# so that the memory is collected.
-		my $priv = $this->__get_private() ;
-		my $proto = $priv->{proto} ;
-		$priv->{proto} = undef ;
-		$proto->{obj_priv} = undef ;
-		$PRIVATES->{$this} = undef ;
+			# Here we have a circular reference so we need to break it
+			# so that the memory is collected.
+			my $priv = $this->__get_private() ;
+			my $proto = $priv->{proto} ;
+			$priv->{proto} = undef ;
+			$proto->{obj_priv} = undef ;
+			$PRIVATES->{$this} = undef ;
+		}
 	}
 	else{
 		# Here we can't untie because we still have a reference in $PRIVATES
diff --git a/Java/Protocol.pm b/Java/Protocol.pm
index 3801b23..99e1673 100644
--- a/Java/Protocol.pm
+++ b/Java/Protocol.pm
@@ -58,10 +58,11 @@ sub ISA {
 	my $this = shift ;
 	my $proto = shift ;
 
-	Inline::Java::debug("checking if $this is a $proto") ;
-
 	my $id = $this->{obj_priv}->{id} ;
 	my $class = $this->{obj_priv}->{java_class} ;
+
+	Inline::Java::debug("checking if $class is a $proto") ;
+
 	my $data = join(" ", 
 		"isa", 
 		$id,
@@ -93,29 +94,7 @@ sub CreateJavaObject {
 }
 
 
-# Called to call a static Java method
-sub CallStaticJavaMethod {
-	my $this = shift ;
-	my $class = shift ;
-	my $method = shift ;
-	my $proto = shift ;
-	my $args = shift ;
-
-	Inline::Java::debug("calling $class.$method" . $this->CreateSignature($args)) ;
-
-	my $data = join(" ", 
-		"call_static_method", 
-		Inline::Java::Class::ValidateClass($class),
-		$this->ValidateMethod($method),
-		$this->CreateSignature($proto, ","),
-		$this->ValidateArgs($args),
-	) ;
-
-	return $this->Send($data) ;
-}
-
-
-# Calls a regular Java method.
+# Calls a Java method.
 sub CallJavaMethod {
 	my $this = shift ;
 	my $method = shift ;
@@ -249,11 +228,12 @@ sub ValidateArgs {
 				croak "A Java method or member can only have Java objects, Java arrays or scalars as arguments" ;
 			}
 
+			my $obj = $arg ;
 			if (UNIVERSAL::isa($arg, "Inline::Java::Array")){
-				$arg = $arg->__get_object() ; 
+				$obj = $arg->__get_object() ; 
 			}
-			my $class = $arg->__get_private()->{java_class} ;
-			my $id = $arg->__get_private()->{id} ;
+			my $class = $obj->__get_private()->{java_class} ;
+			my $id = $obj->__get_private()->{id} ;
 			push @ret, "object:$class:$id" ;
 		}
 		else{
@@ -291,7 +271,7 @@ sub Send {
 		croak $msg ;
 	}
 	elsif ($resp =~ /^ok scalar:([\d.]*)$/){
-		return pack("C*", split(/\./, $1)) ;
+		return pack("C*", split(/\./, $1)) ; 
 	}
 	elsif ($resp =~ /^ok undef:$/){
 		return undef ;
@@ -304,7 +284,7 @@ sub Send {
 		if ($const){
 			$this->{obj_priv}->{java_class} = $class ;
 			$this->{obj_priv}->{id} = $id ;
-			
+
 			return undef ;
 		}
 		else{
@@ -376,10 +356,7 @@ class InlineJavaProtocol {
 		StringTokenizer st = new StringTokenizer(cmd, " ") ;
 		String c = st.nextToken() ;
 
-		if (c.equals("call_static_method")){
-			CallStaticJavaMethod(st) ;
-		}		
-		else if (c.equals("call_method")){
+		if (c.equals("call_method")){
 			CallJavaMethod(st) ;
 		}		
 		else if (c.equals("set_member")){
@@ -480,7 +457,6 @@ class InlineJavaProtocol {
 		st2.nextToken() ;
 
 		String prop = pack(st2.nextToken()) ;
-		System.out.println(prop) ;
 		System.setProperty("java.class.path", prop) ;
 
 		SetResponse(null) ;
@@ -502,7 +478,7 @@ class InlineJavaProtocol {
 			throw new InlineJavaException("Object " + oid.toString() + " is not in HashMap!") ;
 		}
 
-		SetResponse(new Boolean(ijc.DoesExtend(c, d))) ;
+		SetResponse(new Integer(ijc.DoesExtend(c, d))) ;
 	}
 
 
@@ -546,52 +522,23 @@ class InlineJavaProtocol {
 
 
 	/*
-		Calls a static Java method
-	*/
-	void CallStaticJavaMethod(StringTokenizer st) throws InlineJavaException {
-		String class_name = st.nextToken() ;
-		String method = st.nextToken() ;
-		Class c = ijc.ValidateClass(class_name) ;
-		ArrayList f = ValidateMethod(false, c, method, st) ;
-
-		Method m = (Method)f.get(0) ;
-		String name = m.getName() ;
-		Object p[] = (Object [])f.get(1) ;
-		try {
-			Object ret = m.invoke(null, p) ;
-			SetResponse(ret) ;
-		}
-		catch (IllegalAccessException e){
-			throw new InlineJavaException("You are not allowed to invoke static method " + name + " in class " + class_name + ": " + e.getMessage()) ;
-		}
-		catch (IllegalArgumentException e){
-			throw new InlineJavaException("Arguments for static method " + name + " in class " + class_name + " are incompatible: " + e.getMessage()) ;
-		}
-		catch (InvocationTargetException e){
-			Throwable t = e.getTargetException() ;
-			String type = t.getClass().getName() ;
-			String msg = t.getMessage() ;
-			throw new InlineJavaException(
-				"Static method " + name + " in class " + class_name + " threw exception " + type + ": " + msg) ;
-		}
-	}
-
-
-	/*
-		Calls a regular Java method
+		Calls a Java method
 	*/
 	void CallJavaMethod(StringTokenizer st) throws InlineJavaException {
 		int id = Integer.parseInt(st.nextToken()) ;
 
-		Integer oid = new Integer(id) ;
-		Object o = ijs.objects.get(oid) ;
-		if (o == null){
-			throw new InlineJavaException("Object " + oid.toString() + " is not in HashMap!") ;
-		}
-
 		String class_name = st.nextToken() ;
-		// Use the class of the object
-		class_name = o.getClass().getName() ;
+		Object o = null ;
+		if (id > 0){
+			Integer oid = new Integer(id) ;
+			o = ijs.objects.get(oid) ;
+			if (o == null){
+				throw new InlineJavaException("Object " + oid.toString() + " is not in HashMap!") ;
+			}
+
+			// Use the class of the object
+			class_name = o.getClass().getName() ;
+		}
 
 		Class c = ijc.ValidateClass(class_name) ;
 		String method = st.nextToken() ;
@@ -633,15 +580,18 @@ class InlineJavaProtocol {
 	void SetJavaMember(StringTokenizer st) throws InlineJavaException {
 		int id = Integer.parseInt(st.nextToken()) ;
 
-		Integer oid = new Integer(id) ;
-		Object o = ijs.objects.get(oid) ;
-		if (o == null){
-			throw new InlineJavaException("Object " + oid.toString() + " is not in HashMap!") ;
-		}
-
 		String class_name = st.nextToken() ;
-		// Use the class of the object
-		class_name = o.getClass().getName() ;
+		Object o = null ;
+		if (id > 0){
+			Integer oid = new Integer(id) ;
+			o = ijs.objects.get(oid) ;
+			if (o == null){
+				throw new InlineJavaException("Object " + oid.toString() + " is not in HashMap!") ;
+			}
+
+			// Use the class of the object
+			class_name = o.getClass().getName() ;
+		}
 
 		Class c = ijc.ValidateClass(class_name) ;
 		String member = st.nextToken() ;
@@ -690,15 +640,18 @@ class InlineJavaProtocol {
 	void GetJavaMember(StringTokenizer st) throws InlineJavaException {
 		int id = Integer.parseInt(st.nextToken()) ;
 
-		Integer oid = new Integer(id) ;
-		Object o = ijs.objects.get(oid) ;
-		if (o == null){
-			throw new InlineJavaException("Object " + oid.toString() + " is not in HashMap!") ;
-		}
-
 		String class_name = st.nextToken() ;
-		// Use the class of the object
-		class_name = o.getClass().getName() ;
+		Object o = null ;
+		if (id > 0){
+			Integer oid = new Integer(id) ;
+			o = ijs.objects.get(oid) ;
+			if (o == null){
+				throw new InlineJavaException("Object " + oid.toString() + " is not in HashMap!") ;
+			}
+
+			// Use the class of the object
+			class_name = o.getClass().getName() ;
+		}
 
 		Class c = ijc.ValidateClass(class_name) ;
 		String member = st.nextToken() ;
diff --git a/MANIFEST b/MANIFEST
index 05d61d2..38f0428 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -9,7 +9,9 @@ Java/Init.pm
 Java/Object.pm
 Java/Protocol.pm
 Java/Class.pm
+Java/Array.pm
 Java/Makefile.PL
+Java/JVM.pm
 Java/JNI.pm
 Java/JNI.xs
 t/1_init.t
diff --git a/t/02_primitives.t b/t/02_primitives.t
index bbf336d..6a0e146 100644
--- a/t/02_primitives.t
+++ b/t/02_primitives.t
@@ -10,37 +10,142 @@ use Inline(
 
 
 BEGIN {
-	plan(tests => 21) ;
+	plan(tests => 100) ;
 }
 
 
 my $t = new types() ;
-ok($t->_byte("123"),124) ;
-ok($t->_Byte("123"), 123) ;
-ok($t->_short("123"), 124) ;
-ok($t->_Short("123"), 123) ;
-ok($t->_int("123"), 124) ;
-ok($t->_Integer("123"), 123) ;
-ok($t->_long("123"), 124) ;
-ok($t->_Long("123"), 123) ;
-ok($t->_float("123.456"), 124.456) ;
-ok($t->_Float("123.456"), 123.456) ;
-ok($t->_double("123.456"), 124.456) ;
-ok($t->_Double("123.456"), 123.456) ;
-
-ok($t->_boolean("true"), 1) ;
-ok($t->_Boolean("true"), 1) ; 
-ok($t->_boolean(""), 0) ;
-ok($t->_Boolean("0"), 0) ; 
+
+my $max = undef ;
+my $min = undef ;
+
+$max = 127 ;
+$min = -128 ;
+ok($t->_byte(undef) == 1) ;
+ok($t->_byte(0) == 1) ;
+ok($t->_byte($max - 1) == $max) ;
+ok($t->_byte("$min") == $min + 1) ;
+eval {$t->_byte($max + 1)} ; ok($@, qr/out of range/) ;
+eval {$t->_byte($min - 1)} ; ok($@, qr/out of range/) ;
+ok($t->_Byte(undef) == 0) ;
+ok($t->_Byte(0) == 0) ;
+ok($t->_Byte($max) == $max) ;
+ok($t->_Byte("$min") == $min) ;
+eval {$t->_Byte($max + 1)} ; ok($@, qr/out of range/) ;
+eval {$t->_Byte($min - 1)} ; ok($@, qr/out of range/) ;
+
+$max = 32767 ;
+$min = -32768 ;
+ok($t->_short(undef) == 1) ;
+ok($t->_short(0) == 1) ;
+ok($t->_short($max - 1) == $max) ;
+ok($t->_short("$min") == $min + 1) ;
+eval {$t->_short($max + 1)} ; ok($@, qr/out of range/) ;
+eval {$t->_short($min - 1)} ; ok($@, qr/out of range/) ;
+ok($t->_Short(undef) == 0) ;
+ok($t->_Short(0) == 0) ;
+ok($t->_Short($max) == $max) ;
+ok($t->_Short("$min") == $min) ;
+eval {$t->_Short($max + 1)} ; ok($@, qr/out of range/) ;
+eval {$t->_Short($min - 1)} ; ok($@, qr/out of range/) ;
+
+$max = 2147483647 ;
+$min = -2147483648 ;
+ok($t->_int(undef) == 1) ;
+ok($t->_int(0) == 1) ;
+ok($t->_int($max - 1) == $max) ;
+ok($t->_int("$min") == $min + 1) ;
+eval {$t->_int($max + 1)} ; ok($@, qr/out of range/) ;
+eval {$t->_int($min - 1)} ; ok($@, qr/out of range/) ;
+ok($t->_Integer(undef) == 0) ;
+ok($t->_Integer(0) == 0) ;
+ok($t->_Integer($max) == $max) ;
+ok($t->_Integer("$min") == $min) ;
+eval {$t->_Integer($max + 1)} ; ok($@, qr/out of range/) ;
+eval {$t->_Integer($min - 1)} ; ok($@, qr/out of range/) ;
+
+$max = 2147483647 ;
+$min = -2147483648 ;
+ok($t->_long(undef) == 1) ;
+ok($t->_long(0) == 1) ;
+ok($t->_long($max - 1) == $max) ;
+ok($t->_long("$min") == $min + 1) ;
+eval {$t->_long($max + 1)} ; ok($@, qr/out of range/) ;
+eval {$t->_long($min - 1)} ; ok($@, qr/out of range/) ;
+ok($t->_Long(undef) == 0) ;
+ok($t->_Long(0) == 0) ;
+ok($t->_Long($max) == $max) ;
+ok($t->_Long("$min") == $min) ;
+eval {$t->_Long($max + 1)} ; ok($@, qr/out of range/) ;
+eval {$t->_Long($min - 1)} ; ok($@, qr/out of range/) ;
+
+$max = 3.4028235e38 ;
+$min = -3.4028235e38 ;
+ok($t->_float(undef) == 1) ;
+ok($t->_float(0) == 1) ;
+ok($t->_float($max - 1) == $max) ;
+ok($t->_float("$min") == $min + 1) ;
+eval {$t->_float($max + $max)} ; ok($@, qr/out of range/) ;
+eval {$t->_float($min + $min)} ; ok($@, qr/out of range/) ;
+ok($t->_Float(undef) == 0) ;
+ok($t->_Float(0) == 0) ;
+ok($t->_Float($max) == $max) ;
+ok($t->_Float("$min") == $min) ;
+eval {$t->_Float($max + $max)} ; ok($@, qr/out of range/) ;
+eval {$t->_Float($min + $min)} ; ok($@, qr/out of range/) ;
+
+$max = 3.4028235e38 ;
+$min = -3.4028235e38 ;
+ok($t->_double(undef) == 1) ;
+ok($t->_double(0) == 1) ;
+ok($t->_double($max - 1) == $max) ;
+ok($t->_double("$min") == $min + 1) ;
+eval {$t->_double($max + $max)} ; ok($@, qr/out of range/) ;
+eval {$t->_double($min + $min)} ; ok($@, qr/out of range/) ;
+ok($t->_Double(undef) == 0) ;
+ok($t->_Double(0) == 0) ;
+ok($t->_Double($max) == $max) ;
+ok($t->_Double("$min") == $min) ;
+eval {$t->_Double($max + $max)} ; ok($@, qr/out of range/) ;
+eval {$t->_Double($min + $min)} ; ok($@, qr/out of range/) ;
+
+ok(! $t->_boolean(undef)) ;
+ok(! $t->_boolean(0)) ;
+ok(! $t->_boolean("")) ;
+ok($t->_boolean("true")) ;
+ok($t->_boolean(1)) ;
+ok(! $t->_Boolean(undef)) ; 
+ok(! $t->_Boolean(0)) ; 
+ok(! $t->_Boolean("")) ; 
+ok($t->_Boolean("true")) ; 
+ok($t->_Boolean(1)) ; 
+
+ok($t->_char(undef), "\0") ;
+ok($t->_char(0), "0") ;
 ok($t->_char("1"), '1') ;
+eval {$t->_char("10")} ; ok($@, qr/Can't convert/) ;
+ok($t->_Character(undef), "\0") ;
+ok($t->_Character(0), "0") ;
 ok($t->_Character("1"), '1') ;
+eval {$t->_Character("10")} ; ok($@, qr/Can't convert/) ;
 
+ok($t->_String(undef), undef) ;
+ok($t->_String(0), "0") ;
 ok($t->_String("string"), 'string') ;
-ok($t->_StringBuffer("string_buffer"), 'string_buffer') ;
-
-# Test if scalars can pass as java.lang.Object (they should).
+ok($t->_StringBuffer(undef), undef) ;
+ok($t->_StringBuffer(0), "0") ;
+ok($t->_StringBuffer("stringbuffer"), 'stringbuffer') ;
+
+# Test if scalars can pass as java.lang.Object.
+# They should be converted to strings.
+ok($t->_Object(undef), undef) ;
+ok($t->_Object(0), "0") ;
+ok($t->_Object(666) == 666) ;
 ok($t->_Object("object"), 'object') ;
 
+
+
+
 __END__
 
 __Java__
diff --git a/t/03_objects.t b/t/03_objects.t
index 2bac0eb..ba92536 100644
--- a/t/03_objects.t
+++ b/t/03_objects.t
@@ -10,47 +10,43 @@ use Inline(
 
 
 BEGIN {
-	plan(tests => 15) ;
+	plan(tests => 13) ;
 }
 
 
-my $o1 = new obj_test() ;
-my $o2 = new obj_test() ;
-ok($o1->get_data(), "data") ;
-ok($o2->get_data(), "data") ;
-ok($o1->get_this()->get_data(), "data") ;
-ok($o1->get_that($o2)->get_data(), "data") ;
+# Create some objects
+my $t = new types() ;
 
-$o1->set_data("new data") ;
-ok($o1->get_data(), "new data") ;
-ok($o2->get_data(), "new data") ;
+my $obj1 = new obj1() ;
+eval {my $obj2 = new obj2()} ; ok($@, qr/No public constructor/) ;
+my $obj11 = new obj11() ;
 
-obj_test->set_data("new new data") ;
-ok($o1->get_data(), "new new data") ;
-ok($o2->get_data(), "new new data") ;
+ok($t->_obj1(undef), undef) ;
+ok($t->_obj1($obj1)->get_data(), "obj1") ;
+ok($t->_obj11($obj11)->get_data(), "obj11") ;
+ok($t->_obj1($obj11)->get_data(), "obj11") ;
+eval {$t->_int($obj1)} ; ok($@, qr/Can't convert (.*) to primitive int/) ;
+eval {$t->_obj11($obj1)} ; ok($@, qr/is not a kind of/) ;
 
-my $so1 = new sub_obj_test(5) ;
-my $so2 = new sub_obj_test(6) ;
-ok($so1->get_data(), "new new data") ;
-ok($so1->get_number(), 5) ;
-ok($so2->get_number(), 6) ;
+# Receive an unbound object and send it back
+my $unb = $t->get_unbound() ;
+ok($t->send_unbound($unb), "al_elem") ;
 
-$so1->set_number(7) ;
-ok($so1->get_number(), 7) ;
+# Unexisting method
+eval {$t->toto()} ; ok($@, qr/No public method/) ;
 
-my $io = new obj_test::inner_obj_test($o1) ;
-ok($io->get_data(), "new new data") ;
+# Method on unbound object
+eval {$unb->toto()} ; ok($@, qr/Can't call method/) ;
 
-my $al = $o1->new_arraylist() ;
-$o1->set_arraylist($al, "array data") ;
-ok($o1->get_arraylist($al), "array data") ;
+# Incompatible prototype, 1 signature
+eval {$t->_obj1(5)} ; ok($@, qr/Can't convert/) ;
 
+# Incompatible prototype, >1 signature
+eval {$t->__obj1(5)} ; ok($@, qr/Can't find any signature/) ;
+
+# Return a scalar hidden in an object.
+ok($t->_olong(), 12345) ;
 
-my $so3 = new sub_obj_test(100) ;
-my $ow = new obj_wrap($so3) ;
-my $do = new obj_do($ow) ;
-$do->get_obj()->set_obj($so2) ;
-ok($do->get_obj_data()->get_number(), 6) ;
 
 __END__
 
@@ -59,95 +55,84 @@ __Java__
 import java.util.* ;
 
 
-class obj_test {
-	public static String data = "data" ;
+class obj1 {
+	String data = "obj1" ;
 
-	public obj_test(){
+	public obj1() {
 	}
 
-	public obj_test get_this(){
-		return this ;
+	public String get_data(){
+		return data ;
 	}
+}
 
-	public obj_test get_that(obj_test o){
-		return o ;
-	}
+class obj11 extends obj1 {
+	String data = "obj11" ;
 
-	public static String get_data(){
-		return data ;
+	public obj11() {
 	}
 
-	public static void set_data(String d){
-		data = d ;
-	}
-	
-	public ArrayList new_arraylist(){
-		return new ArrayList() ;
+	public String get_data(){
+		return data ;		
 	}
+}
 
-	public void set_arraylist(ArrayList a, String s){
-		a.add(0, s) ;
-	}
 
-	public String get_arraylist(ArrayList a){
-		return (String)a.get(0) ;
-	}
+class obj2 {
+	String data = "obj2" ;
 
-	
-	class inner_obj_test {
-		public inner_obj_test(){
-		}
+	obj2() {
+	}
 
-		public String get_data(){
-			return obj_test.this.get_data() ;
-		}
+	public String get_data(){
+		return data ;		
 	}
 }
 
 
-class sub_obj_test extends obj_test {
-	public int number ;
-
-	public sub_obj_test(int num){
-		super() ;
-		number = num ;
+class types {
+	public types(){
 	}
 
-	public int get_number(){
-		return number ;
+	public int _int(int i){
+		return i + 1 ;
 	}
 
-	public void set_number(int num){
-		number = num ;
+	public Object _Object(Object o){
+		return o ;
 	}
-}
 
+	public obj1 _obj1(obj1 o){
+		return o ;
+	}
 
-/* Has an object as a member variable */
-class obj_wrap {
-	public sub_obj_test obj ;
 
-	public obj_wrap(sub_obj_test o){
-		obj = o ;
+	public obj1 __obj1(obj1 o, int i){
+		return o ;
 	}
 
-	public void set_obj(sub_obj_test o){
-		obj = o ;
+
+	public obj1 __obj1(obj1 o){
+		return o ;
 	}
-}
 
 
-class obj_do {
-	public obj_wrap obj ;
+	public obj11 _obj11(obj11 o){
+		return o ;
+	}
+
+	public ArrayList get_unbound(){
+		ArrayList al = new ArrayList() ;
+		al.add(0, "al_elem") ;
 
-	public obj_do(obj_wrap o){
-		obj = o ;
+		return al ;
 	}
 
-	public obj_wrap get_obj(){
-		return obj ;
+	public String send_unbound(ArrayList al){
+		return (String)al.get(0) ;
 	}
-	public sub_obj_test get_obj_data(){
-		return obj.obj ;
+
+	public Object _olong(){
+		return new Long("12345") ;
 	}
 }
diff --git a/t/04_members.t b/t/04_members.t
index d931138..20e57e6 100644
--- a/t/04_members.t
+++ b/t/04_members.t
@@ -10,31 +10,79 @@ use Inline(
 
 
 BEGIN {
-	plan(tests => 8) ;
+	plan(tests => 27) ;
 }
 
 
-my $o1 = new obj_test() ;
-ok($o1->{i}, 7) ;
-ok($o1->{s}, "data") ;
-my $om = $o1->{om} ;
-ok($om->getl(), 67) ;
-ok($om->{string}, "blablabla") ;
-
-$o1->{i} = 5 ;
-$o1->{s} = 5 ;
-$om->{string} = "yoyo" ;
-
-ok($o1->{i}, 5) ;
-ok($o1->{s}, "5") ;
-ok($om->{string}, "yoyo") ;
-
-my $o2 = new obj_member(123456) ;
-$o1->{om} = $o2 ;
-$om = $o1->{om} ;
-ok($om->getl(), 123456) ;
-
-
+my $t = new types() ;
+
+$t->{_byte} = 123 ;
+ok($t->{_byte} == 123) ;
+$t->{_Byte} = 123 ;
+ok($t->{_Byte} == 123) ;
+
+$t->{_short} = 123 ;
+ok($t->{_short} == 123) ;
+$t->{_Short} = 123 ;
+ok($t->{_Short} == 123) ;
+
+$t->{_int} = 123 ;
+ok($t->{_int} == 123) ;
+$t->{_Integer} = 123 ;
+ok($t->{_Integer} == 123) ;
+
+$t->{_long} = 123 ;
+ok($t->{_long} == 123) ;
+$t->{_Long} = 123 ;
+ok($t->{_Long} == 123) ;
+
+$t->{_float} = 123.456 ;
+ok($t->{_float} == 123.456) ;
+$t->{_Float} = 123.456 ;
+ok($t->{_Float} == 123.456) ;
+
+$t->{_double} = 123.456 ;
+ok($t->{_double} == 123.456) ;
+$t->{_Double} = 123.456 ;
+ok($t->{_Double} == 123.456) ;
+
+$t->{_boolean} = 1 ;
+ok($t->{_boolean}) ;
+$t->{_Boolean} = 1 ;
+ok($t->{_Boolean}) ;
+
+$t->{_char} = "a" ;
+ok($t->{_char}, "a") ;
+$t->{_Character} = "a" ;
+ok($t->{_Character}, "a") ;
+
+$t->{_String} = "string" ;
+ok($t->{_String}, "string") ;
+$t->{_StringBuffer} = "stringbuffer" ;
+ok($t->{_StringBuffer}, "stringbuffer") ;
+
+my $obj1 = new obj1() ;
+$t->{_Object} = $obj1 ;
+ok($t->{_Object}->get_data(), "obj1") ;
+$t->{_Object} = "object" ;
+ok($t->{_Object}, "object") ;
+
+$t->{_Object} = undef ;
+ok($t->{_Object}, undef) ;
+$t->{_int} = undef ;
+ok($t->{_int} == 0) ;
+
+# Receive an unbound object and try to call a member
+my $unb = $t->get_unbound() ;
+eval {$unb->{toto} = 1} ; ok($@, qr/Can't set member/) ;
+eval {my $a = $unb->{toto}} ; ok($@, qr/Can't get member/) ;
+
+# Unexisting member
+eval {$t->{toto} = 1} ; ok($@, qr/No public member/) ;
+eval {my $a = $t->{toto}} ; ok($@, qr/No public member/) ;
+
+# Incompatible type
+eval {$t->{_long} = $obj1} ; ok($@, qr/Can't convert/) ;
 
 __END__
 
@@ -42,26 +90,51 @@ __Java__
 
 import java.util.* ;
 
+class obj1 {
+	String data = "obj1" ;
 
-class obj_test {
-	public int i = 7 ;
-	public String s = "data" ;
-	public obj_member om = new obj_member(67) ;
+	public obj1() {
+	}
 
-	public obj_test(){
+	public String get_data(){
+		return data ;		
 	}
 }
 
 
-class obj_member {
-	long l ;
-	public String string = "blablabla" ;
+class types {
+	public byte _byte ;
+	public Byte _Byte ;
+	public short _short ;
+	public Short _Short ;
+	public int _int ;
+	public Integer _Integer ;
+	public long _long ;
+	public Long _Long ;
+	public float _float ;
+	public Float _Float ;
+	public double _double ;
+	public Double _Double ;
+	public boolean _boolean ;
+	public Boolean _Boolean ;
+	public char _char ;
+	public Character _Character ;
+	public String _String ;
+	public StringBuffer _StringBuffer ;
+	public Object _Object ;
+
+	public types(){
+	}
+
+	public ArrayList get_unbound(){
+		ArrayList al = new ArrayList() ;
+		al.add(0, "al_elem") ;
 
-	public obj_member(long a){
-		l = a ;
+		return al ;
 	}
 
-	public long getl(){
-		return l ;
+	public String send_unbound(ArrayList al){
+		return (String)al.get(0) ;
 	}
 }
+
diff --git a/t/05_arrays.t b/t/05_arrays.t
index 3adc494..54171a6 100644
--- a/t/05_arrays.t
+++ b/t/05_arrays.t
@@ -10,51 +10,173 @@ use Inline(
 
 
 BEGIN {
-	plan(tests => 2) ;
+	plan(tests => 31) ;
 }
 
 
-my $a = new array_test() ;
-my $data = $a->get_data() ;
-ok($a->do_data($data), 'data') ;
-my $sdata = $a->get_sdata() ;
-ok($a->do_sdata($sdata), 'sdata') ;
+my $t = new types() ;
+
+ok($t->_byte([12, 34, 56])->[0] == 123) ;
+ok($t->_Byte([12, 34, 56])->[1] == 34) ;
+ok($t->_short([12, 34, 56])->[0] == 123) ;
+ok($t->_Short([12, 34, 56])->[1] == 34) ;
+ok($t->_int([12, 34, 56])->[0] == 123) ;
+ok($t->_Integer([12, 34, 56])->[1] == 34) ;
+ok($t->_long([12, 34, 56])->[0] == 123) ;
+ok($t->_Long([12, 34, 56])->[1] == 34) ;
+ok($t->_float([12.34, 5.6, 7])->[0] == 123.456) ;
+ok($t->_Float([12.34, 5.6, 7])->[1] == 5.6) ;
+ok($t->_double([12.34, 5.6, 7])->[0] == 123.456) ;
+ok($t->_Double([12.34, 5.6, 7])->[1] == 5.6) ;
+ok($t->_boolean([1, 0, "tree"])->[0]) ;
+ok(! $t->_Boolean([1, 0])->[1]) ;
+ok($t->_char(['a', 'b', 'c'])->[0], "A") ;
+ok($t->_Character(['a', 'b', 'c'])->[1], 'b') ;
+ok($t->_String(["bla", "ble", "bli"])->[0], "STRING") ;
+ok($t->_StringBuffer(["bla", "ble", "bli"])->[0], "STRINGBUFFER") ;
+
+ok($t->_Object(undef), undef) ;
+my $a = $t->_Object([1, "two", $t]) ;
+ok($a->[0], "1") ;
+ok($a->[1], "two") ;
+ok(UNIVERSAL::isa($a->[2], "main::types")) ;
+ok($a->[2]->{data}->[1], "a") ;
+
+# Try some multidimensional arrays.
+$a = $t->_StringString([
+	["00", "01"],
+	["10", "11"]
+]) ;
+ok($a->[1]->[0], "10") ;
+
+# Try some incomplete multidimensional arrays.
+$a = $t->_StringString([
+	[undef, "01", "02"],
+	[undef, "11"],
+	undef,
+]) ;
+ok($a->[1]->[0], undef) ;
+
+# Arrays of other arrays
+$a = $t->_StringString([
+	$a->[0],
+]) ;
+ok($a->[0]->[2], "02") ;
+
+# This is one of the things that won't work. 
+# Try passing an array as an Object.
+eval {$t->_o(["a", "b", "c"])} ; ok($@, qr/Can't create Java array/) ;
+
+# Mixed types
+eval {$t->_int(["3", "3456", "cat"])} ; ok($@, qr/Can't convert/) ;
+ok($t->_Object(["3", "3456", "cat"])->[2], 'cat') ; 
+
+# Badly constructed array
+eval {$t->_int(["3", [], "cat"])} ; ok($@, qr/Java array contains mixed types/) ;
+eval {$t->_StringString([["3"], "string"])} ; ok($@, qr/Java array contains mixed types/) ;
 
 
 __END__
 
 __Java__
 
-class array_test {
+
+class types {
 	public String data[] = {"d", "a", "t", "a"} ;
-	public static String sdata[][] = {{"s"}, {"d"}, {"a"}, {"t"}, {"a"}} ;
+	public types(){
+	}
 
-	public array_test(){
+	public byte[] _byte(byte b[]){
+		b[0] = (byte)123 ;
+		return b ;
 	}
 
-	public String [] get_data(){
-		return data ;
+	public Byte[] _Byte(Byte b[]){
+		return b ;
 	}
 
-	public StringBuffer do_data(String d[]){
-		StringBuffer sb = new StringBuffer() ;
-		for (int i = 0 ; i < d.length ; i++){
-			sb.append(d[i]) ;
-		}
+	public short[] _short(short s[]){
+		s[0] = (short)123 ;
+		return s ;
+	}
 
-		return sb ;
+	public Short[] _Short(Short s[]){
+		return s ;
 	}
 
-	public static String [][] get_sdata(){
-		return sdata ;
+	public int[] _int(int i[]){
+		i[0] = 123 ;
+		return i ;
 	}
 
-	public StringBuffer do_sdata(String d[][]){
-		StringBuffer sb = new StringBuffer() ;
-		for (int i = 0 ; i < d.length ; i++){
-			sb.append(d[i][0]) ;
-		}
+	public Integer[] _Integer(Integer i[]){
+		return i ;
+	}
+
+	public long[] _long(long l[]){
+		l[0] = 123 ;
+		return l ;
+	}
+
+	public Long[] _Long(Long l[]){
+		return l ;
+	}
+
+	public float[] _float(float f[]){
+		f[0] = (float)123.456 ;
+		return f ;
+	}
+
+	public Float[] _Float(Float f[]){
+		return f ;
+	}
+
+	public double[] _double(double d[]){
+		d[0] = 123.456 ;
+		return d ;
+	}
+
+	public Double[] _Double(Double d[]){
+		return d ;
+	}
 
+	public boolean[] _boolean(boolean b[]){
+		b[0] = true ;
+		return b ;
+	}
+
+	public Boolean[] _Boolean(Boolean b[]){
+		return b ;
+	}
+
+	public char[] _char(char c[]){
+		c[0] = 'A' ;
+		return c ;
+	}
+
+	public Character[] _Character(Character c[]){
+		return c ;
+	}
+
+	public String[] _String(String s[]){
+		s[0] = "STRING" ;
+		return s ;
+	}
+
+	public String[][] _StringString(String s[][]){
+		return s ;
+	}
+
+	public StringBuffer[] _StringBuffer(StringBuffer sb[]){
+		sb[0] = new StringBuffer("STRINGBUFFER") ;
 		return sb ;
 	}
+
+	public Object[] _Object(Object o[]){
+		return o ;
+	}
+
+	public Object _o(Object o){
+		return o ;
+	}
 }
diff --git a/t/06_static.t b/t/06_static.t
index 035b3cb..9ffda02 100644
--- a/t/06_static.t
+++ b/t/06_static.t
@@ -10,13 +10,29 @@ use Inline(
 
 
 BEGIN {
-	plan(tests => 2) ;
+	plan(tests => 7) ;
 }
 
 
+# Methods
 ok(types->get("key"), undef) ;
-my $t = new types() ;
-ok(types->get("key"), "value") ;
+my $t = new types("key", "value") ;
+ok($t->get("key"), "value") ;
+
+# Members
+ok($types::i == 5) ;
+$types::i = 7 ;
+ok($t->{i} == 7) ;
+
+my $t2 = new types("key2", "value2") ;
+my $hm = $types::hm ;
+ok(types->get($hm, "key2"), "value2") ;
+
+$types::hm = $hm ;
+ok($t2->get("key2"), "value2") ;
+
+# Calling an instance method without an object reference
+eval {types->set()} ; ok($@, qr/must be called from an object reference/) ;
 
 
 __END__
@@ -24,16 +40,27 @@ __END__
 __Java__
 
 
+import java.util.* ;
+
+
 class types {
-	public static int = 5 ;
+	public static int i = 5 ;
 	public static HashMap hm = new HashMap() ;
 
-	public types(){
-		hm.add("key", "value") ;
+	public types(String k, String v){
+		hm.put(k, v) ;
+	}
+
+	public static String get(String k){
+		return (String)hm.get(k) ; 
+	}
+
+	public static String get(HashMap h, String k){
+		return (String)h.get(k) ; 
 	}
 
-	public static HashMap get(String k){
-		return hm.get(k) ; 
+	public String set(){
+		return "set" ;
 	}
 }
 
diff --git a/t/07_polymorph.t b/t/07_polymorph.t
index 035b3cb..c8b8ddc 100644
--- a/t/07_polymorph.t
+++ b/t/07_polymorph.t
@@ -8,15 +8,37 @@ use Inline(
 	Java => 'DATA'
 ) ;
 
+use Inline::Java qw(cast) ;
+
 
 BEGIN {
-	plan(tests => 2) ;
+	plan(tests => 15) ;
 }
 
 
-ok(types->get("key"), undef) ;
 my $t = new types() ;
-ok(types->get("key"), "value") ;
+my $t1 = new t1() ;
+
+ok($t->func(5), "int") ;
+ok($t->func(cast("char", 5)), "char") ;
+ok($t->func(55), "int") ;
+ok($t->func("str"), "string") ;
+ok($t->func(cast("java.lang.StringBuffer", "str")), "stringbuffer") ;
+
+ok($t->f($t->{hm}), "hashmap") ;
+ok($t->f(cast("java.lang.Object", $t->{hm})), "object") ;
+
+ok($t->f(["a", "b", "c"]), "string[]") ;
+ok($t->f(cast("java.lang.Object", ['a'], "[Ljava.lang.String;")), "object") ;
+
+eval {$t->func($t1)} ; ok($@, qr/Can't find any signature/) ;
+eval {$t->func(cast("int", $t1))} ; ok($@, qr/Can't convert (.*) to primitive int/) ;
+
+my $t2 = new t2() ;
+ok($t2->f($t2), "t1") ;
+ok($t1->f($t2), "t1") ;
+ok($t2->f($t1), "t2") ;
+ok($t2->f(cast("t1", $t2)), "t2") ;
 
 
 __END__
@@ -24,16 +46,60 @@ __END__
 __Java__
 
 
+import java.util.* ;
+
+class t1 {
+	public t1(){
+	}
+
+	public String f(t2 o){
+		return "t1" ;
+	}
+}
+
+
+class t2 extends t1 {
+	public t2(){
+	}
+
+	public String f(t1 o){
+		return "t2" ;
+	}
+}
+
+
 class types {
-	public static int = 5 ;
-	public static HashMap hm = new HashMap() ;
+	public HashMap hm = new HashMap() ;
 
 	public types(){
-		hm.add("key", "value") ;
 	}
 
-	public static HashMap get(String k){
-		return hm.get(k) ; 
+	public String func(String o){
+		return "string" ;
+	}
+
+	public String func(StringBuffer o){
+		return "stringbuffer" ;
+	}
+
+	public String func(int o){
+		return "int" ;
+	}
+
+	public String func(char o){
+		return "char" ;
+	}
+
+	public	String f(HashMap o){
+		return "hashmap" ;
+	}
+
+	public String f(Object o){
+		return "object" ;
+	}
+
+	public String f(String o[]){
+		return "string[]" ;
 	}
 }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libinline-java-perl.git



More information about the Pkg-perl-cvs-commits mailing list