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