1#************************************************************** 2# 3# Licensed to the Apache Software Foundation (ASF) under one 4# or more contributor license agreements. See the NOTICE file 5# distributed with this work for additional information 6# regarding copyright ownership. The ASF licenses this file 7# to you under the Apache License, Version 2.0 (the 8# "License"); you may not use this file except in compliance 9# with the License. You may obtain a copy of the License at 10# 11# http://www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, 14# software distributed under the License is distributed on an 15# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16# KIND, either express or implied. See the License for the 17# specific language governing permissions and limitations 18# under the License. 19# 20#************************************************************** 21 22 23 24package installer::windows::featurecomponent; 25 26use installer::converter; 27use installer::existence; 28use installer::exiter; 29use installer::files; 30use installer::globals; 31use installer::windows::idtglobal; 32 33use strict; 34 35 36################################################################################# 37# Collecting all pairs of features and components from the files collector 38################################################################################# 39 40sub create_featurecomponent_table_from_files_collector ($$) 41{ 42 my ($featurecomponenttableref, $filesref) = @_; 43 44 foreach my $onefile (@$filesref) 45 { 46 my $filecomponent = $onefile->{'componentname'}; 47 my $filemodules = $onefile->{'modules'}; 48 49 if ( $filecomponent eq "" ) 50 { 51 installer::exiter::exit_program( 52 sprintf("ERROR: No component defined for file %s", $onefile->{'Name'}), 53 "create_featurecomponent_table_from_files_collector"); 54 } 55 if ( ! defined $filemodules) 56 { 57 # Temporary for files created from source installation set. 58 die; 59 } 60 if ($filemodules eq "") 61 { 62 installer::exiter::exit_program( 63 sprintf("ERROR: No modules found for file %s", $onefile->{'Name'}), 64 "create_featurecomponent_table_from_files_collector"); 65 } 66 67 my $filemodulesarrayref = installer::converter::convert_stringlist_into_array(\$filemodules, ","); 68 69 foreach my $onemodule (@$filemodulesarrayref) 70 { 71 my %featurecomponent = (); 72 73 $onemodule =~ s/\s*$//; 74 $featurecomponent{'Feature'} = $onemodule; 75 $featurecomponent{'Component'} = $filecomponent; 76 77 # Attention: Features are renamed, because the maximum length is 38. 78 # But in the files collector ($filesref), the original names are saved. 79 80 installer::windows::idtglobal::shorten_feature_gid(\$featurecomponent{'Feature'}); 81 82 my $oneline = "$featurecomponent{'Feature'}\t$featurecomponent{'Component'}\n"; 83 84 # control of uniqueness 85 86 if (! installer::existence::exists_in_array($oneline, $featurecomponenttableref)) 87 { 88 push(@{$featurecomponenttableref}, $oneline); 89 } 90 } 91 } 92} 93 94 95 96 97=head2 create_featurecomponent_table_from_registry_collector ($featurecomponenttableref, $registryref) 98 99 Add entries for the FeatureComponent table for components that contain registry entries. 100 101=cut 102sub create_featurecomponent_table_from_registry_collector ($$) 103{ 104 my ($featurecomponenttableref, $registryref) = @_; 105 106 my $replacement_count = 0; 107 my $unique_count = 0; 108 foreach my $oneregistry (@$registryref) 109 { 110 my $component_name = $oneregistry->{'componentname'}; 111 if ($component_name eq "") 112 { 113 installer::exiter::exit_program( 114 sprintf("ERROR: No component defined for registry %s", $oneregistry->{'gid'}), 115 "create_featurecomponent_table_from_registry_collector"); 116 } 117 118 my $feature_name = $oneregistry->{'ModuleID'}; 119 if ($feature_name eq "") 120 { 121 installer::exiter::exit_program( 122 sprintf("ERROR: No modules found for registry %s", $oneregistry->{'gid'}), 123 "create_featurecomponent_table_from_registry_collector"); 124 } 125 126 # Attention: Features are renamed, because the maximum length is 38. 127 # But in the files collector ($filesref), the original names are saved. 128 129 $feature_name = installer::windows::idtglobal::create_shortend_feature_gid($feature_name); 130 131 my $oneline = sprintf("%s\t%s\n", $feature_name, $component_name); 132 if ( ! installer::existence::exists_in_array($oneline, $featurecomponenttableref)) 133 { 134 push(@$featurecomponenttableref, $oneline); 135 ++$unique_count; 136 } 137 else 138 { 139 $installer::logger::Lang->printf("feature component pair already exists\n"); 140 } 141 } 142 $installer::logger::Lang->printf( 143 "replaced %d (%d) of %d component names in FeatureComponent table\n", 144 $unique_count, 145 $replacement_count, 146 scalar @$registryref); 147} 148 149################################################################################# 150# Collecting all feature that are listed in the featurecomponent table. 151################################################################################# 152 153sub collect_all_features 154{ 155 my ($featurecomponenttable) = @_; 156 157 my @allfeature = (); 158 159 for ( my $i = 3; $i <= $#{$featurecomponenttable}; $i++ ) # beginning in line 4 160 { 161 my $oneline = ${$featurecomponenttable}[$i]; 162 163 if ( $oneline =~ /^\s*(\S+)\s+(\S+)\s*$/ ) 164 { 165 my $feature = $1; 166 167 if (! installer::existence::exists_in_array($feature, \@allfeature)) 168 { 169 push(@allfeature, $feature); 170 } 171 } 172 } 173 174 return \@allfeature; 175} 176 177################################################################################# 178# On Win98 and Win Me there seems to be the problem, that maximum 817 179# components can be added to a feature. Even if Windows Installer 2.0 180# is used. 181################################################################################# 182 183sub check_number_of_components_at_feature 184{ 185 my ($featurecomponenttable) = @_; 186 187 $installer::logger::Lang->print("\n"); 188 $installer::logger::Lang->print("Checking number of components at features. Maximum is 817 (for Win 98 and Win Me)\n"); 189 190 my $allfeature = collect_all_features($featurecomponenttable); 191 192 for ( my $i = 0; $i <= $#{$allfeature}; $i++ ) 193 { 194 my $onefeature = ${$allfeature}[$i]; 195 my $featurecomponents = 0; 196 197 for ( my $j = 0; $j <= $#{$featurecomponenttable}; $j++ ) 198 { 199 if ( ${$featurecomponenttable}[$j] =~ /^\s*\Q$onefeature\E\s+(\S+)\s*$/ ) { $featurecomponents++; } 200 } 201 202 if ( $featurecomponents > 816 ) 203 { 204 installer::exiter::exit_program("ERROR: More than 816 components ($featurecomponents) at feature $onefeature. This causes problems on Win 98 and Win Me!", "check_number_of_components_at_feature"); 205 } 206 207 # Logging the result 208 209 $installer::logger::Lang->printf("Number of components at feature $onefeature : %s\n", $featurecomponents); 210 } 211 212 $installer::logger::Lang->print("\n"); 213} 214 215################################################################################# 216# Creating the file FeatureC.idt dynamically 217# Content: 218# Feature Component 219################################################################################# 220 221sub create_featurecomponent_table ($$$) 222{ 223 my ($filesref, $registryref, $basedir) = @_; 224 225 my @featurecomponenttable = (); 226 my $infoline; 227 228 installer::windows::idtglobal::write_idt_header(\@featurecomponenttable, "featurecomponent"); 229 230 # This is the first time, that features and componentes are related 231 # Problem: How about created profiles, configurationfiles, services.rdb 232 # -> simple solution: putting them all to the root module 233 # Otherwise profiles and configurationfiles cannot be created the way, they are now created 234 # -> especially a problem for the configurationfiles! # ToDo 235 # Very good: All ProfileItems belong to the root 236 # services.rdb belongs to the root anyway. 237 238 # At the moment only the files are related to components (and the files know their modules). 239 # The component for each file is written into the files collector $filesinproductlanguageresolvedarrayref 240 241 create_featurecomponent_table_from_files_collector( 242 \@featurecomponenttable, 243 $filesref); 244 245 create_featurecomponent_table_from_registry_collector( 246 \@featurecomponenttable, 247 $registryref); 248 249 # Additional components have to be added here 250 251 # Checking, whether there are more than 817 components at a feature 252 253 check_number_of_components_at_feature(\@featurecomponenttable); 254 255 # Saving the file 256 257 my $featurecomponenttablename = $basedir . $installer::globals::separator . "FeatureC.idt"; 258 installer::files::save_file($featurecomponenttablename ,\@featurecomponenttable); 259 $installer::logger::Lang->printf("Created idt file: %s\n", $featurecomponenttablename); 260} 261 2621; 263