FileSequenceList.pm (c9b362f6) | FileSequenceList.pm (9f91b7e3) |
---|---|
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 --- 7 unchanged lines hidden (view full) --- 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 | 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 --- 7 unchanged lines hidden (view full) --- 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 XML::LibXML; | |
25use strict; 26 27=head1 NAME 28 29 FileSequenceList.pm - Class for retrieving and processing the 'Sequence' values of the MSI 'File' table. 30 31=cut 32 --- 12 unchanged lines hidden (view full) --- 45 bless($self, $class); 46 47 return $self; 48} 49 50 51 52 | 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 --- 12 unchanged lines hidden (view full) --- 44 bless($self, $class); 45 46 return $self; 47} 48 49 50 51 |
53sub SetFromFileList ($$) | 52sub SetFromMap ($$) |
54{ | 53{ |
55 my ($self, $files) = @_; | 54 my ($self, $map) = @_; |
56 | 55 |
57 my %data = map {$_->{'uniquename'} => $_->{'sequencenumber'}} @$files; 58 $self->{'data'} = \%data; | 56 $self->{'data'} = $map; |
59} 60 61 62 63 | 57} 58 59 60 61 |
64sub SetFromMap ($$) | 62sub SetFromMsi ($$) |
65{ | 63{ |
66 my ($self, $map) = @_; | 64 my ($self, $msi) = @_; |
67 | 65 |
68 $self->{'data'} = $map; | 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; |
69} 70 71 72 73 74sub GetFileCount ($) 75{ 76 my ($self) = @_; 77 78 return scalar keys %{$self->{'data'}}; 79} 80 81 82 83 | 99} 100 101 102 103 104sub GetFileCount ($) 105{ 106 my ($self) = @_; 107 108 return scalar keys %{$self->{'data'}}; 109} 110 111 112 113 |
84=head2 GetSequenceNumbers ($files) 85 86 $files is a hash that maps unique file names (File->File) to sequence 87 numbers (File->Sequence). The later is (expected to be) initially unset and 88 is set in this method. 89 90 For new files -- entries in the given $files that do not exist in the 'data' 91 member -- no sequence numbers are defined. 92 93 When there are removed files -- entries in the 'data' member that do not 94 exist in the given $files -- then a list of these files is returned. In 95 that case the given $files remain unmodified. 96 97 The returned list is empty when everyting is OK. 98 99=cut 100sub GetSequenceNumbers ($$) | 114sub get_removed_files ($@) |
101{ | 115{ |
102 my ($self, $files) = @_; | 116 my ($self, $target_unique_names) = @_; |
103 | 117 |
118 my %uniquename_to_row_map = map{$_->{'uniquename'} => $_->{'row'}} values %{$self->{'data'}}; 119 |
|
104 # Check if files have been removed. 105 my @missing = (); | 120 # Check if files have been removed. 121 my @missing = (); |
106 foreach my $name (keys %{$self->{'data'}}) | 122 foreach my $item (values %{$self->{'data'}}) |
107 { | 123 { |
108 if ( ! defined $files->{$name}) | 124 my ($uniquename, $row) = ($item->{'uniquename'}, $item->{'row'}); 125 if ( ! defined $target_unique_names->{$uniquename}) |
109 { | 126 { |
110 push @missing, $name; | 127 # $name is defined in source but not in target => it has been removed. 128 push @missing, $row; |
111 } 112 } | 129 } 130 } |
113 if (scalar @missing > 0) 114 { 115 # Yes. Return the names of the removed files. 116 return @missing; 117 } 118 119 # No files where removed. Set the sequence numbers. 120 foreach my $name (keys %$files) 121 { 122 $files->{$name} = $self->{'data'}->{$name}; 123 } 124 return (); | 131 return @missing; |
125} 126 127 128 129 | 132} 133 134 135 136 |
130sub GetDifference ($$) | 137sub get_sequence_and_unique_name($$) |
131{ | 138{ |
132 my ($self, $other) = @_; | 139 my ($self, $source_path) = @_; |
133 | 140 |
134 # Create maps for easy reference. 135 my (@files_in_both, @files_in_self, @files_in_other); 136 foreach my $name (keys %{$self->{'data'}}) | 141 my $sequence_and_unique_name = $self->{'data'}->{$source_path}; 142 if ( ! defined $sequence_and_unique_name) |
137 { | 143 { |
138 if (defined $other->{'data'}->{$name}) 139 { 140 push @files_in_both, $name; 141 } 142 else 143 { 144 push @files_in_self, $name; 145 } | 144 $installer::logger::Lang->printf("can not find entry for source path '%s'\n", $source_path); 145 return (undef,undef); |
146 } | 146 } |
147 foreach my $name (keys %{$self->{'data'}}) | 147 else |
148 { | 148 { |
149 if ( ! defined $self->{'data'}->{$name}) 150 { 151 push @files_in_other, $name; 152 } | 149 return ( 150 $sequence_and_unique_name->{'sequence'}, 151 $sequence_and_unique_name->{'uniquename'}); |
153 } | 152 } |
154 155 return (\@files_in_both, \@files_in_self, \@files_in_other); | |
156} 157 158 1591; | 153} 154 155 1561; |