Changeset 27168

Show
Ignore:
Timestamp:
10.04.2013 18:28:32 (7 years ago)
Author:
ak19
Message:

Second part of major restructuring of metadataaction: 1. the x_metadata_array subroutines now take a more complex JSON table which can now have subtables for each docID and whcih can each specify several metavalues to set for a single metaname using either accumulate or override as the metamode. 2. Added set_live_metadata_array. 3. set_index_metadata_array now does what the old set_metadata_array did, while set_metadata_array is a more generic method that takes a where parameter than can be set to a combination of archives|index|import|live. 4. set_index_metadata_array now takes the metamode parameter too. The complex JSON tables for set_archives_meta_array and set_index_meta_array have been tested, as has been the restructured remove_meta subroutines. But live and import metadata and metadata_array and remove subroutines have yet to be tested.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone2/perllib/cgiactions/metadataaction.pm

    r27167 r27168  
    7777    "set-index-metadata" => {  
    7878        'compulsory-args' => [ "d", "metaname", "metavalue" ], 
    79         'optional-args'   => [ "metapos" ] }, 
     79        'optional-args'   => [ "metapos", "metamode" ] }, 
    8080 
    8181    "set-archives-metadata" => {  
     
    8989    #SET METHODS (ARRAY) 
    9090    "set-metadata-array" => {  
    91         'compulsory-args' => [ "json" ], 
     91        'compulsory-args' => [ "where", "json" ], 
    9292        'optional-args'   => [ ] }, 
    9393                      
     
    9797         
    9898    "set-import-metadata-array" => { 
     99        'compulsory-args' => [ "json" ], 
     100        'optional-args'   => [ ] }, 
     101 
     102    "set-index-metadata-array" => { 
     103        'compulsory-args' => [ "json" ], 
     104        'optional-args'   => [ ] }, 
     105     
     106    "set-live-metadata-array" => { 
    99107        'compulsory-args' => [ "json" ], 
    100108        'optional-args'   => [ ] }, 
     
    529537    my $docid     = $self->{'d'}; 
    530538    if ((!defined $docid) || ($docid =~ m/^\s*$/)) { 
    531       $gsdl_cgi->generate_error("No docid (d=...) specified."); 
     539      $gsdl_cgi->generate_error("No docid (d=...) specified."); # generates error and dies 
    532540    } 
    533541    my $metavalue = $self->{'metavalue'}; 
    534    
     542    my $metamode  = $self->{'metamode'} || "accumulate"; 
     543    my $append_or_not = ($metamode eq "accumulate") ? " \"append\"" : ""; 
    535544 
    536545    # Generate the dbkey     
     
    546555 
    547556    # Set the new value 
    548     my $cmd = "gdbmset \"$infodb_file_path\" \"$dbkey\" \"$metavalue\""; 
     557    my $cmd = "gdbmset \"$infodb_file_path\" \"$dbkey\" \"$metavalue\"$append_or_not"; 
    549558    my $status = system($cmd); 
    550559    if ($status != 0) { 
     
    588597} 
    589598 
    590 sub set_metadata_entry 
    591 { 
    592     my $self = shift @_; 
    593     my ($collect_dir,$collect,$infodbtype,$docid,$metaname,$metapos,$metavalue) = @_; 
    594      
     599sub set_index_metadata_entry 
     600{ 
     601    my $self = shift @_; 
     602    my ($collect_dir,$collect,$infodbtype,$docid,$metaname,$metapos,$metavalue,$metamode) = @_; 
     603     
    595604    # To people who know $collect_tail please add some comments 
    596605    # Obtain path to the database 
     
    602611#   print STDERR "**** infodb file path = $infodb_file_path\n"; 
    603612#   print STDERR "***** infodb type = $infodbtype\n"; 
    604      
     613     
    605614    # Read the docid entry 
    606615    my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $infodb_file_path, $docid); 
    607      
     616     
    608617    # Set the metadata value 
    609618    if (defined $metapos) { 
    610         $doc_rec->{$metaname}->[$metapos] = $metavalue; 
    611     } 
    612     else { 
    613         $doc_rec->{$metaname} = [ $metavalue ]; 
     619    # if metamode=accumulate AND metapos, warn user and then use metapos 
     620    if (defined $metamode && $metamode eq "accumulate") { 
     621        print STDERR "**** Warning: metamode is set to accumulate yet metapos is also provided for $docid\n"; 
     622        print STDERR "**** Proceeding by using metapos\n"; 
     623    } 
     624    $doc_rec->{$metaname}->[$metapos] = $metavalue; 
     625    } 
     626    elsif (defined $metamode && $metamode eq "accumulate") { 
     627    if(defined $doc_rec->{$metaname}) { 
     628        push(@{$doc_rec->{$metaname}}, $metavalue); # accumulate the value for that metaname 
     629    } else { 
     630        $doc_rec->{$metaname} = [ $metavalue ]; 
     631    } 
     632 
     633    } 
     634    else { # default for index was to override 
     635    $doc_rec->{$metaname} = [ $metavalue ]; 
    614636    } 
    615637  
    616638    my $status = &dbutil::set_infodb_entry($infodbtype, $infodb_file_path,$docid,$doc_rec); 
    617639     
    618     return $status; 
     640    return $status; 
    619641     
    620642} 
     
    728750    $metamode = "accumulate"; 
    729751    } 
    730      
     752 
    731753    my $status = $self->set_archives_metadata_entry($gsdl_cgi,$archive_dir, $collect_dir,$collect, $infodbtype,$docid, 
    732754                $metaname,$metapos,$metavalue,$metamode,$prevmetavalue); 
     
    775797    my $metavalue = $self->{'metavalue'}; 
    776798    my $infodbtype = $self->{'infodbtype'}; 
    777      
    778     my $status = $self->set_metadata_entry($collect_dir,$collect,$infodbtype,$docid,$metaname,$metapos,$metavalue); 
     799    my $metamode  = $self->{'metamode'};     
     800 
     801    my $status = $self->set_index_metadata_entry($collect_dir,$collect,$infodbtype,$docid,$metaname,$metapos,$metavalue,$metamode); 
    779802     
    780803    if ($status != 0) { 
     
    884907    my $docid     = $self->{'d'}; 
    885908    if ((!defined $docid) || ($docid =~ m/^\s*$/)) { 
    886         $gsdl_cgi->generate_error("No docid (d=...) specified."); 
     909        $gsdl_cgi->generate_error("No docid (d=...) specified."); # generates error and dies 
    887910    }  
    888     else { # we have a docid, so can set archives meta 
    889         $self->_set_archives_metadata(@_); 
    890     } 
     911    # we have a docid, so can set archives meta 
     912    $self->_set_archives_metadata(@_);   
    891913    } 
    892914 
     
    899921        $gsdl_cgi->generate_error("No docid (d=...) specified."); 
    900922    } 
    901     else { # we have a docid, so can set index meta 
    902         $self->_set_index_metadata(@_); 
    903     } 
     923    # we have a docid, so can set index meta 
     924    $self->_set_index_metadata(@_);  
    904925    }    
    905926 
     
    915936{ 
    916937    my $self = shift @_; 
     938 
     939    my $where = $self->{'where'}; 
     940    if(!$where) {    
     941    $self->set_index_metadata_array(@_); # default behaviour is the full version of set_index_meta_array 
     942    return; 
     943    } 
    917944 
    918945    my $username  = $self->{'username'}; 
    919946    my $collect   = $self->{'collect'}; 
    920947    my $gsdl_cgi  = $self->{'gsdl_cgi'}; 
    921     my $gsdlhome  = $self->{'gsdlhome'}; 
    922948 
    923949    if ($baseaction::authentication_enabled) { 
     
    926952    } 
    927953 
     954    # Not sure if the checked_chdir is necessary, since lock_collection also does a chdir 
     955    # But including the stmt during this code reorganisation to preserve as-is what used to happen 
     956    my $site = $self->{'site'}; 
     957    my $collect_dir = $gsdl_cgi->get_collection_dir($site); 
     958    $gsdl_cgi->checked_chdir($collect_dir); 
     959 
     960    # Make sure the collection isn't locked by someone else 
     961    $self->lock_collection($username, $collect); 
     962 
     963    if($where =~ m/import/) { 
     964    $self->_set_import_metadata_array(@_); 
     965    } 
     966    if($where =~ m/archives/) { 
     967    $self->_set_archives_metadata_array(@_); 
     968    } 
     969    if($where =~ m/index/) { 
     970    $self->_set_index_metadata_array(@_); 
     971    } 
     972    if($where =~ m/live/) { 
     973        $self->_set_live_metadata_array(@_); 
     974    } 
     975 
     976    # Release the lock once it is done 
     977    $self->unlock_collection($username, $collect); 
     978} 
     979 
     980sub _set_index_metadata_array 
     981{ 
     982    my $self = shift @_; 
     983 
     984    my $collect   = $self->{'collect'}; 
     985    my $gsdl_cgi  = $self->{'gsdl_cgi'}; 
     986    my $site = $self->{'site'}; 
     987    my $collect_dir = $gsdl_cgi->get_collection_dir($site); 
     988 
     989     
     990    # look up additional args 
     991     
     992    my $infodbtype = $self->{'infodbtype'}; 
     993     
     994    my $json_str      = $self->{'json'}; 
     995    my $doc_array = decode_json $json_str; 
     996     
     997     
     998    my $global_status = 0; 
     999    my $global_mess = ""; 
     1000     
     1001    my @all_docids = (); 
     1002     
     1003    foreach my $doc_array_rec ( @$doc_array ) { 
     1004     
     1005    my $status = -1; 
     1006    my $docid     = $doc_array_rec->{'docid'}; 
     1007     
     1008    push(@all_docids,$docid); 
     1009 
     1010    my $metaname  = $doc_array_rec->{'metaname'}; 
     1011    if(defined $metaname) { 
     1012        my $metapos   = $doc_array_rec->{'metapos'}; 
     1013        my $metavalue = $doc_array_rec->{'metavalue'}; 
     1014        my $metamode = $doc_array_rec->{'metamode'} || $self->{'metamode'}; 
     1015 
     1016        $status = $self->set_index_metadata_entry($collect_dir,$collect,$infodbtype,$docid,$metaname,$metapos,$metavalue,$metamode); 
     1017    } elsif (defined $doc_array_rec->{'metatable'}) { # if no metaname, we expect a metatable 
     1018        my $metatable = $doc_array_rec->{'metatable'}; # a subarray, or need to generate an error saying JSON structure is wrong 
     1019         
     1020        foreach my $metatable_rec ( @$metatable ) { # the subarray metatable is an array of hashmaps 
     1021        $metaname  = $metatable_rec->{'metaname'}; 
     1022        my $metamode  = $metatable_rec->{'metamode'} || $doc_array_rec->{'metamode'} || $self->{'metamode'}; 
     1023        my $metapos = undef; 
     1024        my $metavals = $metatable_rec->{'metavals'}; # a sub-subarray 
     1025 
     1026        foreach my $metavalue ( @$metavals ) { # metavals is an array 
     1027            $status = $self->set_index_metadata_entry($collect_dir,$collect,$infodbtype,$docid,$metaname,$metapos,$metavalue,$metamode); # how do we use metamode in set_meta_entry? 
     1028            if($metamode eq "override") { # now, having overridden the metavalue for the first,  
     1029            # need to accumulate subsequent metavals for this metaname, else the just-assigned 
     1030            # metavalue for this metaname will be lost 
     1031            $metamode = "accumulate"; 
     1032            } 
     1033        }            
     1034        } 
     1035    } 
     1036     
     1037    if ($status != 0) { 
     1038        # Catch error if set infodb entry failed 
     1039        $global_status = $status; 
     1040        $global_mess .= "Failed to set metadata key: $docid\n"; 
     1041        $global_mess .= "Exit status: $status\n"; 
     1042        $global_mess .= "System Error Message: $!\n"; 
     1043        $global_mess .= "-" x 20; 
     1044    } 
     1045    } 
     1046     
     1047    if ($global_status != 0) { 
     1048    $global_mess .= "PATH: $ENV{'PATH'}\n"; 
     1049    $gsdl_cgi->generate_error($global_mess); 
     1050    } 
     1051    else { 
     1052    my $mess = "set-metadata-array successful: Keys[ ".join(", ",@all_docids)."]\n"; 
     1053    $gsdl_cgi->generate_ok_message($mess); 
     1054    } 
     1055} 
     1056 
     1057sub set_index_metadata_array 
     1058{ 
     1059    my $self = shift @_; 
     1060 
     1061    my $username  = $self->{'username'}; 
     1062    my $collect   = $self->{'collect'}; 
     1063    my $gsdl_cgi  = $self->{'gsdl_cgi'}; 
     1064#    my $gsdlhome  = $self->{'gsdlhome'}; 
     1065 
     1066    if ($baseaction::authentication_enabled) { 
     1067    # Ensure the user is allowed to edit this collection 
     1068    &authenticate_user($gsdl_cgi, $username, $collect); 
     1069    } 
     1070 
    9281071    my $site = $self->{'site'}; 
    9291072    my $collect_dir = $gsdl_cgi->get_collection_dir($site); 
     
    9371080    $self->lock_collection($username, $collect); 
    9381081 
     1082    $self->_set_index_metadata_array(@_); 
     1083 
     1084    # Release the lock once it is done 
     1085    $self->unlock_collection($username, $collect); 
     1086} 
     1087 
     1088# experimental, newly added in and untested 
     1089sub _set_live_metadata_array 
     1090{ 
     1091    my $self = shift @_; 
     1092 
     1093    my $collect   = $self->{'collect'}; 
     1094    my $gsdl_cgi  = $self->{'gsdl_cgi'}; 
     1095 
     1096    my $site = $self->{'site'}; 
     1097    my $collect_dir = $gsdl_cgi->get_collection_dir($site); 
     1098 
     1099     
    9391100    # look up additional args 
    940      
    941     my $infodbtype = $self->{'infodbtype'}; 
    942      
    943     my $json_str      = $self->{'json'}; 
    944     my $doc_array = decode_json $json_str; 
    945      
    946      
    947     my $global_status = 0; 
    948     my $global_mess = ""; 
    949      
    950     my @all_docids = (); 
    951      
    952     foreach my $doc_array_rec ( @$doc_array ) { 
    953          
    954         my $docid     = $doc_array_rec->{'docid'}; 
    955         my $metaname  = $doc_array_rec->{'metaname'}; 
    956         my $metapos   = $doc_array_rec->{'metapos'}; 
    957         my $metavalue = $doc_array_rec->{'metavalue'}; 
    958          
    959         push(@all_docids,$docid); 
    960          
    961         my $status = $self->set_metadata_entry($collect_dir,$collect,$infodbtype,$docid,$metaname,$metapos,$metavalue);  
    962          
    963         if ($status != 0) { 
    964             # Catch error if set infodb entry failed 
    965             $global_status = $status; 
    966             $global_mess .= "Failed to set metadata key: $docid\n"; 
    967             $global_mess .= "Exit status: $status\n"; 
    968             $global_mess .= "System Error Message: $!\n"; 
    969             $global_mess .= "-" x 20; 
     1101    my $infodbtype = $self->{'infodbtype'}; 
     1102    # To people who know $collect_tail please add some comments 
     1103    # Obtain path to the database 
     1104    my $collect_tail = $collect; 
     1105    $collect_tail =~ s/^.*[\/\\]//; 
     1106    my $index_text_directory = &util::filename_cat($collect_dir,$collect,"index","text"); 
     1107    my $infodb_file_path = &dbutil::get_infodb_file_path($infodbtype, "live-$collect_tail", $index_text_directory); 
     1108 
     1109     
     1110    my $json_str      = $self->{'json'}; 
     1111    my $doc_array = decode_json $json_str; 
     1112     
     1113     
     1114    my $global_status = 0; 
     1115    my $global_mess = ""; 
     1116     
     1117    my @all_docids = (); 
     1118 
     1119 
     1120    foreach my $doc_array_rec ( @$doc_array ) { 
     1121     
     1122    my $status = -1; 
     1123    my $docid     = $doc_array_rec->{'docid'}; 
     1124 
     1125    push(@all_docids,$docid); 
     1126 
     1127    my $metaname  = $doc_array_rec->{'metaname'}; 
     1128    if(defined $metaname) { 
     1129        my $dbkey = "$docid.$metaname"; 
     1130        my $metavalue = $doc_array_rec->{'metavalue'}; 
     1131        # no metapos for live_meta, so can default metamode to accumulate 
     1132        my $metamode  = $doc_array_rec->{'metamode'} || $self->{'metamode'} || "accumulate"; 
     1133     
     1134        my $append_or_not = ($metamode eq "accumulate") ? " \"append\"" : ""; 
     1135 
     1136        # Set the new value 
     1137        my $cmd = "gdbmset \"$infodb_file_path\" \"$dbkey\" \"$metavalue\"$append_or_not"; 
     1138        $status = system($cmd); 
     1139 
     1140    } elsif (defined $doc_array_rec->{'metatable'}) { # if no metaname, we expect a metatable 
     1141        my $metatable = $doc_array_rec->{'metatable'}; # a subarray, or need to generate an error saying JSON structure is wrong 
     1142        foreach my $metatable_rec ( @$metatable ) { 
     1143        $metaname  = $metatable_rec->{'metaname'}; 
     1144        my $metamode = $metatable_rec->{'metamode'} || $doc_array_rec->{'metamode'} || $self->{'metamode'} || "accumulate"; 
     1145        my $append_or_not = ($metamode eq "accumulate") ? " \"append\"" : ""; 
     1146        my $dbkey = "$docid.$metaname"; 
     1147 
     1148        my $metavals = $metatable_rec->{'metavals'}; # a sub-subarray 
     1149        foreach my $metavalue ( @$metavals ) { 
     1150             my $cmd = "gdbmset \"$infodb_file_path\" \"$dbkey\" \"$metavalue\"$append_or_not"; 
     1151             $status = system($cmd); 
     1152             $append_or_not = " \"append\"";  # even if metamode=override, need to accumulate all subsequent  
     1153             # metavals for this metaname, else the just-assigned metavalue for this metaname will be lost 
    9701154        } 
    971     } 
    972  
    973     if ($global_status != 0) { 
    974         $global_mess .= "PATH: $ENV{'PATH'}\n"; 
    975         $gsdl_cgi->generate_error($global_mess); 
     1155        } 
     1156         
     1157    } 
     1158 
     1159    if ($status != 0) { 
     1160        # Catch error if gdbmget failed 
     1161        $global_status = $status; 
     1162        $global_mess .= "Failed to set metadata key: $docid\n"; # $dbkey 
     1163        $global_mess .= "Exit status: $status\n"; 
     1164        $global_mess .= "System Error Message: $!\n"; 
     1165        $global_mess .= "-" x 20; 
     1166    } 
     1167    } 
     1168     
     1169    if ($global_status != 0) { 
     1170    $global_mess .= "PATH: $ENV{'PATH'}\n"; 
     1171    $gsdl_cgi->generate_error($global_mess); 
    9761172    } 
    9771173    else { 
    978         my $mess = "set-metadata-array successful: Keys[ ".join(", ",@all_docids)."]\n"; 
    979         $gsdl_cgi->generate_ok_message($mess); 
    980     } 
    981      
     1174    my $mess = "set-live-metadata-array successful: Keys[ ".join(", ",@all_docids)."]\n"; 
     1175    $gsdl_cgi->generate_ok_message($mess); 
     1176    } 
     1177} 
     1178 
     1179sub set_live_metadata_array 
     1180{ 
     1181    my $self = shift @_; 
     1182 
     1183    my $username  = $self->{'username'}; 
     1184    my $collect   = $self->{'collect'}; 
     1185    my $gsdl_cgi  = $self->{'gsdl_cgi'}; 
     1186 
     1187    if ($baseaction::authentication_enabled) { 
     1188    # Ensure the user is allowed to edit this collection 
     1189    &authenticate_user($gsdl_cgi, $username, $collect); 
     1190    } 
     1191 
     1192    my $site = $self->{'site'}; 
     1193    my $collect_dir = $gsdl_cgi->get_collection_dir($site); 
     1194     
     1195    $gsdl_cgi->checked_chdir($collect_dir); 
     1196 
     1197    # Make sure the collection isn't locked by someone else 
     1198    $self->lock_collection($username, $collect); 
     1199 
     1200    $self->_set_live_metadata_array(@_); 
     1201 
    9821202    # Release the lock once it is done 
    9831203    $self->unlock_collection($username, $collect); 
     
    13211541    $self->remove_from_doc_xml($gsdl_cgi, &util::filename_cat($archive_dir, $doc_xml_file), $metaname, $metapos, undef, $docid_secnum, $metamode); 
    13221542    } 
    1323      
     1543 
    13241544    # Edit the doc.xml file with the specified metadata name, value and position. 
    13251545    # TODO: there is a potential problem here as this edit_doc_xml function  
     
    13271547    # Running import.pl -groupsize will cause this to have multiple sections in one doc.xml 
    13281548     
     1549    # dxml_metadata method ignores metapos if metamode anything other than override 
    13291550    $self->edit_doc_xml($gsdl_cgi,$doc_xml_filename, 
    13301551            $metaname,$metavalue,$metapos,$metamode,$docid_secnum,$prevmetavalue); 
     
    13441565     
    13451566    if ($baseaction::authentication_enabled) { 
    1346         # Ensure the user is allowed to edit this collection 
    1347         $self->authenticate_user($username, $collect); 
     1567    # Ensure the user is allowed to edit this collection 
     1568    $self->authenticate_user($username, $collect); 
    13481569    } 
    13491570 
     
    13571578} 
    13581579 
     1580sub _set_archives_metadata_array 
     1581{ 
     1582    my $self = shift @_; 
     1583     
     1584    my $collect   = $self->{'collect'}; 
     1585    my $gsdl_cgi  = $self->{'gsdl_cgi'}; 
     1586    my $site = $self->{'site'}; 
     1587    my $collect_dir = $gsdl_cgi->get_collection_dir($site); 
     1588 
     1589    # look up additional args 
     1590     
     1591    my $infodbtype = $self->{'infodbtype'}; 
     1592     
     1593    my $archive_dir = &util::filename_cat($collect_dir,$collect,"archives"); 
     1594     
     1595    my $json_str      = $self->{'json'}; 
     1596    my $doc_array = decode_json $json_str; 
     1597     
     1598     
     1599    my $global_status = 0; 
     1600    my $global_mess = ""; 
     1601     
     1602    my @all_docids = (); 
     1603     
     1604    foreach my $doc_array_rec ( @$doc_array ) { 
     1605    my $status    = -1; 
     1606    my $docid     = $doc_array_rec->{'docid'}; 
     1607 
     1608    push(@all_docids,$docid); 
     1609     
     1610    my $metaname  = $doc_array_rec->{'metaname'}; 
     1611    if(defined $metaname) { 
     1612         
     1613        my $metapos   = $doc_array_rec->{'metapos'} || 0; 
     1614        my $metamode  = $doc_array_rec->{'metamode'} || $self->{'metamode'}; 
     1615        my $metavalue = $doc_array_rec->{'metavalue'}; 
     1616        my $prevmetavalue = $self->{'prevmetavalue'}; # to make this sub behave as _set_archives_metadata 
     1617         
     1618        # Some sanity checks 
     1619        $metapos = 0 if (!defined $metapos); 
     1620         
     1621        if ((!defined $metamode) || ($metamode =~ m/^\s*$/)) { 
     1622        # make "accumulate" the default (less destructive, as it won't actually  
     1623        # delete any existing values) 
     1624        $metamode = "accumulate"; 
     1625        }        
     1626         
     1627        $status = $self->set_archives_metadata_entry($gsdl_cgi,$archive_dir, $collect_dir,$collect, $infodbtype,$docid, 
     1628                $metaname,$metapos,$metavalue,$metamode,$prevmetavalue); 
     1629    } elsif (defined $doc_array_rec->{'metatable'}) { # if no metaname, we expect a metatable 
     1630        my $metatable = $doc_array_rec->{'metatable'}; # a subarray, or need to generate an error saying JSON structure is wrong 
     1631         
     1632        foreach my $metatable_rec ( @$metatable ) { 
     1633        $metaname  = $metatable_rec->{'metaname'}; 
     1634        my $metamode  = $metatable_rec->{'metamode'} || $doc_array_rec->{'metamode'} || $self->{'metamode'}; 
     1635        my $metapos = undef; 
     1636        my $prevmetavalue = undef; 
     1637        my $metavals = $metatable_rec->{'metavals'}; # a sub-subarray 
     1638         
     1639        foreach my $metavalue ( @$metavals ) { 
     1640            $status = $self->set_archives_metadata_entry($gsdl_cgi,$archive_dir, $collect_dir,$collect,$infodbtype, 
     1641                                 $docid,$metaname,$metapos,$metavalue,$metamode,$prevmetavalue); 
     1642             
     1643            if($metamode eq "override") { # now, having overridden the metavalue for the first,  
     1644            # need to accumulate subsequent metavals for this metaname, else the just-assigned 
     1645            # metavalue for this metaname will be lost 
     1646            $metamode = "accumulate"; 
     1647            } 
     1648        }            
     1649        }        
     1650    } 
     1651         
     1652    if ($status != 0) { 
     1653        # Catch error if set infodb entry failed 
     1654        $global_status = $status; 
     1655        $global_mess .= "Failed to set metadata key: $docid\n"; 
     1656        $global_mess .= "Exit status: $status\n"; 
     1657        $global_mess .= "System Error Message: $!\n"; 
     1658        $global_mess .= "-" x 20 . "\n"; 
     1659    } 
     1660    } 
     1661     
     1662    if ($global_status != 0) { 
     1663    $global_mess .= "PATH: $ENV{'PATH'}\n"; 
     1664    $gsdl_cgi->generate_error($global_mess); 
     1665    } 
     1666    else { 
     1667    my $mess = "set-archives-metadata-array successful: Keys[ ".join(", ",@all_docids)."]\n"; 
     1668    $gsdl_cgi->generate_ok_message($mess); 
     1669    } 
     1670} 
    13591671 
    13601672sub set_archives_metadata_array 
     
    13651677    my $collect   = $self->{'collect'}; 
    13661678    my $gsdl_cgi  = $self->{'gsdl_cgi'}; 
    1367     my $gsdlhome  = $self->{'gsdlhome'}; 
     1679#    my $gsdlhome  = $self->{'gsdlhome'}; 
    13681680 
    13691681    if ($baseaction::authentication_enabled) { 
     
    13831695    $self->lock_collection($username, $collect); 
    13841696 
    1385     # look up additional args 
    1386      
    1387     my $infodbtype = $self->{'infodbtype'}; 
    1388  
    1389    my $archive_dir = &util::filename_cat($collect_dir,$collect,"archives"); 
    1390      
    1391     my $json_str      = $self->{'json'}; 
    1392     my $doc_array = decode_json $json_str; 
    1393      
    1394      
    1395     my $global_status = 0; 
    1396     my $global_mess = ""; 
    1397      
    1398     my @all_docids = (); 
    1399      
    1400     foreach my $doc_array_rec ( @$doc_array ) { 
    1401          
    1402         my $docid     = $doc_array_rec->{'docid'}; 
    1403         my $metaname  = $doc_array_rec->{'metaname'}; 
    1404         my $metapos   = $doc_array_rec->{'metapos'}; 
    1405         my $metamode   = $self->{'metamode'}; 
    1406         my $metavalue = $doc_array_rec->{'metavalue'}; 
    1407          
    1408         # Some sanity checks 
    1409         $metapos = 0 if (!defined $metapos); 
    1410              
    1411         if ((!defined $metamode) || ($metamode =~ m/^\s*$/)) { 
    1412             # make "accumulate" the default (less destructive, as won't actually  
    1413             # delete any existing values) 
    1414             $metamode = "accumulate"; 
    1415         }  
    1416      
    1417         push(@all_docids,$docid); 
    1418          
    1419         my $status = $self->set_archives_metadata_entry($gsdl_cgi,$archive_dir, $collect_dir,$collect, $infodbtype,$docid, 
    1420                 $metaname,$metapos,$metavalue,$metamode); 
    1421          
    1422         if ($status != 0) { 
    1423             # Catch error if set infodb entry failed 
    1424             $global_status = $status; 
    1425             $global_mess .= "Failed to set metadata key: $docid\n"; 
    1426             $global_mess .= "Exit status: $status\n"; 
    1427             $global_mess .= "System Error Message: $!\n"; 
    1428             $global_mess .= "-" x 20 . "\n"; 
    1429         } 
    1430     } 
    1431  
    1432     if ($global_status != 0) { 
    1433         $global_mess .= "PATH: $ENV{'PATH'}\n"; 
    1434         $gsdl_cgi->generate_error($global_mess); 
    1435     } 
    1436     else { 
    1437         my $mess = "set-archives-metadata-array successful: Keys[ ".join(", ",@all_docids)."]\n"; 
    1438         $gsdl_cgi->generate_ok_message($mess); 
    1439     } 
     1697    $self->_set_archives_metadata_array(@_); 
    14401698     
    14411699    # Release the lock once it is done 
     
    14641722    my $metaname = $self->{'metaname'}; 
    14651723    my $metapos = $self->{'metapos'}; 
     1724 
    14661725    my $metavalue = $self->{'metavalue'} || undef; # necessary to force fallback to undef here 
    14671726 
     
    14761735    } 
    14771736 
    1478     my $metamode = $self->{'metamode'} || undef;     
    1479      
     1737    my $metamode = $self->{'metamode'} || undef; 
     1738 
    14801739    my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir); 
    14811740    my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid); 
     
    16061865            $parser->{'parameters'}->{'poscount'}++; 
    16071866        } 
    1608  
     1867         
    16091868        # if overriding but no metapos, then clear all the meta for this metaname 
    16101869        if ((defined $parser->{'parameters'}->{'metamode'}) && ($parser->{'parameters'}->{'metamode'} eq "override") && (!defined $parser->{'parameters'}->{'metapos'})) {           
     
    16121871        } 
    16131872    } 
    1614      
     1873 
    16151874    if ((defined $parser->{'parameters'}->{'metapos'}) && ($parser->{'parameters'}->{'metaname'} eq $attrHash->{'name'}) && ($parser->{'parameters'}->{'poscount'} == $parser->{'parameters'}->{'metapos'})) 
    16161875    {    
    16171876        return []; 
    16181877    } 
    1619      
     1878 
    16201879    if ((defined $parser->{'parameters'}->{'metavalue'}) && ($parser->{'parameters'}->{'metaname'} eq $attrHash->{'name'}) && ($parser->{'parameters'}->{'metavalue'} eq $attrHash->{'_content'})) 
    16211880    {    
     
    18662125sub set_import_metadata_array 
    18672126{ 
    1868     my $self = shift @_; 
     2127    my $self = shift @_; 
    18692128 
    18702129    my $username  = $self->{'username'}; 
    18712130    my $collect   = $self->{'collect'}; 
    18722131    my $gsdl_cgi  = $self->{'gsdl_cgi'}; 
    1873     my $gsdlhome  = $self->{'gsdlhome'}; 
     2132#    my $gsdlhome  = $self->{'gsdlhome'}; 
    18742133 
    18752134    if ($baseaction::authentication_enabled) { 
    1876         # Ensure the user is allowed to edit this collection 
    1877         &authenticate_user($gsdl_cgi, $username, $collect); 
    1878     } 
    1879  
    1880     my $site = $self->{'site'}; 
    1881     my $collect_dir = $gsdl_cgi->get_collection_dir($site); 
    1882      
     2135    # Ensure the user is allowed to edit this collection 
     2136    &authenticate_user($gsdl_cgi, $username, $collect); 
     2137    } 
     2138 
     2139    my $site = $self->{'site'}; 
     2140    my $collect_dir = $gsdl_cgi->get_collection_dir($site); 
     2141     
    18832142    $gsdl_cgi->checked_chdir($collect_dir); 
    18842143 
     
    18862145    $self->lock_collection($username, $collect); 
    18872146 
    1888     # look up additional args 
    1889      
    1890     my $infodbtype = $self->{'infodbtype'}; 
    1891  
    1892     my $archive_dir = &util::filename_cat($collect_dir,$collect,"archives"); 
    1893      
    1894     my $json_str = $self->{'json'}; 
    1895     my $doc_array = decode_json $json_str; 
    1896      
    1897     my $global_status = 0; 
    1898     my $global_mess = ""; 
    1899      
    1900     my @all_docids = (); 
    1901      
    1902     foreach my $doc_array_rec ( @$doc_array )  
    1903     {    
    1904         my $docid = $doc_array_rec->{'docid'}; 
    1905         my $metaname = $doc_array_rec->{'metaname'}; 
    1906         my $metamode = $self->{'metamode'}; 
    1907         my $metavalue = $doc_array_rec->{'metavalue'}; 
    1908  
    1909         if ((!defined $metamode) || ($metamode =~ m/^\s*$/)) { 
    1910             # make "accumulate" the default (less destructive, as won't actually  
    1911             # delete any existing values) 
    1912             $metamode = "accumulate"; 
    1913         }  
    1914  
    1915         push(@all_docids,$docid); 
    1916  
    1917         # Obtain where the metadata.xml is from the archiveinfo-doc.gdb file 
    1918         # If the doc oid is not specified, we assume the metadata.xml is next to the specified "f" 
    1919         my $metadata_xml_file; 
    1920         my $import_filename = undef; 
    1921  
    1922         my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir); 
    1923         my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid); 
    1924  
    1925         # This now stores the full pathname 
    1926         $import_filename = $doc_rec->{'src-file'}->[0];  
    1927  
    1928         # figure out correct metadata.xml file [?] 
    1929         # Assuming the metadata.xml file is next to the source file 
    1930         # Note: This will not work if it is using the inherited metadata from the parent folder 
    1931         my ($import_tailname, $import_dirname) = File::Basename::fileparse($import_filename); 
    1932         my $metadata_xml_filename = &util::filename_cat($import_dirname,"metadata.xml"); 
    1933  
    1934         $self->edit_metadata_xml($gsdl_cgi, $metadata_xml_filename, $metaname, $metavalue, $metamode, $import_tailname); 
    1935     } 
    1936  
    1937     my $mess = "set-archives-metadata-array successful: Keys[ ".join(", ",@all_docids)."]\n"; 
    1938     $gsdl_cgi->generate_ok_message($mess); 
    1939      
     2147    $self->_set_import_metadata_array(@_); 
     2148 
    19402149    # Release the lock once it is done 
    19412150    $self->unlock_collection($username, $collect); 
     2151 
     2152} 
     2153 
     2154 
     2155sub _set_import_metadata_array 
     2156{ 
     2157    my $self = shift @_; 
     2158 
     2159    my $collect   = $self->{'collect'}; 
     2160    my $gsdl_cgi  = $self->{'gsdl_cgi'}; 
     2161 
     2162    my $site = $self->{'site'}; 
     2163    my $collect_dir = $gsdl_cgi->get_collection_dir($site); 
     2164     
     2165    # look up additional args 
     2166     
     2167    my $infodbtype = $self->{'infodbtype'}; 
     2168     
     2169    my $archive_dir = &util::filename_cat($collect_dir,$collect,"archives");     
     2170    my $arcinfo_doc_filename = &dbutil::get_infodb_file_path($infodbtype, "archiveinf-doc", $archive_dir); 
     2171     
     2172    my $json_str = $self->{'json'}; 
     2173    my $doc_array = decode_json $json_str; 
     2174     
     2175    my $global_status = 0; 
     2176    my $global_mess = ""; 
     2177     
     2178    my @all_docids = (); 
     2179     
     2180    foreach my $doc_array_rec ( @$doc_array )  
     2181    { 
     2182    my $status = -1; 
     2183    my $docid = $doc_array_rec->{'docid'}; 
     2184     
     2185    push(@all_docids,$docid); 
     2186     
     2187    my $metaname = $doc_array_rec->{'metaname'}; 
     2188    if (defined $metaname) { 
     2189        my $metamode = $doc_array_rec->{'metamode'} || $self->{'metamode'}; 
     2190        my $metavalue = $doc_array_rec->{'metavalue'}; 
     2191         
     2192        if ((!defined $metamode) || ($metamode =~ m/^\s*$/)) { 
     2193        # make "accumulate" the default (less destructive, as won't actually  
     2194        # delete any existing values) 
     2195        $metamode = "accumulate"; 
     2196        } 
     2197         
     2198        $self->set_import_metadata_entry($gsdl_cgi, $arcinfo_doc_filename, $infodbtype, $docid, $metaname, $metavalue, $metamode); 
     2199         
     2200    } elsif (defined $doc_array_rec->{'metatable'}) { # if no metaname, we expect a metatable 
     2201        my $metatable = $doc_array_rec->{'metatable'}; # a subarray, or need to generate an error saying JSON structure is wrong 
     2202         
     2203        foreach my $metatable_rec ( @$metatable ) { 
     2204        $metaname  = $metatable_rec->{'metaname'};  
     2205        my $metamode  = $metatable_rec->{'metamode'} || $doc_array_rec->{'metamode'} || $self->{'metamode'}; 
     2206        if ((!defined $metamode) || ($metamode =~ m/^\s*$/)) { 
     2207            # make "accumulate" the default (less destructive, as won't actually  
     2208            # delete any existing values) 
     2209            $metamode = "accumulate"; 
     2210        } 
     2211        # no metapos for import 
     2212        my $metavals = $metatable_rec->{'metavals'}; # a sub-subarray 
     2213         
     2214        foreach my $metavalue ( @$metavals ) { 
     2215            $self->set_import_metadata_entry($gsdl_cgi, $arcinfo_doc_filename, $infodbtype, $docid, $metaname, $metavalue, $metamode); 
     2216            if($metamode eq "override") { # now, having overridden the first metavalue of the metaname,  
     2217            # need to accumulate subsequent metavals for this metaname, else the just-assigned 
     2218            # metavalue for this metaname will be lost 
     2219            $metamode = "accumulate"; 
     2220            } 
     2221        } 
     2222        } 
     2223    }        
     2224    } 
     2225 
     2226    # always a success message 
     2227    my $mess = "set-archives-metadata-array successful: Keys[ ".join(", ",@all_docids)."]\n"; 
     2228    $gsdl_cgi->generate_ok_message($mess); 
     2229} 
     2230 
     2231# always returns true (1) 
     2232sub set_import_metadata_entry 
     2233{ 
     2234    my $self = shift @_; 
     2235    my ($gsdl_cgi, $arcinfo_doc_filename, $infodbtype, $docid, $metaname, $metavalue, $metamode) = @_; 
     2236 
     2237    # Obtain where the metadata.xml is from the archiveinfo-doc.gdb file 
     2238    # If the doc oid is not specified, we assume the metadata.xml is next to the specified "f" 
     2239    my $metadata_xml_file; 
     2240    my $import_filename = undef; 
     2241     
     2242    my $doc_rec = &dbutil::read_infodb_entry($infodbtype, $arcinfo_doc_filename, $docid); 
     2243 
     2244    # This now stores the full pathname 
     2245    $import_filename = $doc_rec->{'src-file'}->[0];  
     2246     
     2247    # figure out correct metadata.xml file [?] 
     2248    # Assuming the metadata.xml file is next to the source file 
     2249    # Note: This will not work if it is using the inherited metadata from the parent folder 
     2250    my ($import_tailname, $import_dirname) = File::Basename::fileparse($import_filename); 
     2251    my $metadata_xml_filename = &util::filename_cat($import_dirname,"metadata.xml"); 
     2252     
     2253    $self->edit_metadata_xml($gsdl_cgi, $metadata_xml_filename, $metaname, $metavalue, $metamode, $import_tailname); 
     2254    return 1; 
    19422255} 
    19432256 
     
    19482261    my $collect   = $self->{'collect'}; 
    19492262    my $gsdl_cgi  = $self->{'gsdl_cgi'}; 
    1950     my $gsdlhome  = $self->{'gsdlhome'}; 
     2263#   my $gsdlhome  = $self->{'gsdlhome'}; 
    19512264    my $infodbtype = $self->{'infodbtype'}; 
    19522265     
     
    22632576        $metapos = 0; 
    22642577    } 
     2578     
    22652579 
    22662580    # consider check key is defined before deleting?