You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by or...@apache.org on 2013/12/18 14:27:25 UTC

svn commit: r1551937 [19/29] - in /openoffice/branches/ooxml-osba: ./ extras/l10n/source/bg/ extras/l10n/source/de/ extras/l10n/source/nb/ extras/l10n/source/th/ main/ main/accessibility/inc/accessibility/extended/ main/accessibility/inc/accessibility/...

Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/file.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/file.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/file.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/file.pm Wed Dec 18 13:27:09 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,
@@ -47,68 +52,65 @@ sub assign_cab_to_files
 	
 	my $infoline = "";
 
-	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
+	foreach my $file (@$filesref)
 	{
-		if ( ! exists(${$filesref}[$i]->{'modules'}) ) { installer::exiter::exit_program("ERROR: No module assignment found for ${$filesref}[$i]->{'gid'} !", "assign_cab_to_files"); }
-		my $module = ${$filesref}[$i]->{'modules'};
+		if ( ! exists($file->{'modules'}) )
+        {
+            installer::exiter::exit_program(
+                sprintf("ERROR: No module assignment found for %s", $file->{'gid'}),
+                "assign_cab_to_files");
+        }
+		my $module = $file->{'modules'};
 		# If modules contains a list of modules, only taking the first one.
 		if ( $module =~ /^\s*(.*?)\,/ ) { $module = $1; }
 
-		if ( ! exists($installer::globals::allcabinetassigns{$module}) ) { installer::exiter::exit_program("ERROR: No cabinet file assigned to module \"$module\" (${$filesref}[$i]->{'gid'}) !", "assign_cab_to_files"); }
-		${$filesref}[$i]->{'assignedcabinetfile'} = $installer::globals::allcabinetassigns{$module};
+		if ( ! exists($installer::globals::allcabinetassigns{$module}) )
+        {
+            installer::exiter::exit_program(
+                sprintf("ERROR: No cabinet file assigned to module \"%s\" %s",
+                    $module,
+                    $file->{'gid'}),
+                "assign_cab_to_files");
+        }
+		$file->{'assignedcabinetfile'} = $installer::globals::allcabinetassigns{$module};
 
 		# Counting the files in each cabinet file
-		if ( ! exists($installer::globals::cabfilecounter{${$filesref}[$i]->{'assignedcabinetfile'}}) )
+		if ( ! exists($installer::globals::cabfilecounter{$file->{'assignedcabinetfile'}}) )
 		{
-			$installer::globals::cabfilecounter{${$filesref}[$i]->{'assignedcabinetfile'}} = 1;
+			$installer::globals::cabfilecounter{$file->{'assignedcabinetfile'}} = 1;
 		}
 		else
 		{
-			$installer::globals::cabfilecounter{${$filesref}[$i]->{'assignedcabinetfile'}}++;
+			$installer::globals::cabfilecounter{$file->{'assignedcabinetfile'}}++;
 		}
 	}
 
-	# logging the number of files in each cabinet file
-
-	$installer::logger::Lang->print("\n");
-	$installer::logger::Lang->print("Cabinet file content:\n");
-	my $cabfile;
-	foreach $cabfile ( sort keys %installer::globals::cabfilecounter )
-	{
-		$infoline = "$cabfile : $installer::globals::cabfilecounter{$cabfile} files\n";
-		$installer::logger::Lang->print($infoline);
-	}
-	
 	# assigning startsequencenumbers for each cab file
-	
+
+    my %count = ();
 	my $offset = 1;
-	foreach $cabfile ( sort keys %installer::globals::cabfilecounter )
+	foreach my $cabfile ( sort keys %installer::globals::cabfilecounter )
 	{
 		my $filecount = $installer::globals::cabfilecounter{$cabfile};
+        $count{$cabfile} = $filecount;
 		$installer::globals::cabfilecounter{$cabfile} = $offset;
 		$offset = $offset + $filecount;
 		
 		$installer::globals::lastsequence{$cabfile} = $offset - 1;
 	}
-	
-	# logging the start sequence numbers
-
-	$installer::logger::Lang->print("\n");
-	$installer::logger::Lang->print("Cabinet file start sequences:\n");
-	foreach $cabfile ( sort keys %installer::globals::cabfilecounter )
-	{
-		$infoline = "$cabfile : $installer::globals::cabfilecounter{$cabfile}\n";
-		$installer::logger::Lang->print($infoline);
-	}
 
-	# logging the last sequence numbers
+	# logging the number of files in each cabinet file
 
 	$installer::logger::Lang->print("\n");
-	$installer::logger::Lang->print("Cabinet file last sequences:\n");
-	foreach $cabfile ( sort keys %installer::globals::lastsequence )
+	$installer::logger::Lang->print("Cabinet files:\n");
+	foreach my $cabfile (sort keys %installer::globals::cabfilecounter)
 	{
-		$infoline = "$cabfile : $installer::globals::lastsequence{$cabfile}\n";
-		$installer::logger::Lang->print($infoline);
+		$installer::logger::Lang->printf(
+            "%-30s : %4s files, from %4d to %4d\n",
+            $cabfile,
+            $count{$cabfile},
+            $installer::globals::cabfilecounter{$cabfile},
+            $installer::globals::lastsequence{$cabfile});
 	}
 }
 
@@ -123,7 +125,7 @@ sub assign_sequencenumbers_to_files
 	
 	my %directaccess = ();
 	my %allassigns = ();
-	
+
 	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
 	{
 		my $onefile = ${$filesref}[$i];
@@ -161,7 +163,7 @@ sub assign_sequencenumbers_to_files
 		foreach $dest ( sort keys %{$allassigns{$cabfile}} ) # <- sorting the destination!
 		{
 			my $directaccessnumber = $directaccess{$dest};
-			${$filesref}[$directaccessnumber]->{'assignedsequencenumber'} = $counter;			
+            ${$filesref}[$directaccessnumber]->{'assignedsequencenumber'} = $counter;			
 			$counter++;
 		}
 	}
@@ -360,33 +362,25 @@ 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, $uniquefilenamehashref) = @_;
+	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'}; }
-
-	installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$uniquefilename);	# making /registry/schema/org/openoffice/VCL.xcs to VCL.xcs 
-
-	# Reading unique filename with help of "Component_" in File table from old database	
-	if (( $installer::globals::prepare_winpatch ) && ( exists($installer::globals::savedmapping{"$component/$uniquefilename"}) ))
-	{
-		# If we have a FTK mapping for this component/file, use it.
-		$installer::globals::savedmapping{"$component/$uniquefilename"} =~ m/^(.*);/;
-		$uniquefilename = $1;
- 		$lcuniquefilename = lc($uniquefilename);
-		$installer::globals::alluniquefilenames{$uniquefilename} = 1;
-		$installer::globals::alllcuniquefilenames{$lcuniquefilename} = 1;
-		return $uniquefilename;
-	}
+   	# making /registry/schema/org/openoffice/VCL.xcs to VCL.xcs
+	installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$uniquefilename);
 
 	$uniquefilename =~ s/\-/\_/g;		# no "-" allowed
 	$uniquefilename =~ s/\@/\_/g;		# no "@" allowed
@@ -399,8 +393,7 @@ sub generate_unique_filename_for_filetab
 
 	my $newname = 0;
 
-	if ( ! exists($installer::globals::alllcuniquefilenames{$lcuniquefilename}) &&
-	     ! exists($installer::globals::savedrevmapping{$lcuniquefilename}) )
+	if ( ! exists($installer::globals::alllcuniquefilenames{$lcuniquefilename}))
 	{
 		$installer::globals::alluniquefilenames{$uniquefilename} = 1;
 		$installer::globals::alllcuniquefilenames{$lcuniquefilename} = 1;
@@ -414,6 +407,7 @@ sub generate_unique_filename_for_filetab
 		
 		my $uniquefilenamebase = $uniquefilename;
 		
+        my $counter = 0;
 		do
 		{
 			$counter++;
@@ -431,8 +425,7 @@ sub generate_unique_filename_for_filetab
 			$newname = 0;
 			$lcuniquefilename = lc($uniquefilename);	# only lowercase names
 
-			if ( ! exists($installer::globals::alllcuniquefilenames{$lcuniquefilename}) &&
-			     ! exists($installer::globals::savedrevmapping{$lcuniquefilename}) )
+			if ( ! exists($installer::globals::alllcuniquefilenames{$lcuniquefilename}))
 			{
 				$installer::globals::alluniquefilenames{$uniquefilename} = 1;
 				$installer::globals::alllcuniquefilenames{$lcuniquefilename} = 1;
@@ -451,38 +444,28 @@ sub generate_unique_filename_for_filetab
 # The first part has to be 8.3 conform.
 ####################################################################
 
-sub generate_filename_for_filetable
+sub generate_filename_for_filetable ($$)
 {
-	my ($fileref, $shortnamesref, $uniquefilenamehashref) = @_;
+	my ($fileref, $shortnamesref) = @_;
 
 	my $returnstring = "";
 
 	my $filename = $fileref->{'Name'};	
+
+    # making /registry/schema/org/openoffice/VCL.xcs to VCL.xcs 
+	installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$filename);	
 	
-	installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$filename);	# making /registry/schema/org/openoffice/VCL.xcs to VCL.xcs 
-	
-	my $shortstring;
+	my $shortstring = installer::windows::idtglobal::make_eight_three_conform_with_hash($filename, "file", $shortnamesref);
 	
-	# Reading short string with help of "FileName" in File table from old database	
-	if (( $installer::globals::prepare_winpatch ) && ( exists($installer::globals::savedmapping{"$fileref->{'componentname'}/$filename"}) ))
-	{
-		$installer::globals::savedmapping{"$fileref->{'componentname'}/$filename"} =~ m/.*;(.*)/;
-		if ($1 ne '')
-		{
-			$shortstring = $1;
-		}
-		else
-		{
-			$shortstring = installer::windows::idtglobal::make_eight_three_conform_with_hash($filename, "file", $shortnamesref);
-		}
-	}
+	if ( $shortstring eq $filename )
+    {
+        # nothing changed
+        $returnstring = $filename;
+    }
 	else
-	{
-		$shortstring = installer::windows::idtglobal::make_eight_three_conform_with_hash($filename, "file", $shortnamesref);
-	}
-	
-	if ( $shortstring eq $filename ) { $returnstring = $filename; }	# nothing changed
-	else {$returnstring = $shortstring . "\|" . $filename; }
+    {
+        $returnstring = $shortstring . "\|" . $filename;
+    }
 	
 	return $returnstring;
 }
@@ -518,13 +501,16 @@ sub get_filesize
 
 sub get_fileversion
 {
-	my ($onefile, $allvariables, $styles) = @_;
+	my ($onefile, $allvariables) = @_;
 
 	my $fileversion = "";
 
 	if ( $allvariables->{'USE_FILEVERSION'} )
 	{
-		if ( ! $allvariables->{'LIBRARYVERSION'} ) { installer::exiter::exit_program("ERROR: USE_FILEVERSION is set, but not LIBRARYVERSION", "get_fileversion"); } 
+		if ( ! $allvariables->{'LIBRARYVERSION'} )
+        {
+            installer::exiter::exit_program("ERROR: USE_FILEVERSION is set, but not LIBRARYVERSION", "get_fileversion");
+        } 
 		my $libraryversion = $allvariables->{'LIBRARYVERSION'};
 		if ( $libraryversion =~ /^\s*(\d+)\.(\d+)\.(\d+)\s*$/ )
 		{
@@ -535,22 +521,252 @@ sub get_fileversion
 			$libraryversion = $major . "\." . $concat;
 		}
 		my $vendornumber = 0;
-		if ( $allvariables->{'VENDORPATCHVERSION'} ) { $vendornumber = $allvariables->{'VENDORPATCHVERSION'}; }
+		if ( $allvariables->{'VENDORPATCHVERSION'} )
+        {
+            $vendornumber = $allvariables->{'VENDORPATCHVERSION'};
+        }
 		$fileversion = $libraryversion . "\." . $installer::globals::buildid . "\." . $vendornumber;
-		if ( $onefile->{'FileVersion'} ) { $fileversion = $onefile->{'FileVersion'}; } # overriding FileVersion in scp
-
-		# if ( $styles =~ /\bFONT\b/ )
-		# {
-		#	my $newfileversion = installer::windows::font::get_font_version($onefile->{'sourcepath'});
-		#	if ( $newfileversion != 0 ) { $fileversion = $newfileversion; }
-		# }
+		if ( $onefile->{'FileVersion'} )
+        {
+            # overriding FileVersion in scp
+            $fileversion = $onefile->{'FileVersion'};
+        }
 	}
 	
-	if ( $installer::globals::prepare_winpatch ) { $fileversion = ""; } # Windows patches do not allow this version # -> who says so?
+	if ( $installer::globals::prepare_winpatch )
+    {
+        # Windows patches do not allow this version # -> who says so?
+        $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, $source_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($source_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, $source_msi, $component_to_features_map);
+        push @new_files, $file_item;
+    }
+
+    return @new_files;
+}
+
+
+
+
+=head2 create_script_item_for_deleted_file (($file_row, $source_msi, $component_to_features_map)
+
+    Create a new script item for a file that was present in the
+    previous release but isn't anymore.  Most of the necessary
+    information is taken from the 'File' table of the source release.
+
+    The values of 'sourcepath' and 'cyg_sourcepath' will point to the
+    respective file in the unpacked source release.  An alternative
+    would be to let them point to an empty file.  That, however, might
+    make the patch bigger (diff between identical file contents is
+    (almost) empty, diff between file and empty file is the 'inverse'
+    of the file).
+
+=cut
+
+my $use_source_files_for_missing_files = 1;
+
+sub create_script_item_for_deleted_file ($$$)
+{
+    my ($file_row, $source_msi, $component_to_features_map) = @_;
+
+    my $uniquename = $file_row->GetValue('File');
+
+    my $file_map = $source_msi->GetFileMap();
+
+    my $file_item = $file_map->{$uniquename};
+    my $directory_item = $file_item->{'directory'};
+    my $source_path = $directory_item->{'full_source_long_name'};
+    my $target_path = $directory_item->{'full_target_long_name'};
+    my $full_source_name = undef;
+    if ($use_source_files_for_missing_files)
+    {
+        $full_source_name = File::Spec->catfile(
+            installer::patch::InstallationSet::GetUnpackedCabPath(
+                $source_msi->{'version'},
+                $source_msi->{'is_current_version'},
+                $source_msi->{'language'},
+                $source_msi->{'package_format'},
+                $source_msi->{'product_name'}),
+            $source_path,
+            $file_item->{'long_name'});
+    }
+    else
+    {
+        $full_source_name = "/c/tmp/missing/".$uniquename;
+        installer::patch::Tools::touch($full_source_name);
+    }
+    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
 #############################################
@@ -595,6 +811,7 @@ sub generate_registry_keypath
 	return $keypath;	
 }
 
+
 ###################################################################
 # Collecting further conditions for the component table.
 # This is used by multilayer products, to enable installation 
@@ -655,225 +872,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, $uniquefilenamehashref) = @_;
+    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");
+        }
+
+        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 ( 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;
+        }		
+
+        # collecting all properties for table Property
+        if ( ! exists($installer::globals::languageproperties{$property}) )
+        {
+            $installer::globals::languageproperties{$property} = $value;
+        }
+    }
+}
 
-	$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 @allfiles = ();
-	my @filetable = ();
-	my @filehashtable = ();
-	my %allfilecomponents = ();
-	my $counter = 0;
+sub has_style ($$)
+{
+    my ($style_list_string, $style_name) = @_;
 
-	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 = ();
+    return 0 unless defined $style_list_string;
+    return $style_list_string =~ /\b$style_name\b/ ? 1 : 0;
+}
 
-		my $onefile = ${$filesref}[$i];	
 
-		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_'}, $uniquefilenamehashref);
+
+sub prepare_file_table_creation ($$$)
+{
+    my ($file_list, $directory_list, $allvariables) = @_;
+    
+    if ( $^O =~ /cygwin/i )
+    {
+        installer::worker::generate_cygwin_pathes($file_list);
+    }
+
+    # 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'};
+    }
+
+    # 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);
+
+    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'});
+        }
 	
-		$onefile->{'uniquename'} = $file{'File'};
-		$onefile->{'componentname'} = $file{'Component_'};
+		# Collecting all component conditions
+		if ( $file->{'ComponentCondition'} )
+		{			
+			if ( ! exists($installer::globals::componentcondition{$file->{'componentname'}}))
+			{
+				$installer::globals::componentcondition{$file->{'componentname'}}
+                = $file->{'ComponentCondition'};
+			}
+		}
+		# Collecting also all tree conditions for multilayer products
+		get_tree_condition_for_component($file, $file->{'componentname'});
 
-		# Collecting all components
-		# if (!(installer::existence::exists_in_array($file{'Component_'}, $allfilecomponentsref))) { push(@{$allfilecomponentsref}, $file{'Component_'}); }
+		# Collecting all component names, that have flag VERSION_INDEPENDENT_COMP_ID
+		# This should be all components with constant API, for example URE
+		if (has_style($file->{'Styles'}, "VERSION_INDEPENDENT_COMP_ID"))
+		{
+			$installer::globals::base_independent_components{$file->{'componentname'}} = 1;
+		}
 
-		if ( ! exists($allfilecomponents{$file{'Component_'}}) ) { $allfilecomponents{$file{'Component_'}} = 1; }
+        # 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;
+		}	
 
-		$file{'FileName'} = generate_filename_for_filetable($onefile, \%shortnames, $uniquefilenamehashref);
+		$file->{'windows_language'} = get_language_for_file($file);
 
-		$file{'FileSize'} = get_filesize($onefile);
+        process_language_conditions($file);
+    }
 
-		$file{'Version'} = get_fileversion($onefile, $allvariables, $styles);
+    # 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);
+    }
+}
 
-		$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
 
-		$installer::globals::insert_file_at_end = 0;
-		$counter++;
-		$file{'Sequence'} = $counter;
 
-		$onefile->{'sequencenumber'} = $file{'Sequence'};
+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";
+        }
+
+        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;
+	}
 
-		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";
-	
-		push(@filetable, $oneline);
+    return \@file_table_data;
+}
 
-		if ( ! $installer::globals::insert_file_at_end ) { push(@allfiles, $onefile); }
 
-		# Collecting all component conditions
-		if ( $onefile->{'ComponentCondition'} )
-		{			
-			if ( ! exists($installer::globals::componentcondition{$file{'Component_'}}))
-			{
-				$installer::globals::componentcondition{$file{'Component_'}} = $onefile->{'ComponentCondition'};
-			}
-		}
-		
-		# Collecting also all tree conditions for multilayer products
-		get_tree_condition_for_component($onefile, $file{'Component_'});
 
-		# 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/ )
-		{
-			$installer::globals::base_independent_components{$onefile->{'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");
-				}
-			}
+sub collect_components ($)
+{
+    my ($file_list) = @_;
+    
+	my %components = ();
+    foreach my $file (@$file_list)
+    {
+        $components{$file->{'componentname'}} = 1;
+    }
+    return keys %components;
+}
 
-			# 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");
-				}				
-			}
-		}
 
-		# 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;
 
-			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;
-			}		
 
-			# collecting all properties for table Property
-			if ( ! exists($installer::globals::languageproperties{$property}) ) { $installer::globals::languageproperties{$property} = $value; }
-		}
+=head filter_files($file_list, $allvariables)
 
-		if ( $installer::globals::prepare_winpatch )
-		{
-			my $path = $onefile->{'sourcepath'};
-			if ( $^O =~ /cygwin/i ) { $path = $onefile->{'cyg_sourcepath'}; }
+    Filter out Java files when not building a Java product.
 
-			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;
+    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;
+    }
+}
 
-			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'}; }
 
-		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;
-		}	
-	}
 
-	# putting content from %allfilecomponents to $allfilecomponentsref for later usage
-	foreach $localkey (keys %allfilecomponents ) { push( @{$allfilecomponentsref}, $localkey); }
+# 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/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/idtglobal.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/idtglobal.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/idtglobal.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/idtglobal.pm Wed Dec 18 13:27:09 2013
@@ -56,6 +56,19 @@ sub shorten_feature_gid
 	$$stringref =~ s/_Replacement_/_rpl_/;
 }
 
+=head2 create_shortend_feature_gid ($feature_name)
+    
+    This is a side effect free version of shorten_feature_gid.
+    The shortened feature name is returned instead of overwriting the given name.
+    
+=cut
+sub create_shortend_feature_gid ($)
+{
+    my ($feature_name) = @_;
+    shorten_feature_gid(\$feature_name);
+    return $feature_name;
+}
+
 ############################################
 # Getting the next free number, that
 # can be added.
@@ -766,7 +779,7 @@ sub translate_idtfile
 # into one language specific directory
 ##############################################################
 
-sub prepare_language_idt_directory
+sub prepare_language_idt_directory ($$$$$$$)
 {
 	my ($destinationdir, $newidtdir, $onelanguage, $filesref, $iconfilecollector, $binarytablefiles, $allvariables) = @_;
 	
@@ -781,13 +794,21 @@ sub prepare_language_idt_directory
 	if ( -d $installer::globals::idttemplatepath . $installer::globals::separator . "Binary")
 	{
 		installer::systemactions::create_directory($destinationdir . $installer::globals::separator . "Binary");
-		installer::systemactions::copy_directory($installer::globals::idttemplatepath . $installer::globals::separator . "Binary", $destinationdir . $installer::globals::separator . "Binary");
+		installer::systemactions::copy_directory(
+            $installer::globals::idttemplatepath . $installer::globals::separator . "Binary",
+            $destinationdir . $installer::globals::separator . "Binary");
 
 		if ((( $installer::globals::patch ) && ( $allvariables->{'WINDOWSPATCHBITMAPDIRECTORY'} )) || ( $allvariables->{'WINDOWSBITMAPDIRECTORY'} ))
 		{
 			my $bitmapdir = "";
-			if ( $allvariables->{'WINDOWSPATCHBITMAPDIRECTORY'} ) { $bitmapdir = $allvariables->{'WINDOWSPATCHBITMAPDIRECTORY'}; }
-			if ( $allvariables->{'WINDOWSBITMAPDIRECTORY'} ) { $bitmapdir = $allvariables->{'WINDOWSBITMAPDIRECTORY'}; }
+			if ( $allvariables->{'WINDOWSPATCHBITMAPDIRECTORY'} )
+            {
+                $bitmapdir = $allvariables->{'WINDOWSPATCHBITMAPDIRECTORY'};
+            }
+			if ( $allvariables->{'WINDOWSBITMAPDIRECTORY'} )
+            {
+                $bitmapdir = $allvariables->{'WINDOWSBITMAPDIRECTORY'};
+            }
 			
 			my $newsourcedir = $installer::globals::unpackpath . $installer::globals::separator . $bitmapdir; # path setting in list file dependent from unpackpath !?
             $installer::logger::Lang->printf("\n");
@@ -799,9 +820,13 @@ sub prepare_language_idt_directory
 			if ( ! -d $newsourcedir )
 			{
 				my $currentdir = cwd();
-				installer::exiter::exit_program("ERROR: Directory $newsourcedir does not exist! Current directory is: $currentdir", "prepare_language_idt_directory");
+				installer::exiter::exit_program(
+                    "ERROR: Directory $newsourcedir does not exist! Current directory is: $currentdir",
+                    "prepare_language_idt_directory");
 			}
-			installer::systemactions::copy_directory($newsourcedir, $destinationdir . $installer::globals::separator . "Binary");
+			installer::systemactions::copy_directory(
+                $newsourcedir,
+                $destinationdir . $installer::globals::separator . "Binary");
 		}
 	}
 
@@ -809,7 +834,9 @@ sub prepare_language_idt_directory
 
 	if ( -d $installer::globals::idttemplatepath . $installer::globals::separator . "Icon")
 	{
-		installer::systemactions::copy_directory($installer::globals::idttemplatepath . $installer::globals::separator . "Icon", $destinationdir . $installer::globals::separator . "Icon");
+		installer::systemactions::copy_directory(
+            $installer::globals::idttemplatepath . $installer::globals::separator . "Icon",
+            $destinationdir . $installer::globals::separator . "Icon");
 	}
 	
 	# Copying all files in $iconfilecollector, that describe icons of folderitems
@@ -818,18 +845,24 @@ sub prepare_language_idt_directory
 	{
 		my $iconfilename = ${$iconfilecollector}[$i];
 		installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$iconfilename);
-		installer::systemactions::copy_one_file(${$iconfilecollector}[$i], $destinationdir . $installer::globals::separator . "Icon" . $installer::globals::separator . $iconfilename);
+		installer::systemactions::copy_one_file(
+            ${$iconfilecollector}[$i],
+            $destinationdir . $installer::globals::separator . "Icon" . $installer::globals::separator . $iconfilename);
 	}
 
 	# Copying all files in $binarytablefiles in the binary directory
 
-	for ( my $i = 0; $i <= $#{$binarytablefiles}; $i++ )
+	foreach my $binaryfile (@$binarytablefiles)
 	{
-		my $binaryfile = ${$binarytablefiles}[$i];
 		my $binaryfilepath = $binaryfile->{'sourcepath'};
 		my $binaryfilename = $binaryfilepath;
+        $installer::logger::Lang->printf("copying binary file %s to %s\n",
+            $binaryfilepath,
+            $binaryfilename);
 		installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$binaryfilename);
-		installer::systemactions::copy_one_file($binaryfilepath, $destinationdir . $installer::globals::separator . "Binary" . $installer::globals::separator . $binaryfilename);
+		installer::systemactions::copy_one_file(
+            $binaryfilepath,
+            $destinationdir . $installer::globals::separator . "Binary" . $installer::globals::separator . $binaryfilename);
 	}
 
 	# Copying all new created and language independent idt-files to the destination $destinationdir.

Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/inifile.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/inifile.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/inifile.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/inifile.pm Wed Dec 18 13:27:09 2013
@@ -28,6 +28,8 @@ use installer::files;
 use installer::globals;
 use installer::windows::idtglobal;
 
+use strict;
+
 ####################################################
 # Setting the profile for a special profileitem
 ####################################################
@@ -66,21 +68,18 @@ sub file_is_part_of_product
 {
 	my ($profilegid, $filesref) = @_;
 	
-	my $part_of_product = 0;
-
-	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
+	foreach my $file (@$filesref)
 	{
-		$onefile = ${$filesref}[$i];
-		my $filegid = $onefile->{'gid'};
+		my $filegid = $file->{'gid'};
+        next unless defined $filegid;
 
 		if ( $filegid eq $profilegid )
 		{
-			$part_of_product = 1;
-			last;	
+			return 1;	
 		}
 	}
 	
-	return $part_of_product;
+	return 0;
 }
 
 ###########################################################################################################

Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/msiglobal.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/msiglobal.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/msiglobal.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/msiglobal.pm Wed Dec 18 13:27:09 2013
@@ -37,6 +37,9 @@ use installer::systemactions;
 use installer::worker;
 use installer::windows::idtglobal;
 use installer::windows::language;
+use installer::patch::ReleasesList;
+
+use strict;
 
 ###########################################################################
 # Generating the header of the ddf file.
@@ -128,25 +131,6 @@ sub make_relative_ddf_path
 	return $sourcepath;
 }
 
-##########################################################################
-# Returning the order of the sequences in the files array.
-##########################################################################
-
-sub get_sequenceorder
-{
-	my ($filesref) = @_;
-
-	my %order = ();
-	
-	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
-	{
-		my $onefile = ${$filesref}[$i];
-		if ( ! $onefile->{'assignedsequencenumber'} ) { installer::exiter::exit_program("ERROR: No sequence number assigned to $onefile->{'gid'} ($onefile->{'uniquename'})!", "get_sequenceorder"); }
-		$order{$onefile->{'assignedsequencenumber'}} = $i;
-	}
-	
-	return \%order;
-}
 
 ##########################################################################
 # Generation the list, in which the source of the files is connected
@@ -154,243 +138,86 @@ sub get_sequenceorder
 # to be included into a cab file, this has to be done via ddf files.
 ##########################################################################
 
-sub generate_cab_file_list
+sub generate_cab_file_list ($$$$)
 {
 	my ($filesref, $installdir, $ddfdir, $allvariables) = @_;
 	
-	my @cabfilelist = ();
-		
 	installer::logger::include_header_into_logfile("Generating ddf files");
 
-	$installer::logger::Lang->add_timestamp("Performance Info: ddf file generation start");
-
-	if ( $^O =~ /cygwin/i ) { installer::worker::generate_cygwin_pathes($filesref); }
-
-	if ( $installer::globals::fix_number_of_cab_files )
-	{
-		for ( my $i = 0; $i <= $#{$filesref}; $i++ )
-		{	
-			my $onefile = ${$filesref}[$i];
-			my $cabinetfile = $onefile->{'cabinet'};
-			my $sourcepath =  $onefile->{'sourcepath'};
-			if ( $^O =~ /cygwin/i ) { $sourcepath = $onefile->{'cyg_sourcepath'}; }
-			my $uniquename =  $onefile->{'uniquename'};
-
-			my $styles = "";
-			my $doinclude = 1;
-			if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; };
-			if ( $styles =~ /\bDONT_PACK\b/ ) { $doinclude = 0; }
-			
-
-			# to avoid lines with more than 256 characters, it can be useful to use relative pathes
-			if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path($sourcepath); }
-
-			# all files with the same cabinetfile are directly behind each other in the files collector
-
-			my @ddffile = ();
-
-			write_ddf_file_header(\@ddffile, $cabinetfile, $installdir);
-	
-			my $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
-			if ( $doinclude ) { push(@ddffile, $ddfline); }
-
-			my $nextfile = ${$filesref}[$i+1];
-			my $nextcabinetfile = "";
-		
-			if ( $nextfile->{'cabinet'} ) { $nextcabinetfile = $nextfile->{'cabinet'}; }
-		
-			while ( $nextcabinetfile eq $cabinetfile )
-			{
-				$sourcepath =  $nextfile->{'sourcepath'};
-				if ( $^O =~ /cygwin/i ) { $sourcepath = $nextfile->{'cyg_sourcepath'}; }
-				# to avoid lines with more than 256 characters, it can be useful to use relative pathes
-				if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path($sourcepath); }
-				$uniquename =  $nextfile->{'uniquename'};
-				my $localdoinclude = 1;
-				my $nextfilestyles = "";				
-				if ( $nextfile->{'Styles'} ) { $nextfilestyles = $nextfile->{'Styles'}; }
-				if ( $nextfilestyles =~ /\bDONT_PACK\b/ ) { $localdoinclude = 0; }
-				$ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
-				if ( $localdoinclude ) { push(@ddffile, $ddfline); }
-				$i++;											# increasing the counter!
-				$nextfile = ${$filesref}[$i+1];
-				if ( $nextfile ) { $nextcabinetfile = $nextfile->{'cabinet'}; }
-				else { $nextcabinetfile = "_lastfile_"; }
-			}
-		
-			# creating the DDF file
-
-			my $ddffilename = $cabinetfile;
-			$ddffilename =~ s/.cab/.ddf/;
-			$ddfdir =~ s/\Q$installer::globals::separator\E\s*$//;
-			$ddffilename = $ddfdir . $installer::globals::separator . $ddffilename;
-
-			installer::files::save_file($ddffilename ,\@ddffile);
-			my $infoline = "Created ddf file: $ddffilename\n"; 
-			$installer::logger::Lang->print($infoline);
-
-			# lines in ddf files must not be longer than 256 characters
-			check_ddf_file(\@ddffile, $ddffilename);
-
-			# Writing the makecab system call
-
-			my $oneline = "makecab.exe /V3 /F " . $ddffilename . " 2\>\&1 |" . "\n";
-		
-			push(@cabfilelist, $oneline);
-
-			# collecting all ddf files
-			push(@installer::globals::allddffiles, $ddffilename);
-		}
-	}
-	elsif ( $installer::globals::one_cab_file )
-	{
-		my @ddffile = ();
-		
-		my $cabinetfile = "";
-
-		for ( my $i = 0; $i <= $#{$filesref}; $i++ )
-		{
-			my $onefile = ${$filesref}[$i];
-			$cabinetfile = $onefile->{'cabinet'};
-			my $sourcepath =  $onefile->{'sourcepath'};
-			if ( $^O =~ /cygwin/i ) { $sourcepath = $onefile->{'cyg_sourcepath'}; }
-			my $uniquename =  $onefile->{'uniquename'};
-
-			# to avoid lines with more than 256 characters, it can be useful to use relative pathes
-			if ( $allvariables->{'RELATIVE_PATHES_IN_DDF'} ) { $sourcepath = make_relative_ddf_path($sourcepath); }
-
-			if ( $i == 0 ) { write_ddf_file_header(\@ddffile, $cabinetfile, $installdir); }
-
-			my $styles = "";
-			my $doinclude = 1;
-			if ( $onefile->{'Styles'} ) { $styles = $onefile->{'Styles'}; };
-			if ( $styles =~ /\bDONT_PACK\b/ ) { $doinclude = 0; }
-
-			my $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
-			if ( $doinclude ) { push(@ddffile, $ddfline); }
-		}
-		
-		# creating the DDF file
-
-		my $ddffilename = $cabinetfile;
-		$ddffilename =~ s/.cab/.ddf/;
-		$ddfdir =~ s/[\/\\]\s*$//;
-		$ddffilename = $ddfdir . $installer::globals::separator . $ddffilename;
-
-		installer::files::save_file($ddffilename ,\@ddffile);
-		my $infoline = "Created ddf file: $ddffilename\n"; 
-		$installer::logger::Lang->print($infoline);
-
-		# lines in ddf files must not be longer than 256 characters
-		check_ddf_file(\@ddffile, $ddffilename);
-
-		# Writing the makecab system call
-
-		my $oneline = "makecab.exe /F " . $ddffilename . "\n";
-		
-		push(@cabfilelist, $oneline);
-
-		# collecting all ddf files
-		push(@installer::globals::allddffiles, $ddffilename);
-	}
-	else
-	{
-		installer::exiter::exit_program("ERROR: No cab file specification in globals.pm !", "create_media_table");		
-	}
+	if ( $^O =~ /cygwin/i )
+    {
+        installer::worker::generate_cygwin_pathes($filesref);
+    }
+
+    # Make sure that all files point to the same cabinet file.
+    # Multiple cabinet files are not supported anymore.
+    my $cabinetfile = $filesref->[0]->{'cabinet'};
+    foreach my $onefile (@$filesref)
+    {
+        if ($onefile->{'cabinet'} ne $cabinetfile)
+        {
+            installer::exiter::exit_program(
+                "ERROR: multiple cabinet files are not supported",
+                "generate_cab_file_list");
+        }
+    }
 
-	$installer::logger::Lang->add_timestamp("Performance Info: ddf file generation end");
-		
-	return \@cabfilelist;	# contains all system calls for packaging process
-}
+    # Sort files on the sequence number.
+    my @sorted_files = sort {$a->{'sequencenumber'} <=> $b->{'sequencenumber'}} @$filesref;
 
-########################################################################
-# Returning the file sequence of a specified file.
-########################################################################
+    my @ddffile = ();
+    write_ddf_file_header(\@ddffile, $cabinetfile, $installdir);
+    foreach my $onefile (@sorted_files)
+    {	
+        my $styles = $onefile->{'Styles'} // "";
+        if ($styles =~ /\bDONT_PACK\b/)
+        {
+            $installer::logger::Lang->printf("    excluding '%s' from ddf\n", $onefile->{'uniquename'});
+        }
+        
+        my $uniquename = $onefile->{'uniquename'};
+        my $sourcepath = $onefile->{'sourcepath'};
+        if ( $^O =~ /cygwin/i )
+        {
+            $sourcepath = $onefile->{'cyg_sourcepath'};
+        }
 
-sub get_file_sequence
-{
-	my ($filesref, $uniquefilename) = @_;
+        # to avoid lines with more than 256 characters, it can be useful to use relative pathes
+        if ($allvariables->{'RELATIVE_PATHES_IN_DDF'})
+        {
+            $sourcepath = make_relative_ddf_path($sourcepath);
+        }
 
-	my $sequence = "";
-	my $found_sequence = 0;
+        my $ddfline = "\"" . $sourcepath . "\"" . " " . $uniquename . "\n";
+        push(@ddffile, $ddfline);
 
-	for ( my $i = 0; $i <= $#{$filesref}; $i++ )
-	{
-		my $onefile = ${$filesref}[$i];
-		my $uniquename = $onefile->{'uniquename'};
-		
-		if ( $uniquename eq $uniquefilename )
-		{
-			$sequence = $onefile->{'sequencenumber'};			
-			$found_sequence = 1;
-			last;
-		}
-	}
-	
-	if ( ! $found_sequence ) { installer::exiter::exit_program("ERROR: No sequence found for $uniquefilename !", "get_file_sequence"); }
-	
-	return $sequence;
+        $installer::logger::Lang->printf("    adding '%s' with sequence %d to ddf\n",
+            $onefile->{'uniquename'},
+            $onefile->{'sequencenumber'});
+    }
+    # creating the DDF file
+
+    my $ddffilename = $cabinetfile;
+    $ddffilename =~ s/.cab/.ddf/;
+    $ddfdir =~ s/\Q$installer::globals::separator\E\s*$//;
+    $ddffilename = $ddfdir . $installer::globals::separator . $ddffilename;
+    
+    installer::files::save_file($ddffilename ,\@ddffile);
+    $installer::logger::Lang->print("Created ddf file: %s\n", $ddffilename);
+
+    # lines in ddf files must not be longer than 256 characters
+    check_ddf_file(\@ddffile, $ddffilename);
+
+    # collecting all ddf files
+    push(@installer::globals::allddffiles, $ddffilename);
+
+    # Writing the makecab system call
+    # Return a list with all system calls for packaging process.
+	my @cabfilelist = ("makecab.exe /V3 /F " . $ddffilename . " 2\>\&1 |" . "\n");
+	return \@cabfilelist;
 }
 
-########################################################################
-# For update and patch reasons the pack order needs to be saved.
-# The pack order is saved in the ddf files; the names and locations
-# of the ddf files are saved in @installer::globals::allddffiles.
-# The outputfile "packorder.txt" can be saved in
-# $installer::globals::infodirectory . 
-########################################################################
-
-sub save_packorder
-{
-	installer::logger::include_header_into_logfile("Saving pack order");
-
-	$installer::logger::Lang->add_timestamp("Performance Info: saving pack order start");
-
-	my $packorderfilename = "packorder.txt";
-	$packorderfilename = $installer::globals::infodirectory . $installer::globals::separator . $packorderfilename;
-
-	my @packorder = ();
-	
-	my $headerline = "\# Syntax\: Filetable_Sequence Cabinetfilename Physical_FileName Unique_FileName\n\n"; 
-	push(@packorder, $headerline);
-	
-	for ( my $i = 0; $i <= $#installer::globals::allddffiles; $i++ )
-	{
-		my $ddffilename = $installer::globals::allddffiles[$i];
-		my $ddffile = installer::files::read_file($ddffilename);
-		my $cabinetfile = "";
-
-		for ( my $j = 0; $j <= $#{$ddffile}; $j++ )
-		{
-			my $oneline = ${$ddffile}[$j];
-			
-			# Getting the Cabinet file name
-			
-			if ( $oneline =~ /^\s*\.Set\s+CabinetName.*\=(.*?)\s*$/ ) { $cabinetfile = $1; }
-			if ( $oneline =~ /^\s*\.Set\s+/ ) { next; } 
-			
-			if ( $oneline =~ /^\s*\"(.*?)\"\s+(.*?)\s*$/ )
-			{
-				my $sourcefile = $1;
-				my $uniquefilename = $2;
-				
-				installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$sourcefile);
-				
-				# Using the hash created in create_files_table for performance reasons to get the sequence number
-				my $filesequence = "";
-				if ( exists($installer::globals::uniquefilenamesequence{$uniquefilename}) ) { $filesequence = $installer::globals::uniquefilenamesequence{$uniquefilename}; }
-				else { installer::exiter::exit_program("ERROR: No sequence number value for $uniquefilename !", "save_packorder"); }
-				
-				my $line = $filesequence . "\t" . $cabinetfile . "\t" . $sourcefile . "\t" . $uniquefilename . "\n";
-				push(@packorder, $line);
-			}
-		}
-	}
-	
-	installer::files::save_file($packorderfilename ,\@packorder);
 
-	$installer::logger::Lang->add_timestamp("Performance Info: saving pack order end");
-}
 
 #################################################################
 # Returning the name of the msi database
@@ -556,11 +383,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);
@@ -1087,8 +910,7 @@ sub create_setup_ini
 
 	installer::files::save_file($setupinifilename, $setupinifile);	
 
-	$infoline = "Generated file $setupinifilename !\n";
-	$installer::logger::Lang->print($infoline);
+	$installer::logger::Lang->printf("Generated file %s\n", $setupinifilename);
 }
 
 #################################################################
@@ -1133,7 +955,7 @@ sub copy_windows_installer_files_into_in
 
     installer::logger::include_header_into_logfile("Copying Windows installer files into installation set");
 	
-	@copyfile = ();
+	my @copyfile = ();
 	push(@copyfile, "loader2.exe");
 	
 	if ( $allvariables->{'NOLOADERREQUIRED'} ) { @copyfile = (); }
@@ -1186,47 +1008,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);
 }
 
 #################################################################
@@ -1247,6 +1041,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;
 }
@@ -1323,7 +1120,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) = @_;
 	
@@ -1362,19 +1159,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;
 
@@ -1489,7 +1299,7 @@ sub prepare_64bit_database
 			if ( -f $fullfilename )
 			{
 				my $saving_required = 0;
-				$filecontent = installer::files::read_file($fullfilename);		
+				my $filecontent = installer::files::read_file($fullfilename);		
 
 				for ( my $i = 3; $i <= $#{$filecontent}; $i++ ) 	# ignoring the first three lines
 				{
@@ -1690,108 +1500,144 @@ sub execute_packaging
 	$installer::logger::Lang->print($infoline);	
 }
 
-###############################################################
-# Setting the global variables ProductCode and the UpgradeCode
-###############################################################
 
-sub set_global_code_variables
-{
-	my ( $languagesref, $languagestringref, $allvariableshashref, $alloldproperties ) = @_;
+=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);
+    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)
+    {
+        $installer::logger::Lang->printf("no source version defined\n");
+        return (undef, undef);
+    }
+
+    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 $normalized_language = installer::languages::get_normalized_language($languagesref);
+        my $language_data = $release_data->{$normalized_language};
+        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'});
 
-	my $codefile = installer::files::read_file($installer::globals::codefilename);
+            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/%s/%s\n",
+                $installer::globals::source_version,
+                $onelanguage,
+                join(", ",@$languagesref),
+                $normalized_language);
+            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 $isopensource = 0;
-	if ( $allvariableshashref->{'OPENSOURCE'} ) { $isopensource = $allvariableshashref->{'OPENSOURCE'}; } 
 
-	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
+=head2 set_global_code_variables ($languagesref, $allvariableshashref)
 
-		$searchstring = "UPGRADECODE";	# searching in the codes.txt file
-		$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"); }	
+    Determine values for the product code and upgrade code of the target version.
 
-	$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);
+    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.
 
-	# Adding both variables into the variables array 
+    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'}
 
-	$allvariableshashref->{'PRODUCTCODE'} = $installer::globals::productcode;
-	$allvariableshashref->{'UPGRADECODE'} = $installer::globals::upgradecode;
+=cut
+sub set_global_code_variables ($$)
+{
+	my ($languagesref, $allvariableshashref) = @_;
 
-	$infoline = "Defined variable PRODUCTCODE: $installer::globals::productcode \n";
-	$installer::logger::Lang->print($infoline);
+    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);
+        }
 
-	$infoline = "Defined variable UPGRADECODE: $installer::globals::upgradecode \n";
-	$installer::logger::Lang->print($infoline);
+        $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::logger::Lang->printf("there is no source version => created new guids\n");
+    }
+    
+    $installer::globals::productcode = $target_product_code;
+    $installer::globals::upgradecode = $target_upgrade_code;
+    $allvariableshashref->{'PRODUCTCODE'} = $target_product_code;
+	$allvariableshashref->{'UPGRADECODE'} = $target_upgrade_code;
 
+	$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);
 }
 
+
+
+
 ###############################################################
 # Setting the product version used in property table and
 # upgrade table. Saving in global variable $msiproductversion
@@ -1948,167 +1794,6 @@ sub update_removere_table
 	}
 }
 
-##########################################################################
-# Reading saved mappings in Files.idt and Director.idt.
-# This is required, if installation sets shall be created,
-# that can be used for creation of msp files.
-##########################################################################
-
-sub read_saved_mappings
-{
-	installer::logger::include_header_into_logfile("Reading saved mappings from older installation sets:");
-
-	$installer::logger::Lang->add_timestamp("Performance Info: Reading saved mappings start");
-	
-	if ( $installer::globals::previous_idt_dir )
-	{
-		my @errorlines = ();
-		my $errorstring = "";
-		my $error_occured = 0;
-		my $file_error_occured = 0;
-		my $dir_error = 0;
-		
-		my $idtdir = $installer::globals::previous_idt_dir;
-		$idtdir =~ s/\Q$installer::globals::separator\E\s*$//;
-
-		# Reading File.idt
-
-		my $idtfile = $idtdir . $installer::globals::separator . "File.idt";
-        $installer::logger::Global->print("\n");
-        $installer::logger::Global->printf("Analyzing file: %s\n", $idtfile);
-		if ( ! -f $idtfile )
-        {
-            $installer::logger::Global->printf("Warning: File %s does not exist!\n", $idtfile);
-        }
-		
-		my $n = 0;
-		open (F, "<$idtfile") || installer::exiter::exit_program("ERROR: Cannot open file $idtfile for reading", "read_saved_mappings");
-		<F>; <F>; <F>;
-		while (<F>)
-		{
-			m/^([^\t]+)\t([^\t]+)\t((.*)\|)?([^\t]*)/;
-			print "OUT1: \$1: $1, \$2: $2, \$3: $3, \$4: $4, \$5: $5\n";
-			next if ("$1" eq "$5") && (!defined($3));
-			my $lc1 = lc($1);
-			
-			if ( exists($installer::globals::savedmapping{"$2/$5"}))
-			{
-				if ( ! $file_error_occured )
-				{
-					$errorstring = "\nErrors in $idtfile: \n";
-					push(@errorlines, $errorstring);
-				}
-				$errorstring = "Duplicate savedmapping{" . "$2/$5}\n";
-				push(@errorlines, $errorstring);
-				$error_occured = 1;
-				$file_error_occured = 1;
-			}
-			
-			if ( exists($installer::globals::savedrevmapping{$lc1}))
-			{
-				if ( ! $file_error_occured )
-				{
-					$errorstring = "\nErrors in $idtfile: \n";
-					push(@errorlines, $errorstring);
-				}
-				$errorstring = "Duplicate savedrevmapping{" . "$lc1}\n";
-				push(@errorlines, $errorstring);
-				$error_occured = 1;
-				$file_error_occured = 1;
-			}
-			
-			my $shortname = $4 || '';
-
-			# Don't reuse illegal 8.3 mappings that we used to generate in 2.0.4
-			if (index($shortname, '.') > 8 ||
-			    (index($shortname, '.') == -1 && length($shortname) > 8))
-			{
-			    $shortname = '';
-			}
-
-			if (( $shortname ne '' ) && ( index($shortname, '~') > 0 ) && ( exists($installer::globals::savedrev83mapping{$shortname}) ))
-			{
-				if ( ! $file_error_occured )
-				{
-					$errorstring = "\nErrors in $idtfile: \n";
-					push(@errorlines, $errorstring);
-				}
-				$errorstring = "Duplicate savedrev83mapping{" . "$shortname}\n";
-				push(@errorlines, $errorstring);
-				$error_occured = 1;
-				$file_error_occured = 1;
-			}
-
-			$installer::globals::savedmapping{"$2/$5"} = "$1;$shortname";
-			$installer::globals::savedrevmapping{lc($1)} = "$2/$5";
-			$installer::globals::savedrev83mapping{$shortname} = "$2/$5" if $shortname ne '';
-			$n++;
-		}
-
-		close (F);
-
-        $installer::logger::Global->printf("Read %s old file table key or 8.3 name mappings from %s\n",
-            $n, $idtfile);
-
-		# Reading Director.idt
-		
-		$idtfile = $idtdir . $installer::globals::separator . "Director.idt";
-        $installer::logger::Global->print("\n");
-        $installer::logger::Global->printf("Analyzing file %s\n", $idtfile);
-		if ( ! -f $idtfile )
-        {
-            $installer::logger::Global->printf("Warning: File %s does not exist!\n", $idtfile);
-        }
-
-		$n = 0;
-		open (F, "<$idtfile") || installer::exiter::exit_program("ERROR: Cannot open file $idtfile for reading", "read_saved_mappings");
-		<F>; <F>; <F>;
-		while (<F>)
-		{
-			m/^([^\t]+)\t([^\t]+)\t(([^~]+~\d.*)\|)?([^\t]*)/;
-			next if (!defined($3));
-			my $lc1 = lc($1);
-
-			print "OUT2: \$1: $1, \$2: $2, \$3: $3\n";
-
-			if ( exists($installer::globals::saved83dirmapping{$1}) )
-			{
-				if ( ! $dir_error_occured )
-				{
-					$errorstring = "\nErrors in $idtfile: \n";
-					push(@errorlines, $errorstring);
-				}
-				$errorstring = "Duplicate saved83dirmapping{" . "$1}\n";
-				push(@errorlines, $errorstring);
-				$error_occured = 1;
-				$dir_error_occured = 1;
-			}
-
-			$installer::globals::saved83dirmapping{$1} = $4;
-			$n++;
-		}
-		close (F);
-
-        $installer::logger::Global->printf("Read %s old directory 8.3 name mappings from %s\n",
-            $n, $idtfile);
-
-		# Analyzing errors
-		
-		if ( $error_occured )
-		{
-			for my $line (@errorlines)
-			{
-                $installer::logger::Info->print($line);
-                $installer::logger::Global->print($line);
-			}
-			installer::exiter::exit_program("ERROR: Duplicate entries in saved mappings!", "read_saved_mappings");			
-		}
-	} else {
-		installer::exiter::exit_program("ERROR: Windows patch shall be prepared, but environment variable PREVIOUS_IDT_DIR is not set!", "read_saved_mappings");			
-	}
-
-	$installer::logger::Lang->add_timestamp("Performance Info: Reading saved mappings end");
-}
 
 1;
 

Modified: openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/property.pm
URL: http://svn.apache.org/viewvc/openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/property.pm?rev=1551937&r1=1551936&r2=1551937&view=diff
==============================================================================
--- openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/property.pm (original)
+++ openoffice/branches/ooxml-osba/main/solenv/bin/modules/installer/windows/property.pm Wed Dec 18 13:27:09 2013
@@ -208,16 +208,14 @@ sub get_productversion_for_property_tabl
 # required for the Windows patch process.
 #######################################################
 
-sub set_featurename_properties_for_patch
+sub set_featurename_properties_for_patch ($)
 {
-	($propertyfile) = @_;
+	my ($propertyfile) = @_;
 	
-	for ( my $i = 0; $i <= $#installer::globals::featurecollector; $i++ )
+	foreach my $feature_gid (keys %installer::globals::featurecollector)
 	{
-		my $onepropertyline =  $installer::globals::featurecollector[$i] . "\t" . "1" . "\n";
-		push(@{$propertyfile}, $onepropertyline);
+		push @$propertyfile, $feature_gid . "\t" . "1" . "\n";
 	}
-
 }
 
 #######################################################
@@ -308,12 +306,6 @@ sub set_important_properties
     $onepropertyline = "DONTOPTIMIZELIBS" . "\t" . "0" . "\n";
     push(@{$propertyfile}, $onepropertyline);
 
-	if ( $installer::globals::sundirexists )
-	{
-		my $onepropertyline = "SUNDIREXISTS" . "\t" . "1" . "\n";
-		push(@{$propertyfile}, $onepropertyline);			
-	}
-
 	if ( $installer::globals::officedirhostname )
 	{
 		my $onepropertyline = "OFFICEDIRHOSTNAME" . "\t" . $installer::globals::officedirhostname . "\n";
@@ -325,12 +317,6 @@ sub set_important_properties
 		push(@{$propertyfile}, $onepropertyline);
 	}
 
-	if ( $installer::globals::sundirhostname )
-	{
-		my $onepropertyline = "SUNDIRHOSTNAME" . "\t" . $installer::globals::sundirhostname . "\n";
-		push(@{$propertyfile}, $onepropertyline);		
-	}
-		
 	if ( $installer::globals::desktoplinkexists )
 	{
 		my $onepropertyline = "DESKTOPLINKEXISTS" . "\t" . "1" . "\n";