Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/directory.pm URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/directory.pm?rev=1551937&r1=1551936&r2=1551937&view=diff ============================================================================== --- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/directory.pm (original) +++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/directory.pm Wed Dec 18 13:27:09 2013 @@ -29,6 +29,9 @@ use installer::globals; use installer::pathanalyzer; use installer::windows::idtglobal; use installer::windows::msiglobal; +use installer::scriptitems; + +use strict; ############################################################## # Collecting all directory trees in global hash @@ -73,12 +76,22 @@ sub overwrite_programfilesfolder } } -############################################################## -# Maximum length of directory name is 72. -# Taking care of underlines, which are the separator. -############################################################## -sub make_short_dir_version + + +=head2 make_short_dir_version($longstring) + + Transform the given string into one that is at most 70 characters long. + That is done in two steps: + - Cut all parts separated by '_' or '-' down to a length of 5. + - Cut down the result to a length of 60 and fill it up to length 70 + with the MD5 checksum. + + This transform always returns the same result for the same string. + There is no counter and reference to a global set of names to make the string unique. + +=cut +sub make_short_dir_version ($) { my ($longstring) = @_; @@ -90,29 +103,24 @@ sub make_short_dir_version # Splitting the string at each "underline" and allowing only $length characters per directory name. # Checking also uniqueness and length. - my $stringarray = installer::converter::convert_stringlist_into_array_without_newline(\$longstring, "_"); - - foreach my $onestring ( @{$stringarray} ) + my @outer_parts = split(/_/, $longstring); + foreach my $onestring (@outer_parts) { my $partstring = ""; if ( $onestring =~ /\-/ ) { - my $localstringarray = installer::converter::convert_stringlist_into_array_without_newline(\$onestring, "-"); - foreach my $onelocalstring ( @{$localstringarray} ) - { - if ( length($onelocalstring) > $length ) { $onelocalstring = substr($onelocalstring, 0, $length); } - $partstring = $partstring . "-" . $onelocalstring; - } + my @inner_parts = split(/-/, $onestring); + @inner_parts = map {substr($_,0,$length)} @inner_parts; + $partstring = join("-", @inner_parts); $partstring =~ s/^\s*\-//; } else { - if ( length($onestring) > $length ) { $partstring = substr($onestring, 0, $length); } - else { $partstring = $onestring; } + $partstring = substr($onestring, 0, $length); } - $shortstring = $shortstring . "_" . $partstring; + $shortstring .= "_" . $partstring; } $shortstring =~ s/^\s*\_//; @@ -120,185 +128,311 @@ sub make_short_dir_version # Setting unique ID to each directory # No counter allowed, process must be absolute reproducable due to patch creation process. - # chomp(my $id = `echo $longstring_save | md5sum | sed -e "s/ .*//g"`); # Very, very slow - # my $subid = substr($id, 0, 9); # taking only the first 9 digits - my $subid = installer::windows::msiglobal::calculate_id($longstring_save, 9); # taking only the first 9 digits - - if ( length($shortstring) > $cutlength ) { $shortstring = substr($shortstring, 0, $cutlength); } - - $shortstring = $shortstring . "_" . $subid; + $shortstring = substr($shortstring, 0, $cutlength) . "_" . $subid; return $shortstring; } -############################################################## -# Adding unique directory names to the directory collection -############################################################## -sub create_unique_directorynames -{ - my ($directoryref, $allvariables) = @_; - $installer::globals::officeinstalldirectoryset = 0; - my %completedirhashstep1 = (); - my %shortdirhash = (); - my %shortdirhashreverse = (); - my $infoline = ""; - my $errorcount = 0; +=head2 get_unique_name ($hostname, $unique_map, $shortdirhash, $shortdirhashreverse) - for ( my $i = 0; $i <= $#{$directoryref}; $i++ ) - { - my $onedir = ${$directoryref}[$i]; - my $uniquename = $onedir->{'HostName'}; + Return a long and a short unique name for the given $hostname. + Despite the function name and unlike the generation of unique + names for files, the returned names are not really unique. Quite + the opposite. The returned names are quaranteed to return the + same result for the same input. + + The returned short name has at most length 70. + +=cut +sub get_unique_name ($$) +{ + my ($hostname, $hostnamehash) = @_; + + # Make sure that we where not called for this hostname before. Otherwise the other test would be triggered. + if (defined $hostnamehash->{$hostname}) + { + installer::exiter::exit_program( + "ERROR: get_unique_name was already called for hostname ".$hostname, + "get_unique_name"); + } + $hostnamehash->{$hostname} = 1; + + my $uniquename = $hostname; + + $uniquename =~ s/^\s*//g; # removing beginning white spaces + $uniquename =~ s/\s*$//g; # removing ending white spaces + $uniquename =~ s/\s//g; # removing white spaces + $uniquename =~ s/\_//g; # removing existing underlines + $uniquename =~ s/\.//g; # removing dots in directoryname + $uniquename =~ s/OpenOffice/OO/g; + + $uniquename =~ s/\Q$installer::globals::separator\E/\_/g; # replacing slash and backslash with underline + + $uniquename =~ s/_registry/_rgy/g; + $uniquename =~ s/_registration/_rgn/g; + $uniquename =~ s/_extension/_ext/g; + $uniquename =~ s/_frame/_frm/g; + $uniquename =~ s/_table/_tbl/g; + $uniquename =~ s/_chart/_crt/g; + + my $short_uniquename = make_short_dir_version($uniquename); + + return ($uniquename, $short_uniquename); +} - my $styles = ""; - if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; } - $uniquename =~ s/^\s*//g; # removing beginning white spaces - $uniquename =~ s/\s*$//g; # removing ending white spaces - $uniquename =~ s/\s//g; # removing white spaces - $uniquename =~ s/\_//g; # removing existing underlines - $uniquename =~ s/\.//g; # removing dots in directoryname - $uniquename =~ s/OpenOffice/OO/g; - $uniquename =~ s/\Q$installer::globals::separator\E/\_/g; # replacing slash and backslash with underline - $uniquename =~ s/_registry/_rgy/g; - $uniquename =~ s/_registration/_rgn/g; - $uniquename =~ s/_extension/_ext/g; - $uniquename =~ s/_frame/_frm/g; - $uniquename =~ s/_table/_tbl/g; - $uniquename =~ s/_chart/_crt/g; +=head2 check_unique_directorynames($directories) + + The one really important check is made in get_unique_name(). It + checks that get_unique_name() is not called twice for the same + directory host name. The tests in this function contain the + legacy tests that basically only check if there where a collision + of the partial MD5 sum that is used to make the short unique names + unique. + + The maps $unique_map, $shortdirhash, $shortdirhashreverse are used + only to check that _different_ input names are mapped to different + results. They are not used to influence the result. That assumes + that this function is called only once for every directory + hostname. +=cut +sub check_unique_directorynames ($) +{ + my ($directories) = @_; - # The names after this small changes must still be unique! - if ( exists($completedirhashstep1{$uniquename}) ) { installer::exiter::exit_program("ERROR: Error in packaging process. Unallowed modification of directory name, not unique (step 1): \"$uniquename\".", "create_unique_directorynames"); } - $completedirhashstep1{$uniquename} = 1; + my %completedirhashstep1 = (); + my %shortdirhash = (); + my %shortdirhashreverse = (); - # Starting to make unique name for the parent and its directory - my $originaluniquename = $uniquename; + # Check unique name of directories. + foreach my $directory (@$directories) + { + my ($long_uniquename, $short_uniquename) = ($directory->{'long_uniquename'}, $directory->{'uniquename'}); + + # The names after this small changes must still be unique! + if (exists($completedirhashstep1{$long_uniquename})) + { + installer::exiter::exit_program( + sprintf("ERROR: Unallowed modification of directory name, not unique (step 1): \"%s\".", + $short_uniquename), + "check_unique_directorynames"); + } + $completedirhashstep1{$long_uniquename} = 1; + + + # Checking if the same directory already exists, but has another short version. + if (exists($shortdirhash{$long_uniquename}) + && ( $shortdirhash{$long_uniquename} ne $short_uniquename )) + { + installer::exiter::exit_program( + sprintf( + "ERROR: Unallowed modification of directory name, not unique (step 2A): \"%s\".", + $short_uniquename), + "check_unique_directorynames"); + } + $shortdirhash{$long_uniquename} = $short_uniquename; + + # Also checking vice versa + # Checking if the same short directory already exists, but has another long version. + if (exists($shortdirhashreverse{$short_uniquename}) + && ( $shortdirhashreverse{$short_uniquename} ne $long_uniquename )) + { + installer::exiter::exit_program( + sprintf( + "ERROR: Unallowed modification of directory name, not unique (step 2B): \"%s\".", + $short_uniquename), + "check_unique_directorynames"); + } + $shortdirhashreverse{$short_uniquename} = $long_uniquename; + } + + # Check unique name of parents + foreach my $directory (@$directories) + { + my ($long_uniquename, $short_uniquename) + = ($directory->{'long_uniqueparentname'}, $directory->{'uniqueparentname'}); + + # Again checking if the same directory already exists, but has another short version. + if (exists($shortdirhash{$long_uniquename}) + && ( $shortdirhash{$long_uniquename} ne $short_uniquename )) + { + installer::exiter::exit_program( + sprintf( + "ERROR: Unallowed modification of directory name, not unique (step 3A): \"%s\".", + $short_uniquename), + "check_unique_directorynames"); + } + $shortdirhash{$long_uniquename} = $short_uniquename; + + # Also checking vice versa + # Checking if the same short directory already exists, but has another long version. + if (exists($shortdirhashreverse{$short_uniquename}) + && ( $shortdirhashreverse{$short_uniquename} ne $long_uniquename )) + { + installer::exiter::exit_program( + sprintf( + "ERROR: Unallowed modification of directory name, not unique (step 3B): \"%s\".", + $short_uniquename), + "check_unique_directorynames"); + } + $shortdirhashreverse{$short_uniquename} = $long_uniquename; + } +} - $uniquename = make_short_dir_version($uniquename); - # Checking if the same directory already exists, but has another short version. - if (( exists($shortdirhash{$originaluniquename}) ) && ( $shortdirhash{$originaluniquename} ne $uniquename )) { installer::exiter::exit_program("ERROR: Error in packaging process. Unallowed modification of directory name, not unique (step 2A): \"$uniquename\".", "create_unique_directorynames"); } - # Also checking vice versa - # Checking if the same short directory already exists, but has another long version. - if (( exists($shortdirhashreverse{$uniquename}) ) && ( $shortdirhashreverse{$uniquename} ne $originaluniquename )) { installer::exiter::exit_program("ERROR: Error in packaging process. Unallowed modification of directory name, not unique (step 2B): \"$uniquename\".", "create_unique_directorynames"); } - # Creating assignment from long to short directory names - $shortdirhash{$originaluniquename} = $uniquename; - $shortdirhashreverse{$uniquename} = $originaluniquename; +sub get_unique_parent_name ($$) +{ + my ($uniqueparentname, $styles) = @_; + + my $keepparent = 1; + + if ( $uniqueparentname =~ /^\s*(.*)\_(.*?)\s*$/ ) # the underline is now the separator + { + $uniqueparentname = $1; + $keepparent = 0; + } + else + { + $uniqueparentname = $installer::globals::programfilesfolder; + $keepparent = 1; + } + + if ( $styles =~ /\bPROGRAMFILESFOLDER\b/ ) + { + $uniqueparentname = $installer::globals::programfilesfolder; + $keepparent = 1; + } + if ( $styles =~ /\bCOMMONFILESFOLDER\b/ ) + { + $uniqueparentname = $installer::globals::commonfilesfolder; + $keepparent = 1; + } + if ( $styles =~ /\bCOMMONAPPDATAFOLDER\b/ ) + { + $uniqueparentname = $installer::globals::commonappdatafolder; + $keepparent = 1; + } + if ( $styles =~ /\bLOCALAPPDATAFOLDER\b/ ) + { + $uniqueparentname = $installer::globals::localappdatafolder; + $keepparent = 1; + } + + if ( $styles =~ /\bSHAREPOINTPATH\b/ ) + { + $uniqueparentname = "SHAREPOINTPATH"; + $installer::globals::usesharepointpath = 1; + $keepparent = 1; + } + + # also setting short directory name for the parent + + my $originaluniqueparentname = $uniqueparentname; + + if ( ! $keepparent ) + { + $uniqueparentname = make_short_dir_version($uniqueparentname); + } - # Important: The unique parent is generated from the string $originaluniquename (with the use of underlines). + return ($originaluniqueparentname, $uniqueparentname); +} - my $uniqueparentname = $originaluniquename; - my $keepparent = 1; - if ( $uniqueparentname =~ /^\s*(.*)\_(.*?)\s*$/ ) # the underline is now the separator - { - $uniqueparentname = $1; - $keepparent = 0; - } - else - { - $uniqueparentname = $installer::globals::programfilesfolder; - $keepparent = 1; - } - if ( $styles =~ /\bPROGRAMFILESFOLDER\b/ ) - { - $uniqueparentname = $installer::globals::programfilesfolder; - $keepparent = 1; - } - if ( $styles =~ /\bCOMMONFILESFOLDER\b/ ) - { - $uniqueparentname = $installer::globals::commonfilesfolder; - $keepparent = 1; - } - if ( $styles =~ /\bCOMMONAPPDATAFOLDER\b/ ) - { - $uniqueparentname = $installer::globals::commonappdatafolder; - $keepparent = 1; - } - if ( $styles =~ /\bLOCALAPPDATAFOLDER\b/ ) - { - $uniqueparentname = $installer::globals::localappdatafolder; - $keepparent = 1; - } - if ( $styles =~ /\bSHAREPOINTPATH\b/ ) - { - $uniqueparentname = "SHAREPOINTPATH"; - $installer::globals::usesharepointpath = 1; - $keepparent = 1; - } +############################################################## +# Adding unique directory names to the directory collection +############################################################## - # also setting short directory name for the parent - - my $originaluniqueparentname = $uniqueparentname; +sub create_unique_directorynames ($) +{ + my ($directories) = @_; - if ( ! $keepparent ) - { - $uniqueparentname = make_short_dir_version($uniqueparentname); - } + $installer::globals::officeinstalldirectoryset = 0; + + my %hostnamehash = (); + my $infoline = ""; + my $errorcount = 0; + + foreach my $directory (@$directories) + { + next if defined $directory->{'uniquename'}; + + my $styles = $directory->{'Styles'} // ""; - # Again checking if the same directory already exists, but has another short version. - if (( exists($shortdirhash{$originaluniqueparentname}) ) && ( $shortdirhash{$originaluniqueparentname} ne $uniqueparentname )) { installer::exiter::exit_program("ERROR: Error in packaging process. Unallowed modification of directory name, not unique (step 3A): \"$uniqueparentname\".", "create_unique_directorynames"); } + my ($originaluniquename, $uniquename) = get_unique_name( + $directory->{'HostName'}, + \%hostnamehash); - # Also checking vice versa - # Checking if the same short directory already exists, but has another long version. - if (( exists($shortdirhashreverse{$uniqueparentname}) ) && ( $shortdirhashreverse{$uniqueparentname} ne $originaluniqueparentname )) { installer::exiter::exit_program("ERROR: Error in packaging process. Unallowed modification of directory name, not unique (step 3B): \"$uniqueparentname\".", "create_unique_directorynames"); } + my ($originaluniqueparentname, $uniqueparentname) = get_unique_parent_name( + $originaluniquename, + $styles); - $shortdirhash{$originaluniqueparentname} = $uniqueparentname; - $shortdirhashreverse{$uniqueparentname} = $originaluniqueparentname; # Hyphen not allowed in database $uniquename =~ s/\-/\_/g; # making "-" to "_" $uniqueparentname =~ s/\-/\_/g; # making "-" to "_" # And finally setting the values for the directories - $onedir->{'uniquename'} = $uniquename; - $onedir->{'uniqueparentname'} = $uniqueparentname; - + $directory->{'uniquename'} = $uniquename; + $directory->{'uniqueparentname'} = $uniqueparentname; + $directory->{'long_uniquename'} = $originaluniquename; + $directory->{'long_uniqueparentname'} = $originaluniqueparentname; + } + + # Find the installation directory. + foreach my $directory (@$directories) + { + next unless defined $directory->{'Styles'}; + # setting the installlocation directory - if ( $styles =~ /\bISINSTALLLOCATION\b/ ) - { - if ( $installer::globals::installlocationdirectoryset ) { installer::exiter::exit_program("ERROR: Directory with flag ISINSTALLLOCATION alread set: \"$installer::globals::installlocationdirectory\".", "create_unique_directorynames"); } - $installer::globals::installlocationdirectory = $uniquename; - $installer::globals::installlocationdirectoryset = 1; - if ( $installer::globals::installlocationdirectory =~ /oracle_/i ) { $installer::globals::sundirexists = 1; } - } - - # setting the sundirectory - if ( $styles =~ /\bSUNDIRECTORY\b/ ) - { - if ( $installer::globals::vendordirectoryset ) { installer::exiter::exit_program("ERROR: Directory with flag SUNDIRECTORY alread set: \"$installer::globals::vendordirectory\".", "create_unique_directorynames"); } - $installer::globals::vendordirectory = $uniquename; - $installer::globals::vendordirectoryset = 1; - } - } + next unless $directory->{'Styles'} =~ /\bISINSTALLLOCATION\b/; + + if ( $installer::globals::installlocationdirectoryset ) + { + installer::exiter::exit_program( + sprintf( + "ERROR: Directory with flag ISINSTALLLOCATION alread set: \"%s\".", + $installer::globals::installlocationdirectory), + "create_unique_directorynames"); + } + + $installer::globals::installlocationdirectory = $directory->{'uniquename'}; + $installer::globals::installlocationdirectoryset = 1; + } } + + + ##################################################### # Adding ":." to selected default directory names ##################################################### -sub check_sourcedir_addon +sub update_defaultdir ($$) { my ( $onedir, $allvariableshashref ) = @_; - if (($installer::globals::addchildprojects) || - ($installer::globals::patch) || - ($installer::globals::languagepack) || - ($allvariableshashref->{'CHANGETARGETDIR'})) + if ($installer::globals::addchildprojects + || $installer::globals::patch + || $installer::globals::languagepack + || $allvariableshashref->{'CHANGETARGETDIR'}) { my $sourcediraddon = "\:\."; - $onedir->{'defaultdir'} = $onedir->{'defaultdir'} . $sourcediraddon; + return $onedir->{'defaultdir'} . $sourcediraddon; } - + else + { + return $onedir->{'defaultdir'}; + } } ##################################################### @@ -310,7 +444,12 @@ sub set_installlocation_directory { my ( $directoryref, $allvariableshashref ) = @_; - if ( ! $installer::globals::installlocationdirectoryset ) { installer::exiter::exit_program("ERROR: Directory with flag ISINSTALLLOCATION not set!", "set_installlocation_directory"); } + if ( ! $installer::globals::installlocationdirectoryset ) + { + installer::exiter::exit_program( + "ERROR: Directory with flag ISINSTALLLOCATION not set!", + "set_installlocation_directory"); + } for ( my $i = 0; $i <= $#{$directoryref}; $i++ ) { @@ -319,12 +458,12 @@ sub set_installlocation_directory if ( $onedir->{'uniquename'} eq $installer::globals::installlocationdirectory ) { $onedir->{'uniquename'} = "INSTALLLOCATION"; - check_sourcedir_addon($onedir, $allvariableshashref); + $onedir->{'defaultdir'} = update_defaultdir($onedir, $allvariableshashref); } if ( $onedir->{'uniquename'} eq $installer::globals::vendordirectory ) { - check_sourcedir_addon($onedir, $allvariableshashref); + $onedir->{'defaultdir'} = update_defaultdir($onedir, $allvariableshashref); } if ( $onedir->{'uniqueparentname'} eq $installer::globals::installlocationdirectory ) @@ -349,13 +488,38 @@ sub get_last_directory_name } } +sub setup_global_font_directory_name ($) +{ + my ($directories) = @_; + + foreach my $directory (@$directories) + { + next unless defined $directory->{'Dir'}; + next unless defined $directory->{'defaultdir'}; + + next if $directory->{'Dir'} ne "PREDEFINED_OSSYSTEMFONTDIR"; + next if $directory->{'defaultdir'} ne $installer::globals::fontsdirhostname; + + $installer::globals::fontsdirname = $installer::globals::fontsdirhostname; + $installer::globals::fontsdirparent = $directory->{'uniqueparentname'}; + + $installer::logger::Info->printf("%s, fdhn %s, dd %s, ipn %s, HN %s\n", + "PREDEFINED_OSSYSTEMFONTDIR", + $installer::globals::fontsdirhostname, + $directory->{'defaultdir'}, + $directory->{'uniqueparentname'}, + $directory->{'HostName'}); + installer::scriptitems::print_script_item($directory); + } +} + ##################################################### # Creating the defaultdir for the file Director.idt ##################################################### -sub create_defaultdir_directorynames +sub create_defaultdir_directorynames ($) { - my ($directoryref, $shortdirnamehashref) = @_; + my ($directoryref) = @_; my @shortnames = (); if ( $installer::globals::prepare_winpatch ) { @shortnames = values(%installer::globals::saved83dirmapping); } @@ -391,18 +555,6 @@ sub create_defaultdir_directorynames } $onedir->{'defaultdir'} = $defaultdir; - - my $fontdir = ""; - if ( $onedir->{'Dir'} ) { $fontdir = $onedir->{'Dir'}; } - - my $fontdefaultdir = ""; - if ( $onedir->{'defaultdir'} ) { $fontdefaultdir = $onedir->{'defaultdir'}; } - - if (( $fontdir eq "PREDEFINED_OSSYSTEMFONTDIR" ) && ( $fontdefaultdir eq $installer::globals::fontsdirhostname )) - { - $installer::globals::fontsdirname = $onedir->{'defaultdir'}; - $installer::globals::fontsdirparent = $onedir->{'uniqueparentname'}; - } } } @@ -410,23 +562,28 @@ sub create_defaultdir_directorynames # Fill content into the directory table ############################################### -sub create_directorytable_from_collection +sub create_directorytable_from_collection ($$) { my ($directorytableref, $directoryref) = @_; - for ( my $i = 0; $i <= $#{$directoryref}; $i++ ) + foreach my $onedir (@$directoryref) { - my $onedir = ${$directoryref}[$i]; - my $hostname = $onedir->{'HostName'}; - my $dir = ""; - - if ( $onedir->{'Dir'} ) { $dir = $onedir->{'Dir'}; } - - if (( $dir eq "PREDEFINED_PROGDIR" ) && ( $hostname eq "" )) { next; } # removing files from root directory - - my $oneline = $onedir->{'uniquename'} . "\t" . $onedir->{'uniqueparentname'} . "\t" . $onedir->{'defaultdir'} . "\n"; + # Remove entries for special directories. + if (defined $onedir->{'HostName'} + && $onedir->{'HostName'} eq "" + && defined $onedir->{'Dir'} + && $onedir->{'Dir'} eq "PREDEFINED_PROGDIR") + { + next; + } + + my $oneline = sprintf( + "%s\t%s\t%s\n", + $onedir->{'uniquename'}, + $onedir->{'uniqueparentname'}, + $onedir->{'defaultdir'}); - push(@{$directorytableref}, $oneline); + push @{$directorytableref}, $oneline; } } @@ -434,19 +591,10 @@ sub create_directorytable_from_collectio # Defining the root installation structure ############################################### -sub add_root_directories +sub process_root_directories ($$) { - my ($directorytableref, $allvariableshashref) = @_; + my ($allvariableshashref, $functor) = @_; -# my $sourcediraddon = ""; -# if (($installer::globals::addchildprojects) || -# ($installer::globals::patch) || -# ($installer::globals::languagepack) || -# ($allvariableshashref->{'CHANGETARGETDIR'})) -# { -# $sourcediraddon = "\:\."; -# } - my $oneline = ""; if (( ! $installer::globals::patch ) && ( ! $installer::globals::languagepack ) && ( ! $allvariableshashref->{'DONTUSESTARTMENUFOLDER'} )) @@ -474,76 +622,188 @@ sub add_root_directories $realproductkey =~ s/\ /\_/g; } - my $shortproductkey = installer::windows::idtglobal::make_eight_three_conform($productkey, "dir"); # third parameter not used + my $shortproductkey = installer::windows::idtglobal::make_eight_three_conform($productkey, "dir", undef); $shortproductkey =~ s/\s/\_/g; # changing empty space to underline - - $oneline = "$installer::globals::officemenufolder\t$installer::globals::programmenufolder\t$shortproductkey|$realproductkey\n"; - push(@{$directorytableref}, $oneline); - } - - $oneline = "TARGETDIR\t\tSourceDir\n"; - push(@{$directorytableref}, $oneline); - - $oneline = "$installer::globals::programfilesfolder\tTARGETDIR\t.\n"; - push(@{$directorytableref}, $oneline); - - $oneline = "$installer::globals::programmenufolder\tTARGETDIR\t.\n"; - push(@{$directorytableref}, $oneline); - - $oneline = "$installer::globals::startupfolder\tTARGETDIR\t.\n"; - push(@{$directorytableref}, $oneline); - $oneline = "$installer::globals::desktopfolder\tTARGETDIR\t.\n"; - push(@{$directorytableref}, $oneline); - - $oneline = "$installer::globals::startmenufolder\tTARGETDIR\t.\n"; - push(@{$directorytableref}, $oneline); - - $oneline = "$installer::globals::commonfilesfolder\tTARGETDIR\t.\n"; - push(@{$directorytableref}, $oneline); - - $oneline = "$installer::globals::commonappdatafolder\tTARGETDIR\t.\n"; - push(@{$directorytableref}, $oneline); + &$functor( + $installer::globals::officemenufolder, + $installer::globals::programmenufolder, + $shortproductkey . "|". $realproductkey); + } - $oneline = "$installer::globals::localappdatafolder\tTARGETDIR\t.\n"; - push(@{$directorytableref}, $oneline); + &$functor("TARGETDIR", "", "SourceDir"); + &$functor($installer::globals::programfilesfolder, "TARGETDIR", "."); + &$functor($installer::globals::programmenufolder, "TARGETDIR", "."); + &$functor($installer::globals::startupfolder, "TARGETDIR", "."); + &$functor($installer::globals::desktopfolder, "TARGETDIR", "."); + &$functor($installer::globals::startmenufolder, "TARGETDIR", "."); + &$functor($installer::globals::commonfilesfolder, "TARGETDIR", "."); + &$functor($installer::globals::commonappdatafolder, "TARGETDIR", "."); + &$functor($installer::globals::localappdatafolder, "TARGETDIR", "."); if ( $installer::globals::usesharepointpath ) { - $oneline = "SHAREPOINTPATH\tTARGETDIR\t.\n"; - push(@{$directorytableref}, $oneline); + &$functor("SHAREPOINTPATH", "TARGETDIR", "."); } - $oneline = "$installer::globals::systemfolder\tTARGETDIR\t.\n"; - push(@{$directorytableref}, $oneline); + &$functor($installer::globals::systemfolder, "TARGETDIR", "."); my $localtemplatefoldername = $installer::globals::templatefoldername; my $directorytableentry = $localtemplatefoldername; my $shorttemplatefoldername = installer::windows::idtglobal::make_eight_three_conform($localtemplatefoldername, "dir"); - if ( $shorttemplatefoldername ne $localtemplatefoldername ) { $directorytableentry = "$shorttemplatefoldername|$localtemplatefoldername"; } - $oneline = "$installer::globals::templatefolder\tTARGETDIR\t$directorytableentry\n"; - push(@{$directorytableref}, $oneline); + if ( $shorttemplatefoldername ne $localtemplatefoldername ) + { + $directorytableentry = $shorttemplatefoldername . "|" . $localtemplatefoldername; + } + &$functor($installer::globals::templatefolder, "TARGETDIR", $directorytableentry); if ( $installer::globals::fontsdirname ) { - $oneline = "$installer::globals::fontsfolder\t$installer::globals::fontsdirparent\t$installer::globals::fontsfoldername\:$installer::globals::fontsdirname\n"; + &$functor( + $installer::globals::fontsfolder, + $installer::globals::fontsdirparent, + $installer::globals::fontsfoldername . ":" . $installer::globals::fontsdirname); } else { - $oneline = "$installer::globals::fontsfolder\tTARGETDIR\t$installer::globals::fontsfoldername\n"; + &$functor( + $installer::globals::fontsfolder, + "TARGETDIR", + $installer::globals::fontsfoldername); } +} + + - push(@{$directorytableref}, $oneline); +sub find_missing_directories ($$) +{ + my ($directories, $allvariableshashref) = @_; + + # Set up the list of target directories. + my %target_directories = map {$_->{'uniquename'} => 1} @$directories; + # Add special directories. + process_root_directories( + $allvariableshashref, + sub($$$){ + my ($uniquename, $parentname, $defaultdir) = @_; + $target_directories{$uniquename} = 1; + } + ); + + # Set up the list of source directories. + my $source_directory_map = $installer::globals::source_msi->GetDirectoryMap(); + my $source_file_map = $installer::globals::source_msi->GetFileMap(); + my %source_directories = map {$_->{'unique_name'} => $_} values %$source_directory_map; + + # Find the missing source directories. + my @missing_directories = (); + foreach my $source_uniquename (keys %source_directories) + { + if ( ! $target_directories{$source_uniquename}) + { + push @missing_directories, $source_directories{$source_uniquename}; + } + } + + # Report the missing directories. + $installer::logger::Info->printf("found %d missing directories\n", scalar @missing_directories); + my $index = 0; + foreach my $directory_item (@missing_directories) + { + # Print information about the directory. + $installer::logger::Info->printf("missing directory %d: %s\n", + ++$index, + $directory_item->{'full_target_long_name'}); + while (my($key,$value) = each %$directory_item) + { + $installer::logger::Info->printf(" %s -> %s\n", $key, $value); + } + + # Print the referencing files. + my @filenames = (); + while (my ($key,$value) = each %$source_file_map) + { + if ($value->{'directory'}->{'unique_name'} eq $directory_item->{'unique_name'}) + { + push @filenames, $key; + } + } + $installer::logger::Info->printf(" referencing files are %s\n", join(", ", @filenames)); + } + + foreach my $directory (@$directories) + { + $installer::logger::Lang->printf("target directory %s -> HN %s\n", + $directory->{'uniquename'}, + $directory->{'HostName'}); + installer::scriptitems::print_script_item($directory); + } + + # Setup a map of directory uniquenames to verify that the new + # entries don't use unique names that are already in use. + my %unique_names = map {$_->{'uniquename'} => $_} @$directories; + + # Create script items for the missing directories. + my @new_source_directories = (); + foreach my $source_directory_item (@missing_directories) + { + my $new_directory_item = { + 'uniquename' => $source_directory_item->{'unique_name'}, + 'uniqueparentname' => $source_directory_item->{'parent_name'}, + 'defaultdir' => $source_directory_item->{'default_dir'}, + 'HostName' => $source_directory_item->{'full_target_long_name'}, + 'componentname' => $source_directory_item->{'component_name'}, + }; + + if (defined $unique_names{$new_directory_item->{'uniquename'}}) + { + installer::logger::PrintError("newly created directory entry collides with existing directory"); + last; + } + + push @new_source_directories, $new_directory_item; + } + + return @new_source_directories; } + + + +sub prepare_directory_table_creation ($$) +{ + my ($directories, $allvariableshashref) = @_; + + foreach my $directory (@$directories) + { + delete $directory->{'uniquename'}; + } + + overwrite_programfilesfolder($allvariableshashref); + create_unique_directorynames($directories); + check_unique_directorynames($directories); + create_defaultdir_directorynames($directories); # only destdir! + setup_global_font_directory_name($directories); + set_installlocation_directory($directories, $allvariableshashref); + + if ($installer::globals::is_release) + { + my @new_directories = find_missing_directories($directories, $allvariableshashref); + push @$directories, @new_directories; + } +} + + + + ############################################### # Creating the file Director.idt dynamically ############################################### -sub create_directory_table +sub create_directory_table ($$$) { - my ($directoryref, $basedir, $allvariableshashref, $shortdirnamehashref, $loggingdir) = @_; + my ($directoryref, $basedir, $allvariableshashref) = @_; # Structure of the directory table: # Directory Directory_Parent DefaultDir @@ -556,18 +816,17 @@ sub create_directory_table $installer::logger::Lang->add_timestamp("Performance Info: Directory Table start"); my @directorytable = (); - my $infoline; - - overwrite_programfilesfolder($allvariableshashref); - if ( $installer::globals::globallogging ) { installer::files::save_array_of_hashes($loggingdir . "directoriesforidt_local_1.log", $directoryref); } - create_unique_directorynames($directoryref, $allvariableshashref); - if ( $installer::globals::globallogging ) { installer::files::save_array_of_hashes($loggingdir . "directoriesforidt_local_1a.log", $directoryref); } - create_defaultdir_directorynames($directoryref, $shortdirnamehashref); # only destdir! - if ( $installer::globals::globallogging ) { installer::files::save_array_of_hashes($loggingdir . "directoriesforidt_local_2.log", $directoryref); } - set_installlocation_directory($directoryref, $allvariableshashref); - if ( $installer::globals::globallogging ) { installer::files::save_array_of_hashes($loggingdir . "directoriesforidt_local_3.log", $directoryref); } installer::windows::idtglobal::write_idt_header(\@directorytable, "directory"); - add_root_directories(\@directorytable, $allvariableshashref); + + # Add entries for the root directories (and a few special directories like that for fonts). + process_root_directories( + $allvariableshashref, + sub($$$){ + push(@directorytable, join("\t", @_)."\n"); + } + ); + + # Add entries for the non-root directories. create_directorytable_from_collection(\@directorytable, $directoryref); # Saving the file @@ -579,4 +838,5 @@ sub create_directory_table $installer::logger::Lang->add_timestamp("Performance Info: Directory Table end"); } + 1;
Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/feature.pm URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/feature.pm?rev=1551937&r1=1551936&r2=1551937&view=diff ============================================================================== --- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/feature.pm (original) +++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/feature.pm Wed Dec 18 13:27:09 2013 @@ -363,78 +363,140 @@ sub add_uniquekey # Feature Feature_Parent Title Description Display Level Directory_ Attributes ################################################################################# -sub create_feature_table +sub prepare_feature_table ($$$) { - my ($modulesref, $basedir, $languagesarrayref, $allvariableshashref) = @_; + my ($modules, $language, $variables) = @_; - for ( my $m = 0; $m <= $#{$languagesarrayref}; $m++ ) - { - my $onelanguage = ${$languagesarrayref}[$m]; - - my $infoline; - - my @featuretable = (); - - installer::windows::idtglobal::write_idt_header(\@featuretable, "feature"); - - for ( my $i = 0; $i <= $#{$modulesref}; $i++ ) - { - my $onefeature = ${$modulesref}[$i]; - - # Java and Ada only, if the correct settings are set - my $styles = ""; - if ( $onefeature->{'Styles'} ) { $styles = $onefeature->{'Styles'}; } - if (( $styles =~ /\bJAVAMODULE\b/ ) && ( ! ($allvariableshashref->{'JAVAPRODUCT'} ))) { next; } - if (( $styles =~ /\bADAMODULE\b/ ) && ( ! ($allvariableshashref->{'ADAPRODUCT'} ))) { next; } - - # Controlling the language! - # Only language independent feature or feature with the correct language will be included into the table - - if (! (!(( $onefeature->{'ismultilingual'} )) || ( $onefeature->{'specificlanguage'} eq $onelanguage )) ) { next; } - - my %feature = (); - - $feature{'feature'} = get_feature_gid($onefeature); - $feature{'feature_parent'} = get_feature_parent($onefeature); - # if ( $onefeature->{'ParentID'} eq "" ) { $feature{'feature_parent'} = ""; } # Root has no parent - $feature{'Title'} = $onefeature->{'Name'}; - $feature{'Description'} = $onefeature->{'Description'}; - $feature{'Display'} = get_feature_display($onefeature); - $feature{'Level'} = get_feature_level($onefeature); - $feature{'Directory_'} = get_feature_directory($onefeature); - $feature{'Attributes'} = get_feature_attributes($onefeature); - - my $oneline = $feature{'feature'} . "\t" . $feature{'feature_parent'} . "\t" . $feature{'Title'} . "\t" - . $feature{'Description'} . "\t" . $feature{'Display'} . "\t" . $feature{'Level'} . "\t" - . $feature{'Directory_'} . "\t" . $feature{'Attributes'} . "\n"; - - push(@featuretable, $oneline); - - # collecting all feature in global feature collector (so that properties can be set in property table) - if ( ! installer::existence::exists_in_array($feature{'feature'}, \@installer::globals::featurecollector) ) - { - push(@installer::globals::featurecollector, $feature{'feature'}); - } - - # collecting all language feature in feature collector for check of language selection - if (( $styles =~ /\bSHOW_MULTILINGUAL_ONLY\b/ ) && ( $onefeature->{'ParentID'} ne $installer::globals::rootmodulegid )) - { - $installer::globals::multilingual_only_modules{$feature{'feature'}} = 1; - } - - # collecting all application feature in global feature collector for check of application selection - if ( $styles =~ /\bAPPLICATIONMODULE\b/ ) - { - $installer::globals::application_modules{$feature{'feature'}} = 1; - } - } - - # Saving the file - - my $featuretablename = $basedir . $installer::globals::separator . "Feature.idt" . "." . $onelanguage; - installer::files::save_file($featuretablename ,\@featuretable); - $installer::logger::Lang->printf("Created idt file: %s\n", $featuretablename); - } + my $features = []; + + foreach my $onefeature (@$modules) + { + # Java and Ada only, if the correct settings are set + my $styles = $onefeature->{'Styles'} // ""; + if (( $styles =~ /\bJAVAMODULE\b/ ) && ( ! ($variables->{'JAVAPRODUCT'} ))) { next; } + + # Controlling the language! + # Only language independent feature or feature with the correct language will be included into the table + + next if $onefeature->{'ismultilingual'} && ($onefeature->{'specificlanguage'} ne $language); + + my $feature_gid =get_feature_gid($onefeature); + + my $feature = { + 'Feature' => $feature_gid, + 'Feature_Parent' => get_feature_parent($onefeature), + 'Title' => $onefeature->{'Name'}, + 'Description' => $onefeature->{'Description'}, + 'Display' => get_feature_display($onefeature), + 'Level' => get_feature_level($onefeature), + 'Directory_' => get_feature_directory($onefeature), + 'Attributes' => get_feature_attributes($onefeature) + }; + push @$features, $feature; + + # collecting all feature in global feature collector (so that properties can be set in property table) + $installer::globals::featurecollector{$feature_gid} = 1; + + # collecting all language feature in feature collector for check of language selection + if (( $styles =~ /\bSHOW_MULTILINGUAL_ONLY\b/ ) && $onefeature->{'ParentID'} ne $installer::globals::rootmodulegid) + { + $installer::globals::multilingual_only_modules{$feature_gid} = 1; + } + + # collecting all application feature in global feature collector for check of application selection + if ( $styles =~ /\bAPPLICATIONMODULE\b/ ) + { + $installer::globals::application_modules{$feature_gid} = 1; + } + } + + return $features; +} + + + + +=head add_missing_features($features) + + When we are building a release, then there may be features missing + that where present in the source release. As missing features + would prevent patches from being created, we add the missing + features. + + The returned feature hash is either identical to the given + $features or is a copy with the missing features added. + +=cut + +sub add_missing_features ($) +{ + my ($features) = @_; + + return $features if ! $installer::globals::is_release; + + # Aquire the feature list of the source release. + my $source_feature_table = $installer::globals::source_msi->GetTable("Feature"); + my $feature_column_index = $source_feature_table->GetColumnIndex("Feature"); + + # Prepare fast lookup of the target features. + my %target_feature_map = map {$_->{'Feature'} => $_} @$features; + + # Find missing features. + my @missing_features = (); + foreach my $source_feature_row (@{$source_feature_table->GetAllRows()}) + { + my $feature_gid = $source_feature_row->GetValue($feature_column_index); + if ( ! defined $target_feature_map{$feature_gid}) + { + push @missing_features, $source_feature_row; + } + } + + # Return when there are no missing features. + return $features if scalar @missing_features==0; + + # Process the missing features. + my $extended_features = [@$features]; + foreach my $missing_feature_row (@missing_features) + { + my %feature = map + {$_ => $missing_feature_row->GetValue($_)} + ('Feature', 'Feature_Parent', 'Title', 'Description', 'Display', 'Level', 'Directory_', 'Attributes'); + push @$extended_features, \%feature; + + $installer::logger::Lang->printf("added missing feature %s\n", $feature->{'Feature'}); + } + return $extended_features; +} + + + + +sub create_feature_table ($$$) +{ + my ($basedir, $language, $features) = @_; + + my @feature_table = (); + installer::windows::idtglobal::write_idt_header(\@feature_table, "feature"); + + foreach my $feature (@$features) + { + my $line = join("\t", + $feature->{'Feature'}, + $feature->{'Feature_Parent'}, + $feature->{'Title'}, + $feature->{'Description'}, + $feature->{'Display'}, + $feature->{'Level'}, + $feature->{'Directory_'}, + $feature->{'Attributes'}) . "\n"; + + push(@feature_table, $line); + } + + my $filename = $basedir . $installer::globals::separator . "Feature.idt" . "." . $language; + installer::files::save_file($filename ,\@feature_table); + $installer::logger::Lang->printf("Created idt file: %s\n", $filename); } 1; Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/featurecomponent.pm URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/featurecomponent.pm?rev=1551937&r1=1551936&r2=1551937&view=diff ============================================================================== --- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/featurecomponent.pm (original) +++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/featurecomponent.pm Wed Dec 18 13:27:09 2013 @@ -30,37 +30,46 @@ use installer::files; use installer::globals; use installer::windows::idtglobal; +use strict; + + ################################################################################# # Collecting all pairs of features and components from the files collector ################################################################################# -sub create_featurecomponent_table_from_files_collector +sub create_featurecomponent_table_from_files_collector ($$) { my ($featurecomponenttableref, $filesref) = @_; - for ( my $i = 0; $i <= $#{$filesref}; $i++ ) + foreach my $onefile (@$filesref) { - my $onefile = ${$filesref}[$i]; - my $filecomponent = $onefile->{'componentname'}; my $filemodules = $onefile->{'modules'}; if ( $filecomponent eq "" ) { - installer::exiter::exit_program("ERROR: No component defined for file $onefile->{'Name'}", "create_featurecomponent_table_from_files_collector"); - } - if ( $filemodules eq "" ) - { - installer::exiter::exit_program("ERROR: No modules found for file $onefile->{'Name'}", "create_featurecomponent_table_from_files_collector"); + installer::exiter::exit_program( + sprintf("ERROR: No component defined for file %s", $onefile->{'Name'}), + "create_featurecomponent_table_from_files_collector"); + } + if ( ! defined $filemodules) + { + # Temporary for files created from source installation set. + die; + } + if ($filemodules eq "") + { + installer::exiter::exit_program( + sprintf("ERROR: No modules found for file %s", $onefile->{'Name'}), + "create_featurecomponent_table_from_files_collector"); } my $filemodulesarrayref = installer::converter::convert_stringlist_into_array(\$filemodules, ","); - for ( my $j = 0; $j <= $#{$filemodulesarrayref}; $j++ ) + foreach my $onemodule (@$filemodulesarrayref) { my %featurecomponent = (); - my $onemodule = ${$filemodulesarrayref}[$j]; $onemodule =~ s/\s*$//; $featurecomponent{'Feature'} = $onemodule; $featurecomponent{'Component'} = $filecomponent; @@ -70,7 +79,7 @@ sub create_featurecomponent_table_from_f installer::windows::idtglobal::shorten_feature_gid(\$featurecomponent{'Feature'}); - $oneline = "$featurecomponent{'Feature'}\t$featurecomponent{'Component'}\n"; + my $oneline = "$featurecomponent{'Feature'}\t$featurecomponent{'Component'}\n"; # control of uniqueness @@ -82,56 +91,66 @@ sub create_featurecomponent_table_from_f } } -################################################################################# -# Collecting all pairs of features and components from the registry collector -################################################################################# -sub create_featurecomponent_table_from_registry_collector + + +=head2 create_featurecomponent_table_from_registry_collector ($featurecomponenttableref, $registryref) + + Add entries for the FeatureComponent table for components that contain registry entries. + +=cut +sub create_featurecomponent_table_from_registry_collector ($$) { my ($featurecomponenttableref, $registryref) = @_; - for ( my $i = 0; $i <= $#{$registryref}; $i++ ) + my $replacement_count = 0; + my $unique_count = 0; + foreach my $oneregistry (@$registryref) { - my $oneregistry = ${$registryref}[$i]; - - my $registrycomponent = $oneregistry->{'componentname'}; - my $registrymodule = $oneregistry->{'ModuleID'}; - - if ( $registrycomponent eq "" ) + my $component_name = $oneregistry->{'componentname'}; + if ($component_name eq "") { - installer::exiter::exit_program("ERROR: No component defined for registry $oneregistry->{'gid'}", "create_featurecomponent_table_from_registry_collector"); + installer::exiter::exit_program( + sprintf("ERROR: No component defined for registry %s", $oneregistry->{'gid'}), + "create_featurecomponent_table_from_registry_collector"); } - if ( $registrymodule eq "" ) + + my $feature_name = $oneregistry->{'ModuleID'}; + if ($feature_name eq "") { - installer::exiter::exit_program("ERROR: No modules found for registry $oneregistry->{'gid'}", "create_featurecomponent_table_from_registry_collector"); + installer::exiter::exit_program( + sprintf("ERROR: No modules found for registry %s", $oneregistry->{'gid'}), + "create_featurecomponent_table_from_registry_collector"); } - my %featurecomponent = (); - - $featurecomponent{'Feature'} = $registrymodule; - $featurecomponent{'Component'} = $registrycomponent; - # Attention: Features are renamed, because the maximum length is 38. # But in the files collector ($filesref), the original names are saved. - installer::windows::idtglobal::shorten_feature_gid(\$featurecomponent{'Feature'}); - - $oneline = "$featurecomponent{'Feature'}\t$featurecomponent{'Component'}\n"; - - # control of uniqueness - - if (! installer::existence::exists_in_array($oneline, $featurecomponenttableref)) + $feature_name = installer::windows::idtglobal::create_shortend_feature_gid($feature_name); + + my $oneline = sprintf("%s\t%s\n", $feature_name, $component_name); + if ( ! installer::existence::exists_in_array($oneline, $featurecomponenttableref)) { - push(@{$featurecomponenttableref}, $oneline); - } - } + push(@$featurecomponenttableref, $oneline); + ++$unique_count; + } + else + { + $installer::logger::Lang->printf("feature component pair already exists\n"); + } + } + $installer::logger::Lang->printf( + "replaced %d (%d) of %d component names in FeatureComponent table\n", + $unique_count, + $replacement_count, + scalar @$registryref); } ################################################################################# # Collecting all feature that are listed in the featurecomponent table. ################################################################################# -sub collect_all_feature +sub collect_all_features { my ($featurecomponenttable) = @_; @@ -145,7 +164,10 @@ sub collect_all_feature { my $feature = $1; - if (! installer::existence::exists_in_array($feature, \@allfeature)) { push(@allfeature, $feature); } + if (! installer::existence::exists_in_array($feature, \@allfeature)) + { + push(@allfeature, $feature); + } } } @@ -165,7 +187,7 @@ sub check_number_of_components_at_featur $installer::logger::Lang->print("\n"); $installer::logger::Lang->print("Checking number of components at features. Maximum is 817 (for Win 98 and Win Me)\n"); - my $allfeature = collect_all_feature($featurecomponenttable); + my $allfeature = collect_all_features($featurecomponenttable); for ( my $i = 0; $i <= $#{$allfeature}; $i++ ) { @@ -196,7 +218,7 @@ sub check_number_of_components_at_featur # Feature Component ################################################################################# -sub create_featurecomponent_table +sub create_featurecomponent_table ($$$) { my ($filesref, $registryref, $basedir) = @_; @@ -216,9 +238,13 @@ sub create_featurecomponent_table # At the moment only the files are related to components (and the files know their modules). # The component for each file is written into the files collector $filesinproductlanguageresolvedarrayref - create_featurecomponent_table_from_files_collector(\@featurecomponenttable, $filesref); - - create_featurecomponent_table_from_registry_collector(\@featurecomponenttable, $registryref); + create_featurecomponent_table_from_files_collector( + \@featurecomponenttable, + $filesref); + + create_featurecomponent_table_from_registry_collector( + \@featurecomponenttable, + $registryref); # Additional components have to be added here
