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

Jonas Smedegaard dr at jones.dk
Thu Feb 26 11:42:44 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 32b7bcd2cb2eb6392217fd3cc449cab57a68c9bd
Author: patrick <>
Date:   Wed Mar 28 19:44:27 2001 +0000

    *** empty log message ***
---
 Java/Array.pm    | 566 ++++++++++++++++++++++++++++++++++++-------------------
 Java/Class.pm    |  89 +++++++--
 Java/Init.pm     |  21 ++-
 Java/Object.pm   | 135 ++++++++++---
 Java/Protocol.pm | 453 +++++++++++++++++++++++++++++++++++++-------
 MANIFEST         |   3 +-
 Makefile.PL      |  14 +-
 7 files changed, 968 insertions(+), 313 deletions(-)

diff --git a/Java/Array.pm b/Java/Array.pm
index dad42b6..4fb8765 100644
--- a/Java/Array.pm
+++ b/Java/Array.pm
@@ -4,108 +4,309 @@ package Inline::Java::Array ;
 
 use strict ;
 
-$Inline::Java::Array::VERSION = '0.01' ;
+$Inline::Java::Array::VERSION = '0.10' ;
 
-use Inline::Java::Object ;
 use Tie::Array ;
 use Carp ;
 
 
-# This class is instantiated  to do the conversion between a perl
-# array and a Java array. It can take a Perl array, validate it, fill it
-# and flatten it or order to send to Java to get an object created.
-#
-# In the reverse sense, it takes a flattened array from Java and constructs
-# a structure of blessed perl arrays that serves as an interface to the 
-# array. 
-#
-# This class in not meant to be instantiated by the user.
+# Here we store the objects that corresponds to the arrays.
+my $OBJECTS = {} ;
 
 
-# Here we will store each of the arrays in order to be able
-# to add extra data.
-my $ARRAYS = {} ;
+sub new {
+	my $class = shift ;
+	my $object = shift ;
+
+	my @this = () ;
+	my $knot = tie @this, 'Inline::Java::Array' ;
+	my $this = bless (\@this, $class) ;
+
+	$OBJECTS->{$knot} = $object ;
+
+	Inline::Java::debug("this = $this") ; 
+	Inline::Java::debug("knot = $knot") ; 
+
+	return $this ;
+}
+
+
+sub length {
+	my $this = shift ;
+
+	my $obj = $this->__get_object() ;
+
+	my $ret = undef ;
+	eval {
+		$ret = $obj->{private}->{proto}->CallJavaMethod('getLength', [], []) ;
+	} ;
+	croak $@ if $@ ;
+
+	return $ret  ;
+}
+
+
+sub __get_object {
+	my $this = shift ;
+
+	my $knot = tied @{$this} || $this ;
+	Inline::Java::debug("this = $this") ; 
+	Inline::Java::debug("knot = $knot") ; 
+
+	my $obj = $OBJECTS->{$knot} ;
+	if (! defined($obj)){
+		croak "Unknown Java array reference" ;
+	}
+	
+	return $obj ;
+}
+
+
+
+sub AUTOLOAD {
+	my $this = shift ;
+	my @args = @_ ;
+
+	use vars qw($AUTOLOAD) ;
+	my $func_name = $AUTOLOAD ;
+	# Strip package from $func_name, Java will take of finding the correct
+	# method.
+	$func_name =~ s/^(.*)::// ;
+
+	Inline::Java::debug("$func_name") ;
+
+	croak "Can't call method $func_name on Java arrays" ;
+}
+
+
+sub DESTROY {
+	my $this = shift ;
+
+	$OBJECTS->{$this} = undef ;
+}
+
+
+
+######################## Array methods ########################
+
+
+sub TIEARRAY {
+	my $class = shift ;
+
+	return $class->SUPER::TIEARRAY(@_) ;
+}
+
+
+sub FETCHSIZE { 
+ 	my $this = shift ;
+
+	return $this->length() ;  
+}
+
+
+sub STORE { 
+ 	my $this = shift ;
+ 	my $idx = shift ;
+ 	my $s = shift ;
+
+	my $max = $this->length() - 1 ;
+	if ($idx > $max){
+		croak("Java array index out of bounds ($idx > $max)")
+	}
+
+	my $obj = $this->__get_object() ; 
+
+	# Now we need to find out if what we are trying to set matches
+	# the array.
+	my $java_class = $obj->{private}->{java_class} ;
+	my $elem_class = $java_class ;
+	my $an = new Inline::Java::ArrayNorm($java_class) ;
+	if ($an->{req_nb_dim} > 1){
+		$elem_class =~ s/^\[// ;
+	}
+	else{
+		$elem_class = $an->{req_element_class} ;
+	}
+
+	my $ret = undef ;
+	eval {
+		my ($new_args, $score) = Inline::Java::Class::CastArguments([$s], [$elem_class], $obj->{private}->{module}) ;
+		$ret = $obj->{private}->{proto}->SetJavaMember($idx, [$elem_class], $new_args) ;
+	} ;
+	croak $@ if $@ ;
+
+	return $ret ;
+} 
+
+
+sub FETCH { 
+ 	my $this = shift ;
+ 	my $idx = shift ;
+
+	my $max = $this->length() - 1 ;
+	if ($idx > $max){
+		croak("Java array index out of bounds ($idx > $max)")
+	}
+
+	my $obj = $this->__get_object() ; 
+
+	my $ret = undef ;
+	eval {
+		$ret = $obj->{private}->{proto}->GetJavaMember($idx, ['java.lang.Object'], [undef]) ;
+	} ;
+	croak $@ if $@ ;
+
+	return $ret ;
+}
+
+
+sub EXISTS {
+ 	my $this = shift ;
+ 	my $idx = shift ;
+
+	return $this->SUPER::EXISTS($idx) ;
+}
+
+
+sub STORESIZE {
+ 	my $this = shift ;
+ 	my $size = shift ;
+
+	croak "Operation STORESIZE not supported on Java array" ;
+}
+
+
+sub CLEAR {
+ 	my $this = shift ;
+
+	croak "Operation CLEAR not supported on Java array" ;
+}
+
+
+sub POP {
+ 	my $this = shift ;
+
+	croak "Operation POP not supported on Java array" ;
+}
+
+
+sub PUSH {
+ 	my $this = shift ;
+	my @list = @_ ;
+
+	croak "Operation PUSH not supported on Java array" ;
+}
+
+
+sub SHIFT {
+ 	my $this = shift ;
+
+	croak "Operation SHIFT not supported on Java array" ;
+} 
+
+
+sub UNSHIFT {
+ 	my $this = shift ;
+	my @list = @_ ;
+
+	croak "Operation UNSHIFT not supported on Java array" ;
+} 
+
+
+sub DELETE {
+ 	my $this = shift ;
+	my $idx = shift ;
+
+	croak "Operation DELETE not supported on Java array" ;
+}
+
+
+
+######################## Inline::Java::Array::Normalizer ########################
+package Inline::Java::Array::Normalizer ;
+
+
+use Carp ;
+
 
 sub new {
 	my $class = shift ;
 	my $java_class = shift ;
+	my $ref = shift ;
 
 	if (! Inline::Java::Class::ClassIsArray($java_class)){
-		croak "Can't create Inline::Java::Array object for non-array class $java_class" ;
+		croak "Can't create Inline::Java::Array::Normalizer object for non-array class $java_class" ;
 	}
 
-	my @this = [] ;
-	tie @this, 'Inline::Java::Array' ;
-	bless (\@this, $class) ;
-
-	my $this = \@this ;
-	$ARRAYS->{$this} = {
-		array => $this,
-		class => $class,
-		java_class => $java_class,
-		map => {},
-	} ;
+	my $this = {} ;
+	$this->{class} = $class ;
+	$this->{java_class} = $java_class ;
+	$this->{map} = {} ;
+	$this->{ref} = $ref ;
+	$this->{array} = [] ;
+	
+	bless ($this, $class) ;
 
 	# The first thing we want to do is figure out what kind of array we want,
 	# and how many dimensions it should have.
-	$this->__analyze_array_class() ;
+	$this->AnalyzeArrayClass() ;
 
-	# Inline::Java::debug_obj($ARRAYS->{$this}) ;
+	if ($ref){
+		$this->InitFromArray() ;
+	}
 
 	return $this ;
 }
 
 
-sub __init_from_array {
+sub InitFromArray {
 	my $this = shift ;
-	my $ref = shift ;
 	my $level = shift ;
 
-	$this->__validate_array($ref, 1) ;
+	my $ref = $this->{ref} ;
+
+	$this->ValidateArray($ref, 1) ;
 
 	# Now that we now that this array is valid, we need to carry
 	# over the stuff in $ref into ourselves.
 	# sub arrays into array_objects
-	$this->__import_from_array($ref, $level) ;
+	$this->ImportFromArray($level) ;
 
 	if (! $level){
-		Inline::Java::debug_obj($ARRAYS->{$this}) ;
+		# Inline::Java::debug_obj($this) ;
 	}
 }
 
 
-sub __import_from_array {
+sub ImportFromArray {
 	my $this = shift ;
-	my $ref = shift ;
 	my $level = shift ;
 
-	my $extra = $ARRAYS->{$this} ;
+	my $ref = $this->{ref} ;
 
 	for (my $i = 0 ; $i < scalar(@{$ref}) ; $i++){
 		my $elem = $ref->[$i] ;
 
 		if (UNIVERSAL::isa($elem, "ARRAY")){
-			my $java_class = $extra->{java_class} ;
+			my $java_class = $this->{java_class} ;
 
-			# We need top drop the array by 1 dimension
+			# We need to drop the array by 1 dimension
 			$java_class =~ s/^\[// ;
-			my $obj = new Inline::Java::Array($java_class) ;
-			$obj->__init_from_array($elem, $level + 1) ;
-			$elem = $obj ;
+			my $obj = new Inline::Java::Array::Normalizer($java_class, $elem) ;
+			$elem = $obj->{array} ;
 		}
-		my $nb = scalar(@{$this}) ;
-		$this->[$nb] = $elem ;
+		my $nb = scalar(@{$this->{array}}) ;
+		$this->{array}->[$nb] = $elem ;
 	}
 }
 
 
-sub __init_from_flat {
+sub InitFromFlat {
 	my $this = shift ;
 	my $dims = shift ;
 	my $list = shift ;
 	my $level = shift ;
 
-	my $extra = $ARRAYS->{$this} ;
 	my $nb_list = scalar(@{$list}) ;
 	my $parts = $dims->[0] ;
 
@@ -128,32 +329,31 @@ sub __init_from_flat {
 			my $nb_elems = $nb_list / $parts ;
 			my @sub = splice(@{$list}, 0, $nb_elems) ;
 
-			my $java_class = $extra->{java_class} ;
+			my $java_class = $this->{java_class} ;
 			$java_class =~ s/^\[// ;
 
 			my @dims = @{$dims} ;
 			shift @dims ;
-			my $obj = new Inline::Java::Array($java_class) ;
-			$obj->__init_from_flat(\@dims, \@sub, $level + 1) ;
-			$elem = $obj ;
+			my $obj = new Inline::Java::Array::Normalizer($java_class) ;
+			$obj->InitFromFlat(\@dims, \@sub, $level + 1) ;
+			$elem = $obj->{array} ;
 		}
-		my $nb = scalar(@{$this}) ;
-		$this->[$nb] = $elem ;
+		my $nb = scalar(@{$this->{array}}) ;
+		$this->{array}->[$nb] = $elem ;
 	}
 
 	if (! $level){
-		Inline::Java::debug_obj($ARRAYS->{$this}) ;
+		# Inline::Java::debug_obj($this) ;
 	}
 }
 
 
 # Checks if the contents of the Array match the ones prescribed
 # by the Java prototype.
-sub __analyze_array_class {
+sub AnalyzeArrayClass {
 	my $this = shift ;
 	
-	my $extra = $ARRAYS->{$this} ;
-	my $java_class = $extra->{java_class} ;
+	my $java_class = $this->{java_class} ;
 
 	my ($depth_str, $type, $class) = Inline::Java::Class::ValidateClassSplit($java_class) ;
 	$depth_str =~ /^(\[+)/ ;
@@ -176,8 +376,8 @@ sub __analyze_array_class {
 		croak "Can't determine array type for $java_class" ;
 	}
 
-	$extra->{req_element_class} = $pclass ;
-	$extra->{req_nb_dim} = $depth ;
+	$this->{req_element_class} = $pclass ;
+	$this->{req_nb_dim} = $depth ;
 
 	return ;
 }
@@ -187,31 +387,31 @@ sub __analyze_array_class {
 # can be used in a Java function. It will return an array
 # That contains either all scalars or all object references
 # at the lowest level.
-sub __validate_array {
+sub ValidateArray {
 	my $this = shift ;
 	my $ref = shift ;
 	my $fill = shift ;
 	my $level = shift || 0 ;
 
+
 	if (! UNIVERSAL::isa($ref, "ARRAY")){
 		# We must start with an array of some kind...
 		croak "$ref is not an array reference" ;
 	}
 
-	$this->__validate_elements($ref, $level) ;
+	$this->ValidateElements($ref, $level) ;
 
 	foreach my $elem (@{$ref}){
 		if (UNIVERSAL::isa($elem, "ARRAY")){
-			$this->__validate_array($elem, $fill, $level + 1) ;
+			$this->ValidateArray($elem, $fill, $level + 1) ;
 		}
 	}
 
 	if ($fill){
-		$this->__fill_array($ref, $level) ;
+		$this->FillArray($ref, $level) ;
 	}
 
-	my $extra = $ARRAYS->{$this} ;
-	my $map = $extra->{map} ;
+	my $map = $this->{map} ;
 	if (! $level){
 		my @levels = (sort {$a <=> $b} keys %{$map}) ;
 		my $nbl = scalar(@levels) ;
@@ -224,30 +424,29 @@ sub __validate_array {
 			$max_cells *= $map->{$l}->{max} ;
 		}
 		my $nb_cells = ($map->{$last}->{count} || 0) ;
-		# Inline::Java::debug("array is [" . join("][", @dims) . "]") ;
-		# Inline::Java::debug("array has         $nb_cells declared cells") ;
-		# Inline::Java::debug("array should have $max_cells declared cells") ;
-		$extra->{dim} = \@dims ;
-		$extra->{nb_dim} = scalar(@dims) ;
-
-		if ($extra->{nb_dim} != $extra->{req_nb_dim}){
-			croak "Java array should have $extra->{req_nb_dim} instead of " .
-				"$extra->{nb_dim} dimensions" ;
+		Inline::Java::debug("array is [" . join("][", @dims) . "]") ;
+		Inline::Java::debug("array has         $nb_cells declared cells") ;
+		Inline::Java::debug("array should have $max_cells declared cells") ;
+		$this->{dim} = \@dims ;
+		$this->{nb_dim} = scalar(@dims) ;
+
+		if ($this->{nb_dim} != $this->{req_nb_dim}){
+			croak "Java array should have $this->{req_nb_dim} instead of " .
+				"$this->{nb_dim} dimensions" ;
 		}
 		
-		# Inline::Java::debug_obj($extra) ;
+		# Inline::Java::debug_obj($this) ;
 	}
 }
 
 
 # Makes sure that all the elements are of the same type.
-sub __validate_elements {
+sub ValidateElements {
 	my $this = shift ;
 	my $ref = shift ;
 	my $level = shift ;
-	
-	my $extra = $ARRAYS->{$this} ;
-	my $map = $extra->{map} ;
+
+	my $map = $this->{map} ;
 
 	my $cnt = scalar(@{$ref}) ;
 	my $max = $map->{$level}->{max} || 0 ;
@@ -256,15 +455,15 @@ sub __validate_elements {
 		$map->{$level}->{max} = $cnt ;
 	}
 
-	foreach my $elem (@{$ref}){		
+	foreach my $elem (@{$ref}){
 		if (defined($elem)){
 			if (ref($elem)){
 				if (UNIVERSAL::isa($elem, "ARRAY")){
-					$this->__check_map("ARRAY", $level) ;
+					$this->CheckMap("ARRAY", $level) ;
 				}
 				elsif (UNIVERSAL::isa($elem, "Inline::Java::Object")){
-					$this->__check_map("Inline::Java::Object", $level) ;
-					$this->__cast_array_argument($elem) ;
+					$this->CheckMap("Inline::Java::Object", $level) ;
+					$this->CastArrayArgument($elem) ;
 					push @{$map->{$level}->{list}}, $elem ;
 				}
 				else{
@@ -272,8 +471,8 @@ sub __validate_elements {
 				}
 			}
 			else{
-				$this->__check_map("SCALAR", $level) ;
-				$this->__cast_array_argument($elem) ;
+				$this->CheckMap("SCALAR", $level) ;
+				$this->CastArrayArgument($elem) ;
 				push @{$map->{$level}->{list}}, $elem ;
 			}
 		}
@@ -281,13 +480,12 @@ sub __validate_elements {
 }
 
 
-sub __check_map {
+sub CheckMap {
 	my $this = shift ;
 	my $type = shift ;
 	my $level = shift ;
 
-	my $extra = $ARRAYS->{$this} ;
-	my $map = $extra->{map} ;
+	my $map = $this->{map} ;
 
 	if (! exists($map->{$level}->{type})){
 		$map->{$level}->{type} = $type ;
@@ -299,25 +497,23 @@ sub __check_map {
 }
 
 
-sub __cast_array_argument {
+sub CastArrayArgument {
 	my $this = shift ;
 	my $ref = shift ;
 
-	my $extra = $ARRAYS->{$this} ;
-	my $element_class = $extra->{req_element_class} ;
+	my $element_class = $this->{req_element_class} ;
 
 	Inline::Java::Class::CastArgument($ref, $element_class) ;
 }
 
 
 # Makes sure that all the dimensions of the array have the same number of elements
-sub __fill_array {
+sub FillArray {
 	my $this = shift ;
 	my $ref = shift ;
 	my $level = shift ;
 
-	my $extra = $ARRAYS->{$this} ;
-	my $map = $extra->{map} ;
+	my $map = $this->{map} ;
 
 	my $max = $map->{$level}->{max} ;
 	my $nb = scalar(@{$ref}) ;
@@ -347,14 +543,13 @@ sub __fill_array {
 }
 
 
-sub __flatten_array {
+sub FlattenArray {
 	my $this = shift ;
 	my $level = shift ;
 
-	my $extra = $ARRAYS->{$this} ;
-	my $dim = $extra->{dim} ;
+	my $dim = $this->{dim} ;
 	my $last = scalar(@{$dim} - 1) ;
-	my $list = $extra->{map}->{$last}->{list} ;
+	my $list = $this->{map}->{$last}->{list} ;
 	my $nb_elem = scalar(@{$list}) ;
 		
 	my $req_nb_elem = 1 ;
@@ -369,128 +564,113 @@ sub __flatten_array {
 
 	my $ret = [$dim, $list] ;
 
-	Inline::Java::debug_obj($ret) ;
+	# Inline::Java::debug_obj($ret) ;
 
 	return $ret ;
 }
 
 
-sub AUTOLOAD {
-	my $this = shift ;
-	my @args = @_ ;
-
-	use vars qw($AUTOLOAD) ;
-	my $func_name = $AUTOLOAD ;
-	# Strip package from $func_name, Java will take of finding the correct
-	# method.
-	$func_name =~ s/^(.*)::// ;
-
-	Inline::Java::debug("$func_name") ;
-
-	croak "Can't call method $func_name on Java arrays (can't call any methods for that matter)" ;
-}
-
-
-sub DESTROY {
-	my $this = shift ;
-
-	# I think here we should to something similar to Object, to get the object
-	# destroyed.
-}
-
-
-
-######################## Array methods ########################
-
-
-sub TIEARRAY {
-	my $class = shift ;
-
-	return $class->SUPER::TIEARRAY(@_) ;
-}
-
-
-sub FETCHSIZE { 
- 	my $this = shift ;
-
-	return $this->SUPER::FETCHSIZE() ;
-}             
-
-
-sub STORE { 
- 	my $this = shift ;
- 	my $idx = shift ;
- 	my $s = shift ;
-
-	return $this->SUPER::STORE($idx, $s) ;
-} 
-
-
-sub FETCH { 
- 	my $this = shift ;
- 	my $idx = shift ;
-
-	return $this->SUPER::FETCH($idx) ;
-}
-
-
-sub EXISTS {
- 	my $this = shift ;
- 	my $idx = shift ;
-
-	return $this->SUPER::EXISTS($idx) ;
-}
 
+package Inline::Java::Array ;
 
-sub STORESIZE {
- 	my $this = shift ;
- 	my $size = shift ;
 
-	croak "Operation STORESIZE not supported on Java array" ;
-}
+1 ; 
 
 
-sub CLEAR {
- 	my $this = shift ;
+__DATA__
 
-	croak "Operation CLEAR not supported on Java array" ;
-}
 
+class InlineJavaArray {
+	InlineJavaServer ijs ;
+	InlineJavaClass ijc ;
 
-sub POP {
- 	my $this = shift ;
 
-	croak "Operation POP not supported on Java array" ;
-}
+	InlineJavaArray(InlineJavaServer _ijs, InlineJavaClass _ijc){
+		ijs = _ijs ;
+		ijc = _ijc ;
+	}
 
 
-sub PUSH {
- 	my $this = shift ;
-	my @list = @_ ;
+	Object CreateArray(Class c, StringTokenizer st) throws InlineJavaException {
+		StringBuffer sb = new StringBuffer(st.nextToken()) ;
+		sb.replace(0, 1, "") ;
+		sb.replace(sb.length() - 1, sb.length(), "") ;
 
-	croak "Operation PUSH not supported on Java array" ;
-}
+		StringTokenizer st2 = new StringTokenizer(sb.toString(), ",") ;
+		ArrayList al = new ArrayList() ;
+		while (st2.hasMoreTokens()){
+			al.add(al.size(), st2.nextToken()) ;
+		}
 
+		int size = al.size() ;
+		int dims[] = new int[size] ;
+		for (int i = 0 ; i < size ; i++){
+			dims[i] = Integer.parseInt((String)al.get(i)) ;
+			ijs.debug("    array dimension: " + (String)al.get(i)) ;
+		}
 
-sub SHIFT {
- 	my $this = shift ;
+		Object array = null ;
+		try {
+			array = Array.newInstance(c, dims) ;
 
-	croak "Operation SHIFT not supported on Java array" ;
-} 
+			ArrayList args = new ArrayList() ;
+			while (st.hasMoreTokens()){
+				args.add(args.size(), st.nextToken()) ;
+			}
 
+			// Now we need to fill it. Since we have an arbitrary number
+			// of dimensions, we can do this recursively.
 
-sub UNSHIFT {
- 	my $this = shift ;
-	my @list = @_ ;
+			PopulateArray(array, c, dims, args) ;
+		}
+		catch (IllegalArgumentException e){
+			throw new InlineJavaException("Arguments to array constructor for class " + c.getName() + " are incompatible: " + e.getMessage()) ;
+		}
 
-	croak "Operation UNSHIFT not supported on Java array" ;
-} 
+		return array ;
+	}
 
 
-sub DELETE {
- 	my $this = shift ;
-	my $idx = shift ;
+	void PopulateArray (Object array, Class elem, int dims[], ArrayList args) throws InlineJavaException {
+		if (dims.length > 1){
+			int nb_args = args.size() ;
+			int nb_sub_dims = dims[0] ;
+			int nb_args_per_sub_dim = nb_args / nb_sub_dims ;
 
-	croak "Operation DELETE not supported on Java array" ;
+			int sub_dims[] = new int[dims.length - 1] ;
+			for (int i = 1 ; i < dims.length ; i++){
+				sub_dims[i - 1] = dims[i] ;
+			}
+	
+			for (int i = 0 ; i < nb_sub_dims ; i++){
+				// We want the args from i*nb_args_per_sub_dim -> 
+				ArrayList sub_args = new ArrayList() ; 
+				for (int j = (i * nb_args_per_sub_dim) ; j < ((i + 1) * nb_args_per_sub_dim) ; j++){
+					sub_args.add(sub_args.size(), (String)args.get(j)) ;
+				}
+				PopulateArray(((Object [])array)[i], elem, sub_dims, sub_args) ;
+			}
+		}
+		else{
+			String msg = "In creation of array of " + elem.getName() + ": " ;
+			try {
+				for (int i = 0 ; i < dims[0] ; i++){
+					String arg = (String)args.get(i) ;
+
+					Object o = ijc.CastArgument(elem, arg) ;
+					Array.set(array, i, o) ;
+					ijs.debug("      setting array element " + String.valueOf(i) + " to " + o.toString()) ;
+		 		}
+			}
+			catch (InlineJavaCastException e){
+				throw new InlineJavaCastException(msg + e.getMessage()) ;
+			}
+			catch (InlineJavaException e){
+				throw new InlineJavaException(msg + e.getMessage()) ;
+			}
+		}
+	}
 }
+	
+	
 
diff --git a/Java/Class.pm b/Java/Class.pm
index e36cdea..e95362c 100644
--- a/Java/Class.pm
+++ b/Java/Class.pm
@@ -3,12 +3,11 @@ package Inline::Java::Class ;
 
 use strict ;
 
-$Inline::Java::Class::VERSION = '0.01' ;
+$Inline::Java::Class::VERSION = '0.10' ;
 
 use Carp ;
 
 
-
 my $INT_RE = '^[+-]?\d+$' ;
 my $FLOAT_RE = '^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$' ;
 
@@ -81,6 +80,7 @@ sub ValidateClassSplit {
 sub CastArguments {
 	my $args = shift ;
 	my $proto = shift ;
+	my $module = shift ;
 
 	Inline::Java::debug_obj($args) ;
 	Inline::Java::debug_obj($proto) ;
@@ -90,25 +90,55 @@ sub CastArguments {
 	}
 
 	my $ret = [] ;
+	my $score = 0 ;
 	for (my $i = 0 ; $i < scalar(@{$args}) ; $i++){
-		$ret->[$i] = CastArgument($args->[$i], $proto->[$i]) ;
+		my @r = CastArgument($args->[$i], $proto->[$i], $module) ;
+		$ret->[$i] = $r[0] ;
+		$score += $r[1] ;
 	}
 
-	return $ret ;
+	return ($ret, $score) ;
 }
 
 
 sub CastArgument {
 	my $arg = shift ;
 	my $proto = shift ;
+	my $module = shift ;
 
 	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 ($proto ne "java.lang.Object"){
-			croak "Can't convert $arg to object $proto" ;
+		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::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" ;
+			}
+			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))){
@@ -117,7 +147,7 @@ sub CastArgument {
 
 	if (ClassIsNumeric($proto)){
 		if (! defined($arg)){
-			return 0 ;
+			return (0, 0) ;
 		}
 		my $re = $RANGE->{$proto}->{REGEXP} ;
 		my $min = $RANGE->{$proto}->{MIN} ;
@@ -125,7 +155,7 @@ sub CastArgument {
 		Inline::Java::debug("min = $min, max = $max, val = $arg") ;
 		if ($arg =~ /$re/){
 			if (($arg >= $min)&&($arg <= $max)){
-				return $arg ;
+				return ($arg, 0) ;
 			}
 			croak "$arg out of range for type $proto" ;
 		}
@@ -133,29 +163,29 @@ sub CastArgument {
 	}
 	elsif (ClassIsChar($proto)){
 		if (! defined($arg)){
-			return "\0" ;
+			return ("\0", 0) ;
 		}
 		if (length($arg) == 1){
-			return $arg ;
+			return ($arg, 0) ;
 		}
 		croak "Can't convert $arg to $proto" ;
 	}
 	elsif (ClassIsBool($proto)){
 		if ($arg){
-			return 1 ;
+			return (1, 0) ;
 		}
 		else{
-			return 0 ;
+			return (0, 0) ;
 		}
 	}
 	elsif (ClassIsString($proto)){
 		if (! defined($arg)){
-			return "" ;
+			return ("", 0) ;
 		}
-		return $arg ;
+		return ($arg, 0) ;
 	}
 	else{
-		return $arg ;
+		return ($arg, 0) ;
 	}
 }
 
@@ -284,10 +314,20 @@ __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") ;
 	}
 
 
@@ -295,6 +335,11 @@ class InlineJavaClass {
 		Makes sure a class exists
 	*/
 	Class ValidateClass(String name) throws InlineJavaException {
+		String s = (String)hm.get(name) ;
+		if (s != null){
+			name = s ;
+		}
+
 		try {
 			Class c = Class.forName(name) ;
 			return c ;
@@ -633,4 +678,18 @@ class InlineJavaClass {
 
 		return true ;
 	}
+
+	boolean ClassIsArray (Class p){
+		String name = p.getName() ;
+
+		if ((ClassIsReference(p))&&(name.startsWith("["))){
+			return true ;
+		}
+
+		ijs.debug("  class " + name + " is array") ;
+
+		return false ;
+	}
+
 }
+
diff --git a/Java/Init.pm b/Java/Init.pm
index 944c4fc..f674c47 100644
--- a/Java/Init.pm
+++ b/Java/Init.pm
@@ -1,9 +1,13 @@
 package Inline::Java::Init ;
 
-$Inline::Java::Init::VERSION = '0.01' ;
+
+use strict ;
+
+$Inline::Java::Init::VERSION = '0.10' ;
 
 my $DATA = join('', <DATA>) ;
 my $OBJECT_DATA = join('', <Inline::Java::Object::DATA>) ;
+my $ARRAY_DATA = join('', <Inline::Java::Array::DATA>) ;
 my $CLASS_DATA = join('', <Inline::Java::Class::DATA>) ;
 my $PROTO_DATA = join('', <Inline::Java::Protocol::DATA>) ;
 
@@ -23,10 +27,12 @@ sub DumpServerJavaCode {
 
 	my $java = $DATA ;
 	my $java_obj = $OBJECT_DATA ;
+	my $java_array = $ARRAY_DATA ;
 	my $java_class = $CLASS_DATA ;
 	my $java_proto = $PROTO_DATA ;
 
 	$java =~ s/<INLINE_JAVA_OBJECT>/$java_obj/g ;
+	$java =~ s/<INLINE_JAVA_ARRAY>/$java_array/g ;
 	$java =~ s/<INLINE_JAVA_CLASS>/$java_class/g ;
 	$java =~ s/<INLINE_JAVA_PROTOCOL>/$java_proto/g ;
 
@@ -77,7 +83,7 @@ public class InlineJavaServer {
 			try {
 				ss = new ServerSocket(port) ;
 				Socket client = ss.accept() ;
-					
+
 				BufferedReader br = new BufferedReader(
 					new InputStreamReader(client.getInputStream())) ;
 				BufferedWriter bw = new BufferedWriter(
@@ -186,7 +192,7 @@ public class InlineJavaServer {
 						Class decl = x.getDeclaringClass() ;
 						Class type = x.getType() ;
 						pw.append("field" + stat + decl.getName() + " " + x.getName() + " " + type.getName() + "\n") ;
-					}					
+					}
 				}
 			}
 		}
@@ -203,10 +209,15 @@ public class InlineJavaServer {
 		Creates a string representing a method signature
 	*/
 	String CreateSignature(Class param[]){
+		return CreateSignature(param, ", ") ;
+	}
+
+
+	String CreateSignature(Class param[], String del){
 		StringBuffer ret = new StringBuffer() ;
 		for (int i = 0 ; i < param.length ; i++){
 			if (i > 0){
-				ret.append(", ") ;
+				ret.append(del) ;
 			}
 			ret.append(param[i].getName()) ;
 		}
@@ -238,6 +249,8 @@ public class InlineJavaServer {
 
 	<INLINE_JAVA_OBJECT>
 
+	<INLINE_JAVA_ARRAY>
+
 	<INLINE_JAVA_CLASS>
 
 	<INLINE_JAVA_PROTOCOL>
diff --git a/Java/Object.pm b/Java/Object.pm
index 82db239..844d79b 100644
--- a/Java/Object.pm
+++ b/Java/Object.pm
@@ -4,12 +4,11 @@ package Inline::Java::Object ;
 
 use strict ;
 
-$Inline::Java::Object::VERSION = '0.01' ;
+$Inline::Java::Object::VERSION = '0.10' ;
 
-use Carp ;
-use Tie::Hash ;
 use Inline::Java::Protocol ;
-
+use Tie::Hash ;
+use Carp ;
 
 
 # Bogus constructor. We fall here if no public constructor is defined
@@ -28,30 +27,32 @@ sub __new {
 	my $java_class = shift ;
 	my $inline = shift ;
 	my $objid = shift ;
-	my @args = @_ ;
+	my $proto = shift ;
+	my $args = shift ;
 
 	my %this = () ;
-	tie %this, 'Inline::Java::Object' ;
-	bless (\%this, $class) ;
 
-	my $this = \%this ;
+	my $knot = tie %this, 'Inline::Java::Object' ;
+	my $this = bless (\%this, $class) ;
+
 	$this->{private} = {} ;
 	$this->{private}->{class} = $class ;
 	$this->{private}->{java_class} = $java_class ;
 	$this->{private}->{module} = $inline->{modfname} ;
+	$this->{private}->{known_to_perl} = 1 ;
 	$this->{private}->{proto} = new Inline::Java::Protocol($this->{private}, $inline) ;
+
 	if ($objid <= 0){
 		eval {
-			$this->{private}->{proto}->CreateJavaObject($java_class, @args) ;
+			$this->{private}->{proto}->CreateJavaObject($java_class, $proto, $args) ;
 		} ;		
 		croak "In method new of class $class: $@" if $@ ;
-
-		Inline::Java::debug("Object created in perl script ($class):") ;
 	}
 	else{
 		$this->{private}->{id} = $objid ;
 		Inline::Java::debug("Object created in java ($class):") ;
 	}
+
 	Inline::Java::debug_obj($this) ;
 
 	return $this ;
@@ -64,16 +65,49 @@ sub __validate_prototype {
 	my $class = shift ;
 	my $method = shift ;
 	my $args = shift ;
-	my $proto = shift ;
+	my $prototypes = shift ;
+	my $inline = shift ;
+
+	my $matched_protos = [] ;
+	my $new_arguments = [] ;
+	my $scores = [] ;
 
-	my $new_args = undef ;
-	eval {
-		$new_args = Inline::Java::Class::CastArguments($args, $proto) ;
-	} ;
-	my $name = (ref($class) ? $class->{private}->{class} : $class) ;
-	croak "In method $method of class $name: $@" if $@ ;
+	foreach my $proto (@{$prototypes}){
+		my $new_args = undef ;
+		my $score = undef ;
+		eval {
+			($new_args, $score) = Inline::Java::Class::CastArguments($args, $proto, $inline->{modfname}) ;
+		} ;
+		if ($@){
+			# We croaked, so we assume that we were not able to cast 
+			# the arguments to the prototype
+			Inline::Java::debug("Rescued from death: $@") ;
+			next ;
+		}
+		# We passed!
+		push @{$matched_protos}, $proto ;
+		push @{$new_arguments}, $new_args ;
+		push @{$scores}, $score ;
+	}
+
+	if (! scalar(@{$matched_protos})){
+		my $name = (ref($class) ? $class->{private}->{class} : $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. Available signatures are:\n"  ;
+		foreach my $proto (@{$prototypes}){
+			my $s = Inline::Java::Protocol->CreateSignature($proto) ;
+			$msg .= "\t$method$s\n" ;
+		}
+		chomp $msg ;
+		croak $msg ;
+	}
 
-	return @{$new_args} ;
+	# 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]) ;
 }
 
 
@@ -98,12 +132,12 @@ sub AUTOLOAD {
 # and tied to the same package.
 sub DESTROY {
 	my $this = shift ;
-
+	
 	if (! $Inline::Java::DONE){
 		if (! $this->{private}->{deleted}){
 			$this->{private}->{deleted} = 1 ;
 			eval {
-				$this->{private}->{proto}->DeleteJavaObject() ;
+				$this->{private}->{proto}->DeleteJavaObject($this) ;
 			} ;
 			croak "In method DESTROY of class $this->{private}->{class}: $@" if $@ ;
 		}
@@ -114,7 +148,9 @@ sub DESTROY {
 }
 
 
-######################## Hash methods ########################
+
+######################## Hash Methods ########################
+
 
 
 sub TIEHASH {
@@ -137,7 +173,44 @@ sub STORE {
 	my $fields = $inline->get_fields($this->{private}->{java_class}) ;
 
 	if ($fields->{$key}){
-		croak "Setting of public member variables for Java objects is not yet implemented" ;		
+		my $list = $fields->{$key} ;
+
+		my $matched_protos = [] ;
+		my $new_arguments = [] ;
+		my $scores = [] ;
+		foreach my $f (@{$list}){
+			my $new_args = undef ;
+			my $score = undef ;
+			eval {
+				($new_args, $score) = Inline::Java::Class::CastArguments([$value], [$f], $this->{private}->{module}) ;
+			} ;
+			if ($@){
+				# We croaked, so we assume that we were not able to cast 
+				# the arguments to the prototype
+				next ;
+			}
+			# We passed!
+			push @{$matched_protos}, [$f] ;
+			push @{$new_arguments}, $new_args ;
+			push @{$scores}, $score ;
+		}
+
+		if (! scalar(@{$matched_protos})){
+			my $name = $this->{private}->{class} ;
+			my $msg = "For member $key of class $name: Can't assign passed value to variable " .
+				"this variable can accept:\n"  ;
+			foreach my $f (@{$list}){
+				$msg .= "\t$f\n" ;
+			}
+			chomp $msg ;
+			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}) ;
+		$this->{private}->{proto}->SetJavaMember($key, $matched_protos->[$nb - 1], $new_arguments->[$nb - 1]) ;
 	}
 	else{
 		croak "No public member variable $key defined for class $this->{private}->{class}" ;
@@ -151,13 +224,22 @@ sub FETCH {
 
  	if ($key eq "private"){
  		return $this->SUPER::FETCH($key) ;
- 	}
+	}
+
+	Inline::Java::debug("fetching member variable $key") ;
 
 	my $inline = $Inline::Java::INLINE->{$this->{private}->{module}} ;
 	my $fields = $inline->get_fields($this->{private}->{java_class}) ;
 
 	if ($fields->{$key}){
-		return undef ;
+		# Here when the user is requesting a field, we can't know which
+		# one the user wants, so we select the first one.
+		my $proto = $fields->{$key}->[0] ;
+
+		my $ret = $this->{private}->{proto}->GetJavaMember($key, [$proto], [undef]) ;
+		Inline::Java::debug("returning member ($ret)") ;
+	
+		return $ret ;
 	}
 	else{
 		croak "No public member variable $key defined for class $this->{private}->{class}" ;
@@ -209,9 +291,10 @@ sub CLEAR {
 }
 
 
+package Inline::Java::Object ;
 
-1 ;
 
+1 ;
 
 
 __DATA__
diff --git a/Java/Protocol.pm b/Java/Protocol.pm
index 237ac3b..2a1d423 100644
--- a/Java/Protocol.pm
+++ b/Java/Protocol.pm
@@ -3,8 +3,9 @@ package Inline::Java::Protocol ;
 
 use strict ;
 
-$Inline::Java::Protocol::VERSION = '0.01' ;
+$Inline::Java::Protocol::VERSION = '0.10' ;
 
+use Inline::Java::Array ;
 use Carp ;
 
 
@@ -26,17 +27,19 @@ sub new {
 sub CreateJavaObject {
 	my $this = shift ;
 	my $class = shift ;
-	my @args = @_ ;
+	my $proto = shift ;
+	my $args = shift ;
 
-	Inline::Java::debug("creating object new $class(" . join(", ", @args) . ")") ; 	
+	Inline::Java::debug("creating object new $class" . $this->CreateSignature($args)) ; 	
 
 	my $data = join(" ", 
 		"create_object", 
 		Inline::Java::Class::ValidateClass($class),
-		$this->ValidateArgs(@args),
+		$this->CreateSignature($proto, ","),
+		$this->ValidateArgs($args),
 	) ;
 
-	Inline::Java::debug("  packet sent is $data") ;		
+	Inline::Java::debug("  packet sent is $data") ;
 
 	return $this->Send($data, 1) ;
 }
@@ -47,15 +50,17 @@ sub CallStaticJavaMethod {
 	my $this = shift ;
 	my $class = shift ;
 	my $method = shift ;
-	my @args = @_ ;
+	my $proto = shift ;
+	my $args = shift ;
 
-	Inline::Java::debug("calling $class.$method(" . join(", ", @args) . ")") ;
+	Inline::Java::debug("calling $class.$method" . $this->CreateSignature($args)) ;
 
 	my $data = join(" ", 
 		"call_static_method", 
 		Inline::Java::Class::ValidateClass($class),
 		$this->ValidateMethod($method),
-		$this->ValidateArgs(@args),
+		$this->CreateSignature($proto, ","),
+		$this->ValidateArgs($args),
 	) ;
 
 	Inline::Java::debug("  packet sent is $data") ;		
@@ -68,18 +73,70 @@ sub CallStaticJavaMethod {
 sub CallJavaMethod {
 	my $this = shift ;
 	my $method = shift ;
-	my @args = @_ ;
+	my $proto = shift ;
+	my $args = shift ;
 
 	my $id = $this->{obj_priv}->{id} ;
 	my $class = $this->{obj_priv}->{java_class} ;
-	Inline::Java::debug("calling object($id).$method(" . join(", ", @args) . ")") ;
+	Inline::Java::debug("calling object($id).$method" . $this->CreateSignature($args)) ;
 
 	my $data = join(" ", 
 		"call_method", 
 		$id,
 		Inline::Java::Class::ValidateClass($class),
 		$this->ValidateMethod($method),
-		$this->ValidateArgs(@args),
+		$this->CreateSignature($proto, ","),
+		$this->ValidateArgs($args),
+	) ;
+
+	Inline::Java::debug("  packet sent is $data") ;
+
+	return $this->Send($data) ;
+}
+
+
+# Sets a member variable.
+sub SetJavaMember {
+	my $this = shift ;
+	my $member = shift ;
+	my $proto = shift ;
+	my $arg = shift ;
+
+	my $id = $this->{obj_priv}->{id} ;
+	my $class = $this->{obj_priv}->{java_class} ;
+	Inline::Java::debug("setting object($id)->{$member} = $arg->[0]") ;
+	my $data = join(" ", 
+		"set_member", 
+		$id,
+		Inline::Java::Class::ValidateClass($class),
+		$this->ValidateMember($member),
+		Inline::Java::Class::ValidateClass($proto->[0]),
+		$this->ValidateArgs($arg),
+	) ;
+
+	Inline::Java::debug("  packet sent is $data") ;
+
+	return $this->Send($data) ;
+}
+
+
+# Gets a member variable.
+sub GetJavaMember {
+	my $this = shift ;
+	my $member = shift ;
+	my $proto = shift ;
+
+	my $id = $this->{obj_priv}->{id} ;
+	my $class = $this->{obj_priv}->{java_class} ;
+	Inline::Java::debug("getting object($id)->{$member}") ;
+
+	my $data = join(" ", 
+		"get_member", 
+		$id,
+		Inline::Java::Class::ValidateClass($class),
+		$this->ValidateMember($member),
+		Inline::Java::Class::ValidateClass($proto->[0]),
+		"undef:",
 	) ;
 
 	Inline::Java::debug("  packet sent is $data") ;
@@ -91,12 +148,13 @@ sub CallJavaMethod {
 # Deletes a Java object
 sub DeleteJavaObject {
 	my $this = shift ;
+	my $obj = shift ;
 
 	if (defined($this->{obj_priv}->{id})){
 		my $id = $this->{obj_priv}->{id} ;
 		my $class = $this->{obj_priv}->{java_class} ;
 
-		Inline::Java::debug("deleting object $this $id ($class)") ;
+		Inline::Java::debug("deleting object $obj $id ($class)") ;
 
 		my $data = join(" ", 
 			"delete_object", 
@@ -124,19 +182,37 @@ sub ValidateMethod {
 }
 
 
+# This method makes sure that the member we are asking for
+# has the correct form for a Java member.
+sub ValidateMember {
+	my $this = shift ;
+	my $member = shift ;
+
+	if ($member !~ /^(\w+)$/){
+		croak "Invalid Java member name $member" ;
+	}	
+
+	return $member ;
+}
+
+
 # Validates the arguments to be used in a method call.
 sub ValidateArgs {
 	my $this = shift ;
-	my @args = @_ ;
+	my $args = shift ;
 
 	my @ret = () ;
-	foreach my $arg (@args){
+	foreach my $arg (@{$args}){
 		if (! defined($arg)){
 			push @ret, "undef:" ;
 		}
 		elsif (ref($arg)){
-			if (! UNIVERSAL::isa($arg, "Inline::Java::Object")){
-				croak "A Java method can only have Java objects or scalars as arguments" ;
+			if ((! UNIVERSAL::isa($arg, "Inline::Java::Object"))&&(! UNIVERSAL::isa($arg, "Inline::Java::Array"))){
+				croak "A Java method or member can only have Java objects, Java arrays or scalars as arguments" ;
+			}
+
+			if (UNIVERSAL::isa($arg, "Inline::Java::Array")){
+				$arg = $arg->__get_object() ; 
 			}
 			my $class = $arg->{private}->{java_class} ;
 			my $id = $arg->{private}->{id} ;
@@ -151,6 +227,15 @@ sub ValidateArgs {
 }
 
 
+sub CreateSignature {
+	my $this = shift ;
+	my $proto = shift ;
+	my $del = shift || ", " ;
+
+	return "(" . join($del, @{$proto}) . ")" ;
+}
+
+
 # This actually sends the request to the Java program. It also takes
 # care of registering the returned object (if any)
 sub Send {
@@ -170,7 +255,9 @@ sub Send {
 		croak "Can't receive packet over socket: $!" ;
 	}
 	elsif ($resp =~ /^error scalar:([\d.]*)$/){
-		croak pack("C*", split(/\./, $1)) ;
+		my $msg = pack("C*", split(/\./, $1)) ;
+		Inline::Java::debug("  packet recv error: $msg") ;
+		croak $msg ;
 	}
 	elsif ($resp =~ /^ok scalar:([\d.]*)$/){
 		return pack("C*", split(/\./, $1)) ;
@@ -182,27 +269,52 @@ sub Send {
 		# Create the Perl object wrapper and return it.
 		my $id = $1 ;
 		my $class = $2 ;
+
+		my $perl_class = $class ;
+		$perl_class =~ s/[.\$]/::/g ;
+		my $pkg = $inline->{pkg} ;
+		$perl_class = $pkg . "::" . $perl_class ;
+		Inline::Java::debug($perl_class) ;
+
+		my $known = 0 ;
+		{
+			no strict 'refs' ;
+			if (defined(${$perl_class . "::" . "EXISTS"})){
+				Inline::Java::debug("  returned class exists!") ;
+				$known = 1 ;
+			}
+			else{
+				Inline::Java::debug("  returned class doesn't exist!") ;
+			}
+		}
+
 		if ($const){
 			$this->{obj_priv}->{java_class} = $class ;
 			$this->{obj_priv}->{id} = $id ;
+			$this->{obj_priv}->{known_to_perl} = $known ;
 		}
 		else{
-			my $perl_class = $class ;
-			$perl_class =~ s/[.\$]/::/g ;
-			my $pkg = $inline->{pkg} ;
-			$perl_class = $pkg . "::" . $perl_class ;
-			Inline::Java::debug($perl_class) ;
-
 			my $obj = undef ;
-			no strict 'refs' ;
-			if (defined(${$perl_class . "::" . "EXISTS"})){
-				Inline::Java::debug("  returned class exists!") ;
+			if ($known){
+				Inline::Java::debug("creating stub for known object...") ;
 				$obj = $perl_class->__new($class, $inline, $id) ;
+				Inline::Java::debug("stub created ($obj)...") ;
 			}
 			else{
-				Inline::Java::debug("  returned class doesn't exist!") ;
+				Inline::Java::debug("creating stub for unknown object...") ;
 				$obj = Inline::Java::Object->__new($class, $inline, $id) ;
+				Inline::Java::debug("stub created ($obj)...") ;
 			}
+			$obj->{private}->{known_to_perl} = $known ;
+
+			Inline::Java::debug("checking if stub is array...") ;
+			if (Inline::Java::Class::ClassIsArray($class)){
+				Inline::Java::debug("creating array object...") ;
+				$obj = new Inline::Java::Array($obj) ;
+				Inline::Java::debug("array object created...") ;
+			}
+
+			Inline::Java::debug("returning stub...") ;
 			return $obj ;
 		}
 	}
@@ -223,12 +335,14 @@ __DATA__
 class InlineJavaProtocol {
 	InlineJavaServer ijs ;
 	InlineJavaClass ijc ;
+	InlineJavaArray ija ;
 	String cmd ;
 	String response ;
 
 	InlineJavaProtocol(InlineJavaServer _ijs, String _cmd) {
 		ijs = _ijs ;
 		ijc = new InlineJavaClass(ijs, this) ;
+		ija = new InlineJavaArray(ijs, ijc) ;
 
 		cmd = _cmd ;		
 	}
@@ -247,6 +361,12 @@ class InlineJavaProtocol {
 		else if (c.equals("call_method")){
 			CallJavaMethod(st) ;
 		}		
+		else if (c.equals("set_member")){
+			SetJavaMember(st) ;
+		}		
+		else if (c.equals("get_member")){
+			GetJavaMember(st) ;
+		}		
 		else if (c.equals("create_object")){
 			CreateJavaObject(st) ;
 		}
@@ -256,7 +376,49 @@ class InlineJavaProtocol {
 		else if (c.equals("die")){
 			ijs.debug("  received a request to die...") ;
 			System.exit(0) ;
-		}		
+		}
+		else {
+			throw new InlineJavaException("Unknown command " + c) ;
+		}
+	}
+
+
+	/*
+		Creates a Java Object with the specified arguments.
+	*/
+	void CreateJavaObject(StringTokenizer st) throws InlineJavaException {
+		String class_name = st.nextToken() ;
+		Class c = ijc.ValidateClass(class_name) ;
+
+		if (! ijc.ClassIsArray(c)){
+			ArrayList f = ValidateMethod(true, c, class_name, st) ;
+			Constructor con = (Constructor)f.get(0) ;
+			Object p[] = (Object [])f.get(1) ;
+			Class clist[] = (Class [])f.get(2) ;
+
+			Object o = CreateObject(c, p, clist) ;
+			SetResponse(o) ;
+		}
+		else{
+			// Here we send the type of array we want, but CreateArray
+			// exception the element type.
+			StringBuffer sb = new StringBuffer(class_name) ;
+			// Remove the ['s
+			while (sb.toString().startsWith("[")){
+				sb.replace(0, 1, "") ;	
+			}
+			// remove the L and the ;
+			if (sb.toString().startsWith("L")){
+				sb.replace(0, 1, "") ;
+				sb.replace(sb.length() - 1, sb.length(), "") ;
+			}
+
+			Class ec = ijc.ValidateClass(sb.toString()) ;
+
+			ijs.debug("    array elements: " + ec.getName()) ;
+			Object o = ija.CreateArray(ec, st) ;
+			SetResponse(o) ;
+		}
 	}
 
 
@@ -297,55 +459,147 @@ class InlineJavaProtocol {
 	*/
 	void CallJavaMethod(StringTokenizer st) throws InlineJavaException {
 		int id = Integer.parseInt(st.nextToken()) ;
-		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() ;
 		Integer oid = new Integer(id) ;
 		Object o = ijs.objects.get(oid) ;
 		if (o == null){
 			throw new InlineJavaException("Object " + oid.toString() + " is not in HashMap!") ;
 		}
-		Object p[] = (Object [])f.get(1) ;
-		try {
-			Object ret = m.invoke(o, p) ;
-			SetResponse(ret) ;
+
+		String class_name = st.nextToken() ;
+		// Use the class of the object
+		class_name = o.getClass().getName() ;
+
+		Class c = ijc.ValidateClass(class_name) ;
+		String method = st.nextToken() ;
+
+		if ((ijc.ClassIsArray(c))&&(method.equals("getLength"))){
+			int length = Array.getLength(o) ;
+			SetResponse(new Integer(length)) ;
 		}
-		catch (IllegalAccessException e){
-			throw new InlineJavaException("You are not allowed to invoke method " + name + " in class " + class_name + ": " + e.getMessage()) ;
+		else{
+			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(o, p) ;
+				SetResponse(ret) ;
+			}
+			catch (IllegalAccessException e){
+				throw new InlineJavaException("You are not allowed to invoke method " + name + " in class " + class_name + ": " + e.getMessage()) ;
+			}
+			catch (IllegalArgumentException e){
+				throw new InlineJavaException("Arguments for 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(
+					"Method " + name + " in class " + class_name + " threw exception " + type + ": " + msg) ;
+			}
 		}
-		catch (IllegalArgumentException e){
-			throw new InlineJavaException("Arguments for method " + name + " in class " + class_name + " are incompatible: " + e.getMessage()) ;
+	}
+
+
+	/*
+		Sets a Java member variable
+	*/
+	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!") ;
 		}
-		catch (InvocationTargetException e){
-			Throwable t = e.getTargetException() ;
-			String type = t.getClass().getName() ;
-			String msg = t.getMessage() ;
-			throw new InlineJavaException(
-				"Method " + name + " in class " + class_name + " threw exception " + type + ": " + msg) ;
+
+		String class_name = st.nextToken() ;
+		// Use the class of the object
+		class_name = o.getClass().getName() ;
+
+		Class c = ijc.ValidateClass(class_name) ;
+		String member = st.nextToken() ;
+
+		if (ijc.ClassIsArray(c)){
+			int idx = Integer.parseInt(member) ;
+			Class type = ijc.ValidateClass(st.nextToken()) ;
+			String arg = st.nextToken() ;
+
+			String msg = "For array of type " + c.getName() + ", element " + member + ": " ;
+			try {
+				Object elem = ijc.CastArgument(type, arg) ;
+				Array.set(o, idx, elem) ;
+				SetResponse(null) ;
+			}
+			catch (InlineJavaCastException e){
+				throw new InlineJavaCastException(msg + e.getMessage()) ;
+			}
+			catch (InlineJavaException e){
+				throw new InlineJavaException(msg + e.getMessage()) ;
+			}
+		}
+		else{
+			ArrayList fl = ValidateMember(c, member, st) ;
+			Field f = (Field)fl.get(0) ;
+			String name = f.getName() ;
+			Object p = (Object)fl.get(1) ;
+
+			try {
+				f.set(o, p) ;
+				SetResponse(null) ;
+			}
+			catch (IllegalAccessException e){
+				throw new InlineJavaException("You are not allowed to set member " + name + " in class " + class_name + ": " + e.getMessage()) ;
+			}
+			catch (IllegalArgumentException e){
+				throw new InlineJavaException("Argument for member " + name + " in class " + class_name + " is incompatible: " + e.getMessage()) ;
+			}
 		}
 	}
 
 
 	/*
-		Creates a Java Object with the specified arguments.
+		Gets a Java member variable
 	*/
-	void CreateJavaObject(StringTokenizer st) throws InlineJavaException {
+	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() ;
-		Class c = ijc.ValidateClass(class_name) ;
+		// Use the class of the object
+		class_name = o.getClass().getName() ;
 
-		ArrayList f = ValidateMethod(true, c, class_name, st) ;
+		Class c = ijc.ValidateClass(class_name) ;
+		String member = st.nextToken() ;
 
-		Constructor con = (Constructor)f.get(0) ;
-		String name = class_name ;
-		Object p[] = (Object [])f.get(1) ;
-		Class clist[] = (Class [])f.get(2) ;
+		if (ijc.ClassIsArray(c)){
+			int idx = Integer.parseInt(member) ;
+			SetResponse(Array.get(o, idx)) ;
+		}
+		else{
+			ArrayList fl = ValidateMember(c, member, st) ;
 
-		Object o = CreateObject(c, p, clist) ;
-		SetResponse(o) ;
+			Field f = (Field)fl.get(0) ;
+			String name = f.getName() ;
+			try {
+				Object ret = f.get(o) ;
+				SetResponse(ret) ;
+			}
+			catch (IllegalAccessException e){
+				throw new InlineJavaException("You are not allowed to set member " + name + " in class " + class_name + ": " + e.getMessage()) ;
+			}
+			catch (IllegalArgumentException e){
+				throw new InlineJavaException("Argument for member " + name + " in class " + class_name + " is incompatible: " + e.getMessage()) ;
+			}
+		}
 	}
 
 
@@ -366,7 +620,6 @@ class InlineJavaProtocol {
 		Creates a Java Object with the specified arguments.
 	*/
 	Object CreateObject(Class p, Object args[], Class proto[]) throws InlineJavaException {
-
 		p = ijc.FindWrapper(p) ;
 
 		String name = p.getName() ;
@@ -404,7 +657,10 @@ class InlineJavaProtocol {
 	*/
 	ArrayList ValidateMethod(boolean constructor, Class c, String name, StringTokenizer st) throws InlineJavaException {
 		Member ma[] = (constructor ? (Member [])c.getConstructors() : (Member [])c.getMethods()) ;
-		ArrayList ret = new ArrayList(ma.length) ;
+		ArrayList ret = new ArrayList() ;
+
+		// Extract signature
+		String signature = st.nextToken() ;
 
 		// Extract the arguments
 		ArrayList args = new ArrayList() ;
@@ -416,6 +672,7 @@ class InlineJavaProtocol {
 		Class params[] = null ;
 		for (int i = 0 ; i < ma.length ; i++){
 			Member m = ma[i] ;
+
 			if (m.getName().equals(name)){
 				ijs.debug("found a " + name + (constructor ? " constructor" : " method")) ;
 
@@ -425,10 +682,13 @@ class InlineJavaProtocol {
 				else{
 					params = ((Method)m).getParameterTypes() ;
 				}
-			 	if (params.length == args.size()){
-					// We have the same number of arguments
+
+				// Now we check if the signatures match
+				String sign = ijs.CreateSignature(params, ",") ;
+				if (signature.equals(sign)){
+					ijs.debug("  has matching signature " + sign) ;
 					ml.add(ml.size(), m) ;
-					ijs.debug("  has the correct number of params (" +  String.valueOf(args.size()) + ") and signature is " + ijs.CreateSignature(params)) ;
+					break ;
 				}
 			}
 		}
@@ -439,7 +699,7 @@ class InlineJavaProtocol {
 			throw new InlineJavaException(
 				(constructor ? "Constructor " : "Method ") + 
 				name + " for class " + c.getName() + " with signature " +
-				ijs.CreateSignature(params) + " not found") ;
+				signature + " not found") ;
 		}
 		else if (ml.size() == 1){
 			// Now we need to force the arguments received to match
@@ -454,7 +714,7 @@ class InlineJavaProtocol {
 
 			String msg = "In method " + name + " of class " + c.getName() + ": " ;
 			try {
-				ret.add(0, m) ;			
+				ret.add(0, m) ;
 				ret.add(1, ijc.CastArguments(params, args)) ;
 				ret.add(2, params) ;
 			}
@@ -465,8 +725,67 @@ class InlineJavaProtocol {
 				throw new InlineJavaException(msg + e.getMessage()) ;
 			}
 		}
-		else{
-			throw new InlineJavaException("Automatic method selection when multiple signatures are found not yet implemented") ;
+
+		return ret ;
+	}
+
+
+	/*
+		Makes sure a member exists
+	*/
+	ArrayList ValidateMember(Class c, String name, StringTokenizer st) throws InlineJavaException {
+		Field fa[] = c.getFields() ;
+		ArrayList ret = new ArrayList() ;
+
+		// Extract member type
+		String type = st.nextToken() ;
+
+		// Extract the argument
+		String arg = st.nextToken() ;
+
+		ArrayList fl = new ArrayList(fa.length) ;
+		Class param = null ;
+		for (int i = 0 ; i < fa.length ; i++){
+			Field f = fa[i] ;
+
+			if (f.getName().equals(name)){
+				ijs.debug("found a " + name + " member") ;
+
+				param = f.getType() ;
+				String t = param.getName() ;
+				if (type.equals(t)){
+					ijs.debug("  has matching type " + t) ;
+					fl.add(fl.size(), f) ;
+					break ;
+				}
+			}
+		}
+
+		// Now we got a list of matching methods. 
+		// We have to figure out which one we will call.
+		if (fl.size() == 0){
+			throw new InlineJavaException(
+				"Member " + name + " of type " + type + " for class " + c.getName() +
+					" not found") ;
+		}
+		else if (fl.size() == 1){
+			// Now we need to force the arguments received to match
+			// the methods signature.
+			Field f = (Field)fl.get(0) ;
+			param = f.getType() ;
+
+			String msg = "For member " + name + " of class " + c.getName() + ": " ;
+			try {
+				ret.add(0, f) ;
+				ret.add(1, ijc.CastArgument(param, arg)) ;
+				ret.add(2, param) ;
+			}
+			catch (InlineJavaCastException e){
+				throw new InlineJavaCastException(msg + e.getMessage()) ;
+			}
+			catch (InlineJavaException e){
+				throw new InlineJavaException(msg + e.getMessage()) ;
+			}
 		}
 
 		return ret ;
diff --git a/MANIFEST b/MANIFEST
index abba307..21c5c5d 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -12,5 +12,6 @@ Java/Class.pm
 t/1_init.t
 t/2_primitives.t
 t/3_objects.t
-t/4_arrays.t
+t/4_members.t
+t/5_arrays.t
 
diff --git a/Makefile.PL b/Makefile.PL
index 50866db..00bf57e 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -6,12 +6,12 @@ WriteMakefile(
 	PREREQ_PM => {
 		Inline	=> 0.31
 	},
-	# INC => join(" ", 
-	# 	'-I/usr/java1.2/include',
-	# 	'-I/usr/java1.2/include/solaris'
-	# ),
-	# LIBS => [
-	# 	'-L/usr/java1.2/jre/lib/sparc -ljava'
-	# ],
+	INC => join(" ", 
+		'-I/usr/java1.2/include',
+		'-I/usr/java1.2/include/solaris'
+	),
+	LIBS => [
+		'-L/usr/java1.2/jre/lib/sparc -ljvm'
+	],
 	clean => {FILES => '_Inline_test/'},
 ) ;

-- 
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