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::ReleasesList; 23 24use XML::LibXML; 25use File::Spec; 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 34 35my $Instance = undef; 36 37=head2 Instance() 38 39 Return the singleton instance. 40 41=cut 42sub Instance() 43{ 44 if ( ! defined $Instance) 45 { 46 $Instance = new installer::patch::ReleasesList(); 47 } 48 return $Instance; 49} 50 51 52 53 54=head2 new($class) 55 56 Internal constructor. Don't call. 57 58=cut 59sub new ($) 60{ 61 my ($class) = @_; 62 63 my $self = {}; 64 bless($self, $class); 65 66 $self->Read(); 67 68 return $self; 69} 70 71 72 73 74=head2 GetFirstChild ($node, $child_name) 75 76 Internal function that returns the first child. Use only when the 77 first child is the (expected) only child in a list. 78 79=cut 80sub GetFirstChild ($$) 81{ 82 my ($node, $child_name) = @_; 83 84 if ( ! defined $node) 85 { 86 return undef; 87 } 88 else 89 { 90 my @child_nodes = $node->getElementsByTagName($child_name); 91 if (scalar @child_nodes == 0) 92 { 93 return undef; 94 } 95 else 96 { 97 return $child_nodes[0]; 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 110sub GetText ($) 111{ 112 my ($node) = @_; 113 114 if ( ! defined $node) 115 { 116 return ""; 117 } 118 else 119 { 120 my $text = $node->textContent(); 121 $text =~ s/(^\s+|\s+$)//g; 122 return $text; 123 } 124} 125 126 127 128 129=head2 Read($self) 130 131 Read the releases.xml file as doctree and parse its content. 132 133=cut 134sub Read ($) 135{ 136 my ($self) = @_; 137 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")) 142 { 143 my $version_node = GetFirstChild($release_node, "version"); 144 my $version = GetText($version_node); 145 next if $version eq ""; 146 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 ""; 152 153 my $download_data = ParseDownloadData($download_node); 154 if (defined $download_data) 155 { 156 $self->{$version}->{$package_format} = $download_data; 157 } 158 } 159 } 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 171sub ParseDownloadData ($) 172{ 173 my ($download_node) = @_; 174 175 my $url_node = GetFirstChild($download_node, "url-template"); 176 my $url_template = GetText($url_node); 177 if ($url_template eq "") 178 { 179 print STDERR "releases data file corrupt (no URL template)\n"; 180 return undef; 181 } 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")); 196 197 my $url = $url_template; 198 $url =~ s/\%L/$language/g; 199 $download_data->{$language} = { 200 'URL' => $url, 201 'checksum-type' => $checksum_type, 202 'checksum-value' => $checksum_value, 203 'file-size' => $file_size 204 }; 205 } 206 207 return $download_data; 208} 209 2101; 211