1c9b362f6SAndre Fischer#************************************************************** 2c9b362f6SAndre Fischer# 3c9b362f6SAndre Fischer# Licensed to the Apache Software Foundation (ASF) under one 4c9b362f6SAndre Fischer# or more contributor license agreements. See the NOTICE file 5c9b362f6SAndre Fischer# distributed with this work for additional information 6c9b362f6SAndre Fischer# regarding copyright ownership. The ASF licenses this file 7c9b362f6SAndre Fischer# to you under the Apache License, Version 2.0 (the 8c9b362f6SAndre Fischer# "License"); you may not use this file except in compliance 9c9b362f6SAndre Fischer# with the License. You may obtain a copy of the License at 10c9b362f6SAndre Fischer# 11c9b362f6SAndre Fischer# http://www.apache.org/licenses/LICENSE-2.0 12c9b362f6SAndre Fischer# 13c9b362f6SAndre Fischer# Unless required by applicable law or agreed to in writing, 14c9b362f6SAndre Fischer# software distributed under the License is distributed on an 15c9b362f6SAndre Fischer# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16c9b362f6SAndre Fischer# KIND, either express or implied. See the License for the 17c9b362f6SAndre Fischer# specific language governing permissions and limitations 18c9b362f6SAndre Fischer# under the License. 19c9b362f6SAndre Fischer# 20c9b362f6SAndre Fischer#************************************************************** 21c9b362f6SAndre Fischer 22c9b362f6SAndre Fischerpackage installer::patch::ReleasesList; 23c9b362f6SAndre Fischer 249f91b7e3SAndre Fischeruse XML::Parser; 25c9b362f6SAndre Fischeruse File::Spec; 269f91b7e3SAndre Fischer 27c9b362f6SAndre Fischeruse strict; 28c9b362f6SAndre Fischer 29c9b362f6SAndre Fischer=head1 NAME 30c9b362f6SAndre Fischer 31c9b362f6SAndre Fischer package installer::patch::ReleasesList - Functions for accessing the instsetoo_native/data/releases.xml file 32c9b362f6SAndre Fischer 33c9b362f6SAndre Fischer=cut 34c9b362f6SAndre Fischer 35c9b362f6SAndre Fischer 36c9b362f6SAndre Fischermy $Instance = undef; 37c9b362f6SAndre Fischer 38c9b362f6SAndre Fischer=head2 Instance() 39c9b362f6SAndre Fischer 40c9b362f6SAndre Fischer Return the singleton instance. 41c9b362f6SAndre Fischer 42c9b362f6SAndre Fischer=cut 43c9b362f6SAndre Fischersub Instance() 44c9b362f6SAndre Fischer{ 45c9b362f6SAndre Fischer if ( ! defined $Instance) 46c9b362f6SAndre Fischer { 479f91b7e3SAndre Fischer $Instance = new installer::patch::ReleasesList( 489f91b7e3SAndre Fischer File::Spec->catfile($ENV{'SRC_ROOT'}, "instsetoo_native", "data", "releases.xml")); 49c9b362f6SAndre Fischer } 50c9b362f6SAndre Fischer return $Instance; 51c9b362f6SAndre Fischer} 52c9b362f6SAndre Fischer 53c9b362f6SAndre Fischer 54c9b362f6SAndre Fischer 55c9b362f6SAndre Fischer 569f91b7e3SAndre Fischer=head2 new($class, $filename) 57c9b362f6SAndre Fischer 58c9b362f6SAndre Fischer Internal constructor. Don't call. 59c9b362f6SAndre Fischer 60c9b362f6SAndre Fischer=cut 619f91b7e3SAndre Fischersub new ($$) 62c9b362f6SAndre Fischer{ 639f91b7e3SAndre Fischer my ($class, $filename) = @_; 64c9b362f6SAndre Fischer 659f91b7e3SAndre Fischer my $self = { 669f91b7e3SAndre Fischer 'releases' => [] 679f91b7e3SAndre Fischer }; 68c9b362f6SAndre Fischer bless($self, $class); 69c9b362f6SAndre Fischer 709f91b7e3SAndre Fischer 719f91b7e3SAndre Fischer $self->Read($filename); 729f91b7e3SAndre Fischer 73c9b362f6SAndre Fischer 74c9b362f6SAndre Fischer return $self; 75c9b362f6SAndre Fischer} 76c9b362f6SAndre Fischer 77c9b362f6SAndre Fischer 78c9b362f6SAndre Fischer 79c9b362f6SAndre Fischer 80c9b362f6SAndre Fischer=head2 GetFirstChild ($node, $child_name) 81c9b362f6SAndre Fischer 82c9b362f6SAndre Fischer Internal function that returns the first child. Use only when the 83c9b362f6SAndre Fischer first child is the (expected) only child in a list. 84c9b362f6SAndre Fischer 85c9b362f6SAndre Fischer=cut 86c9b362f6SAndre Fischersub GetFirstChild ($$) 87c9b362f6SAndre Fischer{ 88c9b362f6SAndre Fischer my ($node, $child_name) = @_; 89c9b362f6SAndre Fischer 90c9b362f6SAndre Fischer if ( ! defined $node) 91c9b362f6SAndre Fischer { 92c9b362f6SAndre Fischer return undef; 93c9b362f6SAndre Fischer } 94c9b362f6SAndre Fischer else 95c9b362f6SAndre Fischer { 969f91b7e3SAndre Fischer my $value = $node->{$child_name}; 979f91b7e3SAndre Fischer if (ref($value) eq 'ARRAY') 98c9b362f6SAndre Fischer { 999f91b7e3SAndre Fischer return $value->[0]; 100c9b362f6SAndre Fischer } 101c9b362f6SAndre Fischer else 102c9b362f6SAndre Fischer { 1039f91b7e3SAndre Fischer return $value; 104c9b362f6SAndre Fischer } 105c9b362f6SAndre Fischer } 106c9b362f6SAndre Fischer} 107c9b362f6SAndre Fischer 108c9b362f6SAndre Fischer 109c9b362f6SAndre Fischer 110c9b362f6SAndre Fischer 111c9b362f6SAndre Fischer=head2 GetText ($node) 112c9b362f6SAndre Fischer 113c9b362f6SAndre Fischer Internal function that returns the trimmed text content of a node. 114c9b362f6SAndre Fischer 115c9b362f6SAndre Fischer=cut 1169f91b7e3SAndre Fischersub GetText ($;$) 117c9b362f6SAndre Fischer{ 1189f91b7e3SAndre Fischer my ($node, $default_text) = @_; 119c9b362f6SAndre Fischer 120c9b362f6SAndre Fischer if ( ! defined $node) 121c9b362f6SAndre Fischer { 1229f91b7e3SAndre Fischer if (defined $default_text) 1239f91b7e3SAndre Fischer { 1249f91b7e3SAndre Fischer return $default_text; 125c9b362f6SAndre Fischer } 126c9b362f6SAndre Fischer else 127c9b362f6SAndre Fischer { 1289f91b7e3SAndre Fischer return ""; 1299f91b7e3SAndre Fischer } 1309f91b7e3SAndre Fischer } 1319f91b7e3SAndre Fischer else 1329f91b7e3SAndre Fischer { 1339f91b7e3SAndre Fischer my $text = $node->{'__text__'}; 134c9b362f6SAndre Fischer $text =~ s/(^\s+|\s+$)//g; 135c9b362f6SAndre Fischer return $text; 136c9b362f6SAndre Fischer } 137c9b362f6SAndre Fischer} 138c9b362f6SAndre Fischer 139c9b362f6SAndre Fischer 140c9b362f6SAndre Fischer 1419f91b7e3SAndre Fischersub GetAttribute ($$) 1429f91b7e3SAndre Fischer{ 1439f91b7e3SAndre Fischer my ($node, $attribute_name) = @_; 144c9b362f6SAndre Fischer 1459f91b7e3SAndre Fischer my $attributes = $node->{'__attributes__'}; 1469f91b7e3SAndre Fischer if ( ! defined $attributes) 1479f91b7e3SAndre Fischer { 1489f91b7e3SAndre Fischer return undef; 1499f91b7e3SAndre Fischer } 1509f91b7e3SAndre Fischer else 1519f91b7e3SAndre Fischer { 1529f91b7e3SAndre Fischer return $attributes->{$attribute_name}; 1539f91b7e3SAndre Fischer } 1549f91b7e3SAndre Fischer} 1559f91b7e3SAndre Fischer 1569f91b7e3SAndre Fischer 1579f91b7e3SAndre Fischer 1589f91b7e3SAndre Fischer 1599f91b7e3SAndre Fischersub PrintNode($$); 160*d575d58fSAndre Fischer 161*d575d58fSAndre Fischer=head2 ReadDomTree ($filename) 162*d575d58fSAndre Fischer 163*d575d58fSAndre Fischer Read the dom tree for the XML in $filename. 164*d575d58fSAndre Fischer 165*d575d58fSAndre Fischer Note that 166*d575d58fSAndre Fischer a) this was initially written for another XML library that provided the dom tree directly. 167*d575d58fSAndre Fischer b) the dom tree creation is basic and simple but good enough for the current format. 168*d575d58fSAndre Fischer When the format should change substantially, then we may need a better parser. 169*d575d58fSAndre Fischer 170*d575d58fSAndre Fischer=cut 1719f91b7e3SAndre Fischersub ReadDomTree ($) 1729f91b7e3SAndre Fischer{ 1739f91b7e3SAndre Fischer my ($filename) = @_; 1749f91b7e3SAndre Fischer 1759f91b7e3SAndre Fischer my $root = {}; 1769f91b7e3SAndre Fischer my $data = { 1779f91b7e3SAndre Fischer 'current_node' => $root, 1789f91b7e3SAndre Fischer 'node_stack' => [] 1799f91b7e3SAndre Fischer }; 1809f91b7e3SAndre Fischer my $parser = new XML::Parser( 1819f91b7e3SAndre Fischer 'Handlers' => { 1829f91b7e3SAndre Fischer 'Start' => sub {HandleStartTag($data, @_)}, 1839f91b7e3SAndre Fischer 'End' => sub{HandleEndTag($data, @_)}, 1849f91b7e3SAndre Fischer 'Char' => sub{HandleText($data, @_)} 1859f91b7e3SAndre Fischer }); 1869f91b7e3SAndre Fischer $parser->parsefile($filename); 1879f91b7e3SAndre Fischer 1889f91b7e3SAndre Fischer# PrintNode("", $root); 1899f91b7e3SAndre Fischer 1909f91b7e3SAndre Fischer return $root; 1919f91b7e3SAndre Fischer} 1929f91b7e3SAndre Fischer 1939f91b7e3SAndre Fischer 1949f91b7e3SAndre Fischer 1959f91b7e3SAndre Fischer 196*d575d58fSAndre Fischer=head HandleStartTag ($data, $expat, $element_name, @attributes) 197*d575d58fSAndre Fischer 198*d575d58fSAndre Fischer Callback for start tags. 199*d575d58fSAndre Fischer 200*d575d58fSAndre Fischer A new hash is appended to the array that is referenced by the parent by $element_name. 201*d575d58fSAndre Fischer That means that when this function ends there the new hash can be referenced by 202*d575d58fSAndre Fischer my $parent = $data->{'node_stack'}->[-1]; 203*d575d58fSAndre Fischer my $new_hash = $parent->{$element_name}->[-1]; 204*d575d58fSAndre Fischer 205*d575d58fSAndre Fischer Note that, just like in other implementations of dom trees, 206*d575d58fSAndre Fischer $parent->{$element_name} is an array, even when there is only one 207*d575d58fSAndre Fischer element. 208*d575d58fSAndre Fischer 209*d575d58fSAndre Fischer The new hash is empty or contains the given @attributes as hash. 210*d575d58fSAndre Fischer When fully read (ie its end tag has been processed) then it can contain two special keys: 211*d575d58fSAndre Fischer __attributes__ for the attributes 212*d575d58fSAndre Fischer __text__ for the concatenated text parts 213*d575d58fSAndre Fischer 214*d575d58fSAndre Fischer=cut 215*d575d58fSAndre Fischersub HandleStartTag ($$$@) 216*d575d58fSAndre Fischer{ 217*d575d58fSAndre Fischer my ($data, $expat, $element_name, @attributes) = @_; 218*d575d58fSAndre Fischer 219*d575d58fSAndre Fischer # Create new node with attributes. 220*d575d58fSAndre Fischer my $node = {'__attributes__' => {@attributes}}; 221*d575d58fSAndre Fischer 222*d575d58fSAndre Fischer # Append it to the list of $element_name objects. 223*d575d58fSAndre Fischer my $current_node = $data->{'current_node'}; 224*d575d58fSAndre Fischer $current_node->{$element_name} = [] unless defined $current_node->{$element_name}; 225*d575d58fSAndre Fischer push @{$current_node->{$element_name}}, $node; 226*d575d58fSAndre Fischer 227*d575d58fSAndre Fischer # Make the new node the current node. 228*d575d58fSAndre Fischer push @{$data->{'node_stack'}}, $current_node; 229*d575d58fSAndre Fischer $data->{'current_node'} = $node; 230*d575d58fSAndre Fischer} 231*d575d58fSAndre Fischer 232*d575d58fSAndre Fischer=head HandleEndTag ($data, $expat, $element_name, @attributes) 233*d575d58fSAndre Fischer 234*d575d58fSAndre Fischer Callback for end tags. 235*d575d58fSAndre Fischer 236*d575d58fSAndre Fischer=cut 237*d575d58fSAndre Fischersub HandleEndTag ($$$) 238*d575d58fSAndre Fischer{ 239*d575d58fSAndre Fischer my ($data, $expat, $element) = @_; 240*d575d58fSAndre Fischer 241*d575d58fSAndre Fischer # Restore the parent node as current node. 242*d575d58fSAndre Fischer $data->{'current_node'} = pop @{$data->{'node_stack'}}; 243*d575d58fSAndre Fischer} 244*d575d58fSAndre Fischer 245*d575d58fSAndre Fischer=head2 HandleText ($data, $expat, $text) 246*d575d58fSAndre Fischer 247*d575d58fSAndre Fischer Callback for text. 248*d575d58fSAndre Fischer 249*d575d58fSAndre Fischer $text is appended to the __text__ member of the current node in 250*d575d58fSAndre Fischer the dom tree. 251*d575d58fSAndre Fischer 252*d575d58fSAndre Fischer=cut 253*d575d58fSAndre Fischersub HandleText ($$$) 254*d575d58fSAndre Fischer{ 255*d575d58fSAndre Fischer my ($data, $expat, $text) = @_; 256*d575d58fSAndre Fischer if ($text !~ /^\s*$/) 257*d575d58fSAndre Fischer { 258*d575d58fSAndre Fischer $data->{'current_node'}->{'__text__'} .= $text; 259*d575d58fSAndre Fischer } 260*d575d58fSAndre Fischer} 261*d575d58fSAndre Fischer 262*d575d58fSAndre Fischer 263*d575d58fSAndre Fischer 264*d575d58fSAndre Fischer 265*d575d58fSAndre Fischer=head2 PrintNode ($indentation, $node) 266*d575d58fSAndre Fischer 267*d575d58fSAndre Fischer For debugging. 268*d575d58fSAndre Fischer Print $node recursively with initial $indentation. 269*d575d58fSAndre Fischer 270*d575d58fSAndre Fischer=cut 2719f91b7e3SAndre Fischersub PrintNode($$) 2729f91b7e3SAndre Fischer{ 2739f91b7e3SAndre Fischer my ($indentation, $node) = @_; 2749f91b7e3SAndre Fischer 2759f91b7e3SAndre Fischer if (defined $node->{'__attributes__'}) 2769f91b7e3SAndre Fischer { 2779f91b7e3SAndre Fischer while (my ($name,$attribute) = each(%{$node->{'__attributes__'}})) 2789f91b7e3SAndre Fischer { 2799f91b7e3SAndre Fischer printf(" %s%s -> %s\n", $indentation, $name, $attribute); 2809f91b7e3SAndre Fischer } 2819f91b7e3SAndre Fischer } 2829f91b7e3SAndre Fischer 2839f91b7e3SAndre Fischer while (my ($key,$value) = each(%$node)) 2849f91b7e3SAndre Fischer { 2859f91b7e3SAndre Fischer if ($key eq '__text__') 2869f91b7e3SAndre Fischer { 2879f91b7e3SAndre Fischer printf("%stext '%s'\n", $indentation, $value); 2889f91b7e3SAndre Fischer } 2899f91b7e3SAndre Fischer elsif ($key eq '__attributes__') 2909f91b7e3SAndre Fischer { 2919f91b7e3SAndre Fischer next; 2929f91b7e3SAndre Fischer } 2939f91b7e3SAndre Fischer elsif (ref($value) eq "ARRAY") 2949f91b7e3SAndre Fischer { 2959f91b7e3SAndre Fischer foreach my $item (@$value) 2969f91b7e3SAndre Fischer { 2979f91b7e3SAndre Fischer printf("%s%s {\n", $indentation, $key); 2989f91b7e3SAndre Fischer PrintNode($indentation." ", $item); 2999f91b7e3SAndre Fischer printf("%s}\n", $indentation); 3009f91b7e3SAndre Fischer } 3019f91b7e3SAndre Fischer } 3029f91b7e3SAndre Fischer else 3039f91b7e3SAndre Fischer { 3049f91b7e3SAndre Fischer printf("%s%s {\n", $indentation, $key); 3059f91b7e3SAndre Fischer PrintNode($indentation." ", $value); 3069f91b7e3SAndre Fischer printf("%s}\n", $indentation); 3079f91b7e3SAndre Fischer } 3089f91b7e3SAndre Fischer } 3099f91b7e3SAndre Fischer} 3109f91b7e3SAndre Fischer 3119f91b7e3SAndre Fischer 3129f91b7e3SAndre Fischer 3139f91b7e3SAndre Fischer 3149f91b7e3SAndre Fischer=head2 Read($self, $filename) 315c9b362f6SAndre Fischer 316c9b362f6SAndre Fischer Read the releases.xml file as doctree and parse its content. 317c9b362f6SAndre Fischer 318c9b362f6SAndre Fischer=cut 3199f91b7e3SAndre Fischersub Read ($$) 320c9b362f6SAndre Fischer{ 3219f91b7e3SAndre Fischer my ($self, $filename) = @_; 322c9b362f6SAndre Fischer 3239f91b7e3SAndre Fischer my $document = ReadDomTree($filename); 3249f91b7e3SAndre Fischer foreach my $release_node (@{$document->{'releases'}->[0]->{'release'}}) 325c9b362f6SAndre Fischer { 326c9b362f6SAndre Fischer my $version_node = GetFirstChild($release_node, "version"); 3279f91b7e3SAndre Fischer my $version_major = GetText(GetFirstChild($version_node, "major")); 3289f91b7e3SAndre Fischer my $version_minor = GetText(GetFirstChild($version_node, "minor"), "0"); 3299f91b7e3SAndre Fischer my $version_micro = GetText(GetFirstChild($version_node, "micro"), "0"); 3309f91b7e3SAndre Fischer my $version = sprintf("%d.%d.%d", $version_major, $version_minor, $version_micro); 3319f91b7e3SAndre Fischer die "could not read version from releases.xml" if $version eq ""; 332c9b362f6SAndre Fischer 3339f91b7e3SAndre Fischer push @{$self->{'releases'}}, $version; 3349f91b7e3SAndre Fischer 3359f91b7e3SAndre Fischer my $download_node = GetFirstChild($release_node, "downloads"); 3369f91b7e3SAndre Fischer my $package_format = GetText(GetFirstChild($download_node, "package-format")); 3379f91b7e3SAndre Fischer my $url_template = GetText(GetFirstChild($download_node, "url-template")); 3389f91b7e3SAndre Fischer my $upgrade_code = GetText(GetFirstChild($download_node, "upgrade-code")); 3399f91b7e3SAndre Fischer my $build_id = GetText(GetFirstChild($download_node, "build-id")); 3409f91b7e3SAndre Fischer die "could not read package format from releases.xml" if $package_format eq ""; 3419f91b7e3SAndre Fischer 3429f91b7e3SAndre Fischer $self->{$version}->{$package_format}->{'upgrade-code'} = $upgrade_code; 3439f91b7e3SAndre Fischer $self->{$version}->{$package_format}->{'build-id'} = $build_id; 344*d575d58fSAndre Fischer $self->{$version}->{$package_format}->{'url-template'} = $url_template; 3459f91b7e3SAndre Fischer 346*d575d58fSAndre Fischer my @languages = (); 3479f91b7e3SAndre Fischer foreach my $item_node (@{$download_node->{'item'}}) 348c9b362f6SAndre Fischer { 3499f91b7e3SAndre Fischer my ($language, $download_data) = ParseDownloadData($item_node, $url_template); 3509f91b7e3SAndre Fischer if (defined $download_data && defined $language) 351c9b362f6SAndre Fischer { 352*d575d58fSAndre Fischer push @languages, $language; 3539f91b7e3SAndre Fischer $self->{$version}->{$package_format}->{$language} = $download_data; 354c9b362f6SAndre Fischer } 355c9b362f6SAndre Fischer } 356*d575d58fSAndre Fischer $self->{$version}->{$package_format}->{'languages'} = \@languages; 357c9b362f6SAndre Fischer } 358c9b362f6SAndre Fischer} 359c9b362f6SAndre Fischer 360c9b362f6SAndre Fischer 361c9b362f6SAndre Fischer 362c9b362f6SAndre Fischer 363*d575d58fSAndre Fischer=head2 ParseDownloadData ($item_node, $url_template) 364c9b362f6SAndre Fischer 365c9b362f6SAndre Fischer Parse the data for one set of download data (there is one per release and package format). 366c9b362f6SAndre Fischer 367c9b362f6SAndre Fischer=cut 3689f91b7e3SAndre Fischersub ParseDownloadData ($$) 369c9b362f6SAndre Fischer{ 3709f91b7e3SAndre Fischer my ($item_node, $url_template) = @_; 371c9b362f6SAndre Fischer 372c9b362f6SAndre Fischer my $language = GetText(GetFirstChild($item_node, "language")); 373c9b362f6SAndre Fischer my $checksum_node = GetFirstChild($item_node, "checksum"); 374c9b362f6SAndre Fischer if ( ! defined $checksum_node) 375c9b362f6SAndre Fischer { 376c9b362f6SAndre Fischer print STDERR "releases data file corrupt (item has no 'checksum' node)\n"; 377c9b362f6SAndre Fischer return undef; 378c9b362f6SAndre Fischer } 3799f91b7e3SAndre Fischer my $checksum_type = GetAttribute($checksum_node, "type"); 380c9b362f6SAndre Fischer my $checksum_value = GetText($checksum_node); 381c9b362f6SAndre Fischer my $file_size = GetText(GetFirstChild($item_node, "size")); 3829f91b7e3SAndre Fischer my $product_code = GetText(GetFirstChild($item_node, "product-code")); 383c9b362f6SAndre Fischer 384c9b362f6SAndre Fischer my $url = $url_template; 385c9b362f6SAndre Fischer $url =~ s/\%L/$language/g; 3869f91b7e3SAndre Fischer return ( 3879f91b7e3SAndre Fischer $language, 3889f91b7e3SAndre Fischer { 389c9b362f6SAndre Fischer 'URL' => $url, 390c9b362f6SAndre Fischer 'checksum-type' => $checksum_type, 391c9b362f6SAndre Fischer 'checksum-value' => $checksum_value, 3929f91b7e3SAndre Fischer 'file-size' => $file_size, 3939f91b7e3SAndre Fischer 'product-code' => $product_code 3949f91b7e3SAndre Fischer }); 395c9b362f6SAndre Fischer} 396c9b362f6SAndre Fischer 3979f91b7e3SAndre Fischer 3989f91b7e3SAndre Fischer 3999f91b7e3SAndre Fischer 400*d575d58fSAndre Fischer=head2 Write($self, $filename) 401*d575d58fSAndre Fischer 402*d575d58fSAndre Fischer Write the content of the releases data to a file named $filename. 403*d575d58fSAndre Fischer 404*d575d58fSAndre Fischer=cut 405*d575d58fSAndre Fischersub Write ($$) 406*d575d58fSAndre Fischer{ 407*d575d58fSAndre Fischer my ($self, $filename) = @_; 408*d575d58fSAndre Fischer 409*d575d58fSAndre Fischer open my $out, ">", $filename || die "can not write releases data to ".$filename; 410*d575d58fSAndre Fischer $self->WriteHeader($out); 411*d575d58fSAndre Fischer $self->WriteContent($out); 412*d575d58fSAndre Fischer close $out; 413*d575d58fSAndre Fischer} 414*d575d58fSAndre Fischer 415*d575d58fSAndre Fischer 416*d575d58fSAndre Fischer 417*d575d58fSAndre Fischer 418*d575d58fSAndre Fischer=head2 WriteContent ($self, $out) 419*d575d58fSAndre Fischer 420*d575d58fSAndre Fischer Write the content of the releases.xml list. 421*d575d58fSAndre Fischer 422*d575d58fSAndre Fischer=cut 423*d575d58fSAndre Fischersub WriteContent ($$) 424*d575d58fSAndre Fischer{ 425*d575d58fSAndre Fischer my ($self, $out) = @_; 426*d575d58fSAndre Fischer 427*d575d58fSAndre Fischer print $out "<releases>\n"; 428*d575d58fSAndre Fischer # Write the data sets for each releases with the same sort order as @{$self->{'releases'}} 429*d575d58fSAndre Fischer foreach my $version (@{$self->{'releases'}}) 430*d575d58fSAndre Fischer { 431*d575d58fSAndre Fischer print $out " <release>\n"; 432*d575d58fSAndre Fischer 433*d575d58fSAndre Fischer my @version_array = split(/\./, $version); 434*d575d58fSAndre Fischer printf $out " <version>\n"; 435*d575d58fSAndre Fischer printf $out " <major>%s</major>\n", $version_array[0]; 436*d575d58fSAndre Fischer printf $out " <minor>%s</minor>\n", $version_array[1]; 437*d575d58fSAndre Fischer printf $out " <micro>%s</micro>\n", $version_array[2]; 438*d575d58fSAndre Fischer printf $out " </version>\n"; 439*d575d58fSAndre Fischer 440*d575d58fSAndre Fischer # Write one download data set per package format. 441*d575d58fSAndre Fischer while (my ($package_format, $data) = each %{$self->{$version}}) 442*d575d58fSAndre Fischer { 443*d575d58fSAndre Fischer print $out " <download>\n"; 444*d575d58fSAndre Fischer printf $out " <package-format>%s</package-format>\n", $package_format; 445*d575d58fSAndre Fischer print $out " <url-template>\n"; 446*d575d58fSAndre Fischer printf $out " %s\n", $data->{'url-template'}; 447*d575d58fSAndre Fischer print $out " </url-template>\n"; 448*d575d58fSAndre Fischer printf $out " <upgrade-code>%s</upgrade-code>\n", $data->{'upgrade-code'}; 449*d575d58fSAndre Fischer printf $out " <build-id>%s</build-id>\n", $data->{'build-id'}; 450*d575d58fSAndre Fischer 451*d575d58fSAndre Fischer foreach my $language (@{$data->{'languages'}}) 452*d575d58fSAndre Fischer { 453*d575d58fSAndre Fischer my $language_data = $data->{$language}; 454*d575d58fSAndre Fischer print $out " <item>\n"; 455*d575d58fSAndre Fischer printf $out " <language>%s</language>\n", $language; 456*d575d58fSAndre Fischer printf $out " <checksum type=\"%s\">%s</checksum>\n", 457*d575d58fSAndre Fischer $language_data->{'checksum-type'}, 458*d575d58fSAndre Fischer $language_data->{'checksum-value'}; 459*d575d58fSAndre Fischer printf $out " <size>%s</size>\n", $language_data->{'file-size'}; 460*d575d58fSAndre Fischer printf $out " <product-code>%s</product-code>\n", $language_data->{'product-code'}; 461*d575d58fSAndre Fischer print $out " </item>\n"; 462*d575d58fSAndre Fischer } 463*d575d58fSAndre Fischer 464*d575d58fSAndre Fischer print $out " </download>\n"; 465*d575d58fSAndre Fischer } 466*d575d58fSAndre Fischer 467*d575d58fSAndre Fischer print $out " </release>\n"; 468*d575d58fSAndre Fischer } 469*d575d58fSAndre Fischer 470*d575d58fSAndre Fischer print $out "</releases>\n"; 471*d575d58fSAndre Fischer} 472*d575d58fSAndre Fischer 473*d575d58fSAndre Fischer 474*d575d58fSAndre Fischer 475*d575d58fSAndre Fischer 476*d575d58fSAndre Fischer=head2 WriteHeader ($self, $out) 477*d575d58fSAndre Fischer 478*d575d58fSAndre Fischer Write the header for the releases.xml list. 479*d575d58fSAndre Fischer 480*d575d58fSAndre Fischer=cut 481*d575d58fSAndre Fischersub WriteHeader ($$) 482*d575d58fSAndre Fischer{ 483*d575d58fSAndre Fischer my ($self, $out) = @_; 484*d575d58fSAndre Fischer 485*d575d58fSAndre Fischerprint $out <<EOT; 486*d575d58fSAndre Fischer<?xml version='1.0' encoding='UTF-8'?> 487*d575d58fSAndre Fischer<!--*********************************************************** 488*d575d58fSAndre Fischer * 489*d575d58fSAndre Fischer * Licensed to the Apache Software Foundation (ASF) under one 490*d575d58fSAndre Fischer * or more contributor license agreements. See the NOTICE file 491*d575d58fSAndre Fischer * distributed with this work for additional information 492*d575d58fSAndre Fischer * regarding copyright ownership. The ASF licenses this file 493*d575d58fSAndre Fischer * to you under the Apache License, Version 2.0 (the 494*d575d58fSAndre Fischer * "License"); you may not use this file except in compliance 495*d575d58fSAndre Fischer * with the License. You may obtain a copy of the License at 496*d575d58fSAndre Fischer * 497*d575d58fSAndre Fischer * http://www.apache.org/licenses/LICENSE-2.0 498*d575d58fSAndre Fischer * 499*d575d58fSAndre Fischer * Unless required by applicable law or agreed to in writing, 500*d575d58fSAndre Fischer * software distributed under the License is distributed on an 501*d575d58fSAndre Fischer * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 502*d575d58fSAndre Fischer * KIND, either express or implied. See the License for the 503*d575d58fSAndre Fischer * specific language governing permissions and limitations 504*d575d58fSAndre Fischer * under the License. 505*d575d58fSAndre Fischer * 506*d575d58fSAndre Fischer ***********************************************************--> 507*d575d58fSAndre FischerEOT 508*d575d58fSAndre Fischer} 509*d575d58fSAndre Fischer 510*d575d58fSAndre Fischer 511*d575d58fSAndre Fischer 512*d575d58fSAndre Fischer 5139f91b7e3SAndre Fischer=head2 GetPreviousVersion($version) 5149f91b7e3SAndre Fischer 5159f91b7e3SAndre Fischer Look up $version in the sorted list of released versions. Return 5169f91b7e3SAndre Fischer the previous element. Whe $version is not found then return the 5179f91b7e3SAndre Fischer last element (under the assumption that $version will be the next 5189f91b7e3SAndre Fischer released version). 5199f91b7e3SAndre Fischer 5209f91b7e3SAndre Fischer=cut 5219f91b7e3SAndre Fischersub GetPreviousVersion ($) 5229f91b7e3SAndre Fischer{ 5239f91b7e3SAndre Fischer my ($current_version) = @_; 5249f91b7e3SAndre Fischer 5259f91b7e3SAndre Fischer my $release_data = installer::patch::ReleasesList::Instance(); 5269f91b7e3SAndre Fischer my $previous_version = undef; 5279f91b7e3SAndre Fischer foreach my $version (@{$release_data->{'releases'}}) 5289f91b7e3SAndre Fischer { 5299f91b7e3SAndre Fischer if ($version eq $current_version) 5309f91b7e3SAndre Fischer { 5319f91b7e3SAndre Fischer return $previous_version; 532c9b362f6SAndre Fischer } 5339f91b7e3SAndre Fischer else 5349f91b7e3SAndre Fischer { 5359f91b7e3SAndre Fischer $previous_version = $version; 5369f91b7e3SAndre Fischer } 5379f91b7e3SAndre Fischer } 5389f91b7e3SAndre Fischer 5399f91b7e3SAndre Fischer return $previous_version; 5409f91b7e3SAndre Fischer} 5419f91b7e3SAndre Fischer 5429f91b7e3SAndre Fischer 5439f91b7e3SAndre Fischer 5449f91b7e3SAndre Fischer 545c9b362f6SAndre Fischer 546c9b362f6SAndre Fischer1; 547