Index: /trunk/gsdl/perllib/docsave.pm
===================================================================
--- /trunk/gsdl/perllib/docsave.pm	(revision 8516)
+++ /trunk/gsdl/perllib/docsave.pm	(revision 8517)
@@ -35,4 +35,5 @@
 
 use arcinfo;
+use expinfo;
 use docproc;
 use util;
@@ -44,12 +45,18 @@
 
 sub new {
-    my ($class, $collection, $archive_info, $verbosity, 
-	$gzip, $groupsize, $outhandle) = @_;
+    my ($class, $collection, $info, $verbosity, 
+	$gzip, $groupsize, $outhandle, $service, $saveas) = @_;
     my $self = new docproc ();
-    
     
     $groupsize=1 unless defined $groupsize;
     $self->{'collection'} = $collection;
-    $self->{'archive_info'} = $archive_info;
+    if ($service eq "import"){
+	$self->{'archive_info'} = $info;
+    } elsif ($service eq "export"){ 
+	$self->{'export_info'} = $info;
+    } else {
+	return;
+    }
+
     $self->{'verbosity'} = $verbosity;
     $self->{'gzip'} = $gzip;
@@ -60,7 +67,16 @@
     $self->{'outhandle'} = 'STDERR';
     $self->{'outhandle'} = $outhandle if defined $outhandle;
+    $self->{'service'} = $service;
+    $self->{'saveas'} = $saveas;
+
     # set a default for the archive directory
-    $self->{'archive_dir'} = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "archives");
-    
+    if ($service eq "import"){
+	$self->{'archive_dir'} = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "archives");
+    } elsif ($service eq "export") {
+	# set a default for the export directory
+	$self->{'export_dir'} = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "export");
+    } else {
+	return;
+    }
     $self->{'sortmeta'} = undef;
     
@@ -76,4 +92,12 @@
 }
 
+sub setexportdir {
+    my $self = shift (@_);
+    my ($export_dir) = @_;
+ 
+    &util::mk_all_dir ($export_dir) unless -e $export_dir;
+    $self->{'export_dir'} = $export_dir;
+}
+
 sub set_sortmeta {
     my $self = shift (@_);
@@ -81,5 +105,5 @@
     
     $self->{'sortmeta'} = $sortmeta;
-}
+ }
 
 sub process {
@@ -88,5 +112,10 @@
  
     my $outhandle = $self->{'outhandle'};
-   
+    my $service = $self->{'service'} || "import";
+
+    # Define the SaveAs Type
+    my $save_as = $self->{'saveas'} || "GA";
+    my $collection = $self->{'collection'};
+
     if ($self->{'groupsize'} > 1) {
 	$self->group_process ($doc_obj);
@@ -94,88 +123,179 @@
     }
 
+    my $OID = $doc_obj->get_OID();
+    $OID = "NULL" unless defined $OID;
+
+    # get document's directory
+    my $doc_dir = $self->get_doc_dir ($OID);
+
     # groupsize is 1 (i.e. one document per XML file) so sortmeta 
     # may be used
-	
-    my $OID = $doc_obj->get_OID();
-    $OID = "NULL" unless defined $OID;
-
-    # get document's directory
-    my $doc_dir = $self->get_doc_dir ($OID);
-     
+
+    if ($service eq "import") {
+	my $archive_info = $self->{'archive_info'};
+    } elsif ($service eq "export") {
+	my $export_info = $self->{'export_info'};
+    } else {
+	return;
+    }
     
     # copy all the associated files, add this information as metadata
     # to the document
-    $self->process_assoc_files ($doc_obj, $doc_dir);
+    if ($service eq "export" && $save_as eq "DSpace") {
+	# open contents file
+	my $doc_contents_file
+	    = &util::filename_cat ($self->{'export_dir'},$doc_dir, "contents");
 	
-    my $doc_file 
-	= &util::filename_cat ($self->{'archive_dir'}, $doc_dir, "doc.xml");
-      
-    #***define doctxt.xml file
-    my $doc_txt_file
-	= &util::filename_cat ($self->{'archive_dir'}, $doc_dir,"doctxt.xml");
-    my $working_dir
-	=&util::filename_cat ($self->{'archive_dir'}, $doc_dir);
+	if (!open(OUTDOC_EXPORT_CONTENTS,">$doc_contents_file")){
+	    print $outhandle "docsave::process could not write collection contents to file $doc_contents_file\n";
+	    return;
+	} 
+	$self->process_assoc_files ($doc_obj, $doc_dir, 'docsave::OUTDOC_EXPORT_CONTENTS');
+    } else {
+	$self->process_assoc_files ($doc_obj, $doc_dir, '');
+    }
         
-    #***define docmets.xmlfile
-    my $doc_mets_file
-	= &util::filename_cat ($self->{'archive_dir'},$doc_dir, "docmets.xml");
+    my $doc_file;
+    my $doc_mets_file;
+    my $doc_txt_file;
+    my $short_doc_file;
+
+    #Import collection to GS2 in GS Archive format and METs format
+    if ($service eq "import") {
+	my $doc_file 
+	    = &util::filename_cat ($self->{'archive_dir'}, $doc_dir, "doc.xml");
+
+	#***define doctxt.xml file
+	my $doc_txt_file
+	    = &util::filename_cat ($self->{'archive_dir'}, $doc_dir,"doctxt.xml");
+
+	my $import_working_dir
+	    =&util::filename_cat ($self->{'archive_dir'}, $doc_dir);
+	
+	#***define docmets.xml file
+	my $doc_mets_file
+	    = &util::filename_cat ($self->{'archive_dir'},$doc_dir, "docmets.xml");
+	
+	if ($save_as eq "GA") {
+	    $short_doc_file = util::filename_cat ($doc_dir, "doc.xml");
+	} elsif ($save_as eq "METS") {
+	    #my $short_txt_doc_file=&util::filename_cat ($doc_dir, "doctxt.xml");
+	    $short_doc_file = &util::filename_cat ($doc_dir, "docmets.xml");
+	} else {
+	    return;
+	}
+	
+	if ($save_as eq "GA") {
+	    if (!open (OUTDOC, ">$doc_file")) {
+		print $outhandle "docsave::process could not write to file $doc_file\n";
+		return;
+	    }
+	    # save this document
+	    $self->output_xml_header('docsave::OUTDOC');
+	    $doc_obj->output_section('docsave::OUTDOC',
+				 $doc_obj->get_top_section());
+	    $self->output_xml_footer('docsave::OUTDOC');
+	    
+	    close OUTDOC;
+	} elsif ($save_as eq "METS") {
+	    # save the document without metadata:doctxt.xml
+	    
+	    if (!open(OUTDOC_TXT, ">$doc_txt_file")){
+		print $outhandle "docsave::process could not write to file $doc_txt_file\n";
+		return;
+	    }
+	    
+	    $self->output_txt_xml_header('docsave::OUTDOC_TXT');
+	    $doc_obj->output_txt_section('docsave::OUTDOC_TXT', $doc_obj->get_top_section());
+	    #$self->output_txt_xml_footer('docsave::OUTDOC_TXT');
+	    
+	    # Convert doctxt.xml file to docmets.xml
+	    if (!open(OUTDOC_METS,">$doc_mets_file")){
+		print $outhandle "docsave::process could not write to file $doc_mets_file\n";
+		return;
+	    }
+	    
+	    $self->output_mets_xml_header('docsave::OUTDOC_METS', $OID);
+	    $doc_obj->output_mets_section('docsave::OUTDOC_METS',
+					  $doc_obj->get_top_section(),
+					  $import_working_dir);
+	    $self->output_mets_xml_footer('docsave::OUTDOC_METS');
+	    
+	    close OUTDOC_TXT;
+	    close OUTDOC_METS;
+	} else { # save_as isn't GA or METS
+	    print $outhandle "docsave::process unrecognised saveas type, $save_as\n";
+	    return;
+	}
+    }
+    
+    ## Export the collection to METs format or DSpace Archive Format into the export directory
+    if ($service eq "export") {
+	my $doc_dc_file;
+	my $doc_contents_file;
+
+	my $export_working_dir
+	    =&util::filename_cat ($self->{'export_dir'}, $doc_dir);
+       
+	if ($save_as eq "METS") {
+	    $doc_mets_file
+		= &util::filename_cat ($self->{'export_dir'},$doc_dir, "docmets.xml");
+	    
+	    $doc_txt_file
+		= &util::filename_cat ($self->{'export_dir'},$doc_dir, "doctxt.xml");
+	    
+	    if (!open(OUTDOC_EXPORT_TXT, ">$doc_txt_file")){
+		print $outhandle "docsave::process could not write TXT to file $doc_txt_file\n";
+		return;
+	    }
+	    
+	    $self->output_txt_xml_header('docsave::OUTDOC_EXPORT_TXT');
+	    $doc_obj->output_txt_section('docsave::OUTDOC_EXPORT_TXT', $doc_obj->get_top_section());
+	    
+	    if (!open(OUTDOC_EXPORT_METS,">$doc_mets_file")){
+		print $outhandle "docsave::process could not write METS format to file $doc_mets_file\n";
+		return;
+	    }
+	    $self->output_mets_xml_header('docsave::OUTDOC_EXPORT_METS', $OID);
+	    $doc_obj->output_mets_section('docsave::OUTDOC_EXPORT_METS',$doc_obj->get_top_section(), $export_working_dir);
+	    $self->output_mets_xml_footer('docsave::OUTDOC_EXPORT_METS');
+    
+	    close OUTDOC_EXPORT_TXT;
+	    close OUTDOC_EXPORT_METS;
+	} elsif ($save_as eq "DSpace") {
+
+	    # Generate dublin_core.xml file
+	    $doc_dc_file
+		= &util::filename_cat ($self->{'export_dir'},$doc_dir, "dublin_core.xml");
+   
+	    if (!open(OUTDOC_EXPORT_DC,">$doc_dc_file")){
+		print $outhandle "docsave::process could not write dublin core to file $doc_dc_file\n";
+		return;
+	    }   
+	   
+	    $self->output_dc_xml_header('docsave::OUTDOC_EXPORT_DC', $OID);
+	    $doc_obj->output_dc_section('docsave::OUTDOC_EXPORT_DC',$doc_obj->get_top_section(), $export_working_dir);
+	    $self->output_dc_xml_footer('docsave::OUTDOC_EXPORT_DC');
+    
+	    close OUTDOC_EXPORT_DC;
+	    close OUTDOC_EXPORT_CONTENTS;
+	} else { # save_as isn't METS or DSpace
+	    print $outhandle "docsave::process unrecognised saveas type, $save_as\n";
+	    return;
+	}
+
+	if ($save_as eq "METS") {
+	    $short_doc_file = util::filename_cat ($doc_dir, "docmets.xml");
+	} elsif ($save_as eq "DSpace") {
+	    #my $short_txt_doc_file=&util::filename_cat ($doc_dir, "doctxt.xml");
+	    $short_doc_file=&util::filename_cat ($doc_dir, "dublin_core.xml");
+	} else {
+	    return;
+	}
+	
+    }
+    #save for later (for close_file_output())
+    $self->{'short_doc_file'} = $short_doc_file;	
  
-    my $short_doc_file;
-    my $save_as = $self->{'saveas'} || "GA";
-    if ($save_as eq "GA") {
-	$short_doc_file = util::filename_cat ($doc_dir, "doc.xml");
-    } elsif ($save_as eq "METS") {
-	#my $short_txt_doc_file=&util::filename_cat ($doc_dir, "doctxt.xml");
-	$short_doc_file=&util::filename_cat ($doc_dir, "docmets.xml");
-    } else {
-	return;
-    }
-    # save for later (for close_file_output())
-    $self->{'short_doc_file'}=$short_doc_file;
-
-    if ($save_as eq "GA") {
-	if (!open (OUTDOC, ">$doc_file")) {
-	    print $outhandle "docsave::process could not write to file $doc_file\n";
-	    return;
-	}
-	    
-	# save this document
-	$self->output_xml_header('docsave::OUTDOC');
-	$doc_obj->output_section('docsave::OUTDOC',
-				 $doc_obj->get_top_section());
-	$self->output_xml_footer('docsave::OUTDOC');
-
-	close OUTDOC;
-    } elsif ($save_as eq "METS") {
-	# save the document without metadata:doctxt.xml
-
-	if (!open(OUTDOC_TXT, ">$doc_txt_file")){
-	    print $outhandle "docsave::process could not write to file $doc_mets_file\n";
-	    return;
-	}
-
-	$self->output_txt_xml_header('docsave::OUTDOC_TXT');
-	$doc_obj->output_txt_section('docsave::OUTDOC_TXT', $doc_obj->get_top_section());
-	#$self->output_txt_xml_footer('docsave::OUTDOC_TXT');
-	
-	# Convert doctxt.xml file to docmets.xml
-	if (!open(OUTDOC_METS,">$doc_mets_file")){
-	    print $outhandle "docsave::process could not write to file $doc_mets_file\n";
-	    return;
-	}
-	    
-	$self->output_mets_xml_header('docsave::OUTDOC_METS', $OID);
-	$doc_obj->output_mets_section('docsave::OUTDOC_METS',
-				      $doc_obj->get_top_section(),
-				      $working_dir);
-	$self->output_mets_xml_footer('docsave::OUTDOC_METS');
-
-	close OUTDOC_TXT;
-	close OUTDOC_METS;
-    } else { # save_as isn't GA or METS
-	print $outhandle "docsave::process unrecognised saveas type, $save_as\n";
-	return;
-    }
-
     if ($self->{'gzip'}) {
 	my $doc_file = $self->{'gs_filename'};
@@ -190,11 +310,16 @@
 
     # do the sortmeta thing
-    my ($metadata);	if (defined ($self->{'sortmeta'})) {
+    my ($metadata);	
+    if (defined ($self->{'sortmeta'})) {
 	$metadata = $doc_obj->get_metadata_element($doc_obj->get_top_section(),
 						   $self->{'sortmeta'});
     }
 
-    # store reference in the archive_info
-    $self->{'archive_info'}->add_info($OID, $short_doc_file, $metadata);
+    # store reference in the archive_info and export_info
+    if ($service eq "export") {
+	$self->{'export_info'}->add_info($OID, $short_doc_file, $metadata);	
+    } elsif ($service eq "import") {
+	$self->{'archive_info'}->add_info($OID, $short_doc_file, $metadata);
+    }
 }
 
@@ -253,11 +378,24 @@
 }
 
-
 sub get_doc_dir {
     my $self = shift (@_);
     my ($OID) = @_;
-
-    my $doc_info = $self->{'archive_info'}->get_info($OID);
-    my $doc_dir = "";
+    my $doc_info;
+    my $doc_dir;
+    my $service = $self-> {'service'};
+    my $working_dir;
+    my $working_info;
+
+    if ($service eq "import") {
+	$doc_info = $self->{'archive_info'}->get_info($OID);
+	$working_dir = $self->{'archive_dir'};
+	$working_info = $self->{'archive_info'};
+    } elsif ($service eq "export") {
+	$doc_info =$self->{'export_info'}->get_info($OID);
+        $working_dir = $self->{'export_dir'};
+	$working_info = $self->{'export_info'};
+    } else {
+	return;
+    }
     if (defined $doc_info && scalar(@$doc_info) >= 1) {
 	# this OID already has an assigned directory, use the
@@ -276,29 +414,54 @@
 	    }
 	} while ($doc_dir_rest ne "" && 
-		 ((-d &util::filename_cat ($self->{'archive_dir'}, "$doc_dir.dir")) || 
-		  ($self->{'archive_info'}->size() >= 1024 && $doc_dir_num < 2)));
+		 ((-d &util::filename_cat ($working_dir, "$doc_dir.dir")) || 
+		  ($working_info->size() >= 1024 && $doc_dir_num < 2)));
+
 	$doc_dir .= ".dir";
-	
-    }
-	
-    &util::mk_all_dir (&util::filename_cat ($self->{'archive_dir'}, $doc_dir));
-
+	&util::mk_all_dir (&util::filename_cat ($working_dir, $doc_dir));
+    }
     return $doc_dir;
 }
 
-
 sub process_assoc_files {
     my $self = shift (@_);
-    my ($doc_obj, $doc_dir) = @_;
+    my ($doc_obj, $doc_dir, $handle) = @_;
 
     my $outhandle = $self->{'outhandle'};
-
+    
     my @assoc_files = ();
+    my $filename;;
+    my $working_dir;
+    my $service = $self->{'service'};
+    my $save_as = $self->{'saveas'};
+
+    if ($service eq "import") {
+	$working_dir = $self->{'archive_dir'};
+    } elsif ($service eq "export"){
+	$working_dir = $self->{'export_dir'};
+    } else {
+	return;
+    }
+    $doc_obj->get_source_filename()=~ /\/[^\/\\]$/;
+
+    if ($save_as eq "DSpace") {
+	print $handle "$1\n";
+	$filename = &util::filename_cat($working_dir, $doc_dir, $1);
+	&util::hard_link ($doc_obj->get_source_filename(), $filename);
+    }
+           
     foreach my $assoc_file (@{$doc_obj->get_assoc_files()}) {
 	my ($dir, $afile) = $assoc_file->[1] =~ /^(.*?)([^\/\\]+)$/;
 	$dir = "" unless defined $dir;
+
+	# Store the associated file to the "contents" file
+	if ($save_as eq "DSpace") {
+	    print $handle "$assoc_file->[1]\n";
+	}
+
 	if (-e $assoc_file->[0]) {
-	    my $filepath = &util::filename_cat($self->{'archive_dir'}, $doc_dir, $afile);
-	    &util::hard_link ($assoc_file->[0], $filepath);
+	    $filename = &util::filename_cat($working_dir, $doc_dir, $afile);
+
+	    &util::hard_link ($assoc_file->[0], $filename);
+	    
 	    $doc_obj->add_utf8_metadata ($doc_obj->get_top_section(),
 					 "gsdlassocfile",
@@ -318,4 +481,5 @@
 {
     my ($self) = @_;
+    my $service =$self->{'service'};
 
     # make sure that the handle has been opened - it won't be if we failed
@@ -331,8 +495,9 @@
     if (exists($self->{'saveas'}) && $self->{'saveas'} eq "METS") {
 	$short_doc_file=$self->{'short_doc_file'};
-    } else { # "GA"
+    } elsif ($self->{'saveas'} eq "GA") { # "GA"
 	$short_doc_file=$self->{'gs_short_filename'};
-    }
-
+    } else { # "DSpace"
+    }
+    
     if ($self->{'gzip'}) {
 	my $doc_file = $self->{'gs_filename'};
@@ -347,7 +512,12 @@
     }
 
-    # store reference in the archive_info
-    $self->{'archive_info'}->add_info($OID, $short_doc_file);
-   
+    # store reference in the archive_info and export_infor
+    if ($service eq "import") {
+	$self->{'archive_info'}->add_info($OID, $short_doc_file);
+    } elsif ($service eq "export") {
+	$self->{'export_info'}->add_info($OID, $short_doc_file);
+    } else {
+	return;
+    }
     return 1;
 }
@@ -386,4 +556,5 @@
     my $self = shift(@_);
     my ($handle, $OID) = @_;
+
     print $handle '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . "\n";
     print $handle '<!DOCTYPE Archive SYSTEM "http://greenstone.org/dtd/Archive/1.0/Archive.dtd">' . "\n";
@@ -397,6 +568,17 @@
 }
 
+sub output_dc_xml_header(){
+    my $self = shift(@_);
+    my ($handle, $OID) = @_;
+
+    print $handle '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . "\n";
+#    print $handle '<!DOCTYPE Archive SYSTEM "http://greenstone.org/dtd/Archive/1.0/Archive.dtd">' . "\n";
+    print $handle '<dublin_core>' . "\n";
+}
+
+sub output_dc_xml_footer() {
+    my $self = shift(@_);
+    my ($handle) = @_;
+    print $handle '</dublin_core>' . "\n";
+}
 1;
-
-
-
