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;