ReleasesList.pm (c9b362f6) | ReleasesList.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::ReleasesList; 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::ReleasesList; 23 |
24use XML::LibXML; | 24use XML::Parser; |
25use File::Spec; | 25use File::Spec; |
26 |
|
26use strict; 27 28=head1 NAME 29 30 package installer::patch::ReleasesList - Functions for accessing the instsetoo_native/data/releases.xml file 31 32=cut 33 --- 4 unchanged lines hidden (view full) --- 38 39 Return the singleton instance. 40 41=cut 42sub Instance() 43{ 44 if ( ! defined $Instance) 45 { | 27use strict; 28 29=head1 NAME 30 31 package installer::patch::ReleasesList - Functions for accessing the instsetoo_native/data/releases.xml file 32 33=cut 34 --- 4 unchanged lines hidden (view full) --- 39 40 Return the singleton instance. 41 42=cut 43sub Instance() 44{ 45 if ( ! defined $Instance) 46 { |
46 $Instance = new installer::patch::ReleasesList(); | 47 $Instance = new installer::patch::ReleasesList( 48 File::Spec->catfile($ENV{'SRC_ROOT'}, "instsetoo_native", "data", "releases.xml")); |
47 } 48 return $Instance; 49} 50 51 52 53 | 49 } 50 return $Instance; 51} 52 53 54 55 |
54=head2 new($class) | 56=head2 new($class, $filename) |
55 56 Internal constructor. Don't call. 57 58=cut | 57 58 Internal constructor. Don't call. 59 60=cut |
59sub new ($) | 61sub new ($$) |
60{ | 62{ |
61 my ($class) = @_; | 63 my ($class, $filename) = @_; |
62 | 64 |
63 my $self = {}; | 65 my $self = { 66 'releases' => [] 67 }; |
64 bless($self, $class); 65 | 68 bless($self, $class); 69 |
66 $self->Read(); | 70 71 $self->Read($filename); |
67 | 72 |
73 |
|
68 return $self; 69} 70 71 72 73 74=head2 GetFirstChild ($node, $child_name) 75 --- 6 unchanged lines hidden (view full) --- 82 my ($node, $child_name) = @_; 83 84 if ( ! defined $node) 85 { 86 return undef; 87 } 88 else 89 { | 74 return $self; 75} 76 77 78 79 80=head2 GetFirstChild ($node, $child_name) 81 --- 6 unchanged lines hidden (view full) --- 88 my ($node, $child_name) = @_; 89 90 if ( ! defined $node) 91 { 92 return undef; 93 } 94 else 95 { |
90 my @child_nodes = $node->getElementsByTagName($child_name); 91 if (scalar @child_nodes == 0) | 96 my $value = $node->{$child_name}; 97 if (ref($value) eq 'ARRAY') |
92 { | 98 { |
93 return undef; | 99 return $value->[0]; |
94 } 95 else 96 { | 100 } 101 else 102 { |
97 return $child_nodes[0]; | 103 return $value; |
98 } 99 } 100} 101 102 103 104 105=head2 GetText ($node) 106 107 Internal function that returns the trimmed text content of a node. 108 109=cut | 104 } 105 } 106} 107 108 109 110 111=head2 GetText ($node) 112 113 Internal function that returns the trimmed text content of a node. 114 115=cut |
110sub GetText ($) | 116sub GetText ($;$) |
111{ | 117{ |
112 my ($node) = @_; | 118 my ($node, $default_text) = @_; |
113 114 if ( ! defined $node) 115 { | 119 120 if ( ! defined $node) 121 { |
116 return ""; | 122 if (defined $default_text) 123 { 124 return $default_text; 125 } 126 else 127 { 128 return ""; 129 } |
117 } 118 else 119 { | 130 } 131 else 132 { |
120 my $text = $node->textContent(); | 133 my $text = $node->{'__text__'}; |
121 $text =~ s/(^\s+|\s+$)//g; 122 return $text; 123 } 124} 125 126 127 | 134 $text =~ s/(^\s+|\s+$)//g; 135 return $text; 136 } 137} 138 139 140 |
141sub GetAttribute ($$) 142{ 143 my ($node, $attribute_name) = @_; |
|
128 | 144 |
129=head2 Read($self) | 145 my $attributes = $node->{'__attributes__'}; 146 if ( ! defined $attributes) 147 { 148 return undef; 149 } 150 else 151 { 152 return $attributes->{$attribute_name}; 153 } 154} |
130 | 155 |
156 157 158 159sub PrintNode($$); 160sub ReadDomTree ($) 161{ 162 my ($filename) = @_; 163 164 my $root = {}; 165 my $data = { 166 'current_node' => $root, 167 'node_stack' => [] 168 }; 169 my $parser = new XML::Parser( 170 'Handlers' => { 171 'Start' => sub {HandleStartTag($data, @_)}, 172 'End' => sub{HandleEndTag($data, @_)}, 173 'Char' => sub{HandleText($data, @_)} 174 }); 175 $parser->parsefile($filename); 176 177# PrintNode("", $root); 178 179 return $root; 180} 181 182 183 184 185sub PrintNode($$) 186{ 187 my ($indentation, $node) = @_; 188 189 if (defined $node->{'__attributes__'}) 190 { 191 while (my ($name,$attribute) = each(%{$node->{'__attributes__'}})) 192 { 193 printf(" %s%s -> %s\n", $indentation, $name, $attribute); 194 } 195 } 196 197 while (my ($key,$value) = each(%$node)) 198 { 199 if ($key eq '__text__') 200 { 201 printf("%stext '%s'\n", $indentation, $value); 202 } 203 elsif ($key eq '__attributes__') 204 { 205 next; 206 } 207 elsif (ref($value) eq "ARRAY") 208 { 209 foreach my $item (@$value) 210 { 211 printf("%s%s {\n", $indentation, $key); 212 PrintNode($indentation." ", $item); 213 printf("%s}\n", $indentation); 214 } 215 } 216 else 217 { 218 printf("%s%s {\n", $indentation, $key); 219 PrintNode($indentation." ", $value); 220 printf("%s}\n", $indentation); 221 } 222 } 223} 224 225 226sub HandleStartTag ($$$@) 227{ 228 my ($data, $expat, $element, @attributes) = @_; 229 230 # Create new node with attributes. 231 my $node = {'__attributes__' => {@attributes}}; 232 233 # Append it to the list of $element objects. 234 my $current_node = $data->{'current_node'}; 235 $current_node->{$element} = [] unless defined $current_node->{$element}; 236 push @{$current_node->{$element}}, $node; 237 238 # Make the new node the current node. 239 push @{$data->{'node_stack'}}, $current_node; 240 $data->{'current_node'} = $node; 241} 242 243sub HandleEndTag ($$$) 244{ 245 my ($data, $expat, $element) = @_; 246 247 # Restore the parent node as current node. 248 $data->{'current_node'} = pop @{$data->{'node_stack'}}; 249} 250 251sub HandleText ($$$) 252{ 253 my ($data, $expat, $text) = @_; 254 if ($text !~ /^\s*$/) 255 { 256 $data->{'current_node'}->{'__text__'} .= $text; 257 } 258} 259 260=head2 Read($self, $filename) 261 |
|
131 Read the releases.xml file as doctree and parse its content. 132 133=cut | 262 Read the releases.xml file as doctree and parse its content. 263 264=cut |
134sub Read ($) | 265sub Read ($$) |
135{ | 266{ |
136 my ($self) = @_; | 267 my ($self, $filename) = @_; |
137 | 268 |
138 my $filename = File::Spec->catfile($ENV{'SRC_ROOT'}, "instsetoo_native", "data", "releases.xml"); 139 my $parser = XML::LibXML->new(); 140 my $document = $parser->parse_file($filename); 141 foreach my $release_node ($document->getElementsByTagName("release")) | 269 my $document = ReadDomTree($filename); 270 foreach my $release_node (@{$document->{'releases'}->[0]->{'release'}}) |
142 { 143 my $version_node = GetFirstChild($release_node, "version"); | 271 { 272 my $version_node = GetFirstChild($release_node, "version"); |
144 my $version = GetText($version_node); 145 next if $version eq ""; | 273 my $version_major = GetText(GetFirstChild($version_node, "major")); 274 my $version_minor = GetText(GetFirstChild($version_node, "minor"), "0"); 275 my $version_micro = GetText(GetFirstChild($version_node, "micro"), "0"); 276 my $version = sprintf("%d.%d.%d", $version_major, $version_minor, $version_micro); 277 die "could not read version from releases.xml" if $version eq ""; |
146 | 278 |
147 foreach my $download_node (GetFirstChild($release_node, "download")) 148 { 149 my $package_node = GetFirstChild($download_node, "package-format"); 150 my $package_format = GetText($package_node); 151 next if $package_format eq ""; | 279 push @{$self->{'releases'}}, $version; |
152 | 280 |
153 my $download_data = ParseDownloadData($download_node); 154 if (defined $download_data) | 281 my $download_node = GetFirstChild($release_node, "downloads"); 282 my $package_format = GetText(GetFirstChild($download_node, "package-format")); 283 my $url_template = GetText(GetFirstChild($download_node, "url-template")); 284 my $upgrade_code = GetText(GetFirstChild($download_node, "upgrade-code")); 285 my $build_id = GetText(GetFirstChild($download_node, "build-id")); 286 die "could not read package format from releases.xml" if $package_format eq ""; 287 288 $self->{$version}->{$package_format}->{'upgrade-code'} = $upgrade_code; 289 $self->{$version}->{$package_format}->{'build-id'} = $build_id; 290 291 foreach my $item_node (@{$download_node->{'item'}}) 292 { 293 my ($language, $download_data) = ParseDownloadData($item_node, $url_template); 294 if (defined $download_data && defined $language) |
155 { | 295 { |
156 $self->{$version}->{$package_format} = $download_data; | 296 $self->{$version}->{$package_format}->{$language} = $download_data; |
157 } 158 } 159 } | 297 } 298 } 299 } |
160 | |
161} 162 163 164 165 166=head2 ParseDownloadData ($download_node) 167 168 Parse the data for one set of download data (there is one per release and package format). 169 170=cut | 300} 301 302 303 304 305=head2 ParseDownloadData ($download_node) 306 307 Parse the data for one set of download data (there is one per release and package format). 308 309=cut |
171sub ParseDownloadData ($) | 310sub ParseDownloadData ($$) |
172{ | 311{ |
173 my ($download_node) = @_; | 312 my ($item_node, $url_template) = @_; |
174 | 313 |
175 my $url_node = GetFirstChild($download_node, "url-template"); 176 my $url_template = GetText($url_node); 177 if ($url_template eq "") | 314 my $language = GetText(GetFirstChild($item_node, "language")); 315 my $checksum_node = GetFirstChild($item_node, "checksum"); 316 if ( ! defined $checksum_node) |
178 { | 317 { |
179 print STDERR "releases data file corrupt (no URL template)\n"; | 318 print STDERR "releases data file corrupt (item has no 'checksum' node)\n"; |
180 return undef; 181 } | 319 return undef; 320 } |
182 183 my $download_data = {}; 184 foreach my $item_node (@{$download_node->getElementsByTagName("item")}) 185 { 186 my $language = GetText(GetFirstChild($item_node, "language")); 187 my $checksum_node = GetFirstChild($item_node, "checksum"); 188 if ( ! defined $checksum_node) 189 { 190 print STDERR "releases data file corrupt (item has no 'checksum' node)\n"; 191 return undef; 192 } 193 my $checksum_type = $checksum_node->getAttribute("type"); 194 my $checksum_value = GetText($checksum_node); 195 my $file_size = GetText(GetFirstChild($item_node, "size")); | 321 my $checksum_type = GetAttribute($checksum_node, "type"); 322 my $checksum_value = GetText($checksum_node); 323 my $file_size = GetText(GetFirstChild($item_node, "size")); 324 my $product_code = GetText(GetFirstChild($item_node, "product-code")); |
196 | 325 |
197 my $url = $url_template; 198 $url =~ s/\%L/$language/g; 199 $download_data->{$language} = { | 326 my $url = $url_template; 327 $url =~ s/\%L/$language/g; 328 return ( 329 $language, 330 { |
200 'URL' => $url, 201 'checksum-type' => $checksum_type, 202 'checksum-value' => $checksum_value, | 331 'URL' => $url, 332 'checksum-type' => $checksum_type, 333 'checksum-value' => $checksum_value, |
203 'file-size' => $file_size 204 }; | 334 'file-size' => $file_size, 335 'product-code' => $product_code 336 }); 337} 338 339 340 341 342=head2 GetPreviousVersion($version) 343 344 Look up $version in the sorted list of released versions. Return 345 the previous element. Whe $version is not found then return the 346 last element (under the assumption that $version will be the next 347 released version). 348 349=cut 350sub GetPreviousVersion ($) 351{ 352 my ($current_version) = @_; 353 354 my $release_data = installer::patch::ReleasesList::Instance(); 355 my $previous_version = undef; 356 foreach my $version (@{$release_data->{'releases'}}) 357 { 358 if ($version eq $current_version) 359 { 360 return $previous_version; 361 } 362 else 363 { 364 $previous_version = $version; 365 } |
205 } 206 | 366 } 367 |
207 return $download_data; | 368 return $previous_version; |
208} 209 | 369} 370 |
371 372 373 374 |
|
2101; | 3751; |