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