Index: gsdl/trunk/perllib/plugins/DirectoryPlugin.pm
===================================================================
--- gsdl/trunk/perllib/plugins/DirectoryPlugin.pm	(revision 16390)
+++ gsdl/trunk/perllib/plugins/DirectoryPlugin.pm	(revision 16391)
@@ -88,5 +88,5 @@
 	die "ERROR: DirectoryPlugin -use_metadata_files option has been deprecated. Please remove the option and add MetadataXMLPlug to your plugin list instead!\n";
     }
-	    
+	
     $self->{'subdir_extrametakeys'} = {};
 
@@ -135,27 +135,15 @@
 }
 
-# return number of files processed, undef if can't process
-# Note that $base_dir might be "" and that $file might 
-# include directories
-
-# This function passes around metadata hash structures.  Metadata hash
-# structures are hashes that map from a (scalar) key (the metadata element
-# name) to either a scalar metadata value or a reference to an array of
-# such values.
-
-sub read {
-    my $self = shift (@_);
-    my ($pluginfo, $base_dir, $file, $in_metadata, $processor, $maxdocs, $total_count, $gli) = @_;
-    
+sub check_directory_path {
+
+    my $self = shift(@_);
+    my ($dirname) = @_;
+    
+    return undef unless (-d $dirname);
+
+    return 0 if ($self->{'block_exp'} ne "" && $dirname =~ /$self->{'block_exp'}/);
+
     my $outhandle = $self->{'outhandle'};
-    my $verbosity = $self->{'verbosity'};
- 
-    # Calculate the directory name and ensure it is a directory and
-    # that it is not explicitly blocked.
-    my $dirname = $file;
-    $dirname = &util::filename_cat ($base_dir, $file) if $base_dir =~ /\w/;
-    return undef unless (-d $dirname);
-    return 0 if ($self->{'block_exp'} ne "" && $dirname =~ /$self->{'block_exp'}/);
-
+    
     # check to make sure we're not reading the archives or index directory
     my $gsdlhome = quotemeta($ENV{'GSDLHOME'});
@@ -176,15 +164,94 @@
 	return 0;
     }
-    
-    if (($verbosity > 2) && ((scalar keys %$in_metadata) > 0)) {
-        print $outhandle "DirectoryPlugin: metadata passed in: ", 
-	join(", ", keys %$in_metadata), "\n";
-    }
-    
-    # Recur over directory contents.
+
+    return 1;
+}
+
+# this may be called more than once
+sub sort_out_associated_files {
+
+    my $self = shift (@_);
+    my ($block_hash) = @_;
+    if (!scalar (keys %{$block_hash->{'shared_fileroot'}})) {
+	return;
+    }
+
+    $self->{'assocfile_info'} = {} unless defined $self->{'assocfile_info'};
+    my $metadata = $self->{'assocfile_info'};
+    foreach my $prefix (keys %{$block_hash->{'shared_fileroot'}}) {
+	my $record = $block_hash->{'shared_fileroot'}->{$prefix};
+
+	my $tie_to = $record->{'tie_to'};
+	my $exts = $record->{'exts'};
+	
+	if ((defined $tie_to) && (scalar (keys %$exts) > 0)) {
+	    # set up fileblocks and assocfile_tobe
+	    my $base_file = "$prefix$tie_to";
+	    $metadata->{$base_file} = {} unless defined $metadata->{$base_file};
+	    my $base_file_metadata = $metadata->{$base_file};
+	    
+	    $base_file_metadata->{'gsdlassocfile_tobe'} = [] unless defined $base_file_metadata->{'gsdlassocfile_tobe'};
+	    my $assoc_tobe = $base_file_metadata->{'gsdlassocfile_tobe'};
+	    foreach my $e (keys %$exts) {
+		# block the file
+		$block_hash->{'file_blocks'}->{"$prefix$e"} = 1;
+		# set up as an associatd file
+		print STDERR "  $self->{'plugin_type'}: Associating $prefix$e with $tie_to version\n";
+		my $mime_type = ""; # let system auto detect this
+		push(@$assoc_tobe,"$prefix$e:$mime_type:"); 
+
+	    }
+	}
+    } # foreach record
+
+    $block_hash->{'shared_fileroot'} = undef;
+    $block_hash->{'shared_fileroot'} = {};
+
+}
+
+
+# do block exp OR special blocking ???
+
+sub file_is_blocked {
+    my $self = shift (@_);
+    my ($block_hash, $filename_full_path) = @_;
+
+    if (defined $block_hash->{'file_blocks'}->{$filename_full_path}) {
+	$self->{'num_blocked'} ++;
+	return 1;
+    }
+    # check Directory plugin's own block_exp 
+    if ($self->{'block_exp'} ne "" && $filename_full_path =~ /$self->{'block_exp'}/) {
+	$self->{'num_blocked'} ++;
+	return 1; # blocked
+    }
+    return 0;
+}
+
+
+
+sub file_block_read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $gli) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+    my $verbosity = $self->{'verbosity'};
+    
+    # Calculate the directory name and ensure it is a directory and
+    # that it is not explicitly blocked.
+    my $dirname = $file;
+    $dirname = &util::filename_cat ($base_dir, $file) if $base_dir =~ /\w/;
+
+    my $directory_ok = $self->check_directory_path($dirname);
+    return $directory_ok unless (defined $directory_ok && $directory_ok == 1);
+
+    $block_hash->{'file_blocks'} = {} unless defined $block_hash->{'file_blocks'};
+    $block_hash->{'shared_fileroot'} = {} unless defined $block_hash->{'shared_fileroot'};
+
+     # Recur over directory contents.
     my (@dir, $subfile);
-    my $count = 0;
-    
-    print $outhandle "DirectoryPlugin: getting directory $dirname\n" if ($verbosity);
+    #my $count = 0;
+    
+    print $outhandle "DirectoryPlugin block: getting directory $dirname\n" if ($verbosity > 2);
     
     # find all the files in the directory
@@ -198,4 +265,74 @@
     @dir = readdir (DIR);
     closedir (DIR);
+    
+    for (my $i = 0; $i < scalar(@dir); $i++) {
+	my $subfile = $dir[$i];
+	my $this_file_base_dir = $base_dir;
+	next if ($subfile =~ m/^\.\.?$/);
+
+	# Recursively read each $subfile
+	print $outhandle "DirectoryPlugin block recurring: $subfile\n" if ($verbosity > 2);
+	
+	#$count += &plugin::file_block_read ($pluginfo, $this_file_base_dir,
+	&plugin::file_block_read ($pluginfo, $this_file_base_dir,
+				  &util::filename_cat($file, $subfile),
+				  $block_hash, $metadata, $gli);
+	
+    }
+    $self->sort_out_associated_files($block_hash);
+    #return $count;
+    
+}
+# return number of files processed, undef if can't process
+# Note that $base_dir might be "" and that $file might 
+# include directories
+
+# This function passes around metadata hash structures.  Metadata hash
+# structures are hashes that map from a (scalar) key (the metadata element
+# name) to either a scalar metadata value or a reference to an array of
+# such values.
+
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $in_metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+    
+    my $outhandle = $self->{'outhandle'};
+    my $verbosity = $self->{'verbosity'};
+    
+    # Calculate the directory name and ensure it is a directory and
+    # that it is not explicitly blocked.
+    my $dirname;
+    if ($file eq "") {
+	$dirname = $base_dir;
+    } else {
+	$dirname = $file;
+	$dirname = &util::filename_cat ($base_dir, $file) if $base_dir =~ /\w/;
+    }
+
+    my $directory_ok = $self->check_directory_path($dirname);
+    return $directory_ok unless (defined $directory_ok && $directory_ok == 1);
+        
+    if (($verbosity > 2) && ((scalar keys %$in_metadata) > 0)) {
+        print $outhandle "DirectoryPlugin: metadata passed in: ", 
+	join(", ", keys %$in_metadata), "\n";
+    }
+    
+
+    # Recur over directory contents.
+    my (@dir, $subfile);
+    my $count = 0;
+    
+    print $outhandle "DirectoryPlugin read: getting directory $dirname\n" if ($verbosity > 2);
+    
+    # find all the files in the directory
+    if (!opendir (DIR, $dirname)) {
+	if ($gli) {
+	    print STDERR "<ProcessingError n='$file' r='Could not read directory $dirname'>\n";
+	}
+	print $outhandle "DirectoryPlugin: WARNING - couldn't read directory $dirname\n";
+	return -1; # error in processing
+    }
+    @dir = readdir (DIR);
+    closedir (DIR);
 
     # Re-order the files in the list so any directories ending with .all are moved to the end
@@ -211,4 +348,5 @@
     my %extrametadata;               # maps from filespec to extra metadata keys
     my @extrametakeys;               # keys of %extrametadata in order read
+
 
     my $os_dirsep = &util::get_os_dirsep();
@@ -239,15 +377,21 @@
 	last if ($maxdocs != -1 && $count >= $maxdocs);
 	next if ($subfile =~ m/^\.\.?$/);
-
+	my $file_subfile = &util::filename_cat($file, $subfile);
+	my $full_filename = &util::filename_cat($this_file_base_dir, $file_subfile);
+	if ($self->file_is_blocked($block_hash,$full_filename)) {
+	    print STDERR "DirectoryPlugin: file $full_filename was blocked for metadata_read\n" if ($verbosity > 2);
+	    next;
+	}
+	
 	# Recursively read each $subfile
 	print $outhandle "DirectoryPlugin metadata recurring: $subfile\n" if ($verbosity > 2);
 	
 	$count += &plugin::metadata_read ($pluginfo, $this_file_base_dir,
-					  &util::filename_cat($file, $subfile),
+					  $file_subfile,$block_hash,
 					  $out_metadata, \@extrametakeys, \%extrametadata,
 					  $processor, $maxdocs, $gli);
 	$additionalmetadata = 1;
     }
-   
+
     # filter out any extrametakeys that mention subdirectories and store
     # for later use (i.e. when that sub-directory is being processed)
@@ -313,4 +457,13 @@
 	next if ($subfile =~ /^\.\.?$/);
 
+	my $file_subfile = &util::filename_cat($file, $subfile);
+	my $full_filename 
+	    = &util::filename_cat($this_file_base_dir,$file_subfile);
+
+	if ($self->file_is_blocked($block_hash,$full_filename)) {
+	    print STDERR "DirectoryPlugin: file $full_filename was blocked for read\n" if ($verbosity > 2);
+	    next;
+	}
+	
 	# Follow Windows shortcuts
 	if ($subfile =~ /(?i)\.lnk$/ && $ENV{'GSDLOS'} =~ /^windows$/i) {
@@ -350,4 +503,8 @@
 	&metadatautil::combine_metadata_structures($out_metadata, $in_metadata);
 
+	# check the assocfile_info
+	if (defined $self->{'assocfile_info'}->{$full_filename}) {
+	    &metadatautil::combine_metadata_structures($out_metadata, $self->{'assocfile_info'}->{$full_filename});
+	}
         ## encode the filename as perl5 doesn't handle unicode filenames       
         my $tmpfile = Encode::encode_utf8($subfile); 
@@ -369,12 +526,9 @@
 
 
-	my $file_subfile = &util::filename_cat($file, $subfile);
-	my $filename_subfile 
-	    = &util::filename_cat($this_file_base_dir,$file_subfile);
 	if (defined $self->{'inf_timestamp'}) {
 	    my $inf_timestamp = $self->{'inf_timestamp'};
 
-	    if (! -d $filename_subfile) {
-		my $filename_timestamp = -M $filename_subfile;
+	    if (! -d $full_filename) {
+		my $filename_timestamp = -M $full_filename;
 		if ($filename_timestamp > $inf_timestamp) {
 		    # filename has been around for longer than inf
@@ -389,5 +543,5 @@
 	
 	$count += &plugin::read ($pluginfo, $this_file_base_dir,
-				 $file_subfile,
+				 $file_subfile, $block_hash,
 				 $out_metadata, $processor, $maxdocs, ($total_count + $count), $gli);
     }
