You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by af...@apache.org on 2013/12/04 09:51:31 UTC
svn commit: r1547732 [3/4] - in /openoffice/trunk/main:
instsetoo_native/data/ instsetoo_native/util/ solenv/bin/
solenv/bin/modules/installer/ solenv/bin/modules/installer/patch/
solenv/bin/modules/installer/windows/
Modified: openoffice/trunk/main/solenv/bin/modules/installer/windows/directory.pm
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/solenv/bin/modules/installer/windows/directory.pm?rev=1547732&r1=1547731&r2=1547732&view=diff
==============================================================================
--- openoffice/trunk/main/solenv/bin/modules/installer/windows/directory.pm (original)
+++ openoffice/trunk/main/solenv/bin/modules/installer/windows/directory.pm Wed Dec 4 08:51:30 2013
@@ -29,6 +29,7 @@ use installer::globals;
use installer::pathanalyzer;
use installer::windows::idtglobal;
use installer::windows::msiglobal;
+use installer::scriptitems;
use strict;
@@ -133,172 +134,305 @@ sub make_short_dir_version ($)
return $shortstring;
}
-##############################################################
-# Adding unique directory names to the directory collection
-##############################################################
-sub create_unique_directorynames
+
+
+=head2 get_unique_name ($hostname, $unique_map, $shortdirhash, $shortdirhashreverse)
+
+ 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 ($directoryref, $allvariables) = @_;
+ my ($hostname, $hostnamehash) = @_;
- $installer::globals::officeinstalldirectoryset = 0;
+ # 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;
- my %completedirhashstep1 = ();
- my %shortdirhash = ();
- my %shortdirhashreverse = ();
- my $infoline = "";
- my $errorcount = 0;
+ $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;
- for ( my $i = 0; $i <= $#{$directoryref}; $i++ )
- {
- my $onedir = ${$directoryref}[$i];
- my $uniquename = $onedir->{'HostName'};
+ my $short_uniquename = make_short_dir_version($uniquename);
- my $styles = "";
- if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; }
+ return ($uniquename, $short_uniquename);
+}
- $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;
- # 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;
+=head2 check_unique_directorynames($directories)
- # Starting to make unique name for the parent and its directory
- my $originaluniquename = $uniquename;
+ 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.
- $uniquename = make_short_dir_version($uniquename);
+ 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) = @_;
- # 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"); }
+ my %completedirhashstep1 = ();
+ my %shortdirhash = ();
+ my %shortdirhashreverse = ();
- # 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"); }
+ # 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;
+ }
+}
- # Creating assignment from long to short directory names
- $shortdirhash{$originaluniquename} = $uniquename;
- $shortdirhashreverse{$uniquename} = $originaluniquename;
- # Important: The unique parent is generated from the string $originaluniquename (with the use of underlines).
- 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;
- }
+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);
+ }
- 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;
- }
+ return ($originaluniqueparentname, $uniqueparentname);
+}
- 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);
- }
- # 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"); }
+##############################################################
+# Adding unique directory names to the directory collection
+##############################################################
+
+sub create_unique_directorynames ($)
+{
+ my ($directories) = @_;
+
+ $installer::globals::officeinstalldirectoryset = 0;
+
+ my %hostnamehash = ();
+ my $infoline = "";
+ my $errorcount = 0;
+
+ foreach my $directory (@$directories)
+ {
+ next if defined $directory->{'uniquename'};
+
+ my $styles = $directory->{'Styles'} // "";
- # 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 ($originaluniquename, $uniquename) = get_unique_name(
+ $directory->{'HostName'},
+ \%hostnamehash);
+
+ 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;
- }
-
- # 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,6 +488,31 @@ 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
#####################################################
@@ -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'},
+ '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, $loggingdir) = @_;
+ my ($directoryref, $basedir, $allvariableshashref) = @_;
# Structure of the directory table:
# Directory Directory_Parent DefaultDir
@@ -556,14 +816,17 @@ sub create_directory_table ($$$$)
$installer::logger::Lang->add_timestamp("Performance Info: Directory Table start");
my @directorytable = ();
- my $infoline;
-
- overwrite_programfilesfolder($allvariableshashref);
- create_unique_directorynames($directoryref, $allvariableshashref);
- create_defaultdir_directorynames($directoryref); # only destdir!
- set_installlocation_directory($directoryref, $allvariableshashref);
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
@@ -575,4 +838,5 @@ sub create_directory_table ($$$$)
$installer::logger::Lang->add_timestamp("Performance Info: Directory Table end");
}
+
1;
Modified: openoffice/trunk/main/solenv/bin/modules/installer/windows/file.pm
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/solenv/bin/modules/installer/windows/file.pm?rev=1547732&r1=1547731&r2=1547732&view=diff
==============================================================================
--- openoffice/trunk/main/solenv/bin/modules/installer/windows/file.pm (original)
+++ openoffice/trunk/main/solenv/bin/modules/installer/windows/file.pm Wed Dec 4 08:51:30 2013
@@ -35,6 +35,11 @@ use installer::windows::font;
use installer::windows::idtglobal;
use installer::windows::msiglobal;
use installer::windows::language;
+use installer::patch::InstallationSet;
+use installer::patch::FileSequenceList;
+use File::Basename;
+use File::Spec;
+use strict;
##########################################################################
# Assigning one cabinet file to each file. This is requrired,
@@ -357,19 +362,23 @@ sub get_component_from_assigned_file
# In most cases this is simply the filename.
####################################################################
-sub generate_unique_filename_for_filetable ($$)
+sub generate_unique_filename_for_filetable ($)
{
- my ($fileref, $component) = @_;
+ my ($oldname) = @_;
# This new filename has to be saved into $fileref, because this is needed to find the source.
# The filename sbasic.idx/OFFSETS is changed to OFFSETS, but OFFSETS is not unique.
# In this procedure names like OFFSETS5 are produced. And exactly this string has to be added to
# the array of all files.
- my $uniquefilename = "";
- my $counter = 0;
+ my $uniquefilename = $oldname;
+ if ( ! defined $uniquefilename || $uniquefilename eq "")
+ {
+ installer::logger::PrintError("file name does not exist or is empty, can not create unique name for it.");
+ die;
+ return;
+ }
- if ( $fileref->{'Name'} ) { $uniquefilename = $fileref->{'Name'}; }
# making /registry/schema/org/openoffice/VCL.xcs to VCL.xcs
installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$uniquefilename);
@@ -398,6 +407,7 @@ sub generate_unique_filename_for_filetab
my $uniquefilenamebase = $uniquefilename;
+ my $counter = 0;
do
{
$counter++;
@@ -491,7 +501,7 @@ sub get_filesize
sub get_fileversion
{
- my ($onefile, $allvariables, $styles) = @_;
+ my ($onefile, $allvariables) = @_;
my $fileversion = "";
@@ -532,6 +542,204 @@ sub get_fileversion
return $fileversion;
}
+
+
+
+sub retrieve_sequence_and_uniquename ($$)
+{
+ my ($file_list, $source_data) = @_;
+
+ my @added_files = ();
+
+ # Read the sequence numbers of the previous version.
+ if ($installer::globals::is_release)
+ {
+ foreach my $file (@$file_list)
+ {
+ # Use the source path of the file as key to retrieve sequence number and unique name.
+ # The source path is the part of the 'destination' without the first part.
+ # There is a special case when 'Dir' is PREDEFINED_OSSHELLNEWDIR.
+ my $source_path;
+ if (defined $file->{'Dir'} && $file->{'Dir'} eq "PREDEFINED_OSSHELLNEWDIR")
+ {
+ $source_path = $installer::globals::templatefoldername
+ . $installer::globals::separator
+ . $file->{'Name'};
+ }
+ else
+ {
+ $source_path = $file->{'destination'};
+ $source_path =~ s/^[^\/]+\///;
+ }
+ my ($sequence, $uniquename) = $source_data->get_sequence_and_unique_name($source_path);
+ if (defined $sequence && defined $uniquename)
+ {
+ $file->{'sequencenumber'} = $sequence;
+ $file->{'uniquename'} = $uniquename;
+ }
+ else
+ {
+ # No data found in the source release. File has been added.
+ push @added_files, $file;
+ }
+ }
+ }
+
+ return @added_files;
+}
+
+
+
+
+=head2 assign_mssing_sequence_numbers ($file_list)
+
+ Assign sequence numbers where still missing.
+
+ When we are preparing a patch then all files that have no sequence numbers
+ at this point are new. Otherwise no file has a sequence number yet.
+
+=cut
+sub assign_missing_sequence_numbers ($)
+{
+ my ($file_list) = @_;
+
+ # First, set up a hash on the sequence numbers that are already in use.
+ my %used_sequence_numbers = ();
+ foreach my $file (@$file_list)
+ {
+ next unless defined $file->{'sequencenumber'};
+ $used_sequence_numbers{$file->{'sequencenumber'}} = 1;
+ }
+
+ # Assign sequence numbers. Try consecutive numbers, starting at 1.
+ my $current_sequence_number = 1;
+ foreach my $file (@$file_list)
+ {
+ # Skip over all files that already have sequence numbers.
+ next if defined $file->{'sequencenumber'};
+
+ # Find the next available number.
+ while (defined $used_sequence_numbers{$current_sequence_number})
+ {
+ ++$current_sequence_number;
+ }
+
+ # Use the number and mark it as used.
+ $file->{'sequencenumber'} = $current_sequence_number;
+ $used_sequence_numbers{$current_sequence_number} = 1;
+ }
+}
+
+
+
+
+sub create_items_for_missing_files ($$$)
+{
+ my ($missing_items, $msi, $directory_list) = @_;
+
+ # For creation of the FeatureComponent table (in a later step) we
+ # have to provide references from the file to component and
+ # modules (ie features). Note that Each file belongs to exactly
+ # one component but one component can belong to multiple features.
+ my $component_to_features_map = create_feature_component_map($msi);
+
+ my @new_files = ();
+ foreach my $row (@$missing_items)
+ {
+ $installer::logger::Info->printf("creating new file item for '%s'\n", $row->GetValue('File'));
+ my $file_item = create_script_item_for_deleted_file($row, $msi, $component_to_features_map);
+ push @new_files, $file_item;
+ }
+
+ return @new_files;
+}
+
+
+
+
+sub create_script_item_for_deleted_file ($$$)
+{
+ my ($file_row, $msi, $component_to_features_map) = @_;
+
+ my $uniquename = $file_row->GetValue('File');
+
+ my $file_map = $msi->GetFileMap();
+
+ my $directory_item = $file_map->{$uniquename}->{'directory'};
+ my $source_path = $directory_item->{'full_source_long_name'};
+ my $target_path = $directory_item->{'full_target_long_name'};
+ my $full_source_name = File::Spec->catfile(
+ installer::patch::InstallationSet::GetUnpackedCabPath(
+ $msi->{'version'},
+ $msi->{'is_current_version'},
+ $msi->{'language'},
+ $msi->{'package_format'},
+ $msi->{'product_name'}),
+ $source_path,
+ $uniquename);
+ my ($long_name, undef) = installer::patch::Msi::SplitLongShortName($file_row->GetValue("FileName"));
+ my $target_name = File::Spec->catfile($target_path, $long_name);
+ if ( ! -f $full_source_name)
+ {
+ installer::logger::PrintError("can not find file '%s' in previous version (tried '%s')\n",
+ $uniquename,
+ $full_source_name);
+ return undef;
+ }
+ my $cygwin_full_source_name = qx(cygpath -w '$full_source_name');
+ my $component_name = $file_row->GetValue('Component_');
+ my $module_names = join(",", @{$component_to_features_map->{$component_name}});
+ my $sequence_number = $file_row->GetValue('Sequence');
+
+ return {
+ 'uniquename' => $uniquename,
+ 'destination' => $target_name,
+ 'componentname' => $component_name,
+ 'modules' => $module_names,
+ 'UnixRights' => 444,
+ 'Name' => $long_name,
+ 'sourcepath' => $full_source_name,
+ 'cyg_sourcepath' => $cygwin_full_source_name,
+ 'sequencenumber' => $sequence_number
+ };
+}
+
+
+
+
+=head2 create_feature_component_maps($msi)
+
+ Return a hash map that maps from component names to arrays of
+ feature names. In most cases the array of features contains only
+ one element. But there can be cases where the number is greater.
+
+=cut
+sub create_feature_component_map ($)
+{
+ my ($msi) = @_;
+
+ my $component_to_features_map = {};
+ my $feature_component_table = $msi->GetTable("FeatureComponents");
+ my $feature_column_index = $feature_component_table->GetColumnIndex("Feature_");
+ my $component_column_index = $feature_component_table->GetColumnIndex("Component_");
+ foreach my $row (@{$feature_component_table->GetAllRows()})
+ {
+ my $feature = $row->GetValue($feature_column_index);
+ my $component = $row->GetValue($component_column_index);
+ if ( ! defined $component_to_features_map->{$component})
+ {
+ $component_to_features_map->{$component} = [$feature];
+ }
+ else
+ {
+ push @{$component_to_features_map->{$component}}, $feature;
+ }
+ }
+
+ return $component_to_features_map;
+}
+
+
#############################################
# Returning the Windows language of a file
#############################################
@@ -576,6 +784,7 @@ sub generate_registry_keypath
return $keypath;
}
+
###################################################################
# Collecting further conditions for the component table.
# This is used by multilayer products, to enable installation
@@ -636,225 +845,344 @@ sub collect_shortnames_from_old_database
}
}
-############################################
-# Creating the file File.idt dynamically
-############################################
-sub create_files_table ($$$$)
+sub process_language_conditions ($)
{
- my ($filesref, $allfilecomponentsref, $basedir, $allvariables) = @_;
-
- $installer::logger::Lang->add_timestamp("Performance Info: File Table start");
-
- # Structure of the files table:
- # File Component_ FileName FileSize Version Language Attributes Sequence
- # In this function, all components are created.
- #
- # $allfilecomponentsref is empty at the beginning
-
- my $infoline;
+ my ($onefile) = @_;
+
+ # Collecting all languages specific conditions
+ if ( $onefile->{'ismultilingual'} )
+ {
+ if ( $onefile->{'ComponentCondition'} )
+ {
+ installer::exiter::exit_program(
+ "ERROR: Cannot set language condition. There is already another component condition for file $onefile->{'gid'}: \"$onefile->{'ComponentCondition'}\" !", "create_files_table");
+ }
- my @allfiles = ();
- my @filetable = ();
- my @filehashtable = ();
- my %allfilecomponents = ();
- my $counter = 0;
+ if ( $onefile->{'specificlanguage'} eq "" )
+ {
+ installer::exiter::exit_program(
+ "ERROR: There is no specific language for file at language module: $onefile->{'gid'} !", "create_files_table");
+ }
+ my $locallanguage = $onefile->{'specificlanguage'};
+ my $property = "IS" . $onefile->{'windows_language'};
+ my $value = 1;
+ my $condition = $property . "=" . $value;
+
+ $onefile->{'ComponentCondition'} = $condition;
- if ( $^O =~ /cygwin/i ) { installer::worker::generate_cygwin_pathes($filesref); }
-
- # The filenames must be collected because of uniqueness
- # 01-44-~1.DAT, 01-44-~2.DAT, ...
- # my @shortnames = ();
- my %shortnames = ();
-
- installer::windows::idtglobal::write_idt_header(\@filetable, "file");
- installer::windows::idtglobal::write_idt_header(\@filehashtable, "filehash");
-
- for ( my $i = 0; $i <= $#{$filesref}; $i++ )
- {
- my %file = ();
+ if ( exists($installer::globals::componentcondition{$onefile->{'componentname'}}))
+ {
+ if ( $installer::globals::componentcondition{$onefile->{'componentname'}} ne $condition )
+ {
+ installer::exiter::exit_program(
+ sprintf(
+ "ERROR: There is already another component condition for file %s: \"%s\" and \"%s\" !",
+ $onefile->{'gid'},
+ $installer::globals::componentcondition{$onefile->{'componentname'}},
+ $condition),
+ "create_files_table");
+ }
+ }
+ else
+ {
+ $installer::globals::componentcondition{$onefile->{'componentname'}} = $condition;
+ }
- my $onefile = ${$filesref}[$i];
+ # collecting all properties for table Property
+ if ( ! exists($installer::globals::languageproperties{$property}) )
+ {
+ $installer::globals::languageproperties{$property} = $value;
+ }
+ }
+}
- my $styles = "";
- if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; }
- if (( $styles =~ /\bJAVAFILE\b/ ) && ( ! ($allvariables->{'JAVAPRODUCT'} ))) { next; }
- $file{'Component_'} = get_file_component_name($onefile, $filesref);
- $file{'File'} = generate_unique_filename_for_filetable($onefile, $file{'Component_'});
-
- $onefile->{'uniquename'} = $file{'File'};
- $onefile->{'componentname'} = $file{'Component_'};
- # Collecting all components
- # if (!(installer::existence::exists_in_array($file{'Component_'}, $allfilecomponentsref))) { push(@{$allfilecomponentsref}, $file{'Component_'}); }
- if ( ! exists($allfilecomponents{$file{'Component_'}}) ) { $allfilecomponents{$file{'Component_'}} = 1; }
+sub has_style ($$)
+{
+ my ($style_list_string, $style_name) = @_;
- $file{'FileName'} = generate_filename_for_filetable($onefile, \%shortnames);
+ return 0 unless defined $style_list_string;
+ return $style_list_string =~ /\b$style_name\b/ ? 1 : 0;
+}
- $file{'FileSize'} = get_filesize($onefile);
- $file{'Version'} = get_fileversion($onefile, $allvariables, $styles);
- $file{'Language'} = get_language_for_file($onefile);
-
- if ( $styles =~ /\bDONT_PACK\b/ ) { $file{'Attributes'} = "8192"; }
- else { $file{'Attributes'} = "16384"; }
- # $file{'Attributes'} = "16384"; # Sourcefile is packed
- # $file{'Attributes'} = "8192"; # Sourcefile is unpacked
+sub prepare_file_table_creation ($$$)
+{
+ my ($file_list, $directory_list, $allvariables) = @_;
+
+ if ( $^O =~ /cygwin/i )
+ {
+ installer::worker::generate_cygwin_pathes($file_list);
+ }
- $installer::globals::insert_file_at_end = 0;
- $counter++;
- $file{'Sequence'} = $counter;
+ # Reset the fields 'sequencenumber' and 'uniquename'. They should not yet exist but better be sure.
+ foreach my $file (@$file_list)
+ {
+ delete $file->{'sequencenumber'};
+ delete $file->{'uniquename'};
+ }
- $onefile->{'sequencenumber'} = $file{'Sequence'};
+ # Create FileSequenceList object for the old sequence data.
+ if (defined $installer::globals::source_msi)
+ {
+ my $previous_sequence_data = new installer::patch::FileSequenceList();
+ $previous_sequence_data->SetFromMsi($installer::globals::source_msi);
+ my @added_files = retrieve_sequence_and_uniquename($file_list, $previous_sequence_data);
+
+ # Extract just the unique names.
+ my %target_unique_names = map {$_->{'uniquename'} => 1} @$file_list;
+ my @removed_items = $previous_sequence_data->get_removed_files(\%target_unique_names);
+
+ $installer::logger::Lang->printf(
+ "there are %d files that have been removed from source and %d files added\n",
+ scalar @removed_items,
+ scalar @added_files);
+
+ my $file_map = $installer::globals::source_msi->GetFileMap();
+ my $index = 0;
+ foreach my $removed_row (@removed_items)
+ {
+ $installer::logger::Lang->printf(" removed file %d: %s\n",
+ ++$index,
+ $removed_row->GetValue('File'));
+ my $directory = $file_map->{$removed_row->GetValue('File')}->{'directory'};
+ while (my ($key,$value) = each %$directory)
+ {
+ $installer::logger::Lang->printf(" %16s -> %s\n", $key, $value);
+ }
+ }
+ $index = 0;
+ foreach my $added_file (@added_files)
+ {
+ $installer::logger::Lang->printf(" added file %d: %s\n",
+ ++$index,
+ $added_file->{'uniquename'});
+ installer::scriptitems::print_script_item($added_file);
+ }
+ my @new_files = create_items_for_missing_files(
+ \@removed_items,
+ $installer::globals::source_msi,
+ $directory_list);
+ push @$file_list, @new_files;
+ }
+ assign_missing_sequence_numbers($file_list);
- my $oneline = $file{'File'} . "\t" . $file{'Component_'} . "\t" . $file{'FileName'} . "\t"
- . $file{'FileSize'} . "\t" . $file{'Version'} . "\t" . $file{'Language'} . "\t"
- . $file{'Attributes'} . "\t" . $file{'Sequence'} . "\n";
+ foreach my $file (@$file_list)
+ {
+ if ( ! defined $file->{'componentname'})
+ {
+ $file->{'componentname'} = get_file_component_name($file, $file_list);
+ }
+ if ( ! defined $file->{'uniquename'})
+ {
+ $file->{'uniquename'} = generate_unique_filename_for_filetable($file->{'Name'});
+ }
- push(@filetable, $oneline);
-
- if ( ! $installer::globals::insert_file_at_end ) { push(@allfiles, $onefile); }
-
# Collecting all component conditions
- if ( $onefile->{'ComponentCondition'} )
+ if ( $file->{'ComponentCondition'} )
{
- if ( ! exists($installer::globals::componentcondition{$file{'Component_'}}))
+ if ( ! exists($installer::globals::componentcondition{$file->{'componentname'}}))
{
- $installer::globals::componentcondition{$file{'Component_'}} = $onefile->{'ComponentCondition'};
+ $installer::globals::componentcondition{$file->{'componentname'}}
+ = $file->{'ComponentCondition'};
}
}
-
# Collecting also all tree conditions for multilayer products
- get_tree_condition_for_component($onefile, $file{'Component_'});
+ get_tree_condition_for_component($file, $file->{'componentname'});
# Collecting all component names, that have flag VERSION_INDEPENDENT_COMP_ID
# This should be all components with constant API, for example URE
- if ( $styles =~ /\bVERSION_INDEPENDENT_COMP_ID\b/ )
+ if (has_style($file->{'Styles'}, "VERSION_INDEPENDENT_COMP_ID"))
{
- $installer::globals::base_independent_components{$onefile->{'componentname'}} = 1;
+ $installer::globals::base_independent_components{$file->{'componentname'}} = 1;
}
- # Collecting all component ids, that are defined at files in scp project (should not be used anymore)
- if ( $onefile->{'CompID'} )
- {
- if ( ! exists($installer::globals::componentid{$onefile->{'componentname'}}))
- {
- $installer::globals::componentid{$onefile->{'componentname'}} = $onefile->{'CompID'};
- }
- else
- {
- if ( $installer::globals::componentid{$onefile->{'componentname'}} ne $onefile->{'CompID'} )
- {
- installer::exiter::exit_program("ERROR: There is already a ComponentID for component \"$onefile->{'componentname'}\" : \"$installer::globals::componentid{$onefile->{'componentname'}}\" . File \"$onefile->{'gid'}\" uses \"$onefile->{'CompID'}\" !", "create_files_table");
- }
- }
-
- # Also checking vice versa. Is this ComponentID already used? If yes, is the componentname the same?
-
- if ( ! exists($installer::globals::comparecomponentname{$onefile->{'CompID'}}))
- {
- $installer::globals::comparecomponentname{$onefile->{'CompID'}} = $onefile->{'componentname'};
- }
- else
- {
- if ( $installer::globals::comparecomponentname{$onefile->{'CompID'}} ne $onefile->{'componentname'} )
- {
- installer::exiter::exit_program("ERROR: There is already a component for ComponentID \"$onefile->{'CompID'}\" : \"$installer::globals::comparecomponentname{$onefile->{'CompID'}}\" . File \"$onefile->{'gid'}\" has same component id but is included in component \"$onefile->{'componentname'}\" !", "create_files_table");
- }
- }
- }
+ # Special handling for files in PREDEFINED_OSSHELLNEWDIR. These components
+ # need as KeyPath a RegistryItem in HKCU
+ if ($file->{'needs_user_registry_key'}
+ || (defined $file->{'Dir'} && $file->{'Dir'} =~ /\bPREDEFINED_OSSHELLNEWDIR\b/))
+ {
+ my $keypath = generate_registry_keypath($file);
+ $file->{'userregkeypath'} = $keypath;
+ push(@installer::globals::userregistrycollector, $file);
+ $installer::globals::addeduserregitrykeys = 1;
+ }
- # Collecting all language specific conditions
- # if ( $onefile->{'haslanguagemodule'} )
- if ( $onefile->{'ismultilingual'} )
- {
- if ( $onefile->{'ComponentCondition'} ) { installer::exiter::exit_program("ERROR: Cannot set language condition. There is already another component condition for file $onefile->{'gid'}: \"$onefile->{'ComponentCondition'}\" !", "create_files_table"); }
-
- if ( $onefile->{'specificlanguage'} eq "" ) { installer::exiter::exit_program("ERROR: There is no specific language for file at language module: $onefile->{'gid'} !", "create_files_table"); }
- my $locallanguage = $onefile->{'specificlanguage'};
- my $property = "IS" . $file{'Language'};
- my $value = 1;
- my $condition = $property . "=" . $value;
-
- $onefile->{'ComponentCondition'} = $condition;
+ $file->{'windows_language'} = get_language_for_file($file);
- if ( exists($installer::globals::componentcondition{$file{'Component_'}}))
- {
- if ( $installer::globals::componentcondition{$file{'Component_'}} ne $condition ) { installer::exiter::exit_program("ERROR: There is already another component condition for file $onefile->{'gid'}: \"$installer::globals::componentcondition{$file{'Component_'}}\" and \"$condition\" !", "create_files_table"); }
- }
- else
- {
- $installer::globals::componentcondition{$file{'Component_'}} = $condition;
- }
+ process_language_conditions($file);
+ }
- # collecting all properties for table Property
- if ( ! exists($installer::globals::languageproperties{$property}) ) { $installer::globals::languageproperties{$property} = $value; }
- }
+ # The filenames must be collected because of uniqueness
+ # 01-44-~1.DAT, 01-44-~2.DAT, ...
+ my %shortnames = ();
+ foreach my $file (@$file_list)
+ {
+ $file->{'short_name'} = generate_filename_for_filetable($file, \%shortnames);
+ }
+}
- if ( $installer::globals::prepare_winpatch )
- {
- my $path = $onefile->{'sourcepath'};
- if ( $^O =~ /cygwin/i ) { $path = $onefile->{'cyg_sourcepath'}; }
- open(FILE, $path) or die "ERROR: Can't open $path for creating file hash";
- binmode(FILE);
- my $hashinfo = pack("l", 20);
- $hashinfo .= Digest::MD5->new->addfile(*FILE)->digest;
- my @i = unpack ('x[l]l4', $hashinfo);
- $oneline = $file{'File'} . "\t" .
- "0" . "\t" .
- $i[0] . "\t" .
- $i[1] . "\t" .
- $i[2] . "\t" .
- $i[3] . "\n";
- push (@filehashtable, $oneline);
- }
- # Saving the sequence number in a hash with uniquefilename as key.
- # This is used for better performance in "save_packorder"
- $installer::globals::uniquefilenamesequence{$onefile->{'uniquename'}} = $onefile->{'sequencenumber'};
-
- # Special handling for files in PREDEFINED_OSSHELLNEWDIR. These components
- # need as KeyPath a RegistryItem in HKCU
- my $destdir = "";
- if ( $onefile->{'Dir'} ) { $destdir = $onefile->{'Dir'}; }
+sub create_file_table_data ($$)
+{
+ my ($file_list, $allvariables) = @_;
+
+ my @file_table_data = ();
+ foreach my $file (@$file_list)
+ {
+ my $attributes;
+ if (has_style($file->{'Styles'}, "DONT_PACK"))
+ {
+ # Sourcefile is unpacked (msidbFileAttributesNoncompressed).
+ $attributes = "8192";
+ }
+ else
+ {
+ # Sourcefile is packed (msidbFileAttributesCompressed).
+ $attributes = "16384";
+ }
- if (( $destdir =~ /\bPREDEFINED_OSSHELLNEWDIR\b/ ) || ( $onefile->{'needs_user_registry_key'} ))
- {
- my $keypath = generate_registry_keypath($onefile);
- $onefile->{'userregkeypath'} = $keypath;
- push(@installer::globals::userregistrycollector, $onefile);
- $installer::globals::addeduserregitrykeys = 1;
- }
+ my $row_data = {
+ 'File' => $file->{'uniquename'},
+ 'Component_' => $file->{'componentname'},
+ 'FileName' => $file->{'short_name'},
+ 'FileSize' => get_filesize($file),
+ 'Version' => get_fileversion($file, $allvariables),
+ 'Language' => $file->{'windows_language'},
+ 'Attributes' => $attributes,
+ 'Sequence' => $file->{'sequencenumber'}
+ };
+ push @file_table_data, $row_data;
}
- # putting content from %allfilecomponents to $allfilecomponentsref for later usage
- foreach $localkey (keys %allfilecomponents ) { push( @{$allfilecomponentsref}, $localkey); }
+ return \@file_table_data;
+}
+
+
+
+
+sub collect_components ($)
+{
+ my ($file_list) = @_;
+
+ my %components = ();
+ foreach my $file (@$file_list)
+ {
+ $components{$file->{'componentname'}} = 1;
+ }
+ return keys %components;
+}
+
+
+
+
+=head filter_files($file_list, $allvariables)
+
+ Filter out Java files when not building a Java product.
+
+ Is this still triggered?
+
+=cut
+sub filter_files ($$)
+{
+ my ($file_list, $allvariables) = @_;
+
+ if ($allvariables->{'JAVAPRODUCT'})
+ {
+ return $file_list;
+ }
+ else
+ {
+ my @filtered_files = ();
+ foreach my $file (@$file_list)
+ {
+ if ( ! has_style($file->{'Styles'}, "JAVAFILE"))
+ {
+ push @filtered_files, $file;
+ }
+ }
+ return \@filtered_files;
+ }
+}
+
+
+
+
+# Structure of the files table:
+# File Component_ FileName FileSize Version Language Attributes Sequence
+sub create_file_table ($$)
+{
+ my ($file_table_data, $basedir) = @_;
+
+ # Set up the 'File' table.
+ my @filetable = ();
+ installer::windows::idtglobal::write_idt_header(\@filetable, "file");
+ my @keys = ('File', 'Component_', 'FileName', 'FileSize', 'Version', 'Language', 'Attributes', 'Sequence');
+ my $index = 0;
+ foreach my $row_data (@$file_table_data)
+ {
+ ++$index;
+ my @values = map {$row_data->{$_}} @keys;
+ my $line = join("\t", @values) . "\n";
+ push(@filetable, $line);
+ }
- my $filetablename = $basedir . $installer::globals::separator . "File.idt";
+ my $filetablename = $basedir . $installer::globals::separator . "File.idt";
installer::files::save_file($filetablename ,\@filetable);
$installer::logger::Lang->print("\n");
$installer::logger::Lang->printf("Created idt file: %s\n", $filetablename);
+}
- $installer::logger::Lang->add_timestamp("Performance Info: File Table end");
-
- my $filehashtablename = $basedir . $installer::globals::separator . "MsiFileHash.idt";
- installer::files::save_file($filehashtablename ,\@filehashtable);
- $installer::logger::Lang->print("\n");
- $installer::logger::Lang->printf("Created idt file: %s\n", $filehashtablename);
- # Now the new files can be added to the files collector (only in update packaging processes)
- if ( $installer::globals::newfilesexist )
- {
- foreach my $seq (sort keys %installer::globals::newfilescollector) { push(@allfiles, $installer::globals::newfilescollector{$seq}) }
- }
- return \@allfiles;
+
+sub create_filehash_table ($$)
+{
+ my ($file_list, $basedir) = @_;
+
+ my @filehashtable = ();
+
+ if ( $installer::globals::prepare_winpatch )
+ {
+
+ installer::windows::idtglobal::write_idt_header(\@filehashtable, "filehash");
+
+ foreach my $file (@$file_list)
+ {
+ my $path = $file->{'sourcepath'};
+ if ($^O =~ /cygwin/i)
+ {
+ $path = $file->{'cyg_sourcepath'};
+ }
+
+ open(FILE, $path) or die "ERROR: Can't open $path for creating file hash";
+ binmode(FILE);
+ my $hashinfo = pack("l", 20);
+ $hashinfo .= Digest::MD5->new->addfile(*FILE)->digest;
+
+ my @i = unpack ('x[l]l4', $hashinfo);
+ my $oneline = join("\t",
+ (
+ $file->{'uniquename'},
+ "0",
+ @i
+ ));
+ push (@filehashtable, $oneline . "\n");
+ }
+
+ my $filehashtablename = $basedir . $installer::globals::separator . "MsiFileHash.idt";
+ installer::files::save_file($filehashtablename ,\@filehashtable);
+ $installer::logger::Lang->print("\n");
+ $installer::logger::Lang->printf("Created idt file: %s\n", $filehashtablename);
+ }
}
+
1;
Modified: openoffice/trunk/main/solenv/bin/modules/installer/windows/msiglobal.pm
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/solenv/bin/modules/installer/windows/msiglobal.pm?rev=1547732&r1=1547731&r2=1547732&view=diff
==============================================================================
--- openoffice/trunk/main/solenv/bin/modules/installer/windows/msiglobal.pm (original)
+++ openoffice/trunk/main/solenv/bin/modules/installer/windows/msiglobal.pm Wed Dec 4 08:51:30 2013
@@ -37,6 +37,8 @@ use installer::systemactions;
use installer::worker;
use installer::windows::idtglobal;
use installer::windows::language;
+use installer::patch::ReleasesList;
+
use strict;
###########################################################################
@@ -498,11 +500,7 @@ sub get_packagecode_for_sis
{
# always generating a new package code for each package
- my $guidref = get_guid_list(1, 1); # only one GUID shall be generated
-
- ${$guidref}[0] =~ s/\s*$//; # removing ending spaces
-
- my $guid = "\{" . ${$guidref}[0] . "\}";
+ my $guid = "\{" . create_guid() . "\}";
my $infoline = "PackageCode: $guid\n";
$installer::logger::Lang->print($infoline);
@@ -1127,47 +1125,19 @@ sub copy_child_projects_into_installset
}
}
-#################################################################
-# Getting a list of GUID using uuidgen.exe.
-# This works only on Windows
-#################################################################
-sub get_guid_list
-{
- my ($number, $log) = @_;
- if ( $log ) { installer::logger::include_header_into_logfile("Generating $number GUID"); }
-
- my $uuidgen = "uuidgen.exe"; # Has to be in the path
-
- # "-c" for uppercase output
-
- # my $systemcall = "$uuidgen -n$number -c |";
- my $systemcall = "$uuidgen -n$number |";
- open (UUIDGEN, "$systemcall" ) or die("uuidgen is missing.");
- my @uuidlist = <UUIDGEN>;
- close (UUIDGEN);
+=head2 create_guid ()
- my $infoline = "Systemcall: $systemcall\n";
- if ( $log ) { $installer::logger::Lang->print($infoline); }
-
- my $comparenumber = $#uuidlist + 1;
-
- if ( $comparenumber == $number )
- {
- $infoline = "Success: Executed $uuidgen successfully!\n";
- if ( $log ) { $installer::logger::Lang->print($infoline); }
- }
- else
- {
- $infoline = "ERROR: Could not execute $uuidgen successfully!\n";
- if ( $log ) { $installer::logger::Lang->print($infoline); }
- }
-
- # uppercase, no longer "-c", because this is only supported in uuidgen.exe v.1.01
- for ( my $i = 0; $i <= $#uuidlist; $i++ ) { $uuidlist[$i] = uc($uuidlist[$i]); }
-
- return \@uuidlist;
+ Create a single UUID aka GUID via calling the external executable 'uuidgen'.
+ There are Perl modules for that, but do they exist on the build bots?
+
+=cut
+sub create_guid ()
+{
+ my $uuid = qx("uuidgen");
+ $uuid =~ s/\s*$//;
+ return uc($uuid);
}
#################################################################
@@ -1188,6 +1158,9 @@ sub calculate_guid
# my $id = pack("A32", $digest);
my ($first, $second, $third, $fourth, $fifth) = unpack ('A8 A4 A4 A4 A12', $digest);
$guid = "$first-$second-$third-$fourth-$fifth";
+
+ $installer::logger::Lang->printf("guid for '%s' is %s\n",
+ $string, $guid);
return $guid;
}
@@ -1264,7 +1237,7 @@ sub create_new_component_file
# This works only on Windows
#################################################################
-sub set_uuid_into_component_table
+sub __set_uuid_into_component_table
{
my ($idtdirbase, $allvariables) = @_;
@@ -1303,19 +1276,32 @@ sub set_uuid_into_component_table
{
# Calculating new GUID with the help of the component name.
my $useooobaseversion = 1;
- if ( exists($installer::globals::base_independent_components{$componentname})) { $useooobaseversion = 0; }
+ if ( exists($installer::globals::base_independent_components{$componentname}))
+ {
+ $useooobaseversion = 0;
+ }
my $sourcestring = $componentname;
if ( $useooobaseversion )
{
- if ( ! exists($allvariables->{'OOOBASEVERSION'}) ) { installer::exiter::exit_program("ERROR: Could not find variable \"OOOBASEVERSION\" (required value for GUID creation)!", "set_uuid_into_component_table"); }
+ if ( ! exists($allvariables->{'OOOBASEVERSION'}) )
+ {
+ installer::exiter::exit_program(
+ "ERROR: Could not find variable \"OOOBASEVERSION\" (required value for GUID creation)!",
+ "set_uuid_into_component_table");
+ }
$sourcestring = $sourcestring . "_" . $allvariables->{'OOOBASEVERSION'};
}
$uuid = calculate_guid($sourcestring);
$counter++;
# checking, if there is a conflict with an already created guid
- if ( exists($installer::globals::allcalculated_guids{$uuid}) ) { installer::exiter::exit_program("ERROR: \"$uuid\" was already created before!", "set_uuid_into_component_table"); }
+ if ( exists($installer::globals::allcalculated_guids{$uuid}) )
+ {
+ installer::exiter::exit_program(
+ "ERROR: \"$uuid\" was already created before!",
+ "set_uuid_into_component_table");
+ }
$installer::globals::allcalculated_guids{$uuid} = 1;
$installer::globals::calculated_component_guids{$componentname} = $uuid;
@@ -1631,107 +1617,138 @@ sub execute_packaging
$installer::logger::Lang->print($infoline);
}
-###############################################################
-# Setting the global variables ProductCode and the UpgradeCode
-###############################################################
-sub set_global_code_variables ($$)
-{
- my ($languagesref, $allvariableshashref) = @_;
+=head2 get_source_codes($languagesref)
- # In the msi template directory a files "codes.txt" has to exist, in which the ProductCode
- # and the UpgradeCode for the product are defined.
- # The name "codes.txt" can be overwritten in Product definition with CODEFILENAME .
- # Default $installer::globals::codefilename is defined in parameter.pm.
-
- if ( $allvariableshashref->{'CODEFILENAME'} )
- {
- $installer::globals::codefilename = $installer::globals::idttemplatepath . $installer::globals::separator . $allvariableshashref->{'CODEFILENAME'};
- installer::files::check_file($installer::globals::codefilename);
- }
-
- my $infoline = "Using Codes file: $installer::globals::codefilename \n";
- $installer::logger::Lang->print($infoline);
-
- my $codefile = installer::files::read_file($installer::globals::codefilename);
-
- my $isopensource = 0;
- if ( $allvariableshashref->{'OPENSOURCE'} ) { $isopensource = $allvariableshashref->{'OPENSOURCE'}; }
+ Return product code and upgrade code from the source version.
+ When no source version is defined then return undef for both.
+
+=cut
+sub get_source_codes ($)
+{
+ my ($languagesref) = @_;
+
+ if ( ! defined $installer::globals::source_version)
+ {
+ return;
+ }
+
+ my $onelanguage = installer::languages::get_key_language($languagesref);
+
+ my $release_data = installer::patch::ReleasesList::Instance()
+ ->{$installer::globals::source_version}
+ ->{$installer::globals::packageformat};
+ if (defined $release_data)
+ {
+ my $language_data = $release_data->{$onelanguage};
+ if (defined $language_data)
+ {
+ $installer::logger::Lang->printf("source product code is %s\n", $language_data->{'product-code'});
+ $installer::logger::Lang->printf("source upgrade code is %s\n", $release_data->{'upgrade-code'});
+
+ return (
+ $language_data->{'product-code'},
+ $release_data->{'upgrade-code'}
+ );
+ }
+ else
+ {
+ $installer::logger::Info->printf(
+ "Warning: can not access information about previous version %s and language %s\n",
+ $installer::globals::source_version,
+ $onelanguage);
+ return (undef,undef);
+ }
+ }
+ else
+ {
+ $installer::logger::Info->printf("Warning: can not access information about previous version %s\n",
+ $installer::globals::source_version);
+ return (undef,undef);
+ }
+}
- my $onelanguage = "";
-
- if ( $#{$languagesref} > 0 ) # more than one language
- {
- if (( $installer::globals::added_english ) && ( $#{$languagesref} == 1 )) # only multilingual because of added English
- {
- $onelanguage = ${$languagesref}[1]; # setting the first language, that is not english
- }
- else
- {
- if (( ${$languagesref}[1] =~ /jp/ ) ||
- ( ${$languagesref}[1] =~ /ko/ ) ||
- ( ${$languagesref}[1] =~ /zh/ ))
- {
- $onelanguage = "multiasia";
- }
- else
- {
- $onelanguage = "multiwestern";
- }
- }
- }
- else # only one language
- {
- $onelanguage = ${$languagesref}[0];
- }
- # ProductCode must not change, if Windows patches shall be applied
- if ( $installer::globals::prepare_winpatch )
- {
- # ProductCode has to be specified in each language
- my $searchstring = "PRODUCTCODE";
- my $codeblock = installer::windows::idtglobal::get_language_block_from_language_file($searchstring, $codefile);
- $installer::globals::productcode = installer::windows::idtglobal::get_code_from_code_block($codeblock, $onelanguage);
- } else {
- my $guidref = get_guid_list(1, 1); # only one GUID shall be generated
- ${$guidref}[0] =~ s/\s*$//; # removing ending spaces
- $installer::globals::productcode = "\{" . ${$guidref}[0] . "\}";
- }
- if ( $installer::globals::patch ) # patch upgrade codes are defined in soffice.lst
- {
- if ( $allvariableshashref->{'PATCHUPGRADECODE'} ) { $installer::globals::upgradecode = $allvariableshashref->{'PATCHUPGRADECODE'}; }
- else { installer::exiter::exit_program("ERROR: PATCHUPGRADECODE not defined in list file!", "set_global_code_variables"); }
- }
- else
- {
- # UpgradeCode can take english as default, if not defined in specified language
- my $searchstring = "UPGRADECODE"; # searching in the codes.txt file
- my $codeblock = installer::windows::idtglobal::get_language_block_from_language_file($searchstring, $codefile);
- $installer::globals::upgradecode = installer::windows::idtglobal::get_language_string_from_language_block($codeblock, $onelanguage, "");
- }
-
- # if (( $installer::globals::productcode eq "" ) && ( ! $isopensource )) { installer::exiter::exit_program("ERROR: ProductCode for language $onelanguage not defined in $installer::globals::codefilename !", "set_global_code_variables"); }
- if ( $installer::globals::upgradecode eq "" ) { installer::exiter::exit_program("ERROR: UpgradeCode not defined in $installer::globals::codefilename !", "set_global_code_variables"); }
+=head2 set_global_code_variables ($languagesref, $allvariableshashref)
+
+ Determine values for the product code and upgrade code of the target version.
+
+ As perparation for building a Windows patch, certain conditions have to be fullfilled.
+ - The upgrade code changes from old to new version
+ - The product code remains the same
+ In order to inforce that we have to access information about the source version.
+
+ The resulting values are stored as global variables
+ $installer::globals::productcode
+ $installer::globals::upgradecode
+ and as variables in the given hash
+ $allvariableshashref->{'PRODUCTCODE'}
+ $allvariableshashref->{'UPGRADECODE'}
- $infoline = "Setting ProductCode to: $installer::globals::productcode \n";
- $installer::logger::Lang->print($infoline);
- $infoline = "Setting UpgradeCode to: $installer::globals::upgradecode \n";
- $installer::logger::Lang->print($infoline);
+=cut
+sub set_global_code_variables ($$)
+{
+ my ($languagesref, $allvariableshashref) = @_;
- # Adding both variables into the variables array
+ my ($source_product_code, $source_upgrade_code) = get_source_codes($languagesref);
+ my ($target_product_code, $target_upgrade_code) = (undef, undef);
+
+ if (defined $source_product_code && defined $source_upgrade_code)
+ {
+ if ($installer::globals::is_major_release)
+ {
+ # For a major release we have to change the product code.
+ $target_product_code = "{" . create_guid() . "}";
+ $installer::logger::Lang->printf("building a major release, created new product code %s\n",
+ $target_product_code);
+
+ # Let's do a paranoia check that the new and the old guids are
+ # different. In reality the new guid really has to be
+ # different from all other guids used for * codes, components,
+ # etc.
+ if ($target_product_code eq $source_product_code)
+ {
+ installer::logger::PrintError(
+ "new GUID for product code is the same as the old product code but should be different.");
+ }
+ }
+ else
+ {
+ # For minor or micro releases we have to keeep the old product code.
+ $target_product_code = "{" . $source_product_code . "}";
+ $installer::logger::Lang->printf("building a minor or micro release, reusing product code %s\n",
+ $target_product_code);
+ }
+
+ $target_upgrade_code = "{" . create_guid() . "}";
+ # Again, just one test for paranoia.
+ if ($target_upgrade_code eq $source_upgrade_code)
+ {
+ installer::logger::PrintError(
+ "new GUID for upgrade code is the same as the old upgrade code but should be different.");
+ }
+ }
+ else
+ {
+ # There is no previous version with which to compare the product code.
+ # Just create two new uuids.
+ $target_product_code = "{" . create_guid() . "}";
+ $target_upgrade_code = "{" . create_guid() . "}";
+ }
+
+ $installer::globals::productcode = $target_product_code;
+ $installer::globals::upgradecode = $target_upgrade_code;
+ $allvariableshashref->{'PRODUCTCODE'} = $target_product_code;
+ $allvariableshashref->{'UPGRADECODE'} = $target_upgrade_code;
- $allvariableshashref->{'PRODUCTCODE'} = $installer::globals::productcode;
- $allvariableshashref->{'UPGRADECODE'} = $installer::globals::upgradecode;
+ $installer::logger::Lang->printf("target product code is %s\n", $target_product_code);
+ $installer::logger::Lang->printf("target upgrade code is %s\n", $target_upgrade_code);
+}
- $infoline = "Defined variable PRODUCTCODE: $installer::globals::productcode \n";
- $installer::logger::Lang->print($infoline);
- $infoline = "Defined variable UPGRADECODE: $installer::globals::upgradecode \n";
- $installer::logger::Lang->print($infoline);
-}
###############################################################
# Setting the product version used in property table and
Modified: openoffice/trunk/main/solenv/bin/modules/installer/windows/registry.pm
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/solenv/bin/modules/installer/windows/registry.pm?rev=1547732&r1=1547731&r2=1547732&view=diff
==============================================================================
--- openoffice/trunk/main/solenv/bin/modules/installer/windows/registry.pm (original)
+++ openoffice/trunk/main/solenv/bin/modules/installer/windows/registry.pm Wed Dec 4 08:51:30 2013
@@ -29,6 +29,8 @@ use installer::worker;
use installer::windows::msiglobal;
use installer::windows::idtglobal;
+use strict;
+
#####################################################
# Generating the component name from a registryitem
#####################################################
@@ -284,25 +286,6 @@ sub get_registry_val64
return $value;
}
-##############################################################
-# Returning component for registry table.
-##############################################################
-
-sub get_registry_component
-{
- my ($registry, $allvariables) = @_;
-
- # All registry items belonging to one module can
- # be included into one component
-
- my $componentname = get_registry_component_name($registry, $allvariables);
-
- # saving componentname in the registryitem collector
-
- $registry->{'componentname'} = $componentname;
-
- return $componentname;
-}
######################################################
# Adding the content of
@@ -345,20 +328,13 @@ sub add_userregs_to_registry_table
# Content:
# Registry Root Key Name Value Component_
######################################################
-
-sub create_registry_table
+sub prepare_registry_table ($$$)
{
- my ($registryref, $allregistrycomponentsref, $basedir, $languagesarrayref, $allvariableshashref) = @_;
+ my ($registryref, $languagesarrayref, $allvariableshashref) = @_;
my %table_data = ();
foreach my $onelanguage (@$languagesarrayref)
{
-
- my @registrytable = ();
- my @reg64table = ();
-
- installer::windows::idtglobal::write_idt_header(\@registrytable, "registry");
- installer::windows::idtglobal::write_idt_header(\@reg64table, "reg64");
my $table_items = [];
foreach my $oneregistry (@$registryref)
{
@@ -381,12 +357,6 @@ sub create_registry_table
$oneregistry->{'componentname'} = $component_name;
$registry{'Component_'} = $component_name;
- # Collecting all components
- if (!(installer::existence::exists_in_array($registry{'Component_'}, $allregistrycomponentsref)))
- {
- push(@{$allregistrycomponentsref}, $registry{'Component_'});
- }
-
# Collecting all components with DONT_DELETE style
my $style = $oneregistry->{'Styles'} // "";
$registry{'styles'} = $style;
@@ -420,14 +390,93 @@ sub create_registry_table
}
}
- my $oneline = $registry{'Registry'} . "\t" . $registry{'Root'} . "\t" . $registry{'Key'} . "\t"
- . $registry{'Name'} . "\t" . $registry{'Value'} . "\t" . $registry{'Component_'} . "\n";
+ push @$table_items, \%registry;
+ }
+ $table_data{$onelanguage} = $table_items;
+ }
+
+ return \%table_data;
+}
+
+
+
+
+sub collect_registry_components ($)
+{
+ my ($table_data) = @_;
+
+ my %components = ();
+ foreach my $language_data (values %$table_data)
+ {
+ foreach my $item (@$language_data)
+ {
+ $components{$item->{'Component_'}} = 1;
+ }
+ }
+ return keys %components;
+}
+
+
- my $oneline64 = $registry{'Registry'} . "\t" . $registry{'Root'} . "\t" . $registry{'Key'} . "\t"
- . $registry{'Name'} . "\t" . $registry{'Val64'} . "\t" . $registry{'Component_'} . "\n";
- if ( ! ( $style =~ /\bX64_ONLY\b/ )) { push(@registrytable, $oneline); } # standard registry table for 32 Bit
- if (( $style =~ /\bX64\b/ ) || ( $style =~ /\bX64_ONLY\b/ )) { push(@reg64table , $oneline64); }
+sub translate_component_names ($$$)
+{
+ my ($translation_map, $registry_items, $table_data) = @_;
+
+ my $replacement_count = 0;
+ foreach my $item (@$registry_items)
+ {
+ my $translated_name = $translation_map->{$item->{'componentname'}};
+ if (defined $translated_name)
+ {
+ $item->{'componentname'} = $translated_name;
+ ++$replacement_count;
+ }
+ }
+ $installer::logger::Lang->printf("replaced %d component names in registry items\n", $replacement_count);
+
+ $replacement_count = 0;
+ foreach my $language_data (values %$table_data)
+ {
+ foreach my $item (@$language_data)
+ {
+ my $translated_name = $translation_map->{$item->{'Component_'}};
+ if (defined $translated_name)
+ {
+ $item->{'Component_'} = $translated_name;
+ ++$replacement_count;
+ }
+ }
+ }
+ $installer::logger::Lang->printf("replaced %d component names in registry table\n", $replacement_count);
+}
+
+
+
+
+sub create_registry_table_32 ($$$$)
+{
+ my ($basedir, $languagesarrayref, $allvariableshashref, $table_data) = @_;
+
+ foreach my $onelanguage (@$languagesarrayref)
+ {
+ my @registrytable = ();
+ installer::windows::idtglobal::write_idt_header(\@registrytable, "registry");
+
+ foreach my $item (@{$table_data->{$onelanguage}})
+ {
+ next if $item->{'styles'} =~ /\bX64_ONLY\b/;
+
+ my $oneline = join("\t",
+ $item->{'Registry'},
+ $item->{'Root'},
+ $item->{'Key'},
+ $item->{'Name'},
+ $item->{'Value'},
+ $item->{'Component_'})
+ . "\n";
+
+ push(@registrytable, $oneline);
}
# If there are added user registry keys for files collected in
@@ -436,15 +485,47 @@ sub create_registry_table
# files in PREDEFINED_OSSHELLNEWDIR, because their component
# needs as KeyPath a RegistryItem in HKCU.
- if ( $installer::globals::addeduserregitrykeys ) { add_userregs_to_registry_table(\@registrytable, $allvariableshashref); }
+ if ( $installer::globals::addeduserregitrykeys )
+ {
+ add_userregs_to_registry_table(\@registrytable, $allvariableshashref);
+ }
- # Saving the file
-
+ # Save the database file.
my $registrytablename = $basedir . $installer::globals::separator . "Registry.idt" . "." . $onelanguage;
installer::files::save_file($registrytablename ,\@registrytable);
$installer::logger::Lang->printf("Created idt file: %s\n", $registrytablename);
+ }
+}
+
+
+
+
+sub create_registry_table_64 ($$$$)
+{
+ my ($basedir, $languagesarrayref, $allvariableshashref, $table_data) = @_;
+
+ foreach my $onelanguage (@$languagesarrayref)
+ {
+ my @reg64table = ();
+ installer::windows::idtglobal::write_idt_header(\@reg64table, "reg64");
+ foreach my $item (@{$table_data->{$onelanguage}})
+ {
+ next unless $item->{'styles'} =~ /\b(X64|X64_ONLY)\b/;
+
+ my $oneline64 = join("\t",
+ $item->{'Registry'},
+ $item->{'Root'},
+ $item->{'Key'},
+ $item->{'Name'},
+ $item->{'Val64'},
+ $item->{'Component_'})
+ . "\n";
+
+ push(@reg64table , $oneline64);
+ }
- $registrytablename = $basedir . $installer::globals::separator . "Reg64.idt" . "." . $onelanguage;
+ # Save the database file.
+ my $registrytablename = $basedir . $installer::globals::separator . "Reg64.idt" . "." . $onelanguage;
installer::files::save_file($registrytablename ,\@reg64table );
$installer::logger::Lang->printf("Created idt file: %s\n", $registrytablename);
}