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
22
23
24package installer::configuration;
25
26use Cwd;
27use installer::converter;
28use installer::existence;
29use installer::exiter;
30use installer::files;
31use installer::globals;
32use installer::logger;
33use installer::remover;
34use installer::systemactions;
35
36################################################################################
37# Getting package from configurationitem (for instance: org.openoffice.Office)
38# Getting name from configurationitem (for instance: Common)
39################################################################################
40
41sub analyze_path_of_configurationitem
42{
43	my ($configurationitemsref) = @_;
44
45	if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::configuration::analyze_path_of_configurationitem : $#{$configurationitemsref}"); }
46
47	my ($startpath, $nodes, $name, $packagename, $onenode, $first, $second, $third, $bracketnode);
48
49	for ( my $i = 0; $i <= $#{$configurationitemsref}; $i++ )
50	{
51		my $oneconfig = ${$configurationitemsref}[$i];
52		my $path = $oneconfig->{'Path'};
53
54		installer::remover::remove_leading_and_ending_slashes(\$path);	# in scp are some path beginning with "/"
55
56		if ( $path =~ /^\s*(.*?)\/(.*)\s*$/ )
57		{
58			$startpath = $1;
59			$nodes = $2;
60		}
61		else
62		{
63			installer::exiter::exit_program("ERROR: Unknown format of ConfigurationItem path: $path", "analyze_path_of_configurationitem");
64		}
65
66		# Startpath is now: org.openoffice.Setup
67		# Nodes is now: Office/Factories/com.sun.star.chart.ChartDocument
68
69		# Dividing the startpath into package (org.openoffic) and name (Setup).
70
71		$oneconfig->{'startpath'} = $startpath;	# saving the startpath into the hash
72
73		if ( $startpath =~ /^\s*(\S*)\.(\S*?)\s*$/ )
74		{
75			$packagename = $1;
76			$name = $2;
77			$oneconfig->{'name'} = $name;
78			$oneconfig->{'packagename'} = $packagename;
79		}
80		else
81		{
82			installer::exiter::exit_program("ERROR: Unknown format of ConfigurationItem startpath: $startpath", "analyze_path_of_configurationitem");
83		}
84
85		# Collecting all nodes
86
87		installer::remover::remove_leading_and_ending_slashes(\$nodes);
88
89		my $counter = 1;
90
91		# Attention: Do not trust the slash
92		# Filters/Filter['StarWriter 5.0 Vorlage/Template']
93		# Menus/New/*['m10']/Title
94
95		if ( $nodes =~ /^(.*\[\')(.*\/.*)(\'\].*)$/ )
96		{
97			$first = $1;
98			$second = $2;
99			$third = $3;
100
101			$second =~ s/\//SUBSTITUTEDSLASH/g;	# substituting "/" to "SUBSTITUTEDSLASH"
102			$nodes = $first . $second . $third;
103		}
104
105		while ( $nodes =~ /\// )
106		{
107			if ($nodes =~ /^\s*(.*?)\/(.*)\s*$/ )
108			{
109				$onenode = $1;
110				$nodes = $2;
111				$nodename = "node". $counter;
112
113				# Special handling for filters. Difference between:
114				# Filter['StarWriter 5.0 Vorlage/Template']	without oor:op="replace"
115				# *['m10'] with oor:op="replace"
116
117				if ( $onenode =~ /^\s*Filter\[\'(.*)\'\].*$/ ) { $oneconfig->{'isfilter'} = 1; }
118
119				# Changing the nodes with brackets:
120				# Filter['StarWriter 5.0 Vorlage/Template']
121				# *['m10']
122
123				if ( $onenode =~ /^.*\[\'(.*)\'\].*$/ )
124				{
125					$onenode = $1;
126					$bracketnode = "bracket_" . $nodename;
127					$oneconfig->{$bracketnode} = 1;
128				}
129
130				$onenode =~ s/SUBSTITUTEDSLASH/\//g;	# substituting "SUBSTITUTEDSLASH" to "/"
131				$oneconfig->{$nodename} = $onenode;
132
133				# special handling for nodes "Factories"
134
135				if ( $onenode eq "Factories" ) { $oneconfig->{'factoriesnode'} = $counter; }
136				else { $oneconfig->{'factoriesnode'} = -99; }
137			}
138
139			$counter++
140		}
141
142		# and the final node
143
144		if ( $nodes =~ /^\s*Filter\[\'(.*)\'\].*$/ ) { $oneconfig->{'isfilter'} = 1; }
145
146		$nodename = "node". $counter;
147
148		if ( $nodes =~ /^.*\[\'(.*)\'\].*$/ )
149		{
150			$nodes = $1;
151			$bracketnode = "bracket_" . $nodename;
152			$oneconfig->{$bracketnode} = 1;
153		}
154
155		$nodes =~ s/SUBSTITUTEDSLASH/\//g;	# substituting "SUBSTITUTEDSLASH" to "/"
156
157		if (($nodes eq "Name") || ($nodes eq "Title"))	# isocodes below "Name" or "Title"
158		{
159			# if the last node $nodes is "Name" or "Title", it is a Property, not a name! See Common.xcu
160
161			$oneconfig->{'isisocode'} = 1;
162
163			if ( $nodes eq "Name" ) { $oneconfig->{'isname'} = 1; }
164			if ( $nodes eq "Title" ) { $oneconfig->{'istitle'} = 1;	}
165			$counter--;		# decreasing the counter, because "Name" and "Title" are no nodes
166		}
167		else
168		{
169			$oneconfig->{$nodename} = $nodes;
170			$oneconfig->{'isisocode'} = 0;
171		}
172
173		# special handling for nodes "Factories"
174
175		if ( $onenode eq "Factories" ) { $oneconfig->{'factoriesnode'} = $counter; }
176		else { $oneconfig->{'factoriesnode'} = -99; }
177
178		# saving the number of nodes
179
180		$oneconfig->{'nodenumber'} = $counter;
181	}
182}
183
184####################################################################
185# Inserting the start block into a configuration file
186####################################################################
187
188sub insert_start_block_into_configfile
189{
190	my ($configfileref, $oneconfig) = @_;
191
192	if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::configuration::insert_start_block_into_configfile : $#{$configfileref} : $oneconfig->{'name'}"); }
193
194	my $line = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
195	push( @{$configfileref}, $line);
196
197	$line = '<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:install="http://openoffice.org/2004/installation" oor:name="FILENAME" oor:package="PACKAGENAME">' . "\n";
198	my $packagename = $oneconfig->{'packagename'};
199	my $name = $oneconfig->{'name'};
200	$line =~ s/PACKAGENAME/$packagename/g;
201	$line =~ s/FILENAME/$name/g;
202	push( @{$configfileref}, $line);
203
204	$line = "\n";
205	push( @{$configfileref}, $line);
206}
207
208####################################################################
209# Inserting the end block into a configuration file
210####################################################################
211
212sub insert_end_block_into_configfile
213{
214	my ($configfileref) = @_;
215
216	if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::configuration::insert_end_block_into_configfile : $#{$configfileref}"); }
217
218	my $line = "\n" . '</oor:component-data>' . "\n";
219	push( @{$configfileref}, $line);
220}
221
222##############################################################
223# Getting the content of a node
224##############################################################
225
226sub get_node_content
227{
228	my ($nodeline) = @_;
229
230	if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::configuration::get_node_content : $nodeline"); }
231
232	my $content = "";
233
234	if ( $nodeline =~ /name\=\"(.*?)\"/ )
235	{
236		$content = $1;
237	}
238	else
239	{
240		installer::exiter::exit_program("ERROR: Impossible error in function get_node_content!", "get_node_content");
241	}
242
243	return \$content;
244}
245
246##############################################################
247# Getting the line number of an existing node
248# Return "-1" if node does not exist
249##############################################################
250
251sub get_node_line_number
252{
253	my ($nodecount, $oneconfig, $oneconfigfileref) = @_;
254
255	if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::configuration::get_node_line_number : $nodecount : $oneconfig->{'name'} : $#{$oneconfigfileref}"); }
256
257	my $linenumber = -1;	# the node does not exists, if returnvalue is "-1"
258
259	# Attention: Take care of the two title nodes:
260	# Path=org.openoffice.Office.Common/Menus/Wizard/*['m14']/Title
261	# Path=org.openoffice.Office.Common/Menus/Wizard/*['m15']/Title
262	# -> every subnode has to be identical
263
264	# creating the allnodes string from $oneconfig
265
266	my $allnodes = "";
267
268	for ( my $i = 1; $i <= $nodecount; $i++ )
269	{
270		my $nodename = "node" . $i;
271		$allnodes .= $oneconfig->{$nodename} . "/";
272	}
273
274	installer::remover::remove_leading_and_ending_slashes(\$allnodes);	# exactly this string has to be found  in the following iteration
275
276	# Iterating over the already built configuration file
277
278	my @allnodes = ();
279
280	for ( my $i = 0; $i <= $#{$oneconfigfileref}; $i++ )
281	{
282		my $line = ${$oneconfigfileref}[$i];
283		installer::remover::remove_leading_and_ending_whitespaces(\$line);
284		my $nodechanged = 0;
285
286		if ( $line =~ /^\s*\<node/ )	# opening node
287		{
288			$nodechanged = 1;
289			my $nodecontentref = get_node_content($line);
290			push(@allnodes, $$nodecontentref);	# collecting all nodes in an array
291		}
292
293		if ( $line =~ /^\s*\<\/node/ )	# ending node
294		{
295			$nodechanged = 1;
296			pop(@allnodes);		# removing the last node from the array
297		}
298
299		if (( $nodechanged ) && ($#allnodes > -1))	# a node was found and the node array is not empty
300		{
301			# creating the string to compare with the string $allnodes
302
303			my $nodestring = "";
304
305			for ( my $j = 0; $j <= $#allnodes; $j++ )
306			{
307				$nodestring .= $allnodes[$j] . "/";
308			}
309
310			installer::remover::remove_leading_and_ending_slashes(\$nodestring);
311
312			if ( $nodestring eq $allnodes )
313			{
314				# that is exactly the same node
315
316				$linenumber = $i;
317				$linenumber++;	# increasing the linenumber
318				last;
319
320			}
321		}
322	}
323
324	return $linenumber;
325}
326
327##############################################################
328# Inserting one configurationitem into the configurationfile
329##############################################################
330
331sub insert_into_config_file
332{
333	my ($oneconfig, $oneconfigfileref) = @_;
334
335	if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::configuration::insert_into_config_file : $oneconfig->{'nodenumber'} : $#{$oneconfigfileref}"); }
336
337	my ($nodename, $nodecontent, $newnodeline, $bracketkey, $line, $insertline);
338
339	# interpreting the nodes, keys and values
340
341	my $nodeline = '<node oor:name="NODECONTENT" REPLACEPART >' . "\n";
342	my $propline = '<prop oor:name="KEYCONTENT" REPLACEPART TYPEPART>' . "\n";
343	my $valueline = '<value SEPARATORPART>VALUECONTENT</value>' . "\n";
344	my $langvalueline = '<value xml:lang="SAVEDLANGUAGE">VALUECONTENT</value>' . "\n";
345	my $propendline = '</prop>' . "\n";
346	my $nodeendline = '</node>' . "\n";
347
348	my $replacepart = 'oor:op="replace"';
349	my $typepart = 'oor:type="xs:VALUETYPE"';	# VALUETYPE can be "string", "boolean", ...
350
351	my $nodecount = $oneconfig->{'nodenumber'};
352	my $styles = $oneconfig->{'Styles'};
353
354	for ( my $i = 1; $i <= $nodecount; $i++ )
355	{
356		$insertline = get_node_line_number($i, $oneconfig, $oneconfigfileref);
357
358		if ( $insertline == -1)	# if true, the node does not exist
359		{
360			$nodename = "node" . $i;
361			$nodecontent = $oneconfig->{$nodename};
362			$newnodeline = $nodeline;
363
364			$newnodeline =~ s/NODECONTENT/$nodecontent/g;
365
366			# Case1:
367			# Nodes with brackets, need the replacepart 'oor:op="replace"'
368			# Bracket node is set for each node with: bracket_node1=1, bracket_node2=1, ...
369			# Case a: <node oor:name="m0" oor:op="replace">		(Common.xcu needs oor:op="replace")
370			# Case b: <node oor:name="Ami Pro 1.x-3.1 (W4W)">	(TypeDetection.xcu does not need oor:op="replace")
371			# For case b introducting a special case for Filters
372
373			$bracketkey = "bracket_" . $nodename;
374
375			my $localbracketkey = 0;
376
377			if ( $oneconfig->{$bracketkey} ) { $localbracketkey = $oneconfig->{$bracketkey}; }
378
379			if ( $localbracketkey == 1 )	# 'oor:op="replace"' is needed
380			{
381				my $isfilter = 0;
382				if ( $oneconfig->{'isfilter'} ) { $isfilter = $oneconfig->{'isfilter'}; }
383
384				if ( $isfilter == 1 )	# this is a filter
385				{
386					$newnodeline =~ s/REPLACEPART//;
387				}
388				else
389				{
390					$newnodeline =~ s/REPLACEPART/$replacepart/;
391				}
392
393				$newnodeline =~ s/\s*\>/\>/;	# removing resulting whitespaces
394			}
395
396			# Case2:
397			# Nodes below a Node "Factories", also need the replacepart 'oor:op="replace"'
398			# This is saved in $oneconfig->{'factoriesnode'}. If not set, the value is "-99"
399
400			if ( $i == $oneconfig->{'factoriesnode'} )
401			{
402				$newnodeline =~ s/REPLACEPART/$replacepart/;
403				$newnodeline =~ s/\s*\>/\>/;	# removing resulting whitespaces
404			}
405
406			# Case3:
407			# In all other cases, REPLACEPART in nodes can be removed
408
409			$newnodeline =~ s/REPLACEPART//;
410			$newnodeline =~ s/\s*\>/\>/;	# removing resulting whitespaces
411
412			# Finding the correct place for inserting the node
413
414			if ( $i == 1 )	# this is a toplevel node
415			{
416				push(@{$oneconfigfileref}, $newnodeline);
417				push(@{$oneconfigfileref}, $nodeendline);
418			}
419			else
420			{
421				# searching for the parent node
422
423				my $parentnumber = $i-1;
424				$insertline = get_node_line_number($parentnumber, $oneconfig, $oneconfigfileref);
425				splice(@{$oneconfigfileref}, $insertline, 0, ($newnodeline, $nodeendline));
426			}
427		}
428	}
429
430	# Setting variables $isbracketnode and $isfactorynode for the properties
431
432
433	my $isbracketnode = 0;
434	my $isfactorynode = 0;
435
436	for ( my $i = 1; $i <= $nodecount; $i++ )
437	{
438		$nodename = "node" . $i;
439		$bracketkey = "bracket_" . $nodename;
440
441		my $localbracketkey = 0;
442		if ( $oneconfig->{$bracketkey} ) { $localbracketkey = $oneconfig->{$bracketkey}; }
443
444		if ( $localbracketkey == 1 ) { $isbracketnode = 1;	}
445		if ( $i == $oneconfig->{'factoriesnode'} ) { $isfactorynode = 1; }
446	}
447
448	# now all nodes exist, and the key and value can be inserted into the configfile
449	# the next line contains the key, for instance: <prop oor:name="UseDefaultMailer" oor:type="xs:boolean">
450	# my $propline = '<prop oor:name="KEYCONTENT" REPLACEPART TYPEPART>' . "\n";
451	# The type is only needed, if a replace is set.
452
453	my $newpropline = $propline;
454
455	# Replacement of KEYCONTENT, REPLACEPART and TYPEPART
456
457	# Case 1:
458	# Properties with oor:name="Name" (Common.xcu) are simply <prop oor:name="Name">
459	# The information about such a property is stored in $oneconfig->{'isisocode'}
460
461	if ( $oneconfig->{'isisocode'} )
462	{
463		if ( $oneconfig->{'isname'} ) { $newpropline =~ s/KEYCONTENT/Name/; }		# The property name is always "Name"
464		if ( $oneconfig->{'istitle'} ) { $newpropline =~ s/KEYCONTENT/Title/; }		# The property name is always "Title"
465		$newpropline =~ s/REPLACEPART//;
466		$newpropline =~ s/TYPEPART//;
467		$newpropline =~ s/\s*\>/\>/;	# removing resulting whitespaces
468	}
469
470	# Begin of all other cases
471
472	my $key = $oneconfig->{'Key'};
473	$newpropline =~ s/KEYCONTENT/$key/;
474
475	my $valuetype;
476
477	if ( $styles =~ /CFG_STRING\b/ ) { $valuetype = "string"; }
478	elsif ( $styles =~ /CFG_NUMERIC/ ) { $valuetype = "int"; }
479	elsif ( $styles =~ /CFG_BOOLEAN/ ) { $valuetype = "boolean"; }
480	elsif ( $styles =~ /CFG_STRINGLIST/ ) { $valuetype = "string-list"; }
481#	elsif ( $styles =~ /CFG_STRINGLIST/ ) { $valuetype = "string-list oor:separator=\"\|\""; }
482	else
483	{
484		installer::exiter::exit_program("ERROR: Unknown configuration value type: $styles", "insert_into_config_file");
485	}
486
487	# Case 2:
488	# Properties below a node "Factories" do not need a 'oor:op="replace"' and a 'oor:type="xs:VALUETYPE"'
489
490	if ( $isfactorynode )
491	{
492		$newpropline =~ s/REPLACEPART//;
493		$newpropline =~ s/TYPEPART//;
494		$newpropline =~ s/\s*\>/\>/;	# removing resulting whitespaces
495	}
496
497	# Case 3:
498	# Properties below a "bracket" node do not need a 'oor:op="replace"', except they are iso-codes
499	# Assumption here: They are multilingual
500
501	if ( $isbracketnode )
502	{
503		my $localtypepart = $typepart;
504		$localtypepart =~ s/VALUETYPE/$valuetype/;
505		$newpropline =~ s/TYPEPART/$localtypepart/;
506
507		if ( $oneconfig->{'ismultilingual'} )	# This is solved by "Name" and "Title"
508		{
509			$newpropline =~ s/REPLACEPART/$replacepart/;
510		}
511		else
512		{
513			$newpropline =~ s/REPLACEPART//;
514		}
515
516		$newpropline =~ s/\s*\>/\>/;	# removing resulting whitespaces
517	}
518
519	# Case 4:
520	# if the flag CREATE is set, the properties get 'oor:op="replace"' and 'oor:type="xs:VALUETYPE"'
521
522	if (( $styles =~ /\bCREATE\b/ ) && (!($isbracketnode)))
523	{
524		# my $typepart = 'oor:type="xs:VALUETYPE"';	# VALUETYPE can be "string", "boolean", ...
525
526		my $localtypepart = $typepart;
527		$localtypepart =~ s/VALUETYPE/$valuetype/;
528
529		$newpropline =~ s/TYPEPART/$localtypepart/;
530		$newpropline =~ s/REPLACEPART/$replacepart/;
531		$newpropline =~ s/\s*\>/\>/;	# removing resulting whitespaces
532	}
533
534	# Case 5:
535	# all other ConfigurationItems do not need 'oor:op="replace"' and 'oor:type="xs:VALUETYPE"'
536
537	$newpropline =~ s/REPLACEPART//;
538	$newpropline =~ s/TYPEPART//;
539	$newpropline =~ s/\s*\>/\>/;	# removing resulting whitespaces
540
541	# finally the value can be set
542
543	my $value = $oneconfig->{'Value'};
544
545	# Some values in setup script are written during installation process by the setup. These
546	# have values like "<title>". This will lead to an error, because of the brackets. Therefore the
547	# brackets have to be removed.
548
549	# ToDo: Substituting the setup replace variables
550
551	# replace_setting_variables();
552
553	$value =~ s/^\s*\<//;
554	$value =~ s/\>\s*$//;
555
556	# Deal with list separators
557	my $separatorpart = '';
558	if ( ($valuetype eq "string-list") && ($value =~ /\|/) )
559    {
560	    $separatorpart = 'oor:separator="|"';
561    }
562
563	# Fake: substituting german umlauts
564
565	$value =~ s/\�/ae/;
566	$value =~ s/\�/oe/;
567	$value =~ s/\�/ue/;
568	$value =~ s/\�/AE/;
569	$value =~ s/\�/OE/;
570	$value =~ s/\�/UE/;
571
572	my $newvalueline;
573
574	if (!($oneconfig->{'isisocode'} ))	# this is the simpe case
575	{
576		# my $valueline = '<value SEPARATORPART>VALUECONTENT</value>' . "\n";
577		$newvalueline = $valueline;
578		$newvalueline =~ s/VALUECONTENT/$value/g;
579		$newvalueline =~ s/SEPARATORPART/$separatorpart/;
580	}
581	else
582	{
583		# my $langvalueline = '<value xml:lang="SAVEDLANGUAGE">VALUECONTENT</value>' . "\n";
584		$newvalueline = $langvalueline;
585		$newvalueline =~ s/VALUECONTENT/$value/;
586		my $savedlanguage = $oneconfig->{'Key'};
587		$newvalueline =~ s/SAVEDLANGUAGE/$savedlanguage/;
588	}
589
590	# For language dependent values, it is possible, that the property already exist.
591	# In this case the prop must not be created again and only the value has to be included:
592	# <prop oor:name="Name">
593	#  <value xml:lang="de">OpenOffice.org 2.0 Diagramm</value>
594	#  <value xml:lang="en-US">OpenOffice.org 2.0 Chart</value>
595	# </prop>
596
597	# The key has to be written after the line, containing the complete node
598
599	$insertline = get_node_line_number($nodecount, $oneconfig, $oneconfigfileref);
600
601	if ( $oneconfig->{'ismultilingual'} )
602	{
603		if ( $newpropline eq ${$oneconfigfileref}[$insertline] )
604		{
605			if (!($newvalueline eq ${$oneconfigfileref}[$insertline+1]))	# only include, if the value not already exists (example: value="FALSE" for many languages)
606			{
607				splice(@{$oneconfigfileref}, $insertline+1, 0, ($newvalueline));	# only the value needs to be added
608			}
609		}
610		else
611		{
612			splice(@{$oneconfigfileref}, $insertline, 0, ($newpropline, $newvalueline, $propendline));
613		}
614	}
615	else
616	{
617		splice(@{$oneconfigfileref}, $insertline, 0, ($newpropline, $newvalueline, $propendline));
618	}
619
620	return $oneconfigfileref;
621}
622
623##########################################################
624# Inserting tabs for better view into configuration file
625##########################################################
626
627sub insert_tabs_into_configfile
628{
629	my ($configfileref) = @_;
630
631	if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::configuration::insert_tabs_into_configfile : $#{$configfileref}"); }
632
633	my $counter = 0;
634
635	for ( my $i = 0; $i <= $#{$configfileref}; $i++ )
636	{
637		my $line = ${$configfileref}[$i];
638		my $linebefore = ${$configfileref}[$i-1];
639
640		if (( $line =~ /^\s*\<node/ ) || ( $line =~ /^\s*\<prop/ ))
641		{
642			if ((!( $linebefore =~ /^\s*\<\/node/ )) && (!( $linebefore =~ /^\s*\<\/prop/ )))		# do not increase after "</node" and after "</prop"
643			{
644				$counter++;
645			}
646		}
647
648		if ( $line =~ /^\s*\<value/ )
649		{
650			if (!($linebefore =~ /^\s*\<value/ ))		# do not increase counter with "<value>" after "<value>" (multilingual configitems)
651			{
652				$counter++;
653			}
654		}
655
656		if (( $line =~ /^\s*\<\/node\>/ ) || ( $line =~ /^\s*\<\/prop\>/ ))
657		{
658			if ((!( $linebefore =~ /^\s*\<node/ )) && (!( $linebefore =~ /^\s*\<prop/ )))		# do not decrease after "<node" and after "<prop"
659			{
660				$counter--;
661			}
662		}
663
664		if ($counter > 0)
665		{
666			for ( my $j = 0; $j < $counter; $j++ )
667			{
668				$line = "\t" . $line;
669			}
670		}
671
672		${$configfileref}[$i] = $line;
673	}
674}
675
676######################################################################
677# Collecting all different configuration items (Files and Modules)
678######################################################################
679
680sub collect_all_configuration_items
681{
682	my ($configurationitemsref, $item) = @_;
683
684	if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::configuration::collect_all_configuration_items : $#{$configurationitemsref} : $item"); }
685
686	my @allitems = ();
687
688	for ( my $i = 0; $i <= $#{$configurationitemsref}; $i++ )
689	{
690		my $oneconfig = ${$configurationitemsref}[$i];
691
692		if (! installer::existence::exists_in_array($oneconfig->{$item}, \@allitems))
693		{
694			push(@allitems, $oneconfig->{$item});
695		}
696	}
697
698	return \@allitems;
699}
700
701######################################################################
702# Collecting all module specific configuration items
703######################################################################
704
705sub get_all_configitems_at_module
706{
707	my ($moduleid, $configurationitemsref) = @_;
708
709	if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::configuration::get_all_configitems_at_module : $moduleid : $#{$configurationitemsref}"); }
710
711	my @moduleconfigurationitems = ();
712
713	for ( my $i = 0; $i <= $#{$configurationitemsref}; $i++ )
714	{
715		my $oneconfig = ${$configurationitemsref}[$i];
716
717		if ( $oneconfig->{'ModuleID'} eq $moduleid )
718		{
719			push(@moduleconfigurationitems, $oneconfig);
720		}
721	}
722
723	return \@moduleconfigurationitems;
724}
725
726#######################################################
727# Saving and zipping the created configurationfile
728#######################################################
729
730sub save_and_zip_configfile
731{
732	my ($oneconfigfileref, $onefile, $onemodule, $configdir) = @_;
733
734	if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::configuration::save_and_zip_configfile : $#{$oneconfigfileref} : $onefile : $onemodule : $configdir"); }
735
736	my $savefilename = $onefile;
737	$savefilename =~ s/\./\_/g;
738	$savefilename = $savefilename . "_" . $onemodule;
739	$savefilename = $savefilename . ".xcu";
740	my $shortsavefilename = $savefilename;
741
742	$savefilename = $configdir . $installer::globals::separator . $savefilename;
743
744	installer::files::save_file($savefilename, $oneconfigfileref);
745
746	# zipping the configfile
747
748	my $returnvalue = 1;
749
750	my $zipfilename = $shortsavefilename;
751	$zipfilename =~ s/\.xcu/\.zip/;
752
753	my $currentdir = cwd();
754	if ( $installer::globals::iswin ) { $currentdir =~ s/\//\\/g; }
755
756	chdir($configdir);
757
758 	my $systemcall = "$installer::globals::zippath -q -m $zipfilename $shortsavefilename";
759	$returnvalue = system($systemcall);
760
761	chdir($currentdir);
762
763    $installer::logger::Lang->printf("Systemcall: %s\n", $systemcall);
764
765	if ($returnvalue)
766	{
767        $installer::logger::Lang->printf("ERROR: Could not zip %s to %s\n", $savefilename, $zipfilename);
768	}
769	else
770	{
771        $installer::logger::Lang->printf("SUCCESS: Zipped file %s to %s\n", $savefilename, $zipfilename);
772	}
773
774	return $zipfilename;
775}
776
777#####################################################################
778# Adding the newly created configuration file into the file list
779#####################################################################
780
781sub add_zipfile_into_filelist
782{
783	my ($zipfilename, $configdir, $filesarrayref, $onemodule) = @_;
784
785	if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::configuration::add_zipfile_into_filelist: $zipfilename : $configdir : $#{$filesarrayref} : $onemodule"); }
786
787	my $longzipfilename = $configdir . $installer::globals::separator . $zipfilename;
788	my $gid = "gid_" . $zipfilename;
789	$gid =~ s/\./\_/g;
790
791	my %configfile = ();
792
793	# Taking the base data from the "gid_File_Lib_Vcl"
794
795	my $vclgid = "gid_File_Lib_Vcl";
796	my $vclfile = installer::existence::get_specified_file($filesarrayref, $vclgid);
797
798	# copying all base data
799	installer::converter::copy_item_object($vclfile, \%configfile);
800
801	# and overriding all new data
802	$configfile{'ismultilingual'} = 0;
803	$configfile{'sourcepath'} = $longzipfilename;
804	$configfile{'Name'} = $zipfilename;
805	$configfile{'UnixRights'} = "644";
806	$configfile{'gid'} = $gid;
807	$configfile{'Dir'} = "gid_Dir_Share_Uno_Packages";
808	$configfile{'destination'} = "share" . $installer::globals::separator . "uno_packages" . $installer::globals::separator . $zipfilename;
809	$configfile{'modules'} = $onemodule;	# assigning the file to the correct module!
810
811	push(@{$filesarrayref}, \%configfile);
812}
813
814#######################################################
815# Creating configuration files from configurationitems
816#######################################################
817
818sub create_configuration_files
819{
820	my ($configurationitemsref, $filesarrayref, $languagestringref) = @_;
821
822	if ( $installer::globals::debug ) { installer::logger::debuginfo("installer::configuration::create_configuration_files: $#{$configurationitemsref} : $#{$filesarrayref} : $$languagestringref"); }
823
824	installer::logger::include_header_into_logfile("Creating configuration files:");
825
826	# creating the directory
827
828	my $configdir = installer::systemactions::create_directories("configfiles", $languagestringref);
829
830	$configdir = installer::converter::make_path_conform($configdir);
831
832	# collecting an array of all modules
833	my $allmodules = collect_all_configuration_items($configurationitemsref, "ModuleID");
834
835	# iterating over all modules
836
837	for ( my $i = 0; $i <= $#{$allmodules}; $i++ )
838	{
839		my $onemodule = ${$allmodules}[$i];
840
841		my $moduleconfigitems = get_all_configitems_at_module($onemodule, $configurationitemsref);
842
843		# collecting an array of all "startpath". This are all different files (org.openoffice.Office.Common).
844		my $allfiles = collect_all_configuration_items($moduleconfigitems, "startpath");
845
846		# iteration over all files
847
848		for ( my $j = 0; $j <= $#{$allfiles}; $j++ )
849		{
850			my $onefile = ${$allfiles}[$j];
851
852			my @oneconfigfile = ();
853			my $oneconfigfileref = \@oneconfigfile;
854
855			my $startblockwritten = 0;
856
857			for ( my $k = 0; $k <= $#{$moduleconfigitems}; $k++ )
858			{
859				my $oneconfig = ${$moduleconfigitems}[$k];
860
861				my $startpath = $oneconfig->{'startpath'};
862
863				if ($startpath eq $onefile)
864				{
865					if (!($startblockwritten))	# writing some global lines into the xcu file
866					{
867						insert_start_block_into_configfile($oneconfigfileref, $oneconfig);
868						$startblockwritten = 1;
869					}
870
871					$oneconfigfileref = insert_into_config_file($oneconfig, $oneconfigfileref);
872				}
873			}
874
875			insert_end_block_into_configfile($oneconfigfileref);
876
877			# inserting tabs for nice appearance
878			insert_tabs_into_configfile($oneconfigfileref);
879
880			# saving the configfile
881			my $zipfilename = save_and_zip_configfile($oneconfigfileref, $onefile, $onemodule, $configdir);
882
883			# adding the zipped configfile to the list of installed files
884			# Some data are set now, others are taken from the file "soffice.exe" ("soffice.bin")
885
886			add_zipfile_into_filelist($zipfilename, $configdir, $filesarrayref, $onemodule);
887		}
888	}
889
890    $installer::logger::Lang->print("\n");
891}
892
8931;
894