Index: /main/trunk/greenstone2/perllib/cgiactions/buildaction.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cgiactions/buildaction.pm	(revision 24070)
+++ /main/trunk/greenstone2/perllib/cgiactions/buildaction.pm	(revision 24071)
@@ -28,4 +28,6 @@
 use strict;
 
+use JSON;
+
 use cgiactions::baseaction;
 
@@ -33,4 +35,5 @@
 use ghtml;
 
+use util;
 
 BEGIN {
@@ -65,5 +68,9 @@
     
     "incremental-rebuild" => { 'compulsory-args' => [],
-			       'optional-args'   => [] }
+			       'optional-args'   => [] },
+				   
+    "build-by-manifest" => { 'compulsory-args' => [],
+			       'optional-args'   => ["index-files", "reindex-files", "delete-OIDs"] }
+				   
 };
 
@@ -206,6 +213,5 @@
     # Make sure the collection isn't locked by someone else
     $self->lock_collection($username, $collect);
-
-
+	
     my $bin_script = &util::filename_cat($gsdl_home,"bin","script");
     my $cmd = "perl -S full-rebuild.pl \"$collect\"";
@@ -342,5 +348,85 @@
 }
 
-
+sub build_by_manifest
+{
+	my $self = shift @_;
+
+    my $username  = $self->{'username'};
+    my $collect   = $self->{'collect'};
+    my $gsdl_cgi  = $self->{'gsdl_cgi'};
+    my $gsdl_home  = $self->{'gsdlhome'};
+
+    # Authenticate user if it is enabled
+    if ($baseaction::authentication_enabled) {
+	# Ensure the user is allowed to edit this collection
+	&authenticate_user($gsdl_cgi, $username, $collect);
+    }
+	
+    # Obtain the collect dir
+    my $collect_dir = &util::filename_cat($gsdl_home, "collect");
+
+    # Make sure the collection isn't locked by someone else
+    $self->lock_collection($username, $collect);
+
+	my $if_json_str   = $self->{'index-files'};
+	my $rf_json_str   = $self->{'reindex-files'};
+	my $df_json_str   = $self->{'delete-OIDs'};
+	
+		
+	my $index_files   = (defined $if_json_str) ? decode_json $if_json_str : [];
+	my $reindex_files = (defined $rf_json_str) ? decode_json $rf_json_str : [];
+	my $delete_files  = (defined $df_json_str) ? decode_json $df_json_str : [];
+	
+	my $index_files_xml   = join("\n", map { "    <Filename>$_</Filename>" } @$index_files);
+	my $reindex_files_xml = join("\n", map { "    <Filename>$_</Filename>" } @$reindex_files);
+	my $delete_files_xml  = join("\n", map { "    <OID>$_</OID>" } @$delete_files);
+	
+	my $manifest_filename = &util::get_tmp_filename(".xml");
+	my ($status,$report);
+			
+	if (open(MOUT,">$manifest_filename")) {
+		binmode(MOUT,":utf8");
+		print MOUT <<MOUTRAW;
+<Manifest>
+  <Index>
+$index_files_xml
+  </Index>
+  <Reindex>
+$reindex_files_xml
+  </Reindex>
+  <Delete>
+$delete_files_xml
+  </Delete>
+</Manifest>
+MOUTRAW
+		close(MOUT);
+		
+		## my $bin_script = &util::filename_cat($gsdl_home,"bin","script");
+		my $cmd = "perl -S incremental-rebuild.pl -manifest \"$manifest_filename\" \"$collect\"";
+
+		($status,$report) = $self->run_build_cmd($cmd);
+		
+		if ($status==0) {
+			&util::rm($manifest_filename);
+		}
+	}
+	else {
+		$status = -1;
+		$report = "Failed to open '$manifest_filename' for output\n$!\n";
+	}
+	
+   
+    # Release the lock once it is done
+    $self->unlock_collection($username, $collect);
+
+    if ($status==0) {
+	$gsdl_cgi->generate_ok_message($report);
+    }
+    else {
+	$gsdl_cgi->generate_error($report);
+    }
+	
+	# incremental-rebuild.pl -manifest manifest.xml \"" + _greenstoneCollectionName  + "\"";
+ }
 
 
Index: /main/trunk/greenstone2/perllib/cgiactions/explodeaction.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cgiactions/explodeaction.pm	(revision 24070)
+++ /main/trunk/greenstone2/perllib/cgiactions/explodeaction.pm	(revision 24071)
@@ -34,4 +34,6 @@
 use util;
 
+use JSON;
+
 use File::Basename;
 
@@ -50,6 +52,12 @@
 my $action_table =
 { 
-    "explode"          => { 'compulsory-args' => ["d"],
-			    'optional-args'   => [] }
+    "explode-document"          => { 'compulsory-args' => ["d"],
+			    'optional-args'   => [] },
+	"delete-document"           => { 'compulsory-args' => ["d"],
+			    'optional-args'   => [ "onlyadd" ] },
+	"delete-document-array"     => { 'compulsory-args' => ["json"],
+			    'optional-args'   => [ "onlyadd" ] }
+				
+				
 };
 
@@ -257,5 +265,45 @@
 
 
-sub explode 
+sub remove_docoids
+{
+    my $self = shift @_;
+    my ($docids) = @_;
+
+	my $collect   = $self->{'collect'};
+	my $gsdl_cgi  = $self->{'gsdl_cgi'};
+    my $infodb_type = $self->{'infodbtype'};
+
+    # Derive the archives and import directories
+	my $site = $self->{'site'};
+	my $collect_dir = $gsdl_cgi->get_collection_dir($site);
+	
+    my $archive_dir = &util::filename_cat($collect_dir,$collect,"archives");
+
+    # Obtain the doc.xml path for the specified docID
+    my $arcinfo_doc_filename 
+	= &dbutil::get_infodb_file_path($infodb_type, "archiveinf-doc", 
+				 	$archive_dir);
+
+    foreach my $docid (@$docids) {
+
+		my $doc_rec
+			= &dbutil::read_infodb_entry($infodb_type, $arcinfo_doc_filename, 
+					 $docid);
+
+		my $doc_xml_file = $doc_rec->{'doc-file'}->[0];
+
+		# The $doc_xml_file is relative to the archives, so need to do
+		# a bit more work to make sure the right folder containing this
+		# is moved to the right place in the import folder
+
+		my $assoc_path = dirname($doc_xml_file);
+		my $archive_assoc_dir = &util::filename_cat($archive_dir,$assoc_path);
+
+		&util::rm_r($archive_assoc_dir)
+    }
+}
+
+
+sub explode_document 
 {
     my $self = shift @_;
@@ -309,4 +357,151 @@
 
 
+sub delete_document_entry
+{
+	my $self = shift @_;
+	my ($docid_root,$opt_onlyadd) = @_;
+	
+	my $docid_keys = [];
+	if ((defined $opt_onlyadd) && ($opt_onlyadd==1)) {
+		# delete docoid archive folder
+		push(@$docid_keys,$docid_root);
+	}
+	else {
+		print STDERR "**** Not currently implemented for the general case!!\nDeleting 'archive' version only.";
+		
+		push(@$docid_keys,$docid_root);
+		
+		#my $orig_import_filenames = $self->docid_to_import_filenames($docid_root);
+		#$docid_keys = $self->import_filenames_to_docids($orig_import_filenames);
+		#my $expanded_import_filenames = $self->docid_to_import_filenames(@$docid_keys);
+		
+		# need to remove only the files that are not 
+		
+		#$self->remove_import_filenames($expanded_import_filenames);
+	}
+   
+	$self->remove_docoids($docid_keys);
+}
+	
+
+sub delete_document
+{
+    my $self = shift @_;
+
+    my $username  = $self->{'username'};
+    my $collect   = $self->{'collect'};
+    my $gsdl_cgi  = $self->{'gsdl_cgi'};
+    my $gsdl_home  = $self->{'gsdlhome'};
+
+    # Authenticate user if it is enabled
+    if ($baseaction::authentication_enabled) {
+	# Ensure the user is allowed to edit this collection
+	&authenticate_user($gsdl_cgi, $username, $collect);
+    }
+	
+    # Derive the archives dir    
+	my $site = $self->{'site'};
+	my $collect_dir = $gsdl_cgi->get_collection_dir($site);
+	
+	my $archive_dir = &util::filename_cat($collect_dir,$collect,"archives");
+    ##my $archive_dir = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},"archives");
+
+    # Make sure the collection isn't locked by someone else
+    $self->lock_collection($username, $collect);
+
+    # look up additional args
+    my $docid  = $self->{'d'};
+    if ((!defined $docid) || ($docid =~ m/^\s*$/)) {
+	$self->unlock_collection($username, $collect);
+	$gsdl_cgi->generate_error("No docid (d=...) specified.");
+    }
+
+    my ($docid_root,$docid_secnum) = ($docid =~ m/^(.*?)(\..*)?$/);
+
+	my $onlyadd = $self->{'onlyadd'};
+
+	my $status = $self->delete_document_entry($docid_root,$onlyadd);	
+
+    # Release the lock once it is done
+    $self->unlock_collection($username, $collect);
+
+	my $mess = "delete-document successful: Key[$docid_root]\n";
+    $gsdl_cgi->generate_ok_message($mess);
+
+}
+
+
+sub delete_document_array
+{
+    my $self = shift @_;
+
+    my $username  = $self->{'username'};
+    my $collect   = $self->{'collect'};
+    my $gsdl_cgi  = $self->{'gsdl_cgi'};
+    my $gsdlhome  = $self->{'gsdlhome'};
+
+    if ($baseaction::authentication_enabled) {
+	# Ensure the user is allowed to edit this collection
+	&authenticate_user($gsdl_cgi, $username, $collect);
+    }
+
+	my $site = $self->{'site'};
+	my $collect_dir = $gsdl_cgi->get_collection_dir($site);
+	
+    $gsdl_cgi->checked_chdir($collect_dir);
+
+    # Obtain the collect dir
+    ## my $collect_dir = &util::filename_cat($gsdlhome, "collect");
+
+    # Make sure the collection isn't locked by someone else
+    $self->lock_collection($username, $collect);
+
+    # look up additional args
+	
+	my $json_str      = $self->{'json'};
+	my $doc_array = decode_json $json_str;
+
+	my $onlyadd = $self->{'onlyadd'};
+	
+	
+	my $global_status = 0;
+	my $global_mess = "";
+	
+	my @all_docids = ();
+	
+	foreach my $doc_array_rec ( @$doc_array ) {
+		
+		my $docid     = $doc_array_rec->{'docid'};
+		
+		push(@all_docids,$docid);
+		
+		my ($docid_root,$docid_secnum) = ($docid =~ m/^(.*?)(\..*)?$/);
+		  
+		my $status = $self->delete_document_entry($docid_root,$onlyadd);	
+		
+		if ($status != 0) {
+			# Catch error if set infodb entry failed
+			$global_status = $status;
+			$global_mess .= "Failed to delete document key: $docid\n";
+			$global_mess .= "Exit status: $status\n";
+			$global_mess .= "System Error Message: $!\n";
+			$global_mess .= "-" x 20;
+		}
+	}
+
+	if ($global_status != 0) {
+		$global_mess .= "PATH: $ENV{'PATH'}\n";
+		$gsdl_cgi->generate_error($global_mess);
+    }
+    else {
+		my $mess = "delete-document-array successful: Keys[ ".join(", ",@all_docids)."]\n";
+		$gsdl_cgi->generate_ok_message($mess);
+    }
+    
+    # Release the lock once it is done
+    $self->unlock_collection($username, $collect);
+}
+
+
 
 1;
Index: /main/trunk/greenstone2/perllib/cgiactions/metadataaction.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cgiactions/metadataaction.pm	(revision 24070)
+++ /main/trunk/greenstone2/perllib/cgiactions/metadataaction.pm	(revision 24071)
@@ -33,4 +33,6 @@
 use ghtml;
 
+use JSON;
+
 
 BEGIN {
@@ -57,4 +59,7 @@
 			         'optional-args'   => [ "metapos" ] },
 
+	"set-metadata-array"     => { 'compulsory-args' => [ "json" ],
+			         'optional-args'   => [ ] },
+					 
     "set-archives-metadata" => { 'compulsory-args' => [ "d", "metaname", "metavalue" ],
 			         'optional-args'   => [ "metapos", "metamode" ]
@@ -62,4 +67,8 @@
 				},
 
+    "set-archives-metadata-array" => { 'compulsory-args' => [ "json" ],
+			         'optional-args'   => [ "metamode" ]
+				},
+				
     "set-import-metadata"   => { 'compulsory-args' => [ "metaname", "metavalue" ],
 			         'optional-args'   => [ "d", "f", "metamode" ]
@@ -292,4 +301,35 @@
 }
 
+sub set_metadata_entry
+{
+	my $self = shift @_;
+	my ($collect_dir,$collect,$infodbtype,$docid,$metaname,$metapos,$metavalue) = @_;
+	
+    # To people who know $collect_tail please add some comments
+    # Obtain path to the database
+    my $collect_tail = $collect;
+    $collect_tail =~ s/^.*[\/\\]//;
+    my $index_text_directory = &util::filename_cat($collect_dir,$collect,"index","text");
+    my $infodb_file_path = &dbutil::get_infodb_file_path($infodbtype, $collect_tail, $index_text_directory);
+	
+#	print STDERR "**** infodb file path = $infodb_file_path\n";
+#	print STDERR "***** infodb type = $infodbtype\n";
+	
+    # Read the docid entry
+    my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $infodb_file_path, $docid);
+	
+    # Set the metadata value
+    if (defined $metapos) {
+		$doc_rec->{$metaname}->[$metapos] = $metavalue;
+    }
+    else {
+		$doc_rec->{$metaname} = [ $metavalue ];
+    }
+ 
+    my $status = &dbutil::set_infodb_entry($infodbtype, $infodb_file_path,$docid,$doc_rec);
+	
+	return $status;
+	
+}
 
 sub set_metadata
@@ -325,26 +365,6 @@
     my $infodbtype = $self->{'infodbtype'};
 	
-    # To people who know $collect_tail please add some comments
-    # Obtain path to the database
-    my $collect_tail = $collect;
-    $collect_tail =~ s/^.*[\/\\]//;
-    my $index_text_directory = &util::filename_cat($collect_dir,$collect,"index","text");
-    my $infodb_file_path = &dbutil::get_infodb_file_path($infodbtype, $collect_tail, $index_text_directory);
-	
-	print STDERR "**** infodb file path = $infodb_file_path\n";
-	print STDERR "***** infodb type = $infodbtype\n";
-	
-    # Read the docid entry
-    my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $infodb_file_path, $docid);
-	
-    # Set the metadata value
-    if (defined $metapos) {
-	$doc_rec->{$metaname}->[$metapos] = $metavalue;
-    }
-    else {
-	$doc_rec->{$metaname} = [ $metavalue ];
-    }
- 
-    my $status = &dbutil::set_infodb_entry($infodbtype, $infodb_file_path,$docid,$doc_rec);
+	my $status = $self->set_metadata_entry($collect_dir,$collect,$infodbtype,$docid,$metaname,$metapos,$metavalue);
+	
     if ($status != 0) {
         # Catch error if set infodb entry failed
@@ -358,5 +378,5 @@
     }
     else {
-	my $mess = "set-document-metadata successful: Key[$docid]\n";
+	my $mess = "set-metadata successful: Key[$docid]\n";
 	$mess .= "  $metaname";
 	$mess .= "->[$metapos]" if (defined $metapos);
@@ -369,4 +389,80 @@
     $self->unlock_collection($username, $collect);
 }
+
+
+
+
+sub set_metadata_array
+{
+    my $self = shift @_;
+
+    my $username  = $self->{'username'};
+    my $collect   = $self->{'collect'};
+    my $gsdl_cgi  = $self->{'gsdl_cgi'};
+    my $gsdlhome  = $self->{'gsdlhome'};
+
+    if ($baseaction::authentication_enabled) {
+	# Ensure the user is allowed to edit this collection
+	&authenticate_user($gsdl_cgi, $username, $collect);
+    }
+
+	my $site = $self->{'site'};
+	my $collect_dir = $gsdl_cgi->get_collection_dir($site);
+	
+    $gsdl_cgi->checked_chdir($collect_dir);
+
+    # Obtain the collect dir
+    ## my $collect_dir = &util::filename_cat($gsdlhome, "collect");
+
+    # Make sure the collection isn't locked by someone else
+    $self->lock_collection($username, $collect);
+
+    # look up additional args
+	
+	my $infodbtype = $self->{'infodbtype'};
+	
+	my $json_str      = $self->{'json'};
+	my $doc_array = decode_json $json_str;
+	
+	
+	my $global_status = 0;
+	my $global_mess = "";
+	
+	my @all_docids = ();
+	
+	foreach my $doc_array_rec ( @$doc_array ) {
+		
+		my $docid     = $doc_array_rec->{'docid'};
+		my $metaname  = $doc_array_rec->{'metaname'};
+		my $metapos   = $doc_array_rec->{'metapos'};
+		my $metavalue = $doc_array_rec->{'metavalue'};
+		
+		push(@all_docids,$docid);
+		
+		my $status = $self->set_metadata_entry($collect_dir,$collect,$infodbtype,$docid,$metaname,$metapos,$metavalue);	
+		
+		if ($status != 0) {
+			# Catch error if set infodb entry failed
+			$global_status = $status;
+			$global_mess .= "Failed to set metadata key: $docid\n";
+			$global_mess .= "Exit status: $status\n";
+			$global_mess .= "System Error Message: $!\n";
+			$global_mess .= "-" x 20;
+		}
+	}
+
+	if ($global_status != 0) {
+		$global_mess .= "PATH: $ENV{'PATH'}\n";
+		$gsdl_cgi->generate_error($global_mess);
+    }
+    else {
+		my $mess = "set-metadata-array successful: Keys[ ".join(", ",@all_docids)."]\n";
+		$gsdl_cgi->generate_ok_message($mess);
+    }
+    
+    # Release the lock once it is done
+    $self->unlock_collection($username, $collect);
+}
+
 
 
@@ -554,4 +650,36 @@
 }
 
+sub set_archives_metadata_entry
+{
+  	my $self = shift @_;
+	my ($gsdl_cgi,$archive_dir, $collect_dir,$collect, $infodbtype,$docid,$metaname,$metapos,$metavalue,$metamode) = @_;
+	
+    # Obtain the doc.xml path for the specified docID
+    my ($docid_root,$docid_secnum) = ($docid =~ m/^(.*?)(\..*)?$/);
+
+    my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir);
+    my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid_root);
+    my $doc_xml_file = $doc_rec->{'doc-file'}->[0];
+    
+    # The $doc_xml_file is relative to the archives, and now let's get the full path
+    my $archives_dir = &util::filename_cat($collect_dir,$collect,"archives");    
+    my $doc_xml_filename = &util::filename_cat($archives_dir,$doc_xml_file);
+    
+    # Edit the doc.xml file with the specified metadata name, value and position.
+    # TODO: there is a potential problem here as this edit_doc_xml function 
+    # is assuming the simple doc.xml situation where there is only one Section and no SubSections.
+    # Running import.pl -groupsize will cause this to have multiple sections in one doc.xml
+	
+	print STDERR "** away to call edit_doc_xml\n";
+	
+    $self->edit_doc_xml($gsdl_cgi,$doc_xml_filename,
+			$metaname,$metavalue,$metapos,$metamode,$docid_secnum);
+			
+	print STDERR "*** finished edit_doc_xml\n";
+	
+	return 0; # return 0 for now to indicate no error
+			
+}
+
 
 sub set_archives_metadata
@@ -565,13 +693,15 @@
     my $infodbtype = $self->{'infodbtype'};
 	
+
+	
     if ($baseaction::authentication_enabled) {
-	# Ensure the user is allowed to edit this collection
-	$self->authenticate_user($username, $collect);
-    }
-
+		# Ensure the user is allowed to edit this collection
+		$self->authenticate_user($username, $collect);
+    }
+
+	my $site = $self->{'site'};
+		
 	# Obtain the collect and archive dir   
-	my $site = $self->{'site'};
 	my $collect_dir = $gsdl_cgi->get_collection_dir($site);	
-    ## my $collect_dir = &util::filename_cat($gsdlhome, "collect");
 	
     my $archive_dir = &util::filename_cat($collect_dir,$collect,"archives");
@@ -593,34 +723,115 @@
 	# delete any existing values)
 	$metamode = "accumulate";
-    }
-    
-    # Obtain the doc.xml path for the specified docID
-    my ($docid_root,$docid_secnum) = ($docid =~ m/^(.*?)(\..*)?$/);
-
-    my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir);
-    my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid_root);
-    my $doc_xml_file = $doc_rec->{'doc-file'}->[0];
-    
-    # The $doc_xml_file is relative to the archives, and now let's get the full path
-    my $archives_dir = &util::filename_cat($collect_dir,$collect,"archives");    
-    my $doc_xml_filename = &util::filename_cat($archives_dir,$doc_xml_file);
-    
-    # Edit the doc.xml file with the specified metadata name, value and position.
-    # TODO: there is a potential problem here as this edit_doc_xml function 
-    # is assuming the simple doc.xml situation where there is only one Section and no SubSections.
-    # Running import.pl -groupsize will cause this to have multiple sections in one doc.xml
-    $self->edit_doc_xml($gsdl_cgi,$doc_xml_filename,
-			$metaname,$metavalue,$metapos,$metamode,$docid_secnum);
-    
+    } 
+	
+	my $status = $self->set_archives_metadata_entry($gsdl_cgi,$archive_dir, $collect_dir,$collect, $infodbtype,$docid,
+				$metaname,$metapos,$metavalue,$metamode);
+   
     # Release the lock once it is done
     $self->unlock_collection($username, $collect);
 
-    my $mess = "set-archives-metadata successful: Key[$docid]\n";
-    $mess .= "  $metaname";
-    $mess .= "->[$metapos]" if (defined $metapos);
-    $mess .= " = $metavalue";
-    $mess .= " ($metamode)\n";
-	
-    $gsdl_cgi->generate_ok_message($mess);	
+	if ($status == 0) {
+		my $mess = "set-archives-metadata successful: Key[$docid]\n";
+		$mess .= "  $metaname";
+		$mess .= "->[$metapos]" if (defined $metapos);
+		$mess .= " = $metavalue";
+		$mess .= " ($metamode)\n";
+	
+		$gsdl_cgi->generate_ok_message($mess);	
+	}
+	else {
+		my $mess .= "Failed to set archives metadata key: $docid\n";
+		$mess .= "Exit status: $status\n";
+		$mess .= "System Error Message: $!\n";
+		$mess .= "-" x 20 . "\n";
+		
+		$gsdl_cgi->generate_error($mess);
+	}
+}
+
+
+sub set_archives_metadata_array
+{
+    my $self = shift @_;
+
+    my $username  = $self->{'username'};
+    my $collect   = $self->{'collect'};
+    my $gsdl_cgi  = $self->{'gsdl_cgi'};
+    my $gsdlhome  = $self->{'gsdlhome'};
+
+    if ($baseaction::authentication_enabled) {
+	# Ensure the user is allowed to edit this collection
+	&authenticate_user($gsdl_cgi, $username, $collect);
+    }
+
+	my $site = $self->{'site'};
+	my $collect_dir = $gsdl_cgi->get_collection_dir($site);
+	
+    $gsdl_cgi->checked_chdir($collect_dir);
+
+    # Obtain the collect dir
+    ## my $collect_dir = &util::filename_cat($gsdlhome, "collect");
+
+    # Make sure the collection isn't locked by someone else
+    $self->lock_collection($username, $collect);
+
+    # look up additional args
+	
+	my $infodbtype = $self->{'infodbtype'};
+
+   my $archive_dir = &util::filename_cat($collect_dir,$collect,"archives");
+	
+	my $json_str      = $self->{'json'};
+	my $doc_array = decode_json $json_str;
+	
+	
+	my $global_status = 0;
+	my $global_mess = "";
+	
+	my @all_docids = ();
+	
+	foreach my $doc_array_rec ( @$doc_array ) {
+		
+		my $docid     = $doc_array_rec->{'docid'};
+		my $metaname  = $doc_array_rec->{'metaname'};
+		my $metapos   = $doc_array_rec->{'metapos'};
+		my $metamode   = $self->{'metamode'};
+		my $metavalue = $doc_array_rec->{'metavalue'};
+		
+		# Some sanity checks
+		$metapos = 0 if (!defined $metapos);
+			
+		if ((!defined $metamode) || ($metamode =~ m/^\s*$/)) {
+			# make "accumulate" the default (less destructive, as won't actually 
+			# delete any existing values)
+			$metamode = "accumulate";
+		} 
+	
+		push(@all_docids,$docid);
+		
+		my $status = $self->set_archives_metadata_entry($gsdl_cgi,$archive_dir, $collect_dir,$collect, $infodbtype,$docid,
+				$metaname,$metapos,$metavalue,$metamode);
+		
+		if ($status != 0) {
+			# Catch error if set infodb entry failed
+			$global_status = $status;
+			$global_mess .= "Failed to set metadata key: $docid\n";
+			$global_mess .= "Exit status: $status\n";
+			$global_mess .= "System Error Message: $!\n";
+			$global_mess .= "-" x 20 . "\n";
+		}
+	}
+
+	if ($global_status != 0) {
+		$global_mess .= "PATH: $ENV{'PATH'}\n";
+		$gsdl_cgi->generate_error($global_mess);
+    }
+    else {
+		my $mess = "set-archives-metadata-array successful: Keys[ ".join(", ",@all_docids)."]\n";
+		$gsdl_cgi->generate_ok_message($mess);
+    }
+    
+    # Release the lock once it is done
+    $self->unlock_collection($username, $collect);
 }
 
