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