1*b1cdbd2cSJim Jagielski#************************************************************** 2*b1cdbd2cSJim Jagielski# 3*b1cdbd2cSJim Jagielski# Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski# or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski# distributed with this work for additional information 6*b1cdbd2cSJim Jagielski# regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski# to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski# "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski# with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski# 11*b1cdbd2cSJim Jagielski# http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski# 13*b1cdbd2cSJim Jagielski# Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski# software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski# KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski# specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski# under the License. 19*b1cdbd2cSJim Jagielski# 20*b1cdbd2cSJim Jagielski#************************************************************** 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielskipackage installer::patch::FileSequenceList; 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielskiuse strict; 25*b1cdbd2cSJim Jagielski 26*b1cdbd2cSJim Jagielski=head1 NAME 27*b1cdbd2cSJim Jagielski 28*b1cdbd2cSJim Jagielski FileSequenceList.pm - Class for retrieving and processing the 'Sequence' values of the MSI 'File' table. 29*b1cdbd2cSJim Jagielski 30*b1cdbd2cSJim Jagielski=cut 31*b1cdbd2cSJim Jagielski 32*b1cdbd2cSJim Jagielski=head2 new($class) 33*b1cdbd2cSJim Jagielski 34*b1cdbd2cSJim Jagielski Create a new FileSequenceList object. 35*b1cdbd2cSJim Jagielski 36*b1cdbd2cSJim Jagielski=cut 37*b1cdbd2cSJim Jagielskisub new ($) 38*b1cdbd2cSJim Jagielski{ 39*b1cdbd2cSJim Jagielski my ($class) = @_; 40*b1cdbd2cSJim Jagielski 41*b1cdbd2cSJim Jagielski my $self = { 42*b1cdbd2cSJim Jagielski 'data' => undef 43*b1cdbd2cSJim Jagielski }; 44*b1cdbd2cSJim Jagielski bless($self, $class); 45*b1cdbd2cSJim Jagielski 46*b1cdbd2cSJim Jagielski return $self; 47*b1cdbd2cSJim Jagielski} 48*b1cdbd2cSJim Jagielski 49*b1cdbd2cSJim Jagielski 50*b1cdbd2cSJim Jagielski 51*b1cdbd2cSJim Jagielski 52*b1cdbd2cSJim Jagielskisub SetFromMap ($$) 53*b1cdbd2cSJim Jagielski{ 54*b1cdbd2cSJim Jagielski my ($self, $map) = @_; 55*b1cdbd2cSJim Jagielski 56*b1cdbd2cSJim Jagielski $self->{'data'} = $map; 57*b1cdbd2cSJim Jagielski} 58*b1cdbd2cSJim Jagielski 59*b1cdbd2cSJim Jagielski 60*b1cdbd2cSJim Jagielski 61*b1cdbd2cSJim Jagielski 62*b1cdbd2cSJim Jagielskisub SetFromMsi ($$) 63*b1cdbd2cSJim Jagielski{ 64*b1cdbd2cSJim Jagielski my ($self, $msi) = @_; 65*b1cdbd2cSJim Jagielski 66*b1cdbd2cSJim Jagielski my $file_table = $msi->GetTable("File"); 67*b1cdbd2cSJim Jagielski my $file_map = $msi->GetFileMap(); 68*b1cdbd2cSJim Jagielski 69*b1cdbd2cSJim Jagielski my $file_column_index = $file_table->GetColumnIndex("File"); 70*b1cdbd2cSJim Jagielski my $filename_column_index = $file_table->GetColumnIndex("FileName"); 71*b1cdbd2cSJim Jagielski my $sequence_column_index = $file_table->GetColumnIndex("Sequence"); 72*b1cdbd2cSJim Jagielski 73*b1cdbd2cSJim Jagielski my %sequence_data = (); 74*b1cdbd2cSJim Jagielski 75*b1cdbd2cSJim Jagielski printf("extracting columns %d and %d from %d rows\n", 76*b1cdbd2cSJim Jagielski $file_column_index, 77*b1cdbd2cSJim Jagielski $sequence_column_index, 78*b1cdbd2cSJim Jagielski $file_table->GetRowCount()); 79*b1cdbd2cSJim Jagielski 80*b1cdbd2cSJim Jagielski foreach my $row (@{$file_table->GetAllRows()}) 81*b1cdbd2cSJim Jagielski { 82*b1cdbd2cSJim Jagielski my $unique_name = $row->GetValue($file_column_index); 83*b1cdbd2cSJim Jagielski my $filename = $row->GetValue($filename_column_index); 84*b1cdbd2cSJim Jagielski my ($long_filename,$short_filename) = installer::patch::Msi::SplitLongShortName($filename); 85*b1cdbd2cSJim Jagielski my $sequence = $row->GetValue($sequence_column_index); 86*b1cdbd2cSJim Jagielski my $directory_item = $file_map->{$unique_name}->{'directory'}; 87*b1cdbd2cSJim Jagielski my $source_path = $directory_item->{'full_source_long_name'}; 88*b1cdbd2cSJim Jagielski my $target_path = $directory_item->{'full_target_long_name'}; 89*b1cdbd2cSJim Jagielski my $key = $source_path ne "" 90*b1cdbd2cSJim Jagielski ? $source_path."/".$long_filename 91*b1cdbd2cSJim Jagielski : $long_filename; 92*b1cdbd2cSJim Jagielski $sequence_data{$key} = { 93*b1cdbd2cSJim Jagielski 'sequence' => $sequence, 94*b1cdbd2cSJim Jagielski 'uniquename' => $unique_name, 95*b1cdbd2cSJim Jagielski 'row' => $row 96*b1cdbd2cSJim Jagielski }; 97*b1cdbd2cSJim Jagielski } 98*b1cdbd2cSJim Jagielski $self->{'data'} = \%sequence_data; 99*b1cdbd2cSJim Jagielski} 100*b1cdbd2cSJim Jagielski 101*b1cdbd2cSJim Jagielski 102*b1cdbd2cSJim Jagielski 103*b1cdbd2cSJim Jagielski 104*b1cdbd2cSJim Jagielskisub GetFileCount ($) 105*b1cdbd2cSJim Jagielski{ 106*b1cdbd2cSJim Jagielski my ($self) = @_; 107*b1cdbd2cSJim Jagielski 108*b1cdbd2cSJim Jagielski return scalar keys %{$self->{'data'}}; 109*b1cdbd2cSJim Jagielski} 110*b1cdbd2cSJim Jagielski 111*b1cdbd2cSJim Jagielski 112*b1cdbd2cSJim Jagielski 113*b1cdbd2cSJim Jagielski 114*b1cdbd2cSJim Jagielskisub get_removed_files ($@) 115*b1cdbd2cSJim Jagielski{ 116*b1cdbd2cSJim Jagielski my ($self, $target_unique_names) = @_; 117*b1cdbd2cSJim Jagielski 118*b1cdbd2cSJim Jagielski my %uniquename_to_row_map = map{$_->{'uniquename'} => $_->{'row'}} values %{$self->{'data'}}; 119*b1cdbd2cSJim Jagielski 120*b1cdbd2cSJim Jagielski # Check if files have been removed. 121*b1cdbd2cSJim Jagielski my @missing = (); 122*b1cdbd2cSJim Jagielski foreach my $item (values %{$self->{'data'}}) 123*b1cdbd2cSJim Jagielski { 124*b1cdbd2cSJim Jagielski my ($uniquename, $row) = ($item->{'uniquename'}, $item->{'row'}); 125*b1cdbd2cSJim Jagielski if ( ! defined $target_unique_names->{$uniquename}) 126*b1cdbd2cSJim Jagielski { 127*b1cdbd2cSJim Jagielski # $name is defined in source but not in target => it has been removed. 128*b1cdbd2cSJim Jagielski push @missing, $row; 129*b1cdbd2cSJim Jagielski } 130*b1cdbd2cSJim Jagielski } 131*b1cdbd2cSJim Jagielski return @missing; 132*b1cdbd2cSJim Jagielski} 133*b1cdbd2cSJim Jagielski 134*b1cdbd2cSJim Jagielski 135*b1cdbd2cSJim Jagielski 136*b1cdbd2cSJim Jagielski 137*b1cdbd2cSJim Jagielskisub get_sequence_and_unique_name($$) 138*b1cdbd2cSJim Jagielski{ 139*b1cdbd2cSJim Jagielski my ($self, $source_path) = @_; 140*b1cdbd2cSJim Jagielski 141*b1cdbd2cSJim Jagielski my $sequence_and_unique_name = $self->{'data'}->{$source_path}; 142*b1cdbd2cSJim Jagielski if ( ! defined $sequence_and_unique_name) 143*b1cdbd2cSJim Jagielski { 144*b1cdbd2cSJim Jagielski $installer::logger::Lang->printf("can not find entry for source path '%s'\n", $source_path); 145*b1cdbd2cSJim Jagielski return (undef,undef); 146*b1cdbd2cSJim Jagielski } 147*b1cdbd2cSJim Jagielski else 148*b1cdbd2cSJim Jagielski { 149*b1cdbd2cSJim Jagielski return ( 150*b1cdbd2cSJim Jagielski $sequence_and_unique_name->{'sequence'}, 151*b1cdbd2cSJim Jagielski $sequence_and_unique_name->{'uniquename'}); 152*b1cdbd2cSJim Jagielski } 153*b1cdbd2cSJim Jagielski} 154*b1cdbd2cSJim Jagielski 155*b1cdbd2cSJim Jagielski 156*b1cdbd2cSJim Jagielski1; 157