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