source: trunk/gsdl/perllib/docsave.pm@ 9921

Last change on this file since 9921 was 9921, checked in by mdewsnip, 19 years ago

More code without a hope of working on Windows.

  • Property svn:keywords set to Author Date Id Revision
File size: 20.2 KB
Line 
1###########################################################################
2#
3# docsave.pm
4# A component of the Greenstone digital library software
5# from the New Zealand Digital Library Project at the
6# University of Waikato, New Zealand.
7#
8# Copyright (C) 1999 New Zealand Digital Library Project
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24###########################################################################
25
26# This document processor saves a document in the
27# archives directory of a collection (as xml)
28
29use strict;
30no strict 'refs';
31
32package docsave;
33
34eval {require bytes};
35
36use arcinfo;
37use expinfo;
38use docproc;
39use util;
40
41
42sub BEGIN {
43 @docsave::ISA = ('docproc');
44}
45
46sub new {
47 my ($class, $collection, $info, $verbosity,
48 $gzip, $groupsize, $outhandle, $service, $saveas) = @_;
49 my $self = new docproc ();
50
51 $groupsize=1 unless defined $groupsize;
52 $service="import" unless defined $service;
53
54 $self->{'collection'} = $collection;
55 if ($service eq "import"){
56 $self->{'archive_info'} = $info;
57 } elsif ($service eq "export"){
58 $self->{'export_info'} = $info;
59 } else {
60 return;
61 }
62
63 $self->{'verbosity'} = $verbosity;
64 $self->{'gzip'} = $gzip;
65 $self->{'keepimportstructure'} = 0;
66 $self->{'groupsize'} = $groupsize;
67 $self->{'gs_count'} = 0;
68
69 $self->{'outhandle'} = 'STDERR';
70 $self->{'outhandle'} = $outhandle if defined $outhandle;
71 $self->{'service'} = $service;
72 $self->{'saveas'} = $saveas;
73
74 # set a default for the archive directory
75 if ($service eq "import"){
76 $self->{'archive_dir'} = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "archives");
77 } elsif ($service eq "export") {
78 # set a default for the export directory
79 $self->{'export_dir'} = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "export");
80 } else {
81 return;
82 }
83 $self->{'sortmeta'} = undef;
84
85 return bless $self, $class;
86}
87
88sub setarchivedir {
89 my $self = shift (@_);
90 my ($archive_dir) = @_;
91
92 &util::mk_all_dir ($archive_dir) unless -e $archive_dir;
93 $self->{'archive_dir'} = $archive_dir;
94}
95
96sub setexportdir {
97 my $self = shift (@_);
98 my ($export_dir) = @_;
99
100 &util::mk_all_dir ($export_dir) unless -e $export_dir;
101 $self->{'export_dir'} = $export_dir;
102}
103
104sub set_sortmeta {
105 my $self = shift (@_);
106 my ($sortmeta, $removeprefix, $removesuffix) = @_;
107
108 $self->{'sortmeta'} = $sortmeta;
109 if (defined ($removeprefix) && $removeprefix ) {
110 $removeprefix =~ s/^\^//; # don't need a leading ^
111 $self->{'removeprefix'} = $removeprefix;
112 }
113 if (defined ($removesuffix) && $removesuffix) {
114 $removesuffix =~ s/\$$//; # don't need a trailing $
115 $self->{'removesuffix'} = $removesuffix;
116 }
117}
118
119sub process {
120 my $self = shift (@_);
121 my ($doc_obj) = @_;
122
123 my $outhandle = $self->{'outhandle'};
124 my $service = $self->{'service'} || "import";
125
126 # Define the SaveAs Type
127 my $save_as = $self->{'saveas'} || "GA";
128 my $collection = $self->{'collection'};
129
130 if ($self->{'groupsize'} > 1) {
131 $self->group_process ($doc_obj);
132 return;
133 }
134
135 my $OID = $doc_obj->get_OID();
136 $OID = "NULL" unless defined $OID;
137
138 # get document's directory
139 my $doc_dir = $self->get_doc_dir ($OID, $doc_obj->get_source_filename());
140
141 # groupsize is 1 (i.e. one document per XML file) so sortmeta
142 # may be used
143
144 if ($service eq "import") {
145 my $archive_info = $self->{'archive_info'};
146 } elsif ($service eq "export") {
147 my $export_info = $self->{'export_info'};
148 } else {
149 return;
150 }
151
152 # copy all the associated files, add this information as metadata
153 # to the document
154 if ($service eq "export" && $save_as eq "DSpace") {
155 # create handle file based on doc_dir
156
157 my $doc_handle_file
158 = &util::filename_cat ($self->{'export_dir'},$doc_dir, "handle");
159
160 if (!open(OUTDOC_EXPORT_HANDLE,">$doc_handle_file")){
161 print $outhandle "docsave::process could not write collection handle to file $doc_handle_file\n";
162 return;
163 }
164
165 my ($handle) = ($doc_dir =~ m/^(.*)\.dir$/);
166 print OUTDOC_EXPORT_HANDLE "123456789/$handle\n";
167
168 close(OUTDOC_EXPORT_HANDLE);
169
170 # open contents file
171 my $doc_contents_file
172 = &util::filename_cat ($self->{'export_dir'},$doc_dir, "contents");
173
174 if (!open(OUTDOC_EXPORT_CONTENTS,">$doc_contents_file")){
175 print $outhandle "docsave::process could not write collection contents to file $doc_contents_file\n";
176 return;
177 }
178 $self->process_assoc_files ($doc_obj, $doc_dir, 'docsave::OUTDOC_EXPORT_CONTENTS');
179 } else {
180 $self->process_assoc_files ($doc_obj, $doc_dir, '');
181 }
182
183 my $doc_file;
184 my $doc_mets_file;
185 my $doc_txt_file;
186 my $short_doc_file;
187
188 # Save collection as either Greenstone Archive or METS format
189 if ($service eq "import") {
190 my $doc_file
191 = &util::filename_cat ($self->{'archive_dir'}, $doc_dir, "doc.xml");
192
193 # define doctxt.xml file
194 my $doc_txt_file
195 = &util::filename_cat ($self->{'archive_dir'}, $doc_dir,"doctxt.xml");
196
197 my $import_working_dir
198 =&util::filename_cat ($self->{'archive_dir'}, $doc_dir);
199
200 # define docmets.xml file
201 my $doc_mets_file
202 = &util::filename_cat ($self->{'archive_dir'},$doc_dir, "docmets.xml");
203
204 if ($save_as eq "GA") {
205 $short_doc_file = util::filename_cat ($doc_dir, "doc.xml");
206 } elsif ($save_as eq "METS") {
207 #my $short_txt_doc_file=&util::filename_cat ($doc_dir, "doctxt.xml");
208 $short_doc_file = &util::filename_cat ($doc_dir, "docmets.xml");
209 } else {
210 return;
211 }
212
213 if ($save_as eq "GA") {
214 if (!open (OUTDOC, ">$doc_file")) {
215 print $outhandle "docsave::process could not write to file $doc_file\n";
216 return;
217 }
218 # save this document
219 $self->output_xml_header('docsave::OUTDOC');
220 $doc_obj->output_section('docsave::OUTDOC',
221 $doc_obj->get_top_section());
222 $self->output_xml_footer('docsave::OUTDOC');
223
224 close OUTDOC;
225 } elsif ($save_as eq "METS") {
226 # save the document without metadata:doctxt.xml
227
228 if (!open(OUTDOC_TXT, ">$doc_txt_file")){
229 print $outhandle "docsave::process could not write to file $doc_txt_file\n";
230 return;
231 }
232
233 $self->output_txt_xml_header('docsave::OUTDOC_TXT');
234 $doc_obj->output_txt_section('docsave::OUTDOC_TXT', $doc_obj->get_top_section());
235 #$self->output_txt_xml_footer('docsave::OUTDOC_TXT');
236
237 # Convert doctxt.xml file to docmets.xml
238 if (!open(OUTDOC_METS,">$doc_mets_file")){
239 print $outhandle "docsave::process could not write to file $doc_mets_file\n";
240 return;
241 }
242
243 $self->output_mets_xml_header('docsave::OUTDOC_METS', $OID);
244 $doc_obj->output_mets_section('docsave::OUTDOC_METS',
245 $doc_obj->get_top_section());
246 $self->output_mets_xml_footer('docsave::OUTDOC_METS');
247
248 close OUTDOC_TXT;
249 close OUTDOC_METS;
250 } else { # save_as isn't GA or METS
251 print $outhandle "docsave::process unrecognised saveas type, $save_as\n";
252 return;
253 }
254 }
255
256 ## Export the collection to METs format or DSpace Archive Format into the export directory
257 if ($service eq "export") {
258 my $doc_dc_file;
259 my $doc_contents_file;
260
261 my $export_working_dir
262 =&util::filename_cat ($self->{'export_dir'}, $doc_dir);
263
264 if ($save_as eq "METS") {
265 $doc_mets_file
266 = &util::filename_cat ($self->{'export_dir'},$doc_dir, "docmets.xml");
267
268 $doc_txt_file
269 = &util::filename_cat ($self->{'export_dir'},$doc_dir, "doctxt.xml");
270
271 if (!open(OUTDOC_EXPORT_TXT, ">$doc_txt_file")){
272 print $outhandle "docsave::process could not write TXT to file $doc_txt_file\n";
273 return;
274 }
275
276 $self->output_txt_xml_header('docsave::OUTDOC_EXPORT_TXT');
277 $doc_obj->output_txt_section('docsave::OUTDOC_EXPORT_TXT', $doc_obj->get_top_section());
278
279 if (!open(OUTDOC_EXPORT_METS,">$doc_mets_file")){
280 print $outhandle "docsave::process could not write METS format to file $doc_mets_file\n";
281 return;
282 }
283 $self->output_mets_xml_header('docsave::OUTDOC_EXPORT_METS', $OID);
284 $doc_obj->output_mets_section('docsave::OUTDOC_EXPORT_METS',$doc_obj->get_top_section(), $export_working_dir);
285 $self->output_mets_xml_footer('docsave::OUTDOC_EXPORT_METS');
286
287 close OUTDOC_EXPORT_TXT;
288 close OUTDOC_EXPORT_METS;
289 } elsif ($save_as eq "DSpace") {
290
291 # Generate dublin_core.xml file
292 $doc_dc_file
293 = &util::filename_cat ($self->{'export_dir'},$doc_dir, "dublin_core.xml");
294
295 if (!open(OUTDOC_EXPORT_DC,">$doc_dc_file")){
296 print $outhandle "docsave::process could not write dublin core to file $doc_dc_file\n";
297 return;
298 }
299
300 $self->output_dc_xml_header('docsave::OUTDOC_EXPORT_DC', $OID);
301 $doc_obj->output_dc_section('docsave::OUTDOC_EXPORT_DC',$doc_obj->get_top_section(), $export_working_dir);
302 $self->output_dc_xml_footer('docsave::OUTDOC_EXPORT_DC');
303
304 close OUTDOC_EXPORT_DC;
305 close OUTDOC_EXPORT_CONTENTS;
306 } else { # save_as isn't METS or DSpace
307 print $outhandle "docsave::process unrecognised saveas type, $save_as\n";
308 return;
309 }
310
311 if ($save_as eq "METS") {
312 $short_doc_file = util::filename_cat ($doc_dir, "docmets.xml");
313 } elsif ($save_as eq "DSpace") {
314 #my $short_txt_doc_file=&util::filename_cat ($doc_dir, "doctxt.xml");
315 $short_doc_file=&util::filename_cat ($doc_dir, "dublin_core.xml");
316 } else {
317 return;
318 }
319
320 }
321 #save for later (for close_file_output())
322 $self->{'short_doc_file'} = $short_doc_file;
323
324 if ($self->{'gzip'}) {
325 my $doc_file = $self->{'gs_filename'};
326 `gzip $doc_file`;
327 $doc_file .= ".gz";
328 $short_doc_file .= ".gz";
329 if (!-e $doc_file) {
330 print $outhandle "error while gzipping: $doc_file doesn't exist\n";
331 return 0;
332 }
333 }
334
335 # do the sortmeta thing
336 my ($metadata);
337 if (defined ($self->{'sortmeta'})) {
338 $metadata = $doc_obj->get_metadata_element($doc_obj->get_top_section(),
339 $self->{'sortmeta'});
340 }
341 if (defined ($metadata) && $metadata) {
342 # do remove prefix/suffix
343 if (defined($self->{'removeprefix'})) {
344 $metadata =~ s/^$self->{'removeprefix'}//;
345 }
346 if (defined($self->{'removesuffix'})) {
347 $metadata =~ s/$self->{'removesuffix'}$//;
348 }
349 $metadata = &sorttools::format_metadata_for_sorting($self->{'sortmeta'}, $metadata, $doc_obj);
350 }
351 # store reference in the archive_info and export_info
352 if ($service eq "export") {
353 $self->{'export_info'}->add_info($OID, $short_doc_file, $metadata);
354 } elsif ($service eq "import") {
355 $self->{'archive_info'}->add_info($OID, $short_doc_file, $metadata);
356 }
357}
358
359
360sub group_process {
361 my $self = shift (@_);
362 my ($doc_obj) = @_;
363
364 my $outhandle = $self->{'outhandle'};
365
366 my $OID = $doc_obj->get_OID();
367 $OID = "NULL" unless defined $OID;
368
369 my $groupsize = $self->{'groupsize'};
370 my $gs_count = $self->{'gs_count'};
371 my $open_new_file = (($gs_count % $groupsize)==0);
372
373 # opening a new file, or document has assoicated files => directory needed
374 if (($open_new_file) || (scalar(@{$doc_obj->get_assoc_files()})>0)) {
375
376 # get document's directory
377 my $doc_dir = $self->get_doc_dir ($OID, $doc_obj->get_source_filename());
378
379 # copy all the associated files, add this information as metadata
380 # to the document
381 $self->process_assoc_files ($doc_obj, $doc_dir);
382
383
384 if ($open_new_file) {
385 # only if opening new file
386 my $doc_file
387 = &util::filename_cat ($self->{'archive_dir'}, $doc_dir, "doc.xml");
388 my $short_doc_file = &util::filename_cat ($doc_dir, "doc.xml");
389
390 if ($gs_count>0)
391 {
392 return if (!$self->close_file_output());
393 }
394
395 if (!open (OUTDOC, ">$doc_file")) {
396 print $outhandle "docsave::group_process could not write to file $doc_file\n";
397 return;
398 }
399 $self->{'gs_filename'} = $doc_file;
400 $self->{'gs_short_filename'} = $short_doc_file;
401 $self->{'gs_OID'} = $OID;
402
403 $self->output_xml_header('docsave::OUTDOC');
404 }
405 }
406
407 # save this document
408 $doc_obj->output_section('docsave::OUTDOC', $doc_obj->get_top_section());
409
410 $self->{'gs_count'}++;
411}
412
413sub get_doc_dir {
414 my $self = shift (@_);
415 my ($OID, $source_filename) = @_;
416 my $doc_info;
417 my $doc_dir = '';
418 my $service = $self-> {'service'};
419 my $working_dir;
420 my $working_info;
421
422 if ($service eq "import") {
423 $doc_info = $self->{'archive_info'}->get_info($OID);
424 $working_dir = $self->{'archive_dir'};
425 $working_info = $self->{'archive_info'};
426 } elsif ($service eq "export") {
427 $doc_info =$self->{'export_info'}->get_info($OID);
428 $working_dir = $self->{'export_dir'};
429 $working_info = $self->{'export_info'};
430 } else {
431 return;
432 }
433 if (defined $doc_info && scalar(@$doc_info) >= 1) {
434 # this OID already has an assigned directory, use the
435 # same one.
436 $doc_dir = $doc_info->[0];
437 $doc_dir =~ s/\/?((doc(mets)?)|(dublin_core))\.xml(\.gz)?$//;
438 } elsif ($self->{'keepimportstructure'}) {
439 $source_filename = &File::Basename::dirname($source_filename);
440 $source_filename =~ s/[\\\/]+/\//g;
441 $source_filename =~ s/\/$//;
442
443
444 #print STDERR "Source filename: $source_filename; \nImport dir:",$ENV{'GSDLIMPORTDIR'}, "\n";
445 $doc_dir = substr($source_filename, length($ENV{'GSDLIMPORTDIR'}) + 1);
446
447 }
448 if ($doc_dir eq "") {
449 # have to get a new document directory
450
451 if ($service eq "import") {
452 my $doc_dir_rest = $OID;
453 my $doc_dir_num = 0;
454
455 do {
456 $doc_dir .= "/" if $doc_dir_num > 0;
457 if ($doc_dir_rest =~ s/^(.{1,8})//) {
458 $doc_dir .= $1;
459 $doc_dir_num++;
460 }
461 } while ($doc_dir_rest ne "" &&
462 ((-d &util::filename_cat ($working_dir, "$doc_dir.dir")) ||
463 ($working_info->size() >= 1024 && $doc_dir_num < 2)));
464 }
465 else {
466 # Export formats such as DSpace need the directory structure to
467 # be flat. This is simple to arrange (set 'doc_dir' to bit the
468 # documents OID) but breaks Windows 3.1 file system compliance.
469 # Such a loss is not a bit thing in this situation as such
470 # systems don't run on Windows 3.1 anyway.
471
472 $doc_dir = $OID;
473 }
474
475
476 $doc_dir .= ".dir";
477 &util::mk_all_dir (&util::filename_cat ($working_dir, $doc_dir));
478 }
479 return $doc_dir;
480}
481
482sub process_assoc_files {
483 my $self = shift (@_);
484 my ($doc_obj, $doc_dir, $handle) = @_;
485
486 my $outhandle = $self->{'outhandle'};
487
488 my @assoc_files = ();
489 my $filename;;
490 my $working_dir;
491 my $service = $self->{'service'};
492 my $save_as = $self->{'saveas'};
493
494 if ($service eq "import") {
495 $working_dir = $self->{'archive_dir'};
496 } elsif ($service eq "export"){
497 $working_dir = $self->{'export_dir'};
498 } else {
499 return;
500 }
501
502 my $source_filename = $doc_obj->get_source_filename();
503
504 my $collect_dir = $ENV{'GSDLCOLLECTDIR'};
505
506 if (defined $collect_dir) {
507 my $dirsep_regexp = &util::get_os_dirsep();
508
509 if ($collect_dir !~ /$dirsep_regexp$/) {
510 $collect_dir .= &util::get_dirsep(); # ensure there is a slash at the end
511 }
512
513 # This test is never going to fail on Windows -- is this a problem?
514 if ($source_filename !~ /^$dirsep_regexp/) {
515 $source_filename = &util::filename_cat($collect_dir, $source_filename);
516 }
517 }
518
519
520 if ($save_as eq "DSpace") {
521 my ($tail_filename) = ($source_filename =~ m/\/([^\/\\]*)$/);
522
523 print $handle "$tail_filename\n";
524
525 $filename = &util::filename_cat($working_dir, $doc_dir, $tail_filename);
526 &util::hard_link ($source_filename, $filename);
527 }
528
529 foreach my $assoc_file_rec (@{$doc_obj->get_assoc_files()}) {
530 my ($dir, $afile) = $assoc_file_rec->[1] =~ /^(.*?)([^\/\\]+)$/;
531 $dir = "" unless defined $dir;
532
533
534 my $real_filename = $assoc_file_rec->[0];
535 if (-e $real_filename) {
536
537
538 if ($save_as eq "DSpace") {
539 if ($real_filename =~ m/$source_filename$/) {
540 next;
541 }
542 else {
543 my $bundle = "bundle:ORIGINAL";
544
545 if ($afile =~ m/^thumbnail\./) {
546 $bundle = "bundle:THUMBNAIL";
547 }
548
549 # Store the associated file to the "contents" file
550 print $handle "$assoc_file_rec->[1]\t$bundle\n";
551 }
552 }
553
554 $filename = &util::filename_cat($working_dir, $doc_dir, $afile);
555
556
557 &util::hard_link ($real_filename, $filename);
558
559 $doc_obj->add_utf8_metadata ($doc_obj->get_top_section(),
560 "gsdlassocfile",
561 "$afile:$assoc_file_rec->[2]:$dir");
562 $doc_obj->set_utf8_metadata_element ($doc_obj->get_top_section(),
563 "assocfilepath",
564 "$doc_dir");
565 } elsif ($self->{'verbosity'} > 2) {
566 print $outhandle "docsave::process couldn't copy the associated file " .
567 "$real_filename to $afile\n";
568 }
569 }
570}
571
572
573sub close_file_output
574{
575 my ($self) = @_;
576 my $service =$self->{'service'};
577
578 # make sure that the handle has been opened - it won't be if we failed
579 # to import any documents...
580 if (defined(fileno(docsave::OUTDOC))) {
581 $self->output_xml_footer('docsave::OUTDOC');
582 close OUTDOC;
583 }
584
585 my $OID = $self->{'gs_OID'};
586 my $short_doc_file;
587 # can we use 'short_doc_file' for GA too?
588 if (exists($self->{'saveas'}) && $self->{'saveas'} eq "METS") {
589 $short_doc_file=$self->{'short_doc_file'};
590 } elsif ($self->{'saveas'} eq "GA") { # "GA"
591 $short_doc_file=$self->{'gs_short_filename'};
592 } else { # "DSpace"
593 }
594
595 if ($self->{'gzip'}) {
596 my $doc_file = $self->{'gs_filename'};
597 `gzip $doc_file`;
598 $doc_file .= ".gz";
599 $short_doc_file .= ".gz";
600 if (!-e $doc_file) {
601 my $outhandle = $self->{'outhandle'};
602 print $outhandle "error while gzipping: $doc_file doesn't exist\n";
603 return 0;
604 }
605 }
606
607 # store reference in the archive_info and export_infor
608 if ($service eq "import") {
609 $self->{'archive_info'}->add_info($OID, $short_doc_file);
610 } elsif ($service eq "export") {
611 $self->{'export_info'}->add_info($OID, $short_doc_file);
612 } else {
613 return;
614 }
615 return 1;
616}
617
618sub output_xml_header {
619 my $self = shift (@_);
620 my ($handle) = @_;
621
622 print $handle '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . "\n";
623
624 print $handle '<!DOCTYPE Archive SYSTEM "http://greenstone.org/dtd/Archive/1.0/Archive.dtd">' . "\n";
625 print $handle "<Archive>\n";
626}
627
628sub output_xml_footer {
629 my $self = shift (@_);
630 my ($handle) = @_;
631
632 print $handle "</Archive>\n";
633}
634
635sub output_txt_xml_header{
636 my $self = shift (@_);
637 my ($handle) = @_;
638 print $handle '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . "\n";
639 print $handle '<!DOCTYPE Archive SYSTEM "http://greenstone.org/dtd/Archive/1.0/Archive.dtd">' . "\n";
640}
641
642sub output_txt_xml_footer{
643 my $self = shift(@_);
644 my ($handle) = @_;
645 print $handle "<the end of the file>\n";
646}
647
648sub output_mets_xml_header(){
649 my $self = shift(@_);
650 my ($handle, $OID) = @_;
651
652 print $handle '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . "\n";
653 print $handle '<mets:mets xmlns:mets="http://www.loc.gov/METS/"' . "\n";
654 print $handle ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' . "\n";
655 print $handle ' xmlns:gsdl3="http://www.greenstone.org/namespace/gsdlmetadata/1.0/"' . "\n";
656 print $handle ' xmlns:xlink="http://www.w3.org/TR/xlink"' ."\n";
657 print $handle ' xsi:schemaLocation="http://www.loc.gov/METS/' . "\n";
658 print $handle ' http://www.loc.gov/standards/mets/mets.xsd' . "\n";
659 print $handle ' http://www.greenstone.org/namespace/gsdlmetadata/1.0/' . "\n";
660 print $handle ' http://www.greenstone.org/namespace/gsdlmetadata/1.0/gsdl_metadata.xsd"' . "\n";
661 print $handle ' OBJID="'. $OID. ':2">' . "\n";
662}
663
664sub output_mets_xml_footer() {
665 my $self = shift(@_);
666 my ($handle) = @_;
667 print $handle '</mets:mets>' . "\n";
668}
669
670sub output_dc_xml_header(){
671 my $self = shift(@_);
672 my ($handle, $OID) = @_;
673
674 print $handle '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . "\n";
675# print $handle '<!DOCTYPE Archive SYSTEM "http://greenstone.org/dtd/Archive/1.0/Archive.dtd">'."\n";
676 print $handle '<dublin_core>' . "\n";
677}
678
679sub output_dc_xml_footer() {
680 my $self = shift(@_);
681 my ($handle) = @_;
682 print $handle '</dublin_core>' . "\n";
683}
6841;
Note: See TracBrowser for help on using the repository browser.