xref: /AOO41X/main/solenv/bin/modules/installer/configuration.pm (revision fe22d2cfc602815794415026f1317bd625db6f83)
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