19780544fSAndrew Rist#************************************************************** 2cdf0e10cSrcweir# 39780544fSAndrew Rist# Licensed to the Apache Software Foundation (ASF) under one 49780544fSAndrew Rist# or more contributor license agreements. See the NOTICE file 59780544fSAndrew Rist# distributed with this work for additional information 69780544fSAndrew Rist# regarding copyright ownership. The ASF licenses this file 79780544fSAndrew Rist# to you under the Apache License, Version 2.0 (the 89780544fSAndrew Rist# "License"); you may not use this file except in compliance 99780544fSAndrew Rist# with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir# 119780544fSAndrew Rist# http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir# 139780544fSAndrew Rist# Unless required by applicable law or agreed to in writing, 149780544fSAndrew Rist# software distributed under the License is distributed on an 159780544fSAndrew Rist# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 169780544fSAndrew Rist# KIND, either express or implied. See the License for the 179780544fSAndrew Rist# specific language governing permissions and limitations 189780544fSAndrew Rist# under the License. 19cdf0e10cSrcweir# 209780544fSAndrew Rist#************************************************************** 219780544fSAndrew Rist 229780544fSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweirpackage installer::windows::feature; 25cdf0e10cSrcweir 26cdf0e10cSrcweiruse installer::existence; 27cdf0e10cSrcweiruse installer::exiter; 28cdf0e10cSrcweiruse installer::files; 29cdf0e10cSrcweiruse installer::globals; 30cdf0e10cSrcweiruse installer::sorter; 31cdf0e10cSrcweiruse installer::worker; 32cdf0e10cSrcweiruse installer::windows::idtglobal; 33cdf0e10cSrcweiruse installer::windows::language; 34cdf0e10cSrcweir 35cdf0e10cSrcweir############################################################## 36cdf0e10cSrcweir# Returning the gid for a feature. 37cdf0e10cSrcweir# Attention: Maximum length 38cdf0e10cSrcweir############################################################## 39cdf0e10cSrcweir 40cdf0e10cSrcweirsub get_feature_gid 41cdf0e10cSrcweir{ 42cdf0e10cSrcweir my ($onefeature) = @_; 43cdf0e10cSrcweir 44cdf0e10cSrcweir my $gid = ""; 45cdf0e10cSrcweir 46cdf0e10cSrcweir if ( $onefeature->{'gid'} ) { $gid = $onefeature->{'gid'}; } 47cdf0e10cSrcweir 48cdf0e10cSrcweir # Attention: Maximum feature length is 38! 49cdf0e10cSrcweir installer::windows::idtglobal::shorten_feature_gid(\$gid); 50cdf0e10cSrcweir 51cdf0e10cSrcweir return $gid 52cdf0e10cSrcweir} 53cdf0e10cSrcweir 54cdf0e10cSrcweir############################################################## 55cdf0e10cSrcweir# Returning the gid of the parent. 56cdf0e10cSrcweir# Attention: Maximum length 57cdf0e10cSrcweir############################################################## 58cdf0e10cSrcweir 59cdf0e10cSrcweirsub get_feature_parent 60cdf0e10cSrcweir{ 61cdf0e10cSrcweir my ($onefeature) = @_; 62cdf0e10cSrcweir 63cdf0e10cSrcweir my $parentgid = ""; 64cdf0e10cSrcweir 65cdf0e10cSrcweir if ( $onefeature->{'ParentID'} ) { $parentgid = $onefeature->{'ParentID'}; } 66cdf0e10cSrcweir 67cdf0e10cSrcweir # The modules, hanging directly below the root, have to be root modules. 68cdf0e10cSrcweir # Only then it is possible to make the "real" root module invisible by 69cdf0e10cSrcweir # setting the display to "0". 70cdf0e10cSrcweir 71cdf0e10cSrcweir if ( $parentgid eq $installer::globals::rootmodulegid ) { $parentgid = ""; } 72cdf0e10cSrcweir 73cdf0e10cSrcweir # Attention: Maximum feature length is 38! 74cdf0e10cSrcweir installer::windows::idtglobal::shorten_feature_gid(\$parentgid); 75cdf0e10cSrcweir 76cdf0e10cSrcweir return $parentgid 77cdf0e10cSrcweir} 78cdf0e10cSrcweir 79cdf0e10cSrcweir############################################################## 80cdf0e10cSrcweir# Returning the display for a feature. 81cdf0e10cSrcweir# 0: Feature is not shown 82cdf0e10cSrcweir# odd: subfeatures are shown 83cdf0e10cSrcweir# even: subfeatures are not shown 84cdf0e10cSrcweir############################################################## 85cdf0e10cSrcweir 86cdf0e10cSrcweirsub get_feature_display 87cdf0e10cSrcweir{ 88cdf0e10cSrcweir my ($onefeature) = @_; 89cdf0e10cSrcweir 90cdf0e10cSrcweir my $display; 91cdf0e10cSrcweir my $parentid = ""; 92cdf0e10cSrcweir 93cdf0e10cSrcweir if ( $onefeature->{'ParentID'} ) { $parentid = $onefeature->{'ParentID'}; } 94cdf0e10cSrcweir 95cdf0e10cSrcweir if ( $parentid eq "" ) 96cdf0e10cSrcweir { 97cdf0e10cSrcweir $display = "0"; # root module is not visible 98cdf0e10cSrcweir } 99cdf0e10cSrcweir elsif ( $onefeature->{'gid'} eq "gid_Module_Prg") # program module shows subfeatures 100cdf0e10cSrcweir { 101cdf0e10cSrcweir $display = "1"; # root module shows subfeatures 102cdf0e10cSrcweir } 103cdf0e10cSrcweir else 104cdf0e10cSrcweir { 105cdf0e10cSrcweir $display = "2"; # all other modules do not show subfeatures 106cdf0e10cSrcweir } 107cdf0e10cSrcweir 108cdf0e10cSrcweir # special case: Feature has flag "HIDDEN_ROOT" -> $display is 0 109cdf0e10cSrcweir my $styles = ""; 110cdf0e10cSrcweir if ( $onefeature->{'Styles'} ) { $styles = $onefeature->{'Styles'}; } 111cdf0e10cSrcweir if ( $styles =~ /\bHIDDEN_ROOT\b/ ) { $display = "0"; } 112cdf0e10cSrcweir 113cdf0e10cSrcweir # Special handling for language modules. Only visible in multilingual installation set 114cdf0e10cSrcweir if (( $styles =~ /\bSHOW_MULTILINGUAL_ONLY\b/ ) && ( ! $installer::globals::ismultilingual )) { $display = "0"; } 115cdf0e10cSrcweir 116cdf0e10cSrcweir # Special handling for c05office. No program module visible. 117cdf0e10cSrcweir if (( $onefeature->{'gid'} eq "gid_Module_Prg" ) && ( $installer::globals::product =~ /c05office/i )) { $display = "0"; } 118cdf0e10cSrcweir 119cdf0e10cSrcweir # making all feature invisible in Language packs! 120cdf0e10cSrcweir if ( $installer::globals::languagepack ) { $display = "0"; } 121cdf0e10cSrcweir 122cdf0e10cSrcweir return $display 123cdf0e10cSrcweir} 124cdf0e10cSrcweir 125cdf0e10cSrcweir############################################################## 126cdf0e10cSrcweir# Returning the level for a feature. 127cdf0e10cSrcweir############################################################## 128cdf0e10cSrcweir 129cdf0e10cSrcweirsub get_feature_level 130cdf0e10cSrcweir{ 131cdf0e10cSrcweir my ($onefeature) = @_; 132cdf0e10cSrcweir 133cdf0e10cSrcweir my $level = "20"; # the default 134cdf0e10cSrcweir 135cdf0e10cSrcweir my $localdefault = ""; 136cdf0e10cSrcweir 137cdf0e10cSrcweir if ( $onefeature->{'Default'} ) { $localdefault = $onefeature->{'Default'}; } 138cdf0e10cSrcweir 139cdf0e10cSrcweir if ( $localdefault eq "NO" ) # explicitely set Default = "NO" 140cdf0e10cSrcweir { 141cdf0e10cSrcweir $level = "200"; # deselected in default installation, base is 100 142cdf0e10cSrcweir if ( $installer::globals::patch ) { $level = "20"; } 143cdf0e10cSrcweir } 144cdf0e10cSrcweir 145cdf0e10cSrcweir # special handling for Java and Ada 146cdf0e10cSrcweir if ( $onefeature->{'Name'} ) 147cdf0e10cSrcweir { 148cdf0e10cSrcweir if ( $onefeature->{'Name'} =~ /java/i ) { $level = $level + 40; } 149cdf0e10cSrcweir } 150cdf0e10cSrcweir 151cdf0e10cSrcweir # if FeatureLevel is defined in scp, this will be used 152cdf0e10cSrcweir 153cdf0e10cSrcweir if ( $onefeature->{'FeatureLevel'} ) { $level = $onefeature->{'FeatureLevel'}; } 154cdf0e10cSrcweir 155cdf0e10cSrcweir return $level 156cdf0e10cSrcweir} 157cdf0e10cSrcweir 158cdf0e10cSrcweir############################################################## 159cdf0e10cSrcweir# Returning the directory for a feature. 160cdf0e10cSrcweir############################################################## 161cdf0e10cSrcweir 162cdf0e10cSrcweirsub get_feature_directory 163cdf0e10cSrcweir{ 164cdf0e10cSrcweir my ($onefeature) = @_; 165cdf0e10cSrcweir 166cdf0e10cSrcweir my $directory; 167cdf0e10cSrcweir 168cdf0e10cSrcweir $directory = "INSTALLLOCATION"; 169cdf0e10cSrcweir 170cdf0e10cSrcweir return $directory 171cdf0e10cSrcweir} 172cdf0e10cSrcweir 173cdf0e10cSrcweir############################################################## 174cdf0e10cSrcweir# Returning the directory for a feature. 175cdf0e10cSrcweir############################################################## 176cdf0e10cSrcweir 177cdf0e10cSrcweirsub get_feature_attributes 178cdf0e10cSrcweir{ 179cdf0e10cSrcweir my ($onefeature) = @_; 180cdf0e10cSrcweir 181cdf0e10cSrcweir my $attributes; 182cdf0e10cSrcweir 183cdf0e10cSrcweir # No advertising of features and no leaving on network. 184cdf0e10cSrcweir # Feature without parent must not have the "2" 185cdf0e10cSrcweir 186cdf0e10cSrcweir my $parentgid = ""; 187cdf0e10cSrcweir if ( $onefeature->{'ParentID'} ) { $parentgid = $onefeature->{'ParentID'}; } 188cdf0e10cSrcweir 189cdf0e10cSrcweir if (( $parentgid eq "" ) || ( $parentgid eq $installer::globals::rootmodulegid )) { $attributes = "8"; } 190cdf0e10cSrcweir else { $attributes = "10"; } 191cdf0e10cSrcweir 192cdf0e10cSrcweir return $attributes 193cdf0e10cSrcweir} 194cdf0e10cSrcweir 195cdf0e10cSrcweir################################################################################# 196cdf0e10cSrcweir# Replacing one variable in one files 197cdf0e10cSrcweir################################################################################# 198cdf0e10cSrcweir 199cdf0e10cSrcweirsub replace_one_variable 200cdf0e10cSrcweir{ 201cdf0e10cSrcweir my ($translationfile, $variable, $searchstring) = @_; 202cdf0e10cSrcweir 203cdf0e10cSrcweir for ( my $i = 0; $i <= $#{$translationfile}; $i++ ) 204cdf0e10cSrcweir { 205cdf0e10cSrcweir ${$translationfile}[$i] =~ s/\%$searchstring/$variable/g; 206cdf0e10cSrcweir } 207cdf0e10cSrcweir} 208cdf0e10cSrcweir 209cdf0e10cSrcweir################################################################################# 210cdf0e10cSrcweir# Replacing the variables in the feature names and descriptions 211cdf0e10cSrcweir################################################################################# 212cdf0e10cSrcweir 213cdf0e10cSrcweirsub replace_variables 214cdf0e10cSrcweir{ 215cdf0e10cSrcweir my ($translationfile, $variableshashref) = @_; 216cdf0e10cSrcweir 217cdf0e10cSrcweir foreach $key (keys %{$variableshashref}) 218cdf0e10cSrcweir { 219cdf0e10cSrcweir my $value = $variableshashref->{$key}; 220cdf0e10cSrcweir replace_one_variable($translationfile, $value, $key); 221cdf0e10cSrcweir } 222cdf0e10cSrcweir} 223cdf0e10cSrcweir 224cdf0e10cSrcweir################################################################################# 225cdf0e10cSrcweir# Collecting the feature recursively. 226cdf0e10cSrcweir################################################################################# 227cdf0e10cSrcweir 228cdf0e10cSrcweirsub collect_modules_recursive 229cdf0e10cSrcweir{ 230cdf0e10cSrcweir my ($modulesref, $parentid, $feature, $directaccess, $directgid, $directparent, $directsortkey, $sorted) = @_; 231cdf0e10cSrcweir 232cdf0e10cSrcweir my @allchildren = (); 233cdf0e10cSrcweir my $childrenexist = 0; 234cdf0e10cSrcweir 235cdf0e10cSrcweir # Collecting children from Module $parentid 236cdf0e10cSrcweir 237cdf0e10cSrcweir my $modulegid; 238cdf0e10cSrcweir foreach $modulegid ( keys %{$directparent}) 239cdf0e10cSrcweir { 240cdf0e10cSrcweir if ( $directparent->{$modulegid} eq $parentid ) 241cdf0e10cSrcweir { 242cdf0e10cSrcweir my %childhash = ( "gid" => "$modulegid", "Sortkey" => "$directsortkey->{$modulegid}"); 243cdf0e10cSrcweir push(@allchildren, \%childhash); 244cdf0e10cSrcweir $childrenexist = 1; 245cdf0e10cSrcweir } 246cdf0e10cSrcweir } 247cdf0e10cSrcweir 248cdf0e10cSrcweir # Sorting children 249cdf0e10cSrcweir 250cdf0e10cSrcweir if ( $childrenexist ) 251cdf0e10cSrcweir { 252cdf0e10cSrcweir # Sort children 253cdf0e10cSrcweir installer::sorter::sort_array_of_hashes_numerically(\@allchildren, "Sortkey"); 254cdf0e10cSrcweir 255cdf0e10cSrcweir # Adding children to new array 256cdf0e10cSrcweir my $childhashref; 257cdf0e10cSrcweir foreach $childhashref ( @allchildren ) 258cdf0e10cSrcweir { 259cdf0e10cSrcweir my $gid = $childhashref->{'gid'}; 260cdf0e10cSrcweir 261cdf0e10cSrcweir # Saving all lines, that have this 'gid' 262cdf0e10cSrcweir 263cdf0e10cSrcweir my $unique; 264cdf0e10cSrcweir foreach $unique ( keys %{$directgid} ) 265cdf0e10cSrcweir { 266cdf0e10cSrcweir if ( $directgid->{$unique} eq $gid ) 267cdf0e10cSrcweir { 268cdf0e10cSrcweir push(@{$feature}, ${$modulesref}[$directaccess->{$unique}]); 269cdf0e10cSrcweir if ( $sorted->{$unique} == 1 ) { installer::exiter::exit_program("ERROR: Sorting feature failed! \"$unique\" already sorted.", "sort_feature"); } 270cdf0e10cSrcweir $sorted->{$unique} = 1; 271cdf0e10cSrcweir } 272cdf0e10cSrcweir } 273cdf0e10cSrcweir 274cdf0e10cSrcweir collect_modules_recursive($modulesref, $gid, $feature, $directaccess, $directgid, $directparent, $directsortkey, $sorted); 275cdf0e10cSrcweir } 276cdf0e10cSrcweir } 277cdf0e10cSrcweir} 278cdf0e10cSrcweir 279cdf0e10cSrcweir################################################################################# 280cdf0e10cSrcweir# Sorting the feature in specified order. Evaluated is the key "Sortkey", that 281cdf0e10cSrcweir# is set in scp2 projects. 282cdf0e10cSrcweir# The display order of modules in Windows Installer is dependent from the order 283cdf0e10cSrcweir# in the idt file. Therefore the order of the modules array has to be adapted 284cdf0e10cSrcweir# to the Sortkey order, before the idt file is created. 285cdf0e10cSrcweir################################################################################# 286cdf0e10cSrcweir 287cdf0e10cSrcweirsub sort_feature 288cdf0e10cSrcweir{ 289cdf0e10cSrcweir my ($modulesref) = @_; 290cdf0e10cSrcweir 291cdf0e10cSrcweir my @feature = (); 292cdf0e10cSrcweir 293cdf0e10cSrcweir my %directaccess = (); 294cdf0e10cSrcweir my %directparent = (); 295cdf0e10cSrcweir my %directgid = (); 296cdf0e10cSrcweir my %directsortkey = (); 297cdf0e10cSrcweir my %sorted = (); 298cdf0e10cSrcweir 299cdf0e10cSrcweir for ( my $i = 0; $i <= $#{$modulesref}; $i++ ) 300cdf0e10cSrcweir { 301cdf0e10cSrcweir my $onefeature = ${$modulesref}[$i]; 302cdf0e10cSrcweir 303cdf0e10cSrcweir my $uniquekey = $onefeature->{'uniquekey'}; 304cdf0e10cSrcweir my $modulegid = $onefeature->{'gid'}; 305cdf0e10cSrcweir 306cdf0e10cSrcweir $directaccess{$uniquekey} = $i; 307cdf0e10cSrcweir 308cdf0e10cSrcweir $directgid{$uniquekey} = $onefeature->{'gid'}; 309cdf0e10cSrcweir 310cdf0e10cSrcweir # ParentID and Sortkey are not saved for the 'uniquekey', but only for the 'gid' 311cdf0e10cSrcweir 312cdf0e10cSrcweir if ( $onefeature->{'ParentID'} ) { $directparent{$modulegid} = $onefeature->{'ParentID'}; } 313cdf0e10cSrcweir else { $directparent{$modulegid} = ""; } 314cdf0e10cSrcweir 315cdf0e10cSrcweir if ( $onefeature->{'Sortkey'} ) { $directsortkey{$modulegid} = $onefeature->{'Sortkey'}; } 316cdf0e10cSrcweir else { $directsortkey{$modulegid} = "9999"; } 317cdf0e10cSrcweir 318cdf0e10cSrcweir # Bookkeeping: 319cdf0e10cSrcweir $sorted{$uniquekey} = 0; 320cdf0e10cSrcweir } 321cdf0e10cSrcweir 322cdf0e10cSrcweir # Searching all feature recursively, beginning with ParentID = "" 323cdf0e10cSrcweir my $parentid = ""; 324cdf0e10cSrcweir collect_modules_recursive($modulesref, $parentid, \@feature, \%directaccess, \%directgid, \%directparent, \%directsortkey, \%sorted); 325cdf0e10cSrcweir 326cdf0e10cSrcweir # Bookkeeping 327cdf0e10cSrcweir my $modulekey; 328cdf0e10cSrcweir foreach $modulekey ( keys %sorted ) 329cdf0e10cSrcweir { 330cdf0e10cSrcweir if ( $sorted{$modulekey} == 0 ) 331cdf0e10cSrcweir { 332b274bc22SAndre Fischer $installer::logger::Lang->printf( 333b274bc22SAndre Fischer "Warning: Module \"%s\" could not be sorted. Added to the end of the module array.\n", 334b274bc22SAndre Fischer $modulekey); 335cdf0e10cSrcweir push(@feature, ${$modulesref}[$directaccess{$modulekey}]); 336cdf0e10cSrcweir } 337cdf0e10cSrcweir } 338cdf0e10cSrcweir 339cdf0e10cSrcweir return \@feature; 340cdf0e10cSrcweir} 341cdf0e10cSrcweir 342cdf0e10cSrcweir################################################################################# 343cdf0e10cSrcweir# Adding a unique key to the modules array. The gid is not unique for 344cdf0e10cSrcweir# multilingual modules. Only the combination from gid and specific language 345cdf0e10cSrcweir# is unique. Uniqueness is required for sorting mechanism. 346cdf0e10cSrcweir################################################################################# 347cdf0e10cSrcweir 348cdf0e10cSrcweirsub add_uniquekey 349cdf0e10cSrcweir{ 350cdf0e10cSrcweir my ( $modulesref ) = @_; 351cdf0e10cSrcweir 352cdf0e10cSrcweir for ( my $i = 0; $i <= $#{$modulesref}; $i++ ) 353cdf0e10cSrcweir { 354cdf0e10cSrcweir my $uniquekey = ${$modulesref}[$i]->{'gid'}; 355cdf0e10cSrcweir if ( ${$modulesref}[$i]->{'specificlanguage'} ) { $uniquekey = $uniquekey . "_" . ${$modulesref}[$i]->{'specificlanguage'}; } 356cdf0e10cSrcweir ${$modulesref}[$i]->{'uniquekey'} = $uniquekey; 357cdf0e10cSrcweir } 358cdf0e10cSrcweir} 359cdf0e10cSrcweir 360cdf0e10cSrcweir################################################################################# 361cdf0e10cSrcweir# Creating the file Feature.idt dynamically 362cdf0e10cSrcweir# Content: 363cdf0e10cSrcweir# Feature Feature_Parent Title Description Display Level Directory_ Attributes 364cdf0e10cSrcweir################################################################################# 365cdf0e10cSrcweir 366677600b0SAndre Fischersub prepare_feature_table ($$$) 367cdf0e10cSrcweir{ 368677600b0SAndre Fischer my ($modules, $language, $variables) = @_; 369cdf0e10cSrcweir 370677600b0SAndre Fischer my $features = []; 371677600b0SAndre Fischer 372677600b0SAndre Fischer foreach my $onefeature (@$modules) 373cdf0e10cSrcweir { 374cdf0e10cSrcweir # Java and Ada only, if the correct settings are set 375*d62abd1aSAndre Fischer my $styles = $onefeature->{'Styles'}; 376*d62abd1aSAndre Fischer $styles = "" unless defined $styles; 377677600b0SAndre Fischer if (( $styles =~ /\bJAVAMODULE\b/ ) && ( ! ($variables->{'JAVAPRODUCT'} ))) { next; } 378cdf0e10cSrcweir 379cdf0e10cSrcweir # Controlling the language! 380cdf0e10cSrcweir # Only language independent feature or feature with the correct language will be included into the table 381cdf0e10cSrcweir 382677600b0SAndre Fischer next if $onefeature->{'ismultilingual'} && ($onefeature->{'specificlanguage'} ne $language); 383cdf0e10cSrcweir 384677600b0SAndre Fischer my $feature_gid =get_feature_gid($onefeature); 385cdf0e10cSrcweir 386677600b0SAndre Fischer my $feature = { 387677600b0SAndre Fischer 'Feature' => $feature_gid, 388677600b0SAndre Fischer 'Feature_Parent' => get_feature_parent($onefeature), 389677600b0SAndre Fischer 'Title' => $onefeature->{'Name'}, 390677600b0SAndre Fischer 'Description' => $onefeature->{'Description'}, 391677600b0SAndre Fischer 'Display' => get_feature_display($onefeature), 392677600b0SAndre Fischer 'Level' => get_feature_level($onefeature), 393677600b0SAndre Fischer 'Directory_' => get_feature_directory($onefeature), 394677600b0SAndre Fischer 'Attributes' => get_feature_attributes($onefeature) 395677600b0SAndre Fischer }; 396677600b0SAndre Fischer push @$features, $feature; 397cdf0e10cSrcweir 398cdf0e10cSrcweir # collecting all feature in global feature collector (so that properties can be set in property table) 399677600b0SAndre Fischer $installer::globals::featurecollector{$feature_gid} = 1; 400cdf0e10cSrcweir 401cdf0e10cSrcweir # collecting all language feature in feature collector for check of language selection 402677600b0SAndre Fischer if (( $styles =~ /\bSHOW_MULTILINGUAL_ONLY\b/ ) && $onefeature->{'ParentID'} ne $installer::globals::rootmodulegid) 403cdf0e10cSrcweir { 404677600b0SAndre Fischer $installer::globals::multilingual_only_modules{$feature_gid} = 1; 405cdf0e10cSrcweir } 406cdf0e10cSrcweir 407cdf0e10cSrcweir # collecting all application feature in global feature collector for check of application selection 408cdf0e10cSrcweir if ( $styles =~ /\bAPPLICATIONMODULE\b/ ) 409cdf0e10cSrcweir { 410677600b0SAndre Fischer $installer::globals::application_modules{$feature_gid} = 1; 411cdf0e10cSrcweir } 412cdf0e10cSrcweir } 413cdf0e10cSrcweir 414677600b0SAndre Fischer return $features; 415cdf0e10cSrcweir} 416677600b0SAndre Fischer 417677600b0SAndre Fischer 418677600b0SAndre Fischer 419677600b0SAndre Fischer 420677600b0SAndre Fischer=head add_missing_features($features) 421677600b0SAndre Fischer 422677600b0SAndre Fischer When we are building a release, then there may be features missing 423677600b0SAndre Fischer that where present in the source release. As missing features 424677600b0SAndre Fischer would prevent patches from being created, we add the missing 425677600b0SAndre Fischer features. 426677600b0SAndre Fischer 427677600b0SAndre Fischer The returned feature hash is either identical to the given 428677600b0SAndre Fischer $features or is a copy with the missing features added. 429677600b0SAndre Fischer 430677600b0SAndre Fischer=cut 431677600b0SAndre Fischer 432677600b0SAndre Fischersub add_missing_features ($) 433677600b0SAndre Fischer{ 434677600b0SAndre Fischer my ($features) = @_; 435677600b0SAndre Fischer 436677600b0SAndre Fischer return $features if ! $installer::globals::is_release; 437677600b0SAndre Fischer 438677600b0SAndre Fischer # Aquire the feature list of the source release. 439677600b0SAndre Fischer my $source_feature_table = $installer::globals::source_msi->GetTable("Feature"); 440677600b0SAndre Fischer my $feature_column_index = $source_feature_table->GetColumnIndex("Feature"); 441677600b0SAndre Fischer 442677600b0SAndre Fischer # Prepare fast lookup of the target features. 443677600b0SAndre Fischer my %target_feature_map = map {$_->{'Feature'} => $_} @$features; 444677600b0SAndre Fischer 445677600b0SAndre Fischer # Find missing features. 446677600b0SAndre Fischer my @missing_features = (); 447677600b0SAndre Fischer foreach my $source_feature_row (@{$source_feature_table->GetAllRows()}) 448677600b0SAndre Fischer { 449677600b0SAndre Fischer my $feature_gid = $source_feature_row->GetValue($feature_column_index); 450677600b0SAndre Fischer if ( ! defined $target_feature_map{$feature_gid}) 451677600b0SAndre Fischer { 452677600b0SAndre Fischer push @missing_features, $source_feature_row; 453677600b0SAndre Fischer } 454677600b0SAndre Fischer } 455677600b0SAndre Fischer 456677600b0SAndre Fischer # Return when there are no missing features. 457677600b0SAndre Fischer return $features if scalar @missing_features==0; 458677600b0SAndre Fischer 459677600b0SAndre Fischer # Process the missing features. 460677600b0SAndre Fischer my $extended_features = [@$features]; 461677600b0SAndre Fischer foreach my $missing_feature_row (@missing_features) 462677600b0SAndre Fischer { 463677600b0SAndre Fischer my %feature = map 464677600b0SAndre Fischer {$_ => $missing_feature_row->GetValue($_)} 465677600b0SAndre Fischer ('Feature', 'Feature_Parent', 'Title', 'Description', 'Display', 'Level', 'Directory_', 'Attributes'); 466677600b0SAndre Fischer push @$extended_features, \%feature; 467677600b0SAndre Fischer 468677600b0SAndre Fischer $installer::logger::Lang->printf("added missing feature %s\n", $feature->{'Feature'}); 469677600b0SAndre Fischer } 470677600b0SAndre Fischer return $extended_features; 471677600b0SAndre Fischer} 472677600b0SAndre Fischer 473677600b0SAndre Fischer 474677600b0SAndre Fischer 475677600b0SAndre Fischer 476677600b0SAndre Fischersub create_feature_table ($$$) 477677600b0SAndre Fischer{ 478677600b0SAndre Fischer my ($basedir, $language, $features) = @_; 479677600b0SAndre Fischer 480677600b0SAndre Fischer my @feature_table = (); 481677600b0SAndre Fischer installer::windows::idtglobal::write_idt_header(\@feature_table, "feature"); 482677600b0SAndre Fischer 483677600b0SAndre Fischer foreach my $feature (@$features) 484677600b0SAndre Fischer { 485677600b0SAndre Fischer my $line = join("\t", 486677600b0SAndre Fischer $feature->{'Feature'}, 487677600b0SAndre Fischer $feature->{'Feature_Parent'}, 488677600b0SAndre Fischer $feature->{'Title'}, 489677600b0SAndre Fischer $feature->{'Description'}, 490677600b0SAndre Fischer $feature->{'Display'}, 491677600b0SAndre Fischer $feature->{'Level'}, 492677600b0SAndre Fischer $feature->{'Directory_'}, 493677600b0SAndre Fischer $feature->{'Attributes'}) . "\n"; 494677600b0SAndre Fischer 495677600b0SAndre Fischer push(@feature_table, $line); 496677600b0SAndre Fischer } 497677600b0SAndre Fischer 498677600b0SAndre Fischer my $filename = $basedir . $installer::globals::separator . "Feature.idt" . "." . $language; 499677600b0SAndre Fischer installer::files::save_file($filename ,\@feature_table); 500677600b0SAndre Fischer $installer::logger::Lang->printf("Created idt file: %s\n", $filename); 501cdf0e10cSrcweir} 502cdf0e10cSrcweir 503cdf0e10cSrcweir1; 504