Project

General

Profile

1
#!/usr/bin/perl
2
#
3
#  '$RCSfile$'
4
#  Copyright: 2000 Regents of the University of California 
5
#
6
#   '$Author: sgarg $'
7
#     '$Date: 2004-04-26 16:46:37 -0700 (Mon, 26 Apr 2004) $'
8
# '$Revision: 2138 $' 
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
#
24

    
25
#
26
# This is a CGI application for inserting metadata documents into
27
# the Metacat database.  It utilizes the Metacat.pm module for most work.
28
# In this script, we process the form fields passed in from a POST, insert a
29
# metadata document and an ACL document.
30

    
31
use Metacat;
32
use AppConfig qw(:expand :argcount);
33
use XML::LibXML;
34
use XML::LibXSLT;
35
use Template;
36
use Net::SMTP;
37
use CGI qw/:standard :html3/;
38
use strict;
39

    
40
# Global configuration paramters
41
#my $cfgdir = "@install-dir@";
42
#my $cfgdir = "/usr/local/devtools/tomcat/webapps/knb/style/skins";
43
my $cfgdir = "@install-dir@@style-skins-relpath@";
44
my $tmpdir = "@temp-dir@";
45
my $templatesdir = "@install-dir@@style-common-relpath@/templates";
46
my $now = time;
47
my $xslConvDir = "$cfgdir/lib/style/";
48

    
49
# Import all of the HTML form fields as variables
50
import_names('FORM');
51

    
52
# Set up the hash for returning data to the HTML templates
53
my $templateVars = { 'status' => 'success' };
54
my $error = 0;
55
my @errorMessages;
56

    
57
# create a new AppConfig object and load our config parameters
58
# note that this requires the form submission to have a "cfg" paramter
59
# to determine which config file to load
60
my $config = AppConfig->new({
61
    GLOBAL => { ARGCOUNT => ARGCOUNT_ONE, } });
62

    
63
$config->define("metacatUrl");
64
$config->define("username");
65
$config->define("password");
66
$config->define("ldapUrl");
67
$config->define("defaultScope");
68
$config->define("organization");
69
$config->define("orgabbrev");
70
$config->define("orgurl");
71
$config->define("accesspubid");
72
$config->define("accesssysid");
73
$config->define("datasetpubid");
74
$config->define("datasetsysid");
75
$config->define("hasKeyword", { DEFAULT => 'true'} );
76
$config->define("mailhost");
77
$config->define("sender");
78
$config->define("recipient");
79
$config->define("adminname");
80
if ($FORM::cfg eq 'nceas') {
81
    $config->define("nceas_db");
82
    $config->define("nceas_db_user");
83
    $config->define("nceas_db_password");
84
}
85
$config->define("responseTemplate", { DEFAULT => 'crap.tmpl'} );
86
$config->define("entryFormTemplate", { DEFAULT => 'crap.tmpl'} );
87
$config->define("guideTemplate", { DEFAULT => 'crap.tmpl'} );
88
$config->define("confirmDataTemplate", { DEFAULT => 'crap.tmpl'} );
89
$config->define("deleteDataTemplate", { DEFAULT => 'crap.tmpl'} );
90
$config->define("debug", { DEFAULT => '0'} );
91
$config->define("lat", { ARGCOUNT => ARGCOUNT_HASH} );
92
$config->define("lon", { ARGCOUNT => ARGCOUNT_HASH} );
93

    
94
if (! hasContent($FORM::cfg)) {
95
    $error = "Application misconfigured.  Please contact the administrator.";
96
    push(@errorMessages, $error);
97
} else {
98
    my $cfgfile = $cfgdir . "/" . $FORM::cfg . "/" . $FORM::cfg . ".cfg";
99
    $config->file($cfgfile);
100
}
101

    
102
my $metacatUrl = $config->metacatUrl();
103
my $username = $config->username();
104
my $password = $config->password();
105
my $ldapUrl = $config->ldapUrl();
106
my $defaultScope = $config->defaultScope();
107
my $organization = $config->organization();
108
my $orgabbrev = $config->orgabbrev();
109
my $orgurl = $config->orgurl();
110
my $orgfilter = $organization;
111
      $orgfilter =~ s/ /%20/g;
112
my $responseTemplate = $config->responseTemplate();
113
my $entryFormTemplate = $config->entryFormTemplate();
114
my $deleteDataTemplate = $config->deleteDataTemplate();
115
my $guideTemplate = $config->guideTemplate();
116
my $confirmDataTemplate = $config->confirmDataTemplate();
117
my $accesspubid = $config->accesspubid();
118
my $accesssysid = $config->accesssysid();
119
my $datasetpubid = $config->datasetpubid();
120
my $datasetsysid = $config->datasetsysid();
121
my $hasKeyword = $config->hasKeyword();
122
my $mailhost = $config->mailhost();
123
my $sender = $config->sender();
124
my $recipient = $config->recipient();
125
my $adminname = $config->adminname();
126
my $nceas_db;
127
my $nceas_db_user;
128
my $nceas_db_password;
129
if ($FORM::cfg eq 'nceas') {
130
    $nceas_db = $config->nceas_db();
131
    $nceas_db_user = $config->nceas_db_user();
132
    $nceas_db_password = $config->nceas_db_password();
133
}
134
my $debug = $config->debug();
135
my $lat = $config->get('lat');
136
my $lon = $config->get('lon');
137

    
138
# Convert the lat and lon configs into usable data structures
139
my @sitelist;
140
my %siteLatDMS;
141
my %siteLongDMS;
142
foreach my $newsite (keys %$lat) {
143
    my ($latd, $latm, $lats, $latdir) = split(':', $lat->{$newsite});
144
    my ($lond, $lonm, $lons, $londir) = split(':', $lon->{$newsite});
145
    push(@sitelist, $newsite);
146
    $siteLatDMS{$newsite} = [ $latd, $latm, $lats, $latdir ];
147
    $siteLongDMS{$newsite} = [ $lond, $lonm, $lons, $londir ];
148
}
149

    
150
# set some configuration options for the template object
151
my $ttConfig = {
152
             INCLUDE_PATH => $templatesdir, 
153
             INTERPOLATE  => 0,                    
154
             POST_CHOMP   => 1,                   
155
             };
156

    
157
# create an instance of the template processor
158
my $template = Template->new($ttConfig) || die $Template::ERROR, "\n";
159

    
160
print "Content-type: text/html\n\n";
161

    
162
# Set up the template information that is common to all forms
163
$$templateVars{'cfg'} = $FORM::cfg;
164
$$templateVars{'recipient'} = $recipient;
165
$$templateVars{'adminname'} = $adminname;
166
$$templateVars{'organization'} = $organization;
167
$$templateVars{'orgabbrev'} = $orgabbrev;
168
$$templateVars{'orgurl'} = $orgurl;
169
$$templateVars{'orgfilter'} = $orgfilter;
170

    
171
debug("Registry: Initialized");
172
# Process the form based on stage parameter. 
173
if ($FORM::stage =~ "guide") {
174
    # Send back the information on how to fill the form
175
    $$templateVars{'section'} = "Guide on How to Complete Registry Entries";
176
    $template->process( $guideTemplate, $templateVars);
177
    exit(0);
178

    
179
} elsif ($FORM::stage =~ "insert") {
180
    # The user has entered the data. Do data validation and send back data 
181
    # to confirm the data that has been entered. 
182
    toConfirmData();
183
    exit(0);
184

    
185
}elsif ($FORM::dataWrong =~ "No, go back to editing" && $FORM::stage =~ "confirmed") {
186
    # The user wants to correct the data that he has entered. 
187
    # Hence show the data again in entryData form. 
188
    confirmDataToReEntryData();
189
    exit(0);
190

    
191
}elsif ($FORM::stage =~ "modify") {
192
    # Modification of a file has been requested. 
193
    # Show the form will all the values filled in.
194
    my @sortedSites;
195
    foreach my $site (sort @sitelist) {
196
        push(@sortedSites, $site);
197
    }
198
    $$templateVars{'siteList'} = \@sortedSites;
199
    $$templateVars{'section'} = "Modification Form";
200
    $$templateVars{'docid'} = $FORM::docid;
201
    modifyData();
202
    exit(0);
203

    
204
}elsif ($FORM::stage =~ "delete_confirm") {
205

    
206
    # Result from deleteData form. 
207
    if($FORM::deleteData =~ "Delete data"){
208
    # delete Data
209
    deleteData(1);    
210
    exit(0);
211
    } else {
212
    # go back to search page. 
213
    exit(0);
214
    }
215

    
216
}elsif ($FORM::stage =~ "delete") {
217
    # Deletion of a file has been requested. 
218
    # Ask for username and password using deleteDataForm
219
    $$templateVars{'docid'} = $FORM::docid;
220
    $template->process( $deleteDataTemplate, $templateVars);
221
    exit(0);
222

    
223
}elsif ($FORM::stage !~ "confirmed") {
224
    # None of the stages have been reached and data is not being confirmed. 
225
    # Hence, send back entry form for entry of data.  
226
    debug("Registry: Sending form");
227
    my @sortedSites;
228
    foreach my $site (sort @sitelist) {
229
        push(@sortedSites, $site);
230
    }
231
    
232
    if ($FORM::cfg eq 'nceas') {
233
        my $projects = getProjectList();
234
        $$templateVars{'projects'} = $projects;
235
        $$templateVars{'wg'} = \@FORM::wg;
236
    }
237

    
238
    $$templateVars{'hasKeyword'} = $hasKeyword;
239

    
240
    $$templateVars{'siteList'} = \@sortedSites;
241
    $$templateVars{'section'} = "Entry Form";
242
    $$templateVars{'docid'} = "";
243
    debug("Registry: Sending form: ready to process template");
244
    $template->process( $entryFormTemplate, $templateVars);
245
    debug("Registry: Sending form: template processed");
246
    exit(0);
247
}
248

    
249
# Confirm stage has been reached. Enter the data into metacat. 
250

    
251
# Initialize some global vars
252
my $latDeg1 = "";
253
my $latMin1 = "";
254
my $latSec1 = "";
255
my $hemisphLat1 = "";
256
my $longDeg1 = "";
257
my $longMin1 = "";
258
my $longSec1 = "";
259
my $hemisphLong1 = "";
260
my $latDeg2 = "";
261
my $latMin2 = "";
262
my $latSec2 = "";
263
my $hemisphLat2 = "";
264
my $longDeg2 = "";
265
my $longMin2 = "";
266
my $longSec2 = "";
267
my $hemisphLong2 = "";
268

    
269
# validate the input form parameters
270
my $invalidParams;
271

    
272
if (! $error) {
273
    $invalidParams = validateParameters(1);
274
    if (scalar(@$invalidParams)) {
275
        $$templateVars{'status'} = 'failure';
276
        $$templateVars{'invalidParams'} = $invalidParams;
277
        $error = 1;
278
    }
279
}
280

    
281

    
282
my $metacat;
283
my $docid;
284
if (! $error) {
285
    # Parameters have been validated and Create the XML document
286

    
287
    my $xmldoc = createXMLDocument();
288

    
289
    # Write out the XML file for debugging purposes
290
    #my $testFile = $tmpdir . "/test.xml";
291

    
292
    # Create a  metacat object
293
    $metacat = Metacat->new();
294
    if ($metacat) {
295
        $metacat->set_options( metacatUrl => $metacatUrl );
296
    } else {
297
        #die "failed during metacat creation\n";
298
        push(@errorMessages, "Failed during metacat creation.");
299
    }
300

    
301
    # Login to metacat
302
    my $userDN = $FORM::username;
303
    my $userOrg = $FORM::organization;
304
    my $userPass = $FORM::password;
305
    my $dname = "uid=$userDN,o=$userOrg,dc=ecoinformatics,dc=org";
306
    
307
    my $xmldocWithDocID = $xmldoc;
308
    
309
    my $errorMessage = "";
310
    my $response = $metacat->login($dname, $userPass);
311
    if (! $response) {
312
        push(@errorMessages, $metacat->getMessage());
313
        push(@errorMessages, "Failed during login.\n");
314
    }
315

    
316
    debug( "Registry: A");
317
    if ($FORM::docid eq "") {
318
        debug( "Registry: B1");
319
        # document is being inserted 
320
        my $notunique = "NOT_UNIQUE";
321
        while ($notunique eq "NOT_UNIQUE") {
322
            $docid = newAccessionNumber($defaultScope);
323
            
324
	    $xmldocWithDocID = $xmldoc;
325
            $xmldocWithDocID =~ s/docid/$docid/;
326

    
327
	    # Code for testing the xml file being inserted####
328
            #my $testFile = "/tmp/test.xml";
329
            #open (TFILE,">$testFile") || die ("Cant open xml file...\n");
330
            #print TFILE $xmldoc;
331
            #close(TFILE);
332
	    ####
333
    
334
            $notunique = insertMetadata($xmldocWithDocID, $docid);
335
            #  if (!$notunique) {
336
            # Write out the XML file for debugging purposes
337
            #my $testFile = $tmpdir . "/test-new.xml";
338
            #open (TFILE,">$testFile") || die ("Cant open xml file...\n");
339
            #print TFILE $newdoc;
340
            #close(TFILE);
341
            #   }
342

    
343
            # The id wasn't unique, so update our lastid file
344
            if ($notunique eq "NOT_UNIQUE") {
345
                debug( "Registry: Updating lastid (B1.1)");
346
                updateLastId($defaultScope);
347
            }
348
        }
349
        debug("Registry: B2");
350
        if ($notunique ne "SUCCESS") {
351
            debug("Registry: NO SUCCESS");
352
            debug("Message is: $notunique");
353
            push(@errorMessages, $notunique);
354
        }
355

    
356
        debug("Registry: B3");
357
    } else {
358
        # document is being modified
359
        $docid = $FORM::docid;
360
    
361
        my $x;
362
        my $y;
363
        my $z;
364

    
365
        ($x, $y, $z) = split(/\./, $docid); 
366
        $z++;
367
        $docid = "$x.$y.$z";
368
    
369
        $xmldoc =~ s/docid/$docid/;
370
        
371
        my $response = $metacat->update($docid, $xmldoc);
372

    
373
        if (! $response) {
374
            push(@errorMessages, $metacat->getMessage());
375
            push(@errorMessages, "Failed while updating.\n");  
376
        }
377

    
378
        if (scalar(@errorMessages)) {
379
            debug("Registry: ErrorMessages defined in modify.");
380

    
381
	    $$templateVars{'docid'} = $FORM::docid;
382
	    copyFormToTemplateVars();
383
            $$templateVars{'status'} = 'failure';
384
            $$templateVars{'errorMessages'} = \@errorMessages;
385
            $error = 1;
386
        } else {
387
	    $$templateVars{'docid'} = $docid;
388
	    $$templateVars{'cfg'} = $FORM::cfg;
389
	}
390

    
391
        #if (! $error) {
392
            #sendNotification($docid, $mailhost, $sender, $recipient);
393
        #}
394
    
395
        # Create our HTML response and send it back
396
        $$templateVars{'function'} = "modified";
397
        $$templateVars{'section'} = "Modification Status";
398
        $template->process( $responseTemplate, $templateVars);
399

    
400
        exit(0);
401
    }
402
}
403

    
404
debug("Registry: C");
405

    
406
if (scalar(@errorMessages)) {
407
    debug("Registry: ErrorMessages defined.");
408
    $$templateVars{'docid'} = $FORM::docid;
409
    copyFormToTemplateVars();
410
    $$templateVars{'status'} = 'failure';
411
    $$templateVars{'errorMessages'} = \@errorMessages;
412
    $error = 1;
413
} else {
414
    $$templateVars{'docid'} = $docid;
415
    $$templateVars{'cfg'} = $FORM::cfg;
416
}
417

    
418
#if (! $error) {
419
#sendNotification($docid, $mailhost, $sender, $recipient);
420
#}
421

    
422
# Create our HTML response and send it back
423
$$templateVars{'function'} = "submitted";
424
$$templateVars{'section'} = "Submission Status";
425

    
426
$template->process( $responseTemplate, $templateVars);
427

    
428
exit(0);
429

    
430

    
431
################################################################################
432
#
433
# Subroutine for updating a metacat id for a given scope to the highest value
434
#
435
################################################################################
436
sub updateLastId {
437
  my $scope = shift;
438

    
439
  my $errormsg = 0;
440
  my $docid = $metacat->getLastId($scope);
441

    
442
  if ($docid =~ /null/) {
443
      # No docids with this scope present, so do nothing
444
  } elsif ($docid) {
445
      # Update the lastid file for this scope
446
      (my $foundScope, my $id, my $rev) = split(/\./, $docid);
447
      debug("Docid is: $docid\n");
448
      debug("Lastid is: $id");
449
      my $scopeFile = $cfgdir . "/" . $FORM::cfg . "/" . $scope . ".lastid";
450
      open(LASTID, ">$scopeFile") or 
451
          die "Failed to open lastid file for writing!";
452
      print LASTID $id, "\n";
453
      close(LASTID);
454
  } else {
455
    $errormsg = $metacat->getMessage();
456
    debug("Error in getLastId: $errormsg");
457
  }
458
}
459

    
460
################################################################################
461
#
462
# Subroutine for inserting a document to metacat
463
#
464
################################################################################
465
sub insertMetadata {
466
  my $xmldoc = shift;
467
  my $docid = shift;
468

    
469
  my $notunique = "SUCCESS";
470
  debug("Registry: Starting insert (D1)");
471
  my $response = $metacat->insert($docid, $xmldoc);
472
  if (! $response) {
473
    debug("Registry: Response gotten (D2)");
474
    my $errormsg = $metacat->getMessage();
475
    debug("Registry: Error is (D3): ".$errormsg);
476
    if ($errormsg =~ /is already in use/) {
477
      $notunique = "NOT_UNIQUE";
478
      #print "Accession number already used: $docid\n";
479
    } elsif ($errormsg =~ /<login>/) {
480
      $notunique = "SUCCESS";
481
    } else {
482
      #print "<p>Dumping error on failure...</p>\n";
483
      #print "<p>", $errormsg, "</p>\n";
484
      #die "Failed during insert\n";
485
      #print "<p>Failed during insert</p>\n";
486
      $notunique = $errormsg;
487
    }
488
  }
489
  debug("Registry: Ending insert (D4)");
490

    
491
  return $notunique;
492
}
493

    
494
################################################################################
495
#
496
# Subroutine for generating a new accession number
497
#  Note: this is not threadsafe, assumes only one running process at a time
498
#  Also: need to check metacat for max id # used in this scope already
499
################################################################################
500
sub newAccessionNumber {
501
  my $scope = shift;
502
    
503
  my $docrev = 1;
504
  my $lastid = 1;
505

    
506
  my $scopeFile = $cfgdir . "/" . $FORM::cfg . "/" . $scope . ".lastid";
507
  if (-e $scopeFile) {
508
    open(LASTID, "<$scopeFile") or die "Failed to generate accession number!";
509
    $lastid = <LASTID>;
510
    chomp($lastid);
511
    $lastid++;
512
    close(LASTID);
513
  }
514
  open(LASTID, ">$scopeFile") or die "Failed to open lastid file for writing!";
515
  print LASTID $lastid, "\n";
516
  close(LASTID);
517

    
518
  my $docroot = "$scope.$lastid.";
519
  my $docid = $docroot . $docrev;
520
  return $docid;
521
}
522

    
523
################################################################################
524
# 
525
# Validate the parameters to make sure that required params are provided
526
#
527
################################################################################
528
sub validateParameters {
529
    my $chkUser = shift;
530
    my @invalidParams;
531

    
532
    push(@invalidParams, "Provider's first name is missing.")
533
        unless hasContent($FORM::providerGivenName);
534
    push(@invalidParams, "Provider's last name is missing.")
535
        unless hasContent($FORM::providerSurName);
536
    push(@invalidParams, "Name of site is missing.")
537
        unless (hasContent($FORM::site) || $FORM::site =~ /elect/ ||
538
                $FORM::cfg eq "nceas");
539
    push(@invalidParams, "Data set title is missing.")
540
        unless hasContent($FORM::title);
541
    push(@invalidParams, "Originator's first name is missing.")
542
        unless hasContent($FORM::origNamefirst0);
543
    push(@invalidParams, "Originator's last name is missing.")
544
        unless hasContent($FORM::origNamelast0);
545
    push(@invalidParams, "Abstract is missing.")
546
        unless hasContent($FORM::abstract);
547
    push(@invalidParams, "Beginning year of data set is missing.")
548
        unless hasContent($FORM::beginningYear);
549
    push(@invalidParams, "Geographic description is missing.")
550
        unless (hasContent($FORM::geogdesc));
551

    
552
    # If the "use site" coord. box is checked and if the site is in 
553
    # the longitude hash ...  && ($siteLatDMS{$FORM::site})
554
   
555
    if (($FORM::useSiteCoord) && ($siteLatDMS{$FORM::site}) ) {
556
        
557
        $latDeg1 = $siteLatDMS{$FORM::site}[0];
558
        $latMin1 = $siteLatDMS{$FORM::site}[1];
559
        $latSec1 = $siteLatDMS{$FORM::site}[2];
560
        $hemisphLat1 = $siteLatDMS{$FORM::site}[3];
561
        $longDeg1 = $siteLongDMS{$FORM::site}[0];
562
        $longMin1 = $siteLongDMS{$FORM::site}[1];
563
        $longSec1 = $siteLongDMS{$FORM::site}[2];
564
        $hemisphLong1 = $siteLongDMS{$FORM::site}[3];
565
     
566
    }  else {
567
    
568
        $latDeg1 = $FORM::latDeg1;
569
        $latMin1 = $FORM::latMin1;
570
        $latSec1 = $FORM::latSec1;
571
        $hemisphLat1 = $FORM::hemisphLat1;
572
        $longDeg1 = $FORM::longDeg1;
573
        $longMin1 = $FORM::longMin1;
574
        $longSec1 = $FORM::longSec1;
575
        $hemisphLong1 = $FORM::hemisphLong1;
576
    }
577
    
578
    # Check if latDeg1 and longDeg1 has values if useSiteCoord is used. 
579
    # This check is required because some of the sites dont have lat 
580
    # and long mentioned in the config file. 
581

    
582
    if ($FORM::useSiteCoord) {
583
    push(@invalidParams, "The Data Registry doesn't have latitude and longitude information for the site that you chose. Please go back and enter the spatial information.")
584
        unless(hasContent($latDeg1) && hasContent($longDeg1));
585
    }else{
586
    push(@invalidParams, "Latitude degrees are missing.")
587
        unless hasContent($latDeg1);
588
    push(@invalidParams, "Longitude degrees are missing.")
589
        unless hasContent($longDeg1);
590
    }
591

    
592
    push(@invalidParams, 
593
        "You must provide a method description if you provide a method title.")
594
        if (hasContent($FORM::methodTitle) && ( !(scalar(@FORM::methodPara) > 0) 
595
                || (! hasContent($FORM::methodPara[0]))));
596
    push(@invalidParams, 
597
        "You must provide a method description if you provide a study extent description.")
598
        if (hasContent($FORM::studyExtentDescription) && (!(scalar(@FORM::methodPara) > 0) 
599
                || (! hasContent($FORM::methodPara[0]))));
600
    push(@invalidParams, 
601
        "You must provide both a study extent description and a sampling description, or neither.")
602
        if (
603
                (hasContent($FORM::studyExtentDescription) && !hasContent($FORM::samplingDescription)) ||
604
                (!hasContent($FORM::studyExtentDescription) && hasContent($FORM::samplingDescription))
605
           );
606

    
607
    push(@invalidParams, "Contact first name is missing.")
608
    unless (hasContent($FORM::origNamefirstContact) || 
609
        $FORM::useOrigAddress);
610
    push(@invalidParams, "Contact last name is missing.")
611
    unless (hasContent($FORM::origNamelastContact) || 
612
        $FORM::useOrigAddress);
613
    push(@invalidParams, "Data medium is missing.")
614
    unless (hasContent($FORM::dataMedium) || $FORM::dataMedium =~ /elect/);
615
    
616
    return \@invalidParams;
617
}
618

    
619
################################################################################
620
# 
621
# utility function to determine if a paramter is defined and not an empty string
622
#
623
################################################################################
624
sub hasContent {
625
    my $param = shift;
626

    
627
    my $paramHasContent;
628
    if (!defined($param) || $param eq '') { 
629
        $paramHasContent = 0;
630
    } else {
631
        $paramHasContent = 1;
632
    }
633
    return $paramHasContent;
634
}
635

    
636
################################################################################
637
#
638
# Subroutine for replacing characters not recognizable by XML and otherwise. 
639
#
640
################################################################################
641
sub normalize{
642
    my $val = shift;
643

    
644
    $val =~ s/&/&amp;/g;
645

    
646
    $val =~ s/</&lt;/g;
647
    $val =~ s/>/&gt;/g;
648
    $val =~ s/\"/&quot;/g;
649
    
650
    my $returnVal = "";
651
    
652
    foreach (split(//,$val)){
653
	my $var = unpack "C*", $_; 
654
	
655
	if($var<128 && $var>31){
656
	    $returnVal=$returnVal.$_;
657
	} elsif ($var<32){
658
	    if($var == 10){
659
		$returnVal=$returnVal.$_;
660
	    }
661
	    if($var == 13){
662
		$returnVal=$returnVal.$_;
663
	    }
664
	    if($var == 9){
665
		$returnVal=$returnVal.$_;
666
	    }
667
	} else { 
668
	    $returnVal=$returnVal."&#".$var.";";
669
	}
670
    }
671
    
672
    $returnVal =~ s/&/%26/g;    
673
    return $returnVal;
674
}
675

    
676

    
677
################################################################################
678
#
679
# Subroutine for replacing characters that might create problem in HTML. 
680
# Specifically written for " being used in any text field. This create a 
681
# problem in confirmData template, when you specify input name value pair 
682
# with value having a " in it.  
683
#
684
################################################################################
685
sub normalizeCD{
686
    my $val = shift;
687

    
688
    $val =~ s/\"/&quot;/g;
689
    
690
    return $val;
691
}
692

    
693

    
694
################################################################################
695
# 
696
# Create the XML document from the HTML form input
697
# returns the XML document as a string
698
#
699
################################################################################
700
sub createXMLDocument {
701

    
702
    my $orig  = "";
703
    my $role  = "associatedParty";
704
    my $creat = "";
705
    my $metaP = "";
706
    my $apart = "";
707
    my $cont  = "";
708
    my $publ  = "";
709
    my $dso   = "";
710
    my $gmt = gmtime($now);
711

    
712

    
713
    my $doc =  "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
714

    
715
    $doc .= "<eml:eml\n 
716
                     \t packageId=\"docid\" system=\"knb\"\n 
717
                     \t xmlns:eml=\"eml://ecoinformatics.org/eml-2.0.0\"\n
718
                     \t xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n 
719
                     \t xmlns:ds=\"eml://ecoinformatics.org/dataset-2.0.0\"\n 
720
                     \t xmlns:stmml=\"http://www.xml-cml.org/schema/stmml\"\n 
721
                     \t xsi:schemaLocation=\"eml://ecoinformatics.org/eml-2.0.0 eml.xsd\">\n";
722

    
723
    $doc .= "<!-- Person who filled in the catalog entry form: ";
724
    $doc .= normalize($FORM::providerGivenName)." ".normalize($FORM::providerSurName)." -->\n";
725
    $doc .= "<!-- Form filled out at $gmt GMT -->\n";
726
    $doc .= "<dataset>\n";
727
    
728
    if (hasContent($FORM::identifier)) {
729
        $doc .= "<alternateIdentifier system=\"$FORM::site\">";
730
        $doc .= normalize($FORM::identifier) . "</alternateIdentifier>\n";
731
    }
732
    
733
    if (hasContent($FORM::title)) {
734
        $doc .= "<title>".normalize($FORM::title)."</title>\n";
735
    }
736

    
737
    if (hasContent($FORM::origNamelast0)) {
738
    $role = "creator";
739
        $orig .= "<individualName>\n";
740
        $orig .= "<givenName>".normalize($FORM::origNamefirst0)."</givenName>\n";
741
        $orig .= "<surName>".normalize($FORM::origNamelast0)."</surName>\n";
742
        $orig .= "</individualName>\n";
743
    }
744

    
745
    if (hasContent($FORM::origNameOrg)) {
746
        $orig .= "<organizationName>".normalize($FORM::origNameOrg)."</organizationName>\n";
747
    }
748

    
749
    if (hasContent($FORM::origDelivery) || hasContent($FORM::origCity) ||
750
        (hasContent($FORM::origState   ) &&
751
        ($FORM::origState !~ "Select state here.")) ||
752
        hasContent($FORM::origStateOther) ||
753
        hasContent($FORM::origZIP ) || hasContent($FORM::origCountry)) {
754
        $orig .= "<address>\n";
755

    
756
        if (hasContent($FORM::origDelivery)) {
757
            $orig .= "<deliveryPoint>".normalize($FORM::origDelivery)."</deliveryPoint>\n";
758
        }
759
        if (hasContent($FORM::origCity)) {
760
            $orig .= "<city>".normalize($FORM::origCity)."</city>\n";
761
        }
762

    
763
    if (hasContent($FORM::origState) && 
764
            ($FORM::origState !~ "Select state here.")) {
765
            $orig .= "<administrativeArea>".normalize($FORM::origState);
766
            $orig .= "</administrativeArea>\n";
767
        } elsif (hasContent($FORM::origStateOther)) {
768
            $orig .= "<administrativeArea>".normalize($FORM::origStateOther);
769
            $orig .= "</administrativeArea>\n";
770
        }
771
        if (hasContent($FORM::origZIP)) {
772
            $orig .= "<postalCode>".normalize($FORM::origZIP)."</postalCode>\n";
773
        }
774
        if (hasContent($FORM::origCountry)) {
775
            $orig .= "<country>".normalize($FORM::origCountry)."</country>\n";
776
        }
777
        $orig .= "</address>\n";
778
    }
779

    
780
    if (hasContent($FORM::origPhone)) {
781
        $orig .= "<phone>".normalize($FORM::origPhone)."</phone>\n";
782
    }
783
    if (hasContent($FORM::origFAX)) {
784
        $orig .= "<phone phonetype=\"Fax\">".normalize($FORM::origFAX)."</phone>\n";
785
    }
786
    if (hasContent($FORM::origEmail)) {
787
        $orig .= "<electronicMailAddress>".normalize($FORM::origEmail);
788
        $orig .= "</electronicMailAddress>\n";
789
    }
790
    $dso = "<$role>\n$orig</$role>\n";
791
    
792
    if ($FORM::cfg eq 'nceas') {
793
        for (my $i = 0; $i < scalar(@FORM::wg); $i++) {
794
            $creat .= "<creator>\n";
795
            $creat .= "<organizationName>".normalize($FORM::wg[$i])."</organizationName>\n";
796
            $creat .= "</creator>\n";
797
        }
798
    } else {
799
	    $creat .= "<creator>\n";
800
	    $creat .= "<organizationName>".normalize($FORM::site)."</organizationName>\n";
801
	    $creat .= "</creator>\n";
802
    }
803

    
804
    if ($FORM::cfg ne 'knb') {
805
        $creat .= "<creator>\n";
806
        $creat .= "<organizationName>".normalize($organization)."</organizationName>\n";
807
        $creat .= "</creator>\n";
808
    }
809

    
810
    $creat .= $dso;
811

    
812
    if ($FORM::useOrigAddress) {
813
        # Add a contact originator like the original with a different role
814
            $cont .= "<contact>\n";
815
        $cont .= $orig;
816
        $cont .= "</contact>\n";
817
    } else {
818
        $cont .= "<contact>\n";
819

    
820
        $cont .= "<individualName>\n";
821
        $cont .= "<givenName>".normalize($FORM::origNamefirstContact)."</givenName>\n";
822
        $cont .= "<surName>".normalize($FORM::origNamelastContact)."</surName>\n";
823
        $cont .= "</individualName>\n";
824
 
825
    if (hasContent($FORM::origNameOrgContact)) {
826
        $cont .= "<organizationName>".normalize($FORM::origNameOrgContact)."</organizationName>\n";
827
    }
828

    
829
        if (hasContent($FORM::origDeliveryContact) || 
830
            hasContent($FORM::origCityContact) ||
831
            (hasContent($FORM::origStateContact) &&
832
            ($FORM::origStateContact !~ "Select state here.")) ||
833
            hasContent($FORM::origStateOtherContact) ||
834
            hasContent($FORM::origZIPContact) || 
835
            hasContent($FORM::origCountryContact)) {
836
            $cont .= "<address>\n";
837
            if (hasContent($FORM::origDeliveryContact)) {
838
                $cont .= "<deliveryPoint>".normalize($FORM::origDeliveryContact);
839
                $cont .= "</deliveryPoint>\n";
840
            }
841
            if (hasContent($FORM::origCityContact)) {
842
                $cont .= "<city>".normalize($FORM::origCityContact)."</city>\n";
843
            }
844
            if (hasContent($FORM::origStateContact) && 
845
                ($FORM::origStateContact !~ "Select state here.")) {
846
                $cont .= "<administrativeArea>".normalize($FORM::origStateContact);
847
                $cont .= "</administrativeArea>\n";
848
            } elsif (hasContent($FORM::origStateOtherContact)) {
849
                $cont .= "<administrativeArea>".normalize($FORM::origStateOtherContact);
850
                $cont .= "</administrativeArea>\n";
851
            }
852
            if (hasContent($FORM::origZIPContact)) {
853
                $cont .= "<postalCode>".normalize($FORM::origZIPContact)."</postalCode>\n";
854
            }
855
            if (hasContent($FORM::origCountryContact)) {
856
                $cont .= "<country>".normalize($FORM::origCountryContact)."</country>\n";
857
            }
858
            $cont .= "</address>\n";
859
        }
860
        if (hasContent($FORM::origPhoneContact)) {
861
            $cont .= "<phone>".normalize($FORM::origPhoneContact)."</phone>\n";
862
        }
863
    if (hasContent($FORM::origFAXContact)) {
864
        $cont .= "<phone phonetype=\"Fax\">".normalize($FORM::origFAXContact)."</phone>\n";
865
    }
866
        if (hasContent($FORM::origEmailContact)) {
867
            $cont .= "<electronicMailAddress>".normalize($FORM::origEmailContact);
868
            $cont .= "</electronicMailAddress>\n";
869
        }
870
    $cont .= "</contact>\n";
871
    }
872

    
873
    $metaP .= "<metadataProvider>\n";
874
    $metaP .= "<individualName>\n";
875
    $metaP .= "<givenName>".normalize($FORM::providerGivenName)."</givenName>\n";
876
    $metaP .= "<surName>".normalize($FORM::providerSurName)."</surName>\n";
877
    $metaP .= "</individualName>\n";
878
    $metaP .= "</metadataProvider>\n";
879

    
880
    # Additional originators
881
    foreach my $tmp (param()) {
882
        if ($tmp =~ /origNamelast/){
883
            my $tmp1 = $tmp;
884
            $tmp1 =~ s/origNamelast//; # get the index of the parameter 0 to 10
885
            if ( $tmp1 eq '1' 
886
                 || $tmp1 eq '2'
887
                 || $tmp1 eq '3'
888
                 || $tmp1 eq '4'
889
                 || $tmp1 eq '5'
890
                 || $tmp1 eq '6'
891
                 || $tmp1 eq '7'
892
                 || $tmp1 eq '8'
893
                 || $tmp1 eq '9'
894
                 || $tmp1 eq '10'
895
                 ) {
896
     
897
                # do not generate XML for empty originator fields 
898
                if (hasContent(param("origNamefirst" . $tmp1))) {    
899

    
900
            my $add = "";
901
            $add .= "<individualName>\n";
902
            $add .= "<givenName>";
903
            $add .= normalize(param("origNamefirst" . $tmp1));
904
            $add .= "</givenName>\n";
905
            $add .= "<surName>";
906
            $add .= normalize(param("origNamelast" . $tmp1));
907
            $add .= "</surName>\n";
908
            $add .= "</individualName>\n";
909
            
910
            if(param("origRole" . $tmp1) eq "Originator"){
911
            $creat .= "<creator>\n";
912
            $creat .= $add;
913
            $creat .= "</creator>\n";
914
            }
915
            elsif(param("origRole" . $tmp1) eq "Metadata Provider"){
916
            $metaP .= "<metadataProvider>\n";
917
            $metaP .= $add;
918
            $metaP .= "</metadataProvider>\n";
919
            }
920
            elsif((param("origRole" . $tmp1) eq "Publisher")  && ($publ eq "")){
921
            $publ .= "<publisher>\n";
922
            $publ .= $add;
923
            $publ .= "</publisher>\n";
924
            }
925
            else{
926
            $apart .= "<associatedParty>\n";
927
            $apart .= $add;
928
            $apart .= "<role>";
929
            $apart .= param("origRole" . $tmp1);
930
            $apart .= "</role>\n";
931
            $apart .= "</associatedParty>\n";
932
            }
933
        }
934
            }
935
        }
936
    }
937

    
938
    $doc .= $creat;
939
    $doc .= $metaP;
940
    $doc .= $apart;
941

    
942
    $doc .= "<abstract>\n";
943
    $doc .= "<para>".normalize($FORM::abstract)."</para>\n";
944
    $doc .= "</abstract>\n";
945

    
946
    # Keyword information
947
    foreach my $tmp (param()) {
948
        if ($tmp =~ /keyword/) {
949
            my $tmp1 = $tmp;
950
            $tmp1 =~ s/keyword//; # get the index of the parameter 0, ..., 10
951
            if ( $tmp1 =~ /[0-9]/ ){
952
                # don't generate xml for empty keyword fields
953
                # don't generate taxonomic keyword fields, those go in taxonomic coverage
954
                if (hasContent(param($tmp))) {
955
                    $doc .= "<keywordSet>\n";
956
                    $doc .= "<keyword ";
957
                    if (hasContent(param("kwType" . $tmp1)) &&
958
                       (param("kwType" . $tmp1) !~ "none") ) {
959
                         $doc .= "keywordType=\"";
960
                         $doc .= param("kwType" . $tmp1);
961
                         $doc .= "\"";
962
                    }
963
                    $doc .= ">";
964
                    $doc .= normalize(param("keyword" . $tmp1));
965
                    $doc .= "</keyword>\n";
966
                    $doc .= "<keywordThesaurus>";
967
                    $doc .= normalize(param("kwTh" . $tmp1));
968
                    $doc .= "</keywordThesaurus>\n";
969
                    $doc .= "</keywordSet>\n";
970
                }
971
            }
972
        }
973
    }
974

    
975
    if (hasContent($FORM::addComments)) {
976
        $doc .= "<additionalInfo>\n";
977
        $doc .= "<para>".normalize($FORM::addComments)."</para>\n";
978
        $doc .= "</additionalInfo>\n";
979
    }
980

    
981
    if (hasContent($FORM::useConstraints) || 
982
        hasContent($FORM::useConstraintsOther)) {
983
        $doc .= "<intellectualRights>\n";
984
        if (hasContent($FORM::useConstraints)) {
985
            $doc .= "<para>".normalize($FORM::useConstraints)."</para>\n";
986
        }
987
        if (hasContent($FORM::useConstraintsOther)) {
988
            $doc .= "<para>".normalize($FORM::useConstraintsOther)."</para>\n";
989
        }
990
        $doc .= "</intellectualRights>\n";
991
    }
992

    
993
    
994
    if (hasContent($FORM::url)) {
995
    $doc .= "<distribution>\n";
996
        $doc .= "<online>\n";
997
    $doc .= "<url>".normalize($FORM::url)."</url>\n";
998
    $doc .= "</online>\n";
999
    $doc .= "</distribution>\n";
1000
    }
1001
    
1002
    $doc .= "<distribution>\n";
1003
    $doc .= "<offline>\n";
1004
    $doc .= "<mediumName>" . normalize($FORM::dataMedium)." ".normalize($FORM::dataMediumOther);
1005
    $doc .= "</mediumName>\n";
1006
    $doc .= "</offline>\n";
1007
    $doc .= "</distribution>\n";
1008
            
1009
    $doc .= "<coverage>\n";
1010
    $doc .= "<temporalCoverage>\n";
1011

    
1012

    
1013
    if (hasContent($FORM::endingYear)) {
1014
    $doc .= "<rangeOfDates>\n";
1015
    if (hasContent($FORM::beginningMonth)) {
1016
        my $month = ("JAN","FEB","MAR","APR","MAY","JUN",
1017
             "JUL","AUG","SEP","OCT","NOV","DEC")
1018
        [$FORM::beginningMonth - 1];
1019
        $doc .= "<beginDate>\n";
1020
        $doc .= "<calendarDate>";
1021
        $doc .= normalize($FORM::beginningYear)."-".normalize($FORM::beginningMonth)."-".normalize($FORM::beginningDay);
1022
        $doc .= "</calendarDate>\n";
1023
        $doc .= "</beginDate>\n";
1024
    } else {
1025
        $doc .= "<beginDate>\n";
1026
        $doc .= "<calendarDate>";
1027
        $doc .= normalize($FORM::beginningYear);
1028
        $doc .= "</calendarDate>\n";
1029
        $doc .= "</beginDate>\n";
1030
    }
1031

    
1032
    if (hasContent($FORM::endingMonth)) {
1033
        my $month = ("JAN","FEB","MAR","APR","MAY","JUN",
1034
             "JUL","AUG","SEP","OCT","NOV","DEC")
1035
        [$FORM::endingMonth - 1];
1036
        $doc .= "<endDate>\n";
1037
        $doc .= "<calendarDate>";
1038
        $doc .= normalize($FORM::endingYear)."-".normalize($FORM::endingMonth)."-".normalize($FORM::endingDay);
1039
        $doc .= "</calendarDate>\n";
1040
        $doc .= "</endDate>\n";
1041
    } else {
1042
        $doc .= "<endDate>\n";
1043
        $doc .= "<calendarDate>";
1044
        $doc .= normalize($FORM::endingYear);
1045
        $doc .= "</calendarDate>\n";
1046
        $doc .= "</endDate>\n";
1047
    }
1048
    $doc .= "</rangeOfDates>\n";
1049
    } else {
1050
    $doc .= "<singleDateTime>\n";
1051
    if (hasContent($FORM::beginningMonth)) {
1052
        my $month = ("JAN","FEB","MAR","APR","MAY","JUN",
1053
             "JUL","AUG","SEP","OCT","NOV","DEC")
1054
        [$FORM::beginningMonth - 1];
1055
        $doc .= "<calendarDate>";
1056
	$doc .= normalize($FORM::beginningYear)."-".normalize($FORM::beginningMonth)."-".normalize($FORM::beginningDay);
1057
        $doc .= "</calendarDate>\n";
1058
    } else {
1059
        $doc .= "<calendarDate>";
1060
	$doc .= normalize($FORM::beginningYear);
1061
        $doc .= "</calendarDate>\n";
1062
    }
1063
    $doc .= "</singleDateTime>\n";
1064
    }
1065

    
1066
    $doc .= "</temporalCoverage>\n";
1067
    
1068
    $doc .= "<geographicCoverage>\n";
1069
    $doc .= "<geographicDescription>".normalize($FORM::geogdesc)."</geographicDescription>\n";
1070
    $doc .= "<boundingCoordinates>\n";
1071

    
1072
    # if the second latitude is missing, then set the second lat/long pair 
1073
    # equal to the first this makes a point appear like a rectangle 
1074
    if ($FORM::latDeg2 == 0 && $FORM::latMin2 == 0 && $FORM::latSec2 == 0) {
1075
    
1076
        $latDeg2 = $latDeg1;
1077
        $latMin2 = $latMin1;
1078
        $latSec2 = $latSec1;
1079
        $hemisphLat2 = $hemisphLat1;
1080
        $longDeg2 = $longDeg1;
1081
        $longMin2 = $longMin1;
1082
        $longSec2 = $longSec1;
1083
        $hemisphLong2 = $hemisphLong1;
1084
    }
1085
    else
1086
    {
1087
        $latDeg2 = $FORM::latDeg2;
1088
        $latMin2 = $FORM::latMin2;
1089
        $latSec2 = $FORM::latSec2;
1090
        $hemisphLat2 = $FORM::hemisphLat2;
1091
        $longDeg2 = $FORM::longDeg2;
1092
        $longMin2 = $FORM::longMin2;
1093
        $longSec2 = $FORM::longSec2;
1094
        $hemisphLong2 = $FORM::hemisphLong2;
1095
    } 
1096
    
1097
   
1098
    my $hemisph;
1099
    $hemisph = ($hemisphLong1 eq "W") ? -1 : 1;
1100
    $doc .= "<westBoundingCoordinate>";
1101
    $doc .= $hemisph * ($longDeg1 + (60*$longMin1+$longSec1)/3600);
1102
    $doc .= "</westBoundingCoordinate>\n";
1103

    
1104
    $hemisph = ($hemisphLong2 eq "W") ? -1 : 1;
1105
    $doc .= "<eastBoundingCoordinate>";
1106
    $doc .= $hemisph * ($longDeg2 + (60*$longMin2+$longSec2)/3600);
1107
    $doc .= "</eastBoundingCoordinate>\n";
1108

    
1109
    $hemisph = ($hemisphLat1 eq "S") ? -1 : 1;
1110
    $doc .= "<northBoundingCoordinate>";
1111
    $doc .= $hemisph * ($latDeg1 + (60*$latMin1+$latSec1)/3600);
1112
    $doc .= "</northBoundingCoordinate>\n";
1113

    
1114
    $hemisph = ($hemisphLat2 eq "S") ? -1 : 1;
1115
    $doc .= "<southBoundingCoordinate>";
1116
    $doc .= $hemisph * ($latDeg2 + (60*$latMin2+$latSec2)/3600);
1117
    $doc .= "</southBoundingCoordinate>\n";
1118

    
1119
    $doc .= "</boundingCoordinates>\n";
1120
    $doc .= "</geographicCoverage>\n";
1121

    
1122
    # Write out the taxonomic coverage fields
1123
    my $foundFirstTaxon = 0;
1124
    foreach my $trn (param()) {
1125
        if ($trn =~ /taxonRankName/) {
1126
            my $taxIndex = $trn;
1127
            $taxIndex =~ s/taxonRankName//; # get the index of the parameter 0, ..., 10
1128
            my $trv = "taxonRankValue".$taxIndex;
1129
            if ( $taxIndex =~ /[0-9]/ ){
1130
                if (hasContent(param($trn)) && hasContent(param($trv))) {
1131
                    if (! $foundFirstTaxon) {
1132
                        $doc .= "<taxonomicCoverage>\n";
1133
                        $foundFirstTaxon = 1;
1134
                        if (hasContent($FORM::taxaAuth)) {
1135
                            $doc .= "<generalTaxonomicCoverage>".normalize($FORM::taxaAuth)."</generalTaxonomicCoverage>\n";
1136
                        }
1137
                    }
1138
                    $doc .= "<taxonomicClassification>\n";
1139
                    $doc .= "  <taxonRankName>".normalize(param($trn))."</taxonRankName>\n";
1140
                    $doc .= "  <taxonRankValue>".normalize(param($trv))."</taxonRankValue>\n";
1141
                    $doc .= "</taxonomicClassification>\n";
1142
                }
1143
            }
1144
        }
1145
    }
1146
    if ($foundFirstTaxon) {
1147
        $doc .= "</taxonomicCoverage>\n";
1148
    }
1149

    
1150
    $doc .= "</coverage>\n";
1151

    
1152
    $doc .= $cont;
1153
    $doc .= $publ;
1154
    
1155
    if ((hasContent($FORM::methodTitle)) || scalar(@FORM::methodsPara) > 0) {
1156
        my $methods = "<methods><methodStep><description><section>\n";
1157
        if (hasContent($FORM::methodTitle)) {
1158
            $methods .= "<title>".normalize($FORM::methodTitle)."</title>\n";
1159
        }
1160
        for (my $i = 0; $i < scalar(@FORM::methodPara); $i++) {
1161
            $methods .= "<para>".normalize($FORM::methodPara[$i])."</para>\n";
1162
        }
1163
        $methods .= "</section></description></methodStep>\n";
1164
        if (hasContent($FORM::studyExtentDescription)) {
1165
            $methods .= "<sampling><studyExtent><description>\n";
1166
            $methods .= "<para>".normalize($FORM::studyExtentDescription)."</para>\n";
1167
            $methods .= "</description></studyExtent>\n";
1168
            $methods .= "<samplingDescription>\n";
1169
            $methods .= "<para>".normalize($FORM::samplingDescription)."</para>\n";
1170
            $methods .= "</samplingDescription>\n";
1171
            $methods .= "</sampling>\n";
1172
        }
1173
        $methods .= "</methods>\n";
1174
        $doc .= $methods;
1175
    }
1176

    
1177
    $doc .= "<access authSystem=\"knb\" order=\"denyFirst\">\n";
1178
    $doc .= "<allow>\n";
1179
    $doc .= "<principal>$username</principal>\n";
1180
    $doc .= "<permission>all</permission>\n";
1181
    $doc .= "</allow>\n";
1182
    $doc .= "<allow>\n";
1183
    $doc .= "<principal>uid=$FORM::username,o=$FORM::organization,dc=ecoinformatics,dc=org</principal>\n";
1184
    $doc .= "<permission>all</permission>\n";
1185
    $doc .= "</allow>\n";
1186
    $doc .= "<allow>\n";
1187
    $doc .= "<principal>public</principal>\n";
1188
    $doc .= "<permission>read</permission>\n";
1189
    $doc .= "</allow>\n";
1190
    $doc .= "</access>\n";
1191
    
1192
    $doc .= "</dataset>\n</eml:eml>\n";
1193

    
1194
    return $doc;
1195
}
1196

    
1197

    
1198
################################################################################
1199
# 
1200
# send an email message notifying the moderator of a new submission 
1201
#
1202
################################################################################
1203
sub sendNotification {
1204
    my $identifier = shift;
1205
    my $mailhost = shift;
1206
    my $sender = shift;
1207
    my $recipient = shift;
1208

    
1209
    my $smtp = Net::SMTP->new($mailhost);
1210
    $smtp->mail($sender);
1211
    $smtp->to($recipient);
1212

    
1213
    my $message = <<"    ENDOFMESSAGE";
1214
    To: $recipient
1215
    From: $sender
1216
    Subject: New data submission
1217
    
1218
    Data was submitted to the data registry.  
1219
    The identifying information for the new data set is:
1220

    
1221
    Identifier: $identifier
1222
    Title: $FORM::title
1223
    Submitter: $FORM::providerGivenName $FORM::providerSurName
1224

    
1225
    Please review the submmission and grant public read access if appropriate.
1226
    Thanks
1227
    
1228
    ENDOFMESSAGE
1229
    $message =~ s/^[ \t\r\f]+//gm;
1230

    
1231
    $smtp->data($message);
1232
    $smtp->quit;
1233
}
1234

    
1235

    
1236
################################################################################
1237
# 
1238
# read the eml document and send back a form with values filled in. 
1239
#
1240
################################################################################
1241
sub modifyData {
1242
    
1243
    # create metacat instance
1244
    my $metacat;
1245
    my $docid = $FORM::docid;
1246
    my $httpMessage;
1247
    my $doc;
1248
    my $xmldoc;
1249
    my $findType;
1250
    my $parser = XML::LibXML->new();
1251
    my @fileArray;
1252
    my $pushDoc;
1253
    my $alreadyInArray;
1254
    my $node;
1255
    my $response; 
1256
    my $element;
1257
    my $tempfile;
1258

    
1259
    $metacat = Metacat->new();
1260
    if ($metacat) {
1261
        $metacat->set_options( metacatUrl => $metacatUrl );
1262
    } else {
1263
        #die "failed during metacat creation\n";
1264
        push(@errorMessages, "Failed during metacat creation.");
1265
    }
1266
    
1267
    $httpMessage = $metacat->read($docid);
1268
    $doc = $httpMessage->content();
1269
    $xmldoc = $parser->parse_string($doc);
1270

    
1271
    #$tempfile = $xslConvDir.$docid;
1272
    #push (@fileArray, $tempfile);
1273

    
1274
    if ($xmldoc eq "") {
1275
        $error ="Error in parsing the eml document";
1276
        push(@errorMessages, $error);
1277
    } else {
1278
        $findType = $xmldoc->findnodes('//dataset/identifier');
1279
        if ($findType->size() > 0) {
1280
            # This is a eml beta6 document
1281
            # Read the documents mentioned in triples also
1282
        
1283
            $findType = $xmldoc->findnodes('//dataset/triple');
1284
            if ($findType->size() > 0) {
1285
                foreach $node ($findType->get_nodelist) {
1286
                    $pushDoc = findValue($node, 'subject');
1287
            
1288
                    # If the file is already in @fileArray then do not add it 
1289
                    $alreadyInArray = 0;
1290
                    foreach $element (@fileArray) {
1291
                        $tempfile = $tmpdir."/".$pushDoc;
1292
                        if ($element eq $pushDoc) {
1293
                            $alreadyInArray = 1;
1294
                        }
1295
                    }
1296
            
1297
                    if (!$alreadyInArray) {
1298
                        $tempfile = $tmpdir."/".$pushDoc;
1299
                        $response = "";
1300
                        $response = $metacat->read($pushDoc);    
1301
                        if (! $response) {
1302
                            # could not read
1303
                            #push(@errorMessages, $response);
1304
                            push(@errorMessages, $metacat->getMessage());
1305
                            push(@errorMessages, "Failed during reading.\n");
1306
                        } else {
1307
                            my $xdoc = $response->content();
1308
                            #$tempfile = $xslConvDir.$pushDoc;
1309
                            open (TFILE,">$tempfile") || 
1310
                                die ("Cant open xml file... $tempfile\n");
1311
                            print TFILE $xdoc;
1312
                            close(TFILE);
1313
                            push (@fileArray, $tempfile);
1314
                        }
1315
                    }
1316
                }
1317
            }
1318

    
1319
            # Read the main document. 
1320

    
1321
            $tempfile = $tmpdir."/".$docid; #= $xslConvDir.$docid;
1322
            open (TFILE,">$tempfile") || die ("Cant open xml file...\n");
1323
            print TFILE $doc;
1324
            close(TFILE);
1325
        
1326
            # Transforming beta6 to eml 2
1327
            my $xslt;
1328
            my $triplesheet;
1329
            my $results;
1330
            my $stylesheet;
1331
            my $resultsheet;
1332
        
1333
            $xslt = XML::LibXSLT->new();
1334
            #$tempfile = $xslConvDir."triple_info.xsl";
1335
            $tempfile = $tmpdir."/"."triple_info.xsl";
1336
    
1337
            $triplesheet = $xslt->parse_stylesheet_file($tempfile);
1338

    
1339
            #$results = $triplesheet->transform($xmldoc, packageDir => "\'$tmpdir/\'", packageName => "\'$docid\'");
1340
            $results = $triplesheet->transform($xmldoc, packageDir => "\'$tmpdir/\'", packageName => "\'$docid\'");
1341

    
1342
            #$tempfile = $xslConvDir."emlb6toeml2.xsl";
1343
            $tempfile = $tmpdir."/"."emlb6toeml2.xsl";
1344
            $stylesheet = $xslt->parse_stylesheet_file($tempfile);
1345
            $resultsheet = $stylesheet->transform($results);
1346
        
1347
            #$tempfile = "/usr/local/apache2/htdocs/xml/test.xml";;
1348
            #open (TFILE,">$tempfile") || die ("Cant open xml file...\n");
1349
            #print TFILE $stylesheet->output_string($resultsheet);
1350
            #close(TFILE);
1351

    
1352
            getFormValuesFromEml2($resultsheet);
1353
            
1354
            # Delete the files written earlier. 
1355
            unlink @fileArray;
1356

    
1357
        } else {
1358
            getFormValuesFromEml2($xmldoc);
1359
        }
1360
    }   
1361
    
1362
    if (scalar(@errorMessages)) {
1363
        # if any errors, print them in the response template 
1364
        $$templateVars{'status'} = 'failure';
1365
        $$templateVars{'errorMessages'} = \@errorMessages;
1366
        $error = 1;
1367
        $$templateVars{'function'} = "modification";
1368
        $$templateVars{'section'} = "Modification Status";
1369
        $template->process( $responseTemplate, $templateVars); 
1370
    } else {
1371
        $$templateVars{'form'} = 're_entry';
1372
        $template->process( $entryFormTemplate, $templateVars);
1373
    }
1374
}
1375

    
1376
################################################################################
1377
# 
1378
# Parse an EML 2.0.0 file and extract the metadata into perl variables for 
1379
# processing and returning to the template processor
1380
#
1381
################################################################################
1382
sub getFormValuesFromEml2 {
1383
    
1384
    my $doc = shift;
1385
    my $results;
1386
    my $error;
1387
    my $node;
1388
    my $tempResult;
1389
    my $tempNode;
1390
    my $aoCount = 1;
1391
    my $foundDSO;
1392

    
1393
    # set variable values
1394
    $$templateVars{'hasKeyword'} = $hasKeyword;
1395
    
1396
    # find out the tag <alternateIdentifier>. 
1397
    $results = $doc->findnodes('//dataset/alternateIdentifier');
1398
    if ($results->size() > 1) {
1399
        errMoreThanOne("alternateIdentifier");
1400
    } else {
1401
        foreach $node ($results->get_nodelist) {
1402
            $$templateVars{'identifier'} = findValue($node, '../alternateIdentifier');
1403
        }
1404
    }
1405

    
1406
    # find out the tag <title>. 
1407
    $results = $doc->findnodes('//dataset/title');
1408
    if ($results->size() > 1) {
1409
        errMoreThanOne("title");
1410
    } elsif ($results->size() < 1) {
1411
        $error ="Following tag not found: title. Please use Morpho to edit this document";
1412
        push(@errorMessages, $error."\n");
1413
        #if ($DEBUG == 1){ print $error;}
1414
    } else {
1415
        foreach $node ($results->get_nodelist) {
1416
            $$templateVars{'title'} = findValue($node, '../title');
1417
        }
1418
    }
1419

    
1420
    # find out the tag <creator>. 
1421
    $results = $doc->findnodes('//dataset/creator/individualName');
1422
    debug("Registry: Creators: ".$results->size());
1423
    if ($results->size() > 11) {
1424
        errMoreThanN("creator/individualName");
1425
    } else {
1426
        foreach $node ($results->get_nodelist) {
1427
            dontOccur($node, "../positionName|../onlineURL|../userId", 
1428
              "positionName, onlineURL, userId");
1429
        
1430
            dontOccur($node, "./saluation", "saluation");                
1431
        
1432
            debug("Registry: Checking a creator in loop 1...");
1433
            $tempResult = $node->findnodes('../address|../phone|../electronicmailAddress|../organizationName');
1434
            if($tempResult->size > 0) {
1435
                if($foundDSO == 0) {
1436
                    $foundDSO = 1;
1437
     
1438
                    debug("Registry: Recording a creator in loop 1...");
1439
                    $$templateVars{'origNamefirst0'} = findValue($node, 'givenName');
1440
                    $$templateVars{'origNamelast0'} = findValue($node, 'surName');
1441
            
1442
                    my $tempResult2 = $node->findnodes('../address');
1443
                    if ($tempResult2->size > 1) {
1444
                        errMoreThanOne("address");
1445
                    } else {
1446
                        foreach my $tempNode2 ($tempResult2->get_nodelist) {
1447
                            $$templateVars{'origDelivery'} = findValue($tempNode2, 'deliveryPoint');
1448
                            $$templateVars{'origCity'} = findValue($tempNode2, 'city');
1449
                            $$templateVars{'origState'} = findValue($tempNode2, 'administrativeArea');
1450
                            $$templateVars{'origZIP'} = findValue($tempNode2, 'postalCode');
1451
                            $$templateVars{'origCountry'} = findValue($tempNode2, 'country');
1452
                        }
1453
                    }
1454
            
1455
                    my $tempResult3 = $node->findnodes('../phone');
1456
                    if ($tempResult3->size > 2) {
1457
                        errMoreThanN("phone");
1458
                    } else {
1459
                        foreach my $tempNode2 ($tempResult3->get_nodelist) {
1460
                            if ($tempNode2->hasAttributes()) {
1461
                                my @attlist = $tempNode2->attributes();
1462
                                if ($attlist[0]->value eq "Fax") {
1463
                                    $$templateVars{'origFAX'} = $tempNode2->textContent();
1464
                                } else {
1465
                                    $$templateVars{'origPhone'} = $tempNode2->textContent();
1466
                                }
1467
                            } else {
1468
                                $$templateVars{'origPhone'} = $tempNode2->textContent();
1469
                            }
1470
                        }
1471
                    }
1472
                    $$templateVars{'origEmail'} = findValue($node, '../electronicMailAddress');
1473
                    $$templateVars{'origNameOrg'} = findValue($node, '../organizationName');
1474
                } else {
1475
                    errMoreThanN("address, phone and electronicMailAddress");
1476
                }
1477
            }
1478
        }
1479
        foreach $node ($results->get_nodelist) {
1480
            debug("Registry: Checking a creator in loop 2...");
1481
            $tempResult = $node->findnodes('../address|../phone|../electronicmailAddress|../organizationName');
1482
            if ($tempResult->size == 0) {
1483
                if ($foundDSO == 0) {
1484
                    debug("Registry: Recording a creator in loop 2 block A...");
1485
                    $foundDSO = 1;
1486
                    $$templateVars{'origNamefirst0'} = findValue($node, 'givenName');
1487
                    $$templateVars{'origNamelast0'} = findValue($node, 'surName');
1488
                    $$templateVars{'origNameOrg'} = findValue($node, '../organizationName');
1489
                } else {
1490
                    debug("Registry: Recording a creator in loop 2 block B...");
1491
                    $$templateVars{"origNamefirst$aoCount"} =  findValue($node, './givenName');
1492
                    $$templateVars{"origNamelast$aoCount"} =  findValue($node, './surName');
1493
                    $$templateVars{"origRole$aoCount"} = "Originator";
1494
                    $aoCount++;
1495
                }
1496
            }
1497
        }
1498
    }
1499

    
1500
    $results = $doc->findnodes('//dataset/creator/organizationName');
1501
    my $wgroups = $doc->findnodes("//dataset/creator/organizationName[contains(text(),'(NCEAS ')]");
1502
    debug("Registry: Number Org: ".$results->size());
1503
    debug("Registry:  Number WG: ".$wgroups->size());
1504
    if ($results->size() - $wgroups->size() > 3) {
1505
        errMoreThanN("creator/organizationName");    
1506
    } else {
1507
        foreach $node ($results->get_nodelist) {
1508
            my $tempValue = findValue($node,'../organizationName');
1509
            $tempResult = $node->findnodes('../individualName');
1510
            if ($tempResult->size == 0 && $tempValue ne $organization) {
1511
                $$templateVars{'site'} = $tempValue;
1512
            }
1513
        }
1514
        if ($FORM::cfg eq 'nceas') {
1515
            my @wg;
1516
            foreach $node ($results->get_nodelist) {
1517
                my $tempValue = findValue($node,'../organizationName');
1518
                $wg[scalar(@wg)] = $tempValue;
1519
            }
1520
            my $projects = getProjectList();
1521
            $$templateVars{'projects'} = $projects;
1522
            $$templateVars{'wg'} = \@wg;
1523
        }
1524
    }
1525

    
1526
    $results = $doc->findnodes('//dataset/metadataProvider');
1527
    if ($results->size() > 11) {
1528
        errMoreThanN("metadataProvider");    
1529
    } else {
1530
        foreach $node ($results->get_nodelist) {
1531
            dontOccur($node, "./organizationName|./positionName|./onlineURL|./userId|./electronicMailAddress|./phone|./address", 
1532
                "organizationName, positionName, onlineURL, userId, electronicMailAddress, phone, address in metadataProvider");
1533
        
1534
            $tempResult = $node->findnodes('./individualName');
1535
            if ($tempResult->size > 1) {
1536
                errMoreThanOne("metadataProvider/indvidualName");
1537
            } else {
1538
                foreach $tempNode ($tempResult->get_nodelist) {
1539
                    if ($$templateVars{'providerGivenName'} ne "") {
1540
                        $$templateVars{"origNamefirst$aoCount"} =  findValue($tempNode, './givenName');
1541
                        $$templateVars{"origNamelast$aoCount"} =  findValue($tempNode, './surName');
1542
                        $$templateVars{"origRole$aoCount"} = "Metadata Provider";
1543
                        $aoCount++;
1544
                    } else {
1545
                        $$templateVars{'providerGivenName'} =  findValue($tempNode, './givenName');
1546
                        $$templateVars{'providerSurName'} =  findValue($tempNode, './surName');
1547
                    }
1548
                }
1549
            }
1550
        }
1551
    }
1552

    
1553
    $results = $doc->findnodes('//dataset/associatedParty');
1554
    if ($results->size() > 10) {
1555
        errMoreThanN("associatedParty");
1556
    } else {
1557
        foreach $node ($results->get_nodelist) {
1558
            dontOccur($node, "./organizationName|./positionName|./onlineURL|./userId|./electronicMailAddress|./phone|./address", 
1559
                "organizationName, positionName, onlineURL, userId, electronicMailAddress, phone, address in associatedParty");
1560
       
1561
            $tempResult = $node->findnodes('./individualName');
1562
            if ($tempResult->size > 1) {
1563
                errMoreThanOne("associatedParty/indvidualName");
1564
            } else {
1565
                foreach $tempNode ($tempResult->get_nodelist) {
1566
                    $$templateVars{"origNamefirst$aoCount"} =  findValue($tempNode, './givenName');
1567
                    $$templateVars{"origNamelast$aoCount"} =  findValue($tempNode, './surName');
1568
                    $$templateVars{"origRole$aoCount"} = findValue($tempNode, '../role');
1569
                    $aoCount++;           
1570
                }
1571
            }
1572
        }
1573
    }
1574

    
1575
    $results = $doc->findnodes('//dataset/publisher');
1576
    if ($results->size() > 10) {
1577
        errMoreThanN("publisher");
1578
    } else {
1579
        foreach $node ($results->get_nodelist) {
1580
            dontOccur($node, "./organizationName|./positionName|./onlineURL|./userId|./electronicMailAddress|./phone|./address", 
1581
                "organizationName, positionName, onlineURL, userId, electronicMailAddress, phone, address in associatedParty");
1582
       
1583
            $tempResult = $node->findnodes('./individualName');
1584
            if ($tempResult->size > 1) {
1585
                errMoreThanOne("publisher/indvidualName");
1586
            } else {
1587
                foreach $tempNode ($tempResult->get_nodelist) {
1588
                    $$templateVars{"origNamefirst$aoCount"} =  findValue($tempNode, './givenName');
1589
                    $$templateVars{"origNamelast$aoCount"} =  findValue($tempNode, './surName');
1590
                    $$templateVars{"origRole$aoCount"} = "Publisher";
1591
                    $aoCount++;           
1592
                }
1593
            }
1594
        }
1595
    }
1596

    
1597
    if ($aoCount > 11) {
1598
        errMoreThanN("Additional Originators");
1599
    } 
1600

    
1601
    dontOccur($doc, "./pubDate", "pubDate");
1602
    dontOccur($doc, "./language", "language");
1603
    dontOccur($doc, "./series", "series");
1604

    
1605
    $results = $doc->findnodes('//dataset/abstract');
1606
    if ($results->size() > 1) {
1607
        errMoreThanOne("abstract");
1608
    } else {
1609
        foreach my $node ($results->get_nodelist) {
1610
            dontOccur($node, "./section", "section");
1611
            $$templateVars{'abstract'} = findValueNoChild($node, "para");
1612
        }
1613
    }
1614

    
1615
    $results = $doc->findnodes('//dataset/keywordSet');
1616

    
1617
    my $count = 0;
1618
    foreach $node ($results->get_nodelist) {
1619
	$tempResult = $node->findnodes('./keyword');
1620
	if ($tempResult->size() > 1) {
1621
	    errMoreThanOne("keyword");
1622
	} else {
1623
	    $count++;
1624
	    foreach $tempNode ($tempResult->get_nodelist) {
1625
		$$templateVars{"keyword$count"} = $tempNode->textContent();
1626
		if ($tempNode->hasAttributes()) {
1627
		    my @attlist = $tempNode->attributes();
1628
		    $$templateVars{"kwType$count"} = $attlist[0]->value;
1629
		}  
1630
	    }
1631
	}
1632
	$$templateVars{"kwTh$count"} = findValue($node, "keywordThesaurus");
1633
    }
1634
    $$templateVars{'keyCount'} = $count;
1635
    if($count > 0 ){
1636
       $$templateVars{'hasKeyword'} = "true";
1637
    }
1638

    
1639
    $results = $doc->findnodes('//dataset/additionalInfo');
1640
    if ($results->size() > 1) {
1641
        errMoreThanOne("additionalInfo");
1642
    } else {
1643
        foreach $node ($results->get_nodelist) {
1644
            dontOccur($node, "./section", "section");
1645
            $$templateVars{'addComments'} = findValueNoChild($node, "para");
1646
        }
1647
    }
1648

    
1649
    $$templateVars{'useConstraints'} = "";
1650
    $results = $doc->findnodes('//dataset/intellectualRights');
1651
    if ($results->size() > 1) {
1652
        errMoreThanOne("intellectualRights");
1653
    } else {
1654
        foreach $node ($results->get_nodelist) {
1655
            dontOccur($node, "./section", "section in intellectualRights");
1656

    
1657
            $tempResult = $node->findnodes("para");
1658
            if ($tempResult->size > 2) {
1659
                   errMoreThanN("para");
1660
            } else {
1661
                foreach $tempNode ($tempResult->get_nodelist) {
1662
                    my $childNodes = $tempNode->childNodes;
1663
                    if ($childNodes->size() > 1) {
1664
                        $error ="The tag para in intellectualRights has children which cannot be shown using the form. Please use Morpho to edit this document";    
1665
                        push(@errorMessages, $error);
1666
                        #if ($DEBUG == 1){ print $error."\n";}
1667
                    } else {
1668
                        #print $tempNode->nodeName().":".$tempNode->textContent();
1669
                        #print "\n";
1670
                        if ($$templateVars{'useConstraints'} eq "") {
1671
                            $$templateVars{'useConstraints'} = $tempNode->textContent();
1672
                        } else {
1673
                            $$templateVars{'useConstraintsOther'} = $tempNode->textContent();
1674
                        }
1675
                    }
1676
                }
1677
            }
1678
        }
1679
    }
1680

    
1681
    $results = $doc->findnodes('//dataset/distribution/online');
1682
    if ($results->size() > 1) {
1683
        errMoreThanOne("distribution/online");
1684
    } else {
1685
        foreach my $tempNode ($results->get_nodelist){
1686
            $$templateVars{'url'} = findValue($tempNode, "url");
1687
            dontOccur($tempNode, "./connection", "/distribution/online/connection");
1688
            dontOccur($tempNode, "./connectionDefinition", "/distribution/online/connectionDefinition");
1689
        }
1690
    }
1691

    
1692
    $results = $doc->findnodes('//dataset/distribution/offline');
1693
    if ($results->size() > 1) {
1694
        errMoreThanOne("distribution/online");
1695
    } else {
1696
        foreach my $tempNode ($results->get_nodelist) {
1697
            $$templateVars{'dataMedium'} = findValue($tempNode, "mediumName");
1698
            dontOccur($tempNode, "./mediumDensity", "/distribution/offline/mediumDensity");
1699
            dontOccur($tempNode, "./mediumDensityUnits", "/distribution/offline/mediumDensityUnits");
1700
            dontOccur($tempNode, "./mediumVolume", "/distribution/offline/mediumVolume");
1701
            dontOccur($tempNode, "./mediumFormat", "/distribution/offline/mediumFormat");
1702
            dontOccur($tempNode, "./mediumNote", "/distribution/offline/mediumNote");
1703
        }
1704
    }
1705

    
1706
    dontOccur($doc, "./inline", "//dataset/distribution/inline");
1707

    
1708
    $results = $doc->findnodes('//dataset/coverage');
1709
    if ($results->size() > 1) {
1710
        errMoreThanOne("coverage");
1711
    } else {
1712
        foreach $node ($results->get_nodelist) {
1713
            dontOccur($node, "./temporalCoverage/rangeOfDates/beginDate/time|./temporalCoverage/rangeOfDates/beginDate/alternativeTimeScale|./temporalCoverage/rangeOfDates/endDate/time|./temporalCoverage/rangeOfDates/endDate/alternativeTimeScale|./taxonomicCoverage/taxonomicSystem|./taxonomicCoverage/taxonomicClassification/commonName|./taxonomicCoverage/taxonomicClassification/taxonomicClassification|./geographicCoverage/datasetGPolygon|./geographicCoverage/boundingCoordinates/boundingAltitudes", "temporalCoverage/rangeOfDates/beginDate/time, /temporalCoverage/rangeOfDates/beginDate/alternativeTimeScale, /temporalCoverage/rangeOfDates/endDate/time, /temporalCoverage/rangeOfDates/endDate/alternativeTimeScale, /taxonomicCoverage/taxonomicSystem, /taxonomicCoverage/taxonomicClassification/commonName, /taxonomicCoverage/taxonomicClassification/taxonomicClassification, /geographicCoverage/datasetGPolygon, /geographicCoverage/boundingCoordinates/boundingAltitudes");
1714

    
1715
            $tempResult = $node->findnodes('./temporalCoverage');
1716
            if ($tempResult->size > 1) {
1717
                   errMoreThanOne("temporalCoverage");
1718
            } else {
1719
                foreach $tempNode ($tempResult->get_nodelist) {
1720
                    my $x;
1721
                    my $y;
1722
                    my $z;
1723
                    my $tempdate = findValue($tempNode, "rangeOfDates/beginDate/calendarDate");
1724
                    ($x, $y, $z) = split("-", $tempdate); 
1725
                    $$templateVars{'beginningYear'} = $x;
1726
                    $$templateVars{'beginningMonth'} = $y;
1727
                    $$templateVars{'beginningDay'} = $z;
1728
    
1729
                    $tempdate = findValue($tempNode, "rangeOfDates/endDate/calendarDate");
1730
                    ($x, $y, $z) = split("-", $tempdate);
1731
                    $$templateVars{'endingYear'} = $x;
1732
                    $$templateVars{'endingMonth'} = $y;
1733
                    $$templateVars{'endingDay'} = $z;
1734
                
1735
                    $tempdate = "";
1736
                    $tempdate = findValue($tempNode, "singleDateTime/calendarDate");
1737
                    if($tempdate ne ""){
1738
                        ($x, $y, $z) = split("-", $tempdate);
1739
                        $$templateVars{'beginningYear'} = $x;
1740
                        $$templateVars{'beginningMonth'} = $y;
1741
                        $$templateVars{'beginningDay'} = $z;
1742
                    }  
1743
                }
1744
            }
1745

    
1746
            $tempResult = $node->findnodes('./geographicCoverage');
1747
            if ($tempResult->size > 1) {
1748
                errMoreThanOne("geographicCoverage");
1749
            } else {
1750
                foreach $tempNode ($tempResult->get_nodelist) {
1751
                    my $geogdesc = findValue($tempNode, "geographicDescription");
1752
                    debug("Registry: geogdesc from xml is: $geogdesc");
1753
                    $$templateVars{'geogdesc'} = $geogdesc;
1754
                    my $coord = findValue($tempNode, "boundingCoordinates/westBoundingCoordinate");
1755
                    if ($coord > 0) {
1756
                        #print "+";
1757
                        $$templateVars{'hemisphLong1'} = "E";
1758
                    } else {
1759
                        #print "-";
1760
                        eval($coord = $coord * -1);
1761
                        $$templateVars{'hemisphLong1'} = "W";
1762
                    }
1763
                    eval($$templateVars{'longDeg1'} = int($coord));
1764
                    eval($coord = ($coord - int($coord))*60);
1765
                    eval($$templateVars{'longMin1'} = int($coord));
1766
                    eval($coord = ($coord - int($coord))*60);
1767
                    eval($$templateVars{'longSec1'} = int($coord));
1768
                    
1769
                    $coord = findValue($tempNode, "boundingCoordinates/southBoundingCoordinate");
1770
                    if ($coord > 0) {
1771
                        #print "+";
1772
                        $$templateVars{'hemisphLat2'} = "N";
1773
                    } else {
1774
                        #print "-";
1775
                        eval($coord = $coord * -1);
1776
                        $$templateVars{'hemisphLat2'} = "S";
1777
                    }
1778
                    eval($$templateVars{'latDeg2'} = int($coord));
1779
                    eval($coord = ($coord - int($coord))*60);
1780
                    eval($$templateVars{'latMin2'} = int($coord));
1781
                    eval($coord = ($coord - int($coord))*60);
1782
                    eval($$templateVars{'latSec2'} = int($coord));
1783
        
1784
                    $coord = findValue($tempNode, "boundingCoordinates/northBoundingCoordinate");
1785
                    if ($coord > 0) {
1786
                        #print "+";
1787
                        $$templateVars{'hemisphLat1'} = "N";
1788
                    } else {
1789
                        #print "-";
1790
                        eval($coord = $coord * -1);
1791
                        $$templateVars{'hemisphLat1'} = "S";
1792
                    }
1793
                    eval($$templateVars{'latDeg1'} = int($coord));
1794
                    eval($coord = ($coord - int($coord))*60);
1795
                    eval($$templateVars{'latMin1'} = int($coord));
1796
                    eval($coord = ($coord - int($coord))*60);
1797
                    eval($$templateVars{'latSec1'} = int($coord));
1798
        
1799
                    $coord = findValue($tempNode, "boundingCoordinates/eastBoundingCoordinate");
1800
                    if ($coord > 0) {
1801
                        #print "+";
1802
                        $$templateVars{'hemisphLong2'} = "E";
1803
                    } else {
1804
                        #print "-";
1805
                        eval($coord = $coord * -1);
1806
                        $$templateVars{'hemisphLong2'} = "W";
1807
                    }
1808
                    eval($$templateVars{'longDeg2'} = int($coord));
1809
                    eval($coord = ($coord - int($coord))*60);
1810
                    eval($$templateVars{'longMin2'} = int($coord));
1811
                    eval($coord = ($coord - int($coord))*60);
1812
                    eval($$templateVars{'longSec2'} = int($coord));
1813
                }
1814
            }
1815

    
1816
            $tempResult = $node->findnodes('./taxonomicCoverage/taxonomicClassification');
1817
            my $taxonIndex = 0;
1818
            foreach $tempNode ($tempResult->get_nodelist) {
1819
                $taxonIndex++;
1820
                my $taxonRankName = findValue($tempNode, "taxonRankName");
1821
                my $taxonRankValue = findValue($tempNode, "taxonRankValue");
1822
                $$templateVars{"taxonRankName".$taxonIndex} = $taxonRankName;
1823
                $$templateVars{"taxonRankValue".$taxonIndex} = $taxonRankValue;
1824
            }
1825
            $$templateVars{'taxaCount'} = $taxonIndex;
1826
            my $taxaAuth = findValue($node, "./taxonomicCoverage/generalTaxonomicCoverage");
1827
            $$templateVars{'taxaAuth'} = $taxaAuth;
1828
        }
1829
    }
1830
    dontOccur($doc, "./purpose", "purpose");
1831
    dontOccur($doc, "./maintenance", "maintnance");
1832

    
1833
    $results = $doc->findnodes('//dataset/contact/individualName');
1834
    if ($results->size() > 1) {
1835
        errMoreThanOne("contact/individualName");
1836
    } else {
1837
        foreach $node ($results->get_nodelist) {
1838
            dontOccur($node, "../positionName|../onlineURL|../userId", 
1839
              "positionName, onlineURL, userId in contact tag");
1840
            dontOccur($node, "./saluation", "saluation in contact tag");                
1841
        
1842
            $tempResult = $node->findnodes('../address|../phone|../electronicmailAddress|../organizationName');
1843
            if ($tempResult->size > 0) {
1844
                $$templateVars{'origNamefirstContact'} = findValue($node, 'givenName');
1845
                $$templateVars{'origNamelastContact'} = findValue($node, 'surName');
1846
    
1847
                my $tempResult2 = $node->findnodes('../address');
1848
                if ($tempResult2->size > 1) {
1849
                    errMoreThanOne("address");
1850
                } else {
1851
                    foreach my $tempNode2 ($tempResult2->get_nodelist) {
1852
                        $$templateVars{'origDeliveryContact'} = findValue($tempNode2, 'deliveryPoint');
1853
                        $$templateVars{'origCityContact'} = findValue($tempNode2, 'city');
1854
                        $$templateVars{'origStateContact'} = findValue($tempNode2, 'administrativeArea');
1855
                        $$templateVars{'origZIPContact'} = findValue($tempNode2, 'postalCode');
1856
                        $$templateVars{'origCountryContact'} = findValue($tempNode2, 'country');
1857
                    }
1858
                }
1859
            
1860
                my $tempResult3 = $node->findnodes('../phone');
1861
                if ($tempResult3->size > 2) {
1862
                    errMoreThanN("phone");
1863
                } else {
1864
                    foreach my $tempNode2 ($tempResult3->get_nodelist) {
1865
                        if ($tempNode2->hasAttributes()) {
1866
                            my @attlist = $tempNode2->attributes();
1867
                            if ($attlist[0]->value eq "Fax") {
1868
                                $$templateVars{'origFAXContact'} = $tempNode2->textContent();
1869
                            } else {
1870
                                $$templateVars{'origPhoneContact'} = $tempNode2->textContent();
1871
                            }
1872
                        } else {
1873
                            $$templateVars{'origPhoneContact'} = $tempNode2->textContent();
1874
                        }
1875
                    }
1876
                }
1877
                $$templateVars{'origEmailContact'} = findValue($node, '../electronicMailAddress');
1878
                $$templateVars{'origNameOrgContact'} = findValue($node, '../organizationName');
1879
            } else {
1880
                $$templateVars{'origNamefirstContact'} = findValue($node, 'givenName');
1881
                $$templateVars{'origNamelastContact'} = findValue($node, 'surName');
1882
                $$templateVars{'origNameOrgContact'} = findValue($node, '../organizationName');
1883
            }
1884
        }
1885
    }
1886
    
1887
    $results = $doc->findnodes(
1888
            '//dataset/methods/methodStep/description/section');
1889
    debug("Registry: Number methods: ".$results->size());
1890
    if ($results->size() > 1) {
1891
        errMoreThanN("methods/methodStep/description/section");    
1892
    } else {
1893

    
1894
        my @methodPara;
1895
        foreach $node ($results->get_nodelist) {
1896
            my @children = $node->childNodes;
1897
            for (my $i = 0; $i < scalar(@children); $i++) {
1898
                debug("Registry: Method child loop ($i)");
1899
                my $child = $children[$i];
1900
                if ($child->nodeName eq 'title') {
1901
                    my $title = $child->textContent();
1902
                    debug("Registry: Method title ($title)");
1903
                    $$templateVars{'methodTitle'} = $title;
1904
                } elsif ($child->nodeName eq 'para') {
1905
                    my $para = $child->textContent();
1906
                    debug("Registry: Method para ($para)");
1907
                    $methodPara[scalar(@methodPara)] = $para;
1908
                }
1909
            }
1910
        }
1911
        if (scalar(@methodPara) > 0) {
1912
            $$templateVars{'methodPara'} = \@methodPara;
1913
        }
1914
    }
1915

    
1916
    $results = $doc->findnodes(
1917
            '//dataset/methods/sampling/studyExtent/description/para');
1918
    if ($results->size() > 1) {
1919
        errMoreThanN("methods/sampling/studyExtent/description/para");    
1920
    } else {
1921
        foreach $node ($results->get_nodelist) {
1922
            my $studyExtentDescription = $node->textContent();
1923
            $$templateVars{'studyExtentDescription'} = $studyExtentDescription;
1924
        }
1925
    }
1926

    
1927
    $results = $doc->findnodes(
1928
            '//dataset/methods/sampling/samplingDescription/para');
1929
    if ($results->size() > 1) {
1930
        errMoreThanN("methods/sampling/samplingDescription/para");    
1931
    } else {
1932
        foreach $node ($results->get_nodelist) {
1933
            my $samplingDescription = $node->textContent();
1934
            $$templateVars{'samplingDescription'} = $samplingDescription;
1935
        }
1936
    }
1937

    
1938
    dontOccur($doc, "//methodStep/citation", "methodStep/citation");
1939
    dontOccur($doc, "//methodStep/protocol", "methodStep/protocol");
1940
    dontOccur($doc, "//methodStep/instrumentation", "methodStep/instrumentation");
1941
    dontOccur($doc, "//methodStep/software", "methodStep/software");
1942
    dontOccur($doc, "//methodStep/subStep", "methodStep/subStep");
1943
    dontOccur($doc, "//methodStep/dataSource", "methodStep/dataSource");
1944
    dontOccur($doc, "//methods/qualityControl", "methods/qualityControl");
1945

    
1946
    dontOccur($doc, "//methods/sampling/spatialSamplingUnits", "methods/sampling/spatialSamplingUnits");
1947
    dontOccur($doc, "//methods/sampling/citation", "methods/sampling/citation");
1948
    dontOccur($doc, "./pubPlace", "pubPlace");
1949
    dontOccur($doc, "./project", "project");
1950
    
1951
    dontOccur($doc, "./dataTable", "dataTable");
1952
    dontOccur($doc, "./spatialRaster", "spatialRaster");
1953
    dontOccur($doc, "./spatialVector", "spatialVector");
1954
    dontOccur($doc, "./storedProcedure", "storedProcedure");
1955
    dontOccur($doc, "./view", "view");
1956
    dontOccur($doc, "./otherEntity", "otherEntity");
1957
    dontOccur($doc, "./references", "references");
1958
    
1959
    dontOccur($doc, "//citation", "citation");
1960
    dontOccur($doc, "//software", "software");
1961
    dontOccur($doc, "//protocol", "protocol");
1962
    dontOccur($doc, "//additionalMetadata", "additionalMetadata");    
1963
}
1964

    
1965
################################################################################
1966
# 
1967
# Delete the eml file that has been requested for deletion. 
1968
#
1969
################################################################################
1970
sub deleteData {
1971
    my $deleteAll = shift;
1972
    
1973
    # create metacat instance
1974
    my $metacat;
1975
    my $docid = $FORM::docid;
1976
    
1977
    $metacat = Metacat->new();
1978
    if ($metacat) {
1979
        $metacat->set_options( metacatUrl => $metacatUrl );
1980
    } else {
1981
        #die "failed during metacat creation\n";
1982
        push(@errorMessages, "Failed during metacat creation.");
1983
    }
1984

    
1985
    # Login to metacat
1986
    my $userDN = $FORM::username;
1987
    my $userOrg = $FORM::organization;
1988
    my $userPass = $FORM::password;
1989
    my $dname = "uid=$userDN,o=$userOrg,dc=ecoinformatics,dc=org";
1990
    
1991
    my $errorMessage = "";
1992
    my $response = $metacat->login($dname, $userPass);
1993

    
1994
    if (! $response) {
1995
    # Could not login
1996
        push(@errorMessages, $metacat->getMessage());
1997
        push(@errorMessages, "Failed during login.\n");
1998

    
1999
    } else {
2000
    #Able to login - try to delete the file    
2001

    
2002
    my $parser;
2003
    my @fileArray;
2004
    my $httpMessage;
2005
    my $xmldoc;
2006
    my $doc;
2007
    my $pushDoc;
2008
    my $alreadyInArray;
2009
    my $findType;
2010
        my $node;
2011
    my $response; 
2012
    my $element;
2013

    
2014
    push (@fileArray, $docid);
2015
    $parser = XML::LibXML->new();
2016

    
2017
        $httpMessage = $metacat->read($docid);
2018
    $doc = $httpMessage->content();    
2019
    $xmldoc = $parser->parse_string($doc);
2020

    
2021
    if ($xmldoc eq "") {
2022
        $error ="Error in parsing the eml document";
2023
        push(@errorMessages, $error);
2024
    } else {
2025

    
2026
        $findType = $xmldoc->findnodes('//dataset/identifier');
2027
        if($findType->size() > 0){
2028
        # This is a eml beta6 document
2029
        # Delete the documents mentioned in triples also
2030
        
2031
        $findType = $xmldoc->findnodes('//dataset/triple');
2032
        if($findType->size() > 0){
2033
            foreach $node ($findType->get_nodelist){
2034
            $pushDoc = findValue($node, 'subject');
2035
            
2036
            # If the file is already in the @fileArray then do not add it 
2037
            $alreadyInArray = 0;
2038
            foreach $element (@fileArray){
2039
                if($element eq $pushDoc){
2040
                $alreadyInArray = 1;
2041
                }
2042
            }
2043
            
2044
            if(!$alreadyInArray){
2045
                # If not already in array then delete the file. 
2046
                push (@fileArray, $pushDoc);
2047
                $response = $metacat->delete($pushDoc);
2048
                
2049
                if (! $response) {
2050
                # Could not delete
2051
                #push(@errorMessages, $response);
2052
                push(@errorMessages, $metacat->getMessage());
2053
                push(@errorMessages, "Failed during deleting $pushDoc. Please check if you are authorized to delete this document.\n");
2054
                }
2055
            }
2056
            }
2057
        }
2058
        }
2059
    }
2060
    
2061
    # Delete the main document. 
2062
    if($deleteAll){
2063
        $response = $metacat->delete($docid);  
2064
        if (! $response) {
2065
        # Could not delete
2066
        #push(@errorMessages, $response);
2067
        push(@errorMessages, $metacat->getMessage());
2068
        push(@errorMessages, "Failed during deleting $docid. Please check if you are authorized to delete this document.\n");
2069
        }
2070
    }
2071
    }
2072
    
2073
    if (scalar(@errorMessages)) {
2074
    # If any errors, print them in the response template 
2075
    $$templateVars{'status'} = 'failure';
2076
    $$templateVars{'errorMessages'} = \@errorMessages;
2077
    $error = 1;
2078
    }
2079
    
2080
    # Process the response template
2081
    if($deleteAll){
2082

    
2083
    $$templateVars{'function'} = "deleted";
2084
    $$templateVars{'section'} = "Deletion Status";
2085
    $template->process( $responseTemplate, $templateVars);
2086
    }
2087
}
2088

    
2089

    
2090
################################################################################
2091
# 
2092
# Do data validation and send the data to confirm data template.
2093
#
2094
################################################################################
2095
sub toConfirmData{
2096
    # Check if any invalid parameters
2097
 
2098
    my $invalidParams;
2099
    if (! $error) {
2100
    $invalidParams = validateParameters(0);
2101
    if (scalar(@$invalidParams)) {
2102
        $$templateVars{'status'} = 'failure';
2103
        $$templateVars{'invalidParams'} = $invalidParams;
2104
        $error = 1;
2105
    }
2106
    }
2107

    
2108

    
2109
    $$templateVars{'providerGivenName'} = normalizeCD($FORM::providerGivenName);
2110
    $$templateVars{'providerSurName'} = normalizeCD($FORM::providerSurName);
2111
    if($FORM::site eq "Select your station here."){
2112
        $$templateVars{'site'} = "";
2113
    }else{
2114
        $$templateVars{'site'} = $FORM::site;
2115
    }
2116
    if($FORM::cfg eq "nceas"){
2117
        $$templateVars{'wg'} = \@FORM::wg;
2118
    }
2119
    $$templateVars{'identifier'} = normalizeCD($FORM::identifier);
2120
    $$templateVars{'title'} = normalizeCD($FORM::title);
2121
    $$templateVars{'origNamefirst0'} = normalizeCD($FORM::origNamefirst0);
2122
    $$templateVars{'origNamelast0'} = normalizeCD($FORM::origNamelast0);
2123
    $$templateVars{'origNameOrg'} = normalizeCD($FORM::origNameOrg);
2124
    # $$templateVars{'origRole0'} = $FORM::origRole0;
2125
    $$templateVars{'origDelivery'} = normalizeCD($FORM::origDelivery);
2126
    $$templateVars{'origCity'} = normalizeCD($FORM::origCity);
2127
    if($FORM::origState eq "Select State Here."){
2128
        $$templateVars{'origState'} = "";
2129
    }else{
2130
        $$templateVars{'origState'} = $FORM::origState;
2131
    }
2132
    $$templateVars{'origStateOther'} = normalizeCD($FORM::origStateOther);
2133
    $$templateVars{'origZIP'} = normalizeCD($FORM::origZIP);
2134
    $$templateVars{'origCountry'} = normalizeCD($FORM::origCountry);
2135
    $$templateVars{'origPhone'} = normalizeCD($FORM::origPhone);
2136
    $$templateVars{'origFAX'} = normalizeCD($FORM::origFAX);
2137
    $$templateVars{'origEmail'} = normalizeCD($FORM::origEmail);
2138
    $$templateVars{'useOrigAddress'} = normalizeCD($FORM::useOrigAddress);
2139
    if($FORM::useOrigAddress eq "on"){
2140
        $$templateVars{'origNamefirstContact'} = normalizeCD($FORM::origNamefirst0);
2141
        $$templateVars{'origNamelastContact'} = normalizeCD($FORM::origNamelast0);
2142
        $$templateVars{'origNameOrgContact'} = normalizeCD($FORM::origNameOrg);
2143
        $$templateVars{'origDeliveryContact'} = normalizeCD($FORM::origDelivery); 
2144
        $$templateVars{'origCityContact'} = normalizeCD($FORM::origCity);
2145
        if($FORM::origState eq "Select State Here."){
2146
        $$templateVars{'origStateContact'} = "";
2147
        }else{
2148
        $$templateVars{'origStateContact'} = $FORM::origState;
2149
        }
2150
        $$templateVars{'origStateOtherContact'} = normalizeCD($FORM::origStateOther);
2151
        $$templateVars{'origZIPContact'} = normalizeCD($FORM::origZIP);
2152
        $$templateVars{'origCountryContact'} = normalizeCD($FORM::origCountry);
2153
        $$templateVars{'origPhoneContact'} = normalizeCD($FORM::origPhone);
2154
        $$templateVars{'origFAXContact'} = normalizeCD($FORM::origFAX);
2155
        $$templateVars{'origEmailContact'} = normalizeCD($FORM::origEmail);
2156
    }else{
2157
        $$templateVars{'origNamefirstContact'} = normalizeCD($FORM::origNamefirstContact);
2158
        $$templateVars{'origNamelastContact'} = normalizeCD($FORM::origNamelastContact);
2159
        $$templateVars{'origNameOrgContact'} = normalizeCD($FORM::origNameOrgContact);
2160
        $$templateVars{'origDeliveryContact'} = normalizeCD($FORM::origDeliveryContact); 
2161
        $$templateVars{'origCityContact'} = normalizeCD($FORM::origCityContact);
2162
        if($FORM::origStateContact eq "Select State Here."){
2163
        $$templateVars{'origStateContact'} = "";
2164
        }else{
2165
        $$templateVars{'origStateContact'} = $FORM::origStateContact;
2166
        }
2167
        $$templateVars{'origStateOtherContact'} = normalizeCD($FORM::origStateOtherContact);
2168
        $$templateVars{'origZIPContact'} = normalizeCD($FORM::origZIPContact);
2169
        $$templateVars{'origCountryContact'} = normalizeCD($FORM::origCountryContact);
2170
        $$templateVars{'origPhoneContact'} = normalizeCD($FORM::origPhoneContact);
2171
        $$templateVars{'origFAXContact'} = normalizeCD($FORM::origFAXContact);
2172
        $$templateVars{'origEmailContact'} = normalizeCD($FORM::origEmailContact);    
2173
    }
2174
    $$templateVars{'origNamefirst1'} = normalizeCD($FORM::origNamefirst1);
2175
    $$templateVars{'origNamelast1'} = normalizeCD($FORM::origNamelast1);
2176
    if($FORM::origNamefirst1 eq "" && $FORM::origNamelast1 eq ""){
2177
        $$templateVars{'origRole1'} = "";
2178
    }else{
2179
        $$templateVars{'origRole1'} = $FORM::origRole1;
2180
    }
2181
    $$templateVars{'origNamefirst2'} = normalizeCD($FORM::origNamefirst2);
2182
    $$templateVars{'origNamelast2'} = normalizeCD($FORM::origNamelast2);
2183
    if($FORM::origNamefirst2 eq "" && $FORM::origNamelast2 eq ""){
2184
        $$templateVars{'origRole2'} = "";
2185
    }else{
2186
        $$templateVars{'origRole2'} = $FORM::origRole2;
2187
    }
2188
    $$templateVars{'origNamefirst3'} = normalizeCD($FORM::origNamefirst3);
2189
    $$templateVars{'origNamelast3'} = normalizeCD($FORM::origNamelast3);
2190
    if($FORM::origNamefirst3 eq "" && $FORM::origNamelast3 eq ""){
2191
        $$templateVars{'origRole3'} = "";
2192
    }else{
2193
        $$templateVars{'origRole3'} = $FORM::origRole3;
2194
    }
2195
    $$templateVars{'origNamefirst4'} = normalizeCD($FORM::origNamefirst4);
2196
    $$templateVars{'origNamelast4'} = normalizeCD($FORM::origNamelast4);
2197
    if($FORM::origNamefirst4 eq "" && $FORM::origNamelast4 eq ""){
2198
        $$templateVars{'origRole4'} = "";
2199
    }else{
2200
        $$templateVars{'origRole4'} = $FORM::origRole4;
2201
    }
2202
    $$templateVars{'origNamefirst5'} = normalizeCD($FORM::origNamefirst5);
2203
    $$templateVars{'origNamelast5'} = normalizeCD($FORM::origNamelast5);
2204
    if($FORM::origNamefirst5 eq "" && $FORM::origNamelast5 eq ""){
2205
        $$templateVars{'origRole5'} = "";
2206
    }else{
2207
        $$templateVars{'origRole5'} = $FORM::origRole5;
2208
    }
2209
    $$templateVars{'origNamefirst6'} = normalizeCD($FORM::origNamefirst6);
2210
    $$templateVars{'origNamelast6'} = normalizeCD($FORM::origNamelast6);
2211
    if($FORM::origNamefirst6 eq "" && $FORM::origNamelast6 eq ""){
2212
        $$templateVars{'origRole6'} = "";
2213
    }else{
2214
        $$templateVars{'origRole6'} = $FORM::origRole6;
2215
    }
2216
    $$templateVars{'origNamefirst7'} = normalizeCD($FORM::origNamefirst7);
2217
    $$templateVars{'origNamelast7'} = normalizeCD($FORM::origNamelast7);
2218
    if($FORM::origNamefirst7 eq "" && $FORM::origNamelast7 eq ""){
2219
        $$templateVars{'origRole7'} = "";
2220
    }else{
2221
        $$templateVars{'origRole7'} = $FORM::origRole7;
2222
    }
2223
    $$templateVars{'origNamefirst8'} = normalizeCD($FORM::origNamefirst8);
2224
    $$templateVars{'origNamelast8'} = normalizeCD($FORM::origNamelast8);
2225
    if($FORM::origNamefirst8 eq "" && $FORM::origNamelast8 eq ""){
2226
        $$templateVars{'origRole8'} = "";
2227
    }else{
2228
        $$templateVars{'origRole8'} = $FORM::origRole8;
2229
    }
2230
    $$templateVars{'origNamefirst9'} = normalizeCD($FORM::origNamefirst9);
2231
    $$templateVars{'origNamelast9'} = normalizeCD($FORM::origNamelast9);
2232
    if($FORM::origNamefirst9 eq "" && $FORM::origNamelast9 eq ""){
2233
        $$templateVars{'origRole9'} = "";
2234
    }else{
2235
        $$templateVars{'origRole9'} = $FORM::origRole9;
2236
    }
2237
    $$templateVars{'origNamefirst10'} = normalizeCD($FORM::origNamefirst10);
2238
    $$templateVars{'origNamelast10'} = normalizeCD($FORM::origNamelast10);
2239
    if($FORM::origNamefirst10 eq "" && $FORM::origNamelast10 eq ""){
2240
        $$templateVars{'origRole10'} = "";
2241
    }else{
2242
        $$templateVars{'origRole10'} = $FORM::origRole10;
2243
    }
2244
    $$templateVars{'abstract'} = normalizeCD($FORM::abstract);
2245
    $$templateVars{'keyCount'} = $FORM::keyCount;
2246
    foreach my $kyd (param()) {
2247
	if ($kyd =~ /keyword/) {
2248
	    my $keyIndex = $kyd;
2249
	    $keyIndex =~ s/keyword//; # get the index of the parameter 0, ..., 10
2250
	    my $keyType = "kwType".$keyIndex;
2251
	    my $keyTh = "kwTh".$keyIndex;
2252
	    if ( $keyIndex =~ /[0-9]/ ){
2253
		if (hasContent(param($kyd)) && hasContent(param($keyType)) && hasContent(param($keyTh))) {
2254
		    debug("Registry processing keyword: $kyd = ".param($kyd)." $keyType = ".param($keyType)." $keyTh = ".param($keyTh));
2255
		    $$templateVars{$kyd} = normalizeCD(param($kyd));
2256
		    $$templateVars{$keyType} = param($keyType);
2257
		    $$templateVars{$keyTh} = param($keyTh);
2258
		}
2259
	    }
2260
	}
2261
    }
2262
    $$templateVars{'addComments'} = normalizeCD($FORM::addComments);
2263
    $$templateVars{'useConstraints'} = $FORM::useConstraints;
2264
    $$templateVars{'useConstraintsOther'} = $FORM::useConstraintsOther;
2265
    $$templateVars{'url'} = $FORM::url;
2266
    if($FORM::dataMedium eq "Select type of medium here."){
2267
        $$templateVars{'dataMedium'} = "";
2268
    }else{
2269
        $$templateVars{'dataMedium'} = $FORM::dataMedium;
2270
    }    
2271
    $$templateVars{'dataMediumOther'} = normalizeCD($FORM::dataMediumOther);
2272
    $$templateVars{'beginningYear'} = $FORM::beginningYear;
2273
    $$templateVars{'beginningMonth'} = $FORM::beginningMonth;
2274
    $$templateVars{'beginningDay'} = $FORM::beginningDay;
2275
    $$templateVars{'endingYear'} = $FORM::endingYear;
2276
    $$templateVars{'endingMonth'} = $FORM::endingMonth;
2277
    $$templateVars{'endingDay'} = $FORM::endingDay;
2278
    $$templateVars{'geogdesc'} = normalizeCD($FORM::geogdesc);
2279
    $$templateVars{'useSiteCoord'} = $FORM::useSiteCoord;
2280
    $$templateVars{'latDeg1'} = $FORM::latDeg1;
2281
    $$templateVars{'latMin1'} = $FORM::latMin1;
2282
    $$templateVars{'latSec1'} = $FORM::latSec1;
2283
    $$templateVars{'hemisphLat1'} = $FORM::hemisphLat1;
2284
    $$templateVars{'longDeg1'} = $FORM::longDeg1;
2285
    $$templateVars{'longMin1'} = $FORM::longMin1;
2286
    $$templateVars{'longSec1'} = $FORM::longSec1;
2287
    $$templateVars{'hemisphLong1'} = $FORM::hemisphLong1;
2288
    $$templateVars{'latDeg2'} = $FORM::latDeg2;
2289
    $$templateVars{'latMin2'} = $FORM::latMin2;
2290
    $$templateVars{'latSec2'} = $FORM::latSec2;
2291
    $$templateVars{'hemisphLat2'} = $FORM::hemisphLat2;
2292
    $$templateVars{'longDeg2'} = $FORM::longDeg2;
2293
    $$templateVars{'longMin2'} = $FORM::longMin2;
2294
    $$templateVars{'longSec2'} = $FORM::longSec2;
2295
    $$templateVars{'hemisphLong2'} = $FORM::hemisphLong2;
2296

    
2297
    $$templateVars{'taxaCount'} = $FORM::taxaCount;
2298
    foreach my $trn (param()) {
2299
        if ($trn =~ /taxonRankName/) {
2300
            my $taxIndex = $trn;
2301
            $taxIndex =~ s/taxonRankName//; # get the index of the parameter 0, ..., 10
2302
            my $trv = "taxonRankValue".$taxIndex;
2303
            if ( $taxIndex =~ /[0-9]/ ){
2304
                if (hasContent(param($trn)) && hasContent(param($trv))) {
2305
                    debug("Registry processing taxon: $trn = ".param($trn)." $trv = ".param($trv));
2306
                    $$templateVars{$trn} = normalizeCD(param($trn));
2307
                    $$templateVars{$trv} = normalizeCD(param($trv));
2308
                }
2309
            }
2310
        }
2311
    }
2312
    $$templateVars{'taxaAuth'} = normalizeCD($FORM::taxaAuth);
2313

    
2314
    $$templateVars{'methodTitle'} = normalizeCD($FORM::methodTitle);
2315

    
2316
    my @tempMethodPara;
2317
    for (my $i = 0; $i < scalar(@FORM::methodPara); $i++) {
2318
	$tempMethodPara[$i] = normalizeCD($FORM::methodPara[$i]);
2319
    }
2320
    $$templateVars{'methodPara'} = \@tempMethodPara;
2321
    $$templateVars{'studyExtentDescription'} = normalizeCD($FORM::studyExtentDescription);
2322
    $$templateVars{'samplingDescription'} = normalizeCD($FORM::samplingDescription);
2323
    $$templateVars{'origStateContact'} = $FORM::origState;
2324

    
2325
    $$templateVars{'hasKeyword'} = $FORM::hasKeyword;
2326
    $$templateVars{'docid'} = $FORM::docid;
2327

    
2328
    if (! $error) {
2329
	# If no errors, then print out data in confirm Data template
2330

    
2331
	$$templateVars{'section'} = "Confirm Data";
2332
	$template->process( $confirmDataTemplate, $templateVars);
2333

    
2334
    } else{    
2335
    # Errors from validation function. print the errors out using the response template
2336
    if (scalar(@errorMessages)) {
2337
        $$templateVars{'status'} = 'failure';
2338
        $$templateVars{'errorMessages'} = \@errorMessages;
2339
        $error = 1;
2340
    }
2341
        # Create our HTML response and send it back
2342
    $$templateVars{'function'} = "submitted";
2343
    $$templateVars{'section'} = "Submission Status";
2344
    $template->process( $responseTemplate, $templateVars);
2345
    }
2346
}
2347

    
2348

    
2349
################################################################################
2350
# 
2351
# From confirm Data template - user wants to make some changes.
2352
#
2353
################################################################################
2354
sub confirmDataToReEntryData{
2355
    my @sortedSites;
2356
    foreach my $site (sort @sitelist) {
2357
        push(@sortedSites, $site);
2358
    }
2359

    
2360
    $$templateVars{'siteList'} = \@sortedSites;
2361
    $$templateVars{'section'} = "Re-Entry Form";
2362
    copyFormToTemplateVars();
2363
    $$templateVars{'docid'} = $FORM::docid;
2364

    
2365
    $$templateVars{'form'} = 're_entry';
2366
    $template->process( $entryFormTemplate, $templateVars);
2367
}
2368

    
2369

    
2370
################################################################################
2371
# 
2372
# Copy form data to templateVars.....
2373
#
2374
################################################################################
2375
sub copyFormToTemplateVars{
2376
    $$templateVars{'providerGivenName'} = $FORM::providerGivenName;
2377
    $$templateVars{'providerSurName'} = $FORM::providerSurName;
2378
    $$templateVars{'site'} = $FORM::site;
2379
    if ($FORM::cfg eq "nceas") {
2380
        my $projects = getProjectList();
2381
        $$templateVars{'projects'} = $projects;
2382
        $$templateVars{'wg'} = \@FORM::wg;
2383
    }
2384
    $$templateVars{'identifier'} = $FORM::identifier;
2385
    $$templateVars{'title'} = $FORM::title;
2386
    $$templateVars{'origNamefirst0'} = $FORM::origNamefirst0;
2387
    $$templateVars{'origNamelast0'} = $FORM::origNamelast0;
2388
    $$templateVars{'origNameOrg'} = $FORM::origNameOrg;
2389
 #   $$templateVars{'origRole0'} = $FORM::origRole0;
2390
    $$templateVars{'origDelivery'} = $FORM::origDelivery;
2391
    $$templateVars{'origCity'} = $FORM::origCity;
2392
    $$templateVars{'origState'} = $FORM::origState;
2393
    $$templateVars{'origStateOther'} = $FORM::origStateOther;
2394
    $$templateVars{'origZIP'} = $FORM::origZIP;
2395
    $$templateVars{'origCountry'} = $FORM::origCountry;
2396
    $$templateVars{'origPhone'} = $FORM::origPhone;
2397
    $$templateVars{'origFAX'} = $FORM::origFAX;
2398
    $$templateVars{'origEmail'} = $FORM::origEmail;
2399
    if ($FORM::useSiteCoord ne "") {
2400
        $$templateVars{'useOrigAddress'} = "CHECKED";
2401
    }else{
2402
        $$templateVars{'useOrigAddress'} = $FORM::useOrigAddress;
2403
    }
2404
    $$templateVars{'origNamefirstContact'} = $FORM::origNamefirstContact;
2405
    $$templateVars{'origNamelastContact'} = $FORM::origNamelastContact;
2406
    $$templateVars{'origNameOrgContact'} = $FORM::origNameOrgContact;
2407
    $$templateVars{'origDeliveryContact'} = $FORM::origDeliveryContact; 
2408
    $$templateVars{'origCityContact'} = $FORM::origCityContact;
2409
    $$templateVars{'origStateContact'} = $FORM::origStateContact;
2410
    $$templateVars{'origStateOtherContact'} = $FORM::origStateOtherContact;
2411
    $$templateVars{'origZIPContact'} = $FORM::origZIPContact;
2412
    $$templateVars{'origCountryContact'} = $FORM::origCountryContact;
2413
    $$templateVars{'origPhoneContact'} = $FORM::origPhoneContact;
2414
    $$templateVars{'origFAXContact'} = $FORM::origFAXContact;
2415
    $$templateVars{'origEmailContact'} = $FORM::origEmailContact;    
2416
    $$templateVars{'origNamefirst1'} = $FORM::origNamefirst1;
2417
    $$templateVars{'origNamelast1'} = $FORM::origNamelast1;
2418
    $$templateVars{'origRole1'} = $FORM::origRole1;
2419
    $$templateVars{'origNamefirst2'} = $FORM::origNamefirst2;
2420
    $$templateVars{'origNamelast2'} = $FORM::origNamelast2;
2421
    $$templateVars{'origRole2'} = $FORM::origRole2;
2422
    $$templateVars{'origNamefirst3'} = $FORM::origNamefirst3;
2423
    $$templateVars{'origNamelast3'} = $FORM::origNamelast3;
2424
    $$templateVars{'origRole3'} = $FORM::origRole3;
2425
    $$templateVars{'origNamefirst4'} = $FORM::origNamefirst4;
2426
    $$templateVars{'origNamelast4'} = $FORM::origNamelast4;
2427
    $$templateVars{'origRole4'} = $FORM::origRole4;
2428
    $$templateVars{'origNamefirst5'} = $FORM::origNamefirst5;
2429
    $$templateVars{'origNamelast5'} = $FORM::origNamelast5;
2430
    $$templateVars{'origRole5'} = $FORM::origRole5;
2431
    $$templateVars{'origNamefirst6'} = $FORM::origNamefirst6;
2432
    $$templateVars{'origNamelast6'} = $FORM::origNamelast6;
2433
    $$templateVars{'origRole6'} = $FORM::origRole6;
2434
    $$templateVars{'origNamefirst7'} = $FORM::origNamefirst7;
2435
    $$templateVars{'origNamelast7'} = $FORM::origNamelast7;
2436
    $$templateVars{'origRole7'} = $FORM::origRole7;
2437
    $$templateVars{'origNamefirst8'} = $FORM::origNamefirst8;
2438
    $$templateVars{'origNamelast8'} = $FORM::origNamelast8;
2439
    $$templateVars{'origRole8'} = $FORM::origRole8;
2440
    $$templateVars{'origNamefirst9'} = $FORM::origNamefirst9;
2441
    $$templateVars{'origNamelast9'} = $FORM::origNamelast9;
2442
    $$templateVars{'origRole9'} = $FORM::origRole9;
2443
    $$templateVars{'origNamefirst10'} = $FORM::origNamefirst10;
2444
    $$templateVars{'origNamelast10'} = $FORM::origNamelast10;
2445
    $$templateVars{'origRole10'} = $FORM::origRole10;
2446
    $$templateVars{'abstract'} = $FORM::abstract;
2447
    $$templateVars{'keyCount'} = $FORM::keyCount;
2448
    foreach my $kyd (param()) {
2449
	if ($kyd =~ /keyword/) {
2450
	    my $keyIndex = $kyd;
2451
	    $keyIndex =~ s/keyword//; # get the index of the parameter 0, ..., 10
2452
	    my $keyType = "kwType".$keyIndex;
2453
	    my $keyTh = "kwTh".$keyIndex;
2454
	    if ( $keyIndex =~ /[0-9]/ ){
2455
		if (hasContent(param($kyd)) && hasContent(param($keyType)) && hasContent(param($keyTh))) {
2456
		    debug("Registry processing keyword: $kyd = ".param($kyd)." $keyType = ".param($keyType)." $keyTh = ".param($keyTh));
2457
		    $$templateVars{$kyd} = param($kyd);
2458
		    $$templateVars{$keyType} = param($keyType);
2459
		    $$templateVars{$keyTh} = param($keyTh);
2460
		}
2461
	    }
2462
	}
2463
    }
2464
    $$templateVars{'addComments'} = $FORM::addComments;
2465
    $$templateVars{'useConstraints'} = $FORM::useConstraints;
2466
    $$templateVars{'useConstraintsOther'} = $FORM::useConstraintsOther;
2467
    $$templateVars{'url'} = $FORM::url;
2468
    $$templateVars{'dataMedium'} = $FORM::dataMedium;
2469
    $$templateVars{'dataMediumOther'} = $FORM::dataMediumOther;
2470
    $$templateVars{'beginningYear'} = $FORM::beginningYear;
2471
    $$templateVars{'beginningMonth'} = $FORM::beginningMonth;
2472
    $$templateVars{'beginningDay'} = $FORM::beginningDay;
2473
    $$templateVars{'endingYear'} = $FORM::endingYear;
2474
    $$templateVars{'endingMonth'} = $FORM::endingMonth;
2475
    $$templateVars{'endingDay'} = $FORM::endingDay;
2476
    $$templateVars{'geogdesc'} = $FORM::geogdesc;
2477
    if($FORM::useSiteCoord ne ""){
2478
    $$templateVars{'useSiteCoord'} = "CHECKED";
2479
    }else{
2480
    $$templateVars{'useSiteCoord'} = "";
2481
    }
2482
    $$templateVars{'latDeg1'} = $FORM::latDeg1;
2483
    $$templateVars{'latMin1'} = $FORM::latMin1;
2484
    $$templateVars{'latSec1'} = $FORM::latSec1;
2485
    $$templateVars{'hemisphLat1'} = $FORM::hemisphLat1;
2486
    $$templateVars{'longDeg1'} = $FORM::longDeg1;
2487
    $$templateVars{'longMin1'} = $FORM::longMin1;
2488
    $$templateVars{'longSec1'} = $FORM::longSec1;
2489
    $$templateVars{'hemisphLong1'} = $FORM::hemisphLong1;
2490
    $$templateVars{'latDeg2'} = $FORM::latDeg2;
2491
    $$templateVars{'latMin2'} = $FORM::latMin2;
2492
    $$templateVars{'latSec2'} = $FORM::latSec2;
2493
    $$templateVars{'hemisphLat2'} = $FORM::hemisphLat2;
2494
    $$templateVars{'longDeg2'} = $FORM::longDeg2;
2495
    $$templateVars{'longMin2'} = $FORM::longMin2;
2496
    $$templateVars{'longSec2'} = $FORM::longSec2;
2497
    $$templateVars{'hemisphLong2'} = $FORM::hemisphLong2;
2498
    $$templateVars{'taxaCount'} = $FORM::taxaCount;
2499
    foreach my $trn (param()) {
2500
        if ($trn =~ /taxonRankName/) {
2501
            my $taxIndex = $trn;
2502
            $taxIndex =~ s/taxonRankName//; # get the index of the parameter 0, ..., 10
2503
            my $trv = "taxonRankValue".$taxIndex;
2504
            if ( $taxIndex =~ /[0-9]/ ){
2505
                if (hasContent(param($trn)) && hasContent(param($trv))) {
2506
                    debug("Registry processing taxon: $trn = ".param($trn)." $trv = ".param($trv));
2507
                    $$templateVars{$trn} = param($trn);
2508
                    $$templateVars{$trv} = param($trv);
2509
                }
2510
            }
2511
        }
2512
    }
2513
    $$templateVars{'taxaAuth'} = $FORM::taxaAuth;
2514
    $$templateVars{'methodTitle'} = $FORM::methodTitle;
2515
    $$templateVars{'methodPara'} = \@FORM::methodPara;
2516
    $$templateVars{'studyExtentDescription'} = $FORM::studyExtentDescription;
2517
    $$templateVars{'samplingDescription'} = $FORM::samplingDescription;
2518
    
2519
     $$templateVars{'hasKeyword'} = $FORM::hasKeyword;
2520
}
2521

    
2522
################################################################################
2523
# 
2524
# check if there is multiple occurence of the given tag and find its value.
2525
#
2526
################################################################################
2527

    
2528
sub findValue {
2529
    my $node = shift;
2530
    my $value = shift;
2531
    my $result;
2532
    my $tempNode;
2533

    
2534
    $result = $node->findnodes("./$value");
2535
    if ($result->size > 1) {
2536
        errMoreThanOne("$value");
2537
    } else {
2538
        foreach $tempNode ($result->get_nodelist){
2539
            #print $tempNode->nodeName().":".$tempNode->textContent();
2540
            #print "\n";
2541
            return $tempNode->textContent();
2542
        }
2543
    }
2544
}
2545

    
2546

    
2547
################################################################################
2548
# 
2549
# check if given tags has any children. if not return the value
2550
#
2551
################################################################################
2552
sub findValueNoChild {
2553
    my $node = shift;
2554
    my $value = shift;
2555
    my $tempNode;
2556
    my $childNodes;
2557
    my $result;
2558
    my $error;
2559

    
2560
    $result = $node->findnodes("./$value");
2561
    if($result->size > 1){
2562
       errMoreThanOne("$value");
2563
    } else {
2564
        foreach $tempNode ($result->get_nodelist) {
2565
            $childNodes = $tempNode->childNodes;
2566
            if ($childNodes->size() > 1) {
2567
                $error ="The tag $value has children which cannot be shown using the form. Please use Morpho to edit this document";    
2568
                push(@errorMessages, $error);
2569
                #if ($DEBUG == 1){ print $error."\n";}
2570
            } else {
2571
                #print $tempNode->nodeName().":".$tempNode->textContent();
2572
                #print "\n";
2573
                return $tempNode->textContent();
2574
            }
2575
        }
2576
    }
2577
}
2578

    
2579

    
2580
################################################################################
2581
# 
2582
# check if given tags are children of given node.
2583
#
2584
################################################################################
2585
sub dontOccur {
2586
    my $node = shift;
2587
    my $value = shift;
2588
    my $errVal = shift;
2589

    
2590
    my $result = $node->findnodes("$value");
2591
    if($result->size > 0){
2592
        $error ="One of the following tags found: $errVal. Please use Morpho to edit this document";
2593
        push(@errorMessages, $error."\n");
2594
        #if ($DEBUG == 1){ print $error;}
2595
    } 
2596
}
2597

    
2598

    
2599
################################################################################
2600
# 
2601
# print out error for more than one occurence of a given tag
2602
#
2603
################################################################################
2604
sub errMoreThanOne {
2605
    my $value = shift;
2606
    my $error ="More than one occurence of the tag $value found. Please use Morpho to edit this document";
2607
    push(@errorMessages, $error."\n");
2608
    # if ($DEBUG == 1){ print $error;}
2609
}
2610

    
2611

    
2612
################################################################################
2613
# 
2614
# print out error for more than given number of occurences of a given tag
2615
#
2616
################################################################################
2617
sub errMoreThanN {
2618
    my $value = shift;
2619
    my $error ="More occurences of the tag $value found than that can be shown in the form. Please use Morpho to edit this document";
2620
    push(@errorMessages, $error);
2621
    #if ($DEBUG == 1){ print $error."\n";}
2622
}
2623

    
2624

    
2625
################################################################################
2626
# 
2627
# convert coord to degrees, minutes and seconds form. 
2628
#
2629
################################################################################
2630
#sub convertCoord {
2631
#    my $wx = shift;
2632
#    print $deg." ".$min." ".$sec;
2633
#    print "\n";
2634
#}
2635

    
2636

    
2637
################################################################################
2638
# 
2639
# print debugging messages to stderr
2640
#
2641
################################################################################
2642
sub debug {
2643
    my $msg = shift;
2644
    
2645
    if ($debug) {
2646
        print STDERR "$msg\n";
2647
    }
2648
}
2649

    
2650
################################################################################
2651
# 
2652
# get the list of projects
2653
#
2654
################################################################################
2655
sub getProjectList {
2656
    
2657
    use NCEAS::AdminDB;
2658
    my $admindb = NCEAS::AdminDB->new();
2659
    $admindb->connect($nceas_db, $nceas_db_user, $nceas_db_password);
2660
    my $projects = $admindb->getProjects();
2661
    #my $projects = getTestProjectList();
2662
    return $projects;
2663
}
2664

    
2665
################################################################################
2666
# 
2667
# get a test list of projects for use only in testing where the NCEAS
2668
# admin db is not available.
2669
#
2670
################################################################################
2671
sub getTestProjectList {
2672
    # This block is for testing only!  Remove for production use
2673
    my @row1;
2674
    $row1[0] = 6000; $row1[1] = 'Andelman'; $row1[2] = 'Sandy'; $row1[3] = 'The very long and windy path to an apparent ecological conclusion: statistics lie';
2675
    my @row2; 
2676
    $row2[0] = 7000; $row2[1] = 'Bascompte'; $row2[2] = 'Jordi'; $row2[3] = 'Postdoctoral Fellow';
2677
    my @row3; 
2678
    $row3[0] = 7001; $row3[1] = 'Hackett'; $row3[2] = 'Edward'; $row3[3] = 'Sociology rules the world';
2679
    my @row4; 
2680
    $row4[0] = 7002; $row4[1] = 'Jones'; $row4[2] = 'Matthew'; $row4[3] = 'Informatics rules the world';
2681
    my @row5; 
2682
    $row5[0] = 7003; $row5[1] = 'Schildhauer'; $row5[2] = 'Mark'; $row5[3] = 'Excel rocks my world, assuming a, b, and c';
2683
    my @row6; 
2684
    $row6[0] = 7004; $row6[1] = 'Rogers'; $row6[2] = 'Bill'; $row6[3] = 'Graduate Intern';
2685
    my @row7; 
2686
    $row7[0] = 7005; $row7[1] = 'Zedfried'; $row7[2] = 'Karl'; $row7[3] = 'A multivariate analysis of thing that go bump in the night';
2687
    my @projects;
2688
    $projects[0] = \@row1;
2689
    $projects[1] = \@row2;
2690
    $projects[2] = \@row3;
2691
    $projects[3] = \@row4;
2692
    $projects[4] = \@row5;
2693
    $projects[5] = \@row6;
2694
    $projects[6] = \@row7;
2695
    return \@projects;
2696
}
(2-2/3)