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;