1 // Copyright (c) Microsoft. All rights reserved. 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 4 using System; 5 using System.Collections; 6 using System.Collections.Generic; 7 using System.Diagnostics; 8 using System.Globalization; 9 using System.Xml; 10 using System.Runtime.InteropServices; 11 12 namespace Microsoft.Build.Tasks.Deployment.Bootstrapper 13 { 14 internal enum CopyAllFilesType 15 { 16 CopyAllFilesFalse, CopyAllFilesTrue, CopyAllFilesIfNotHomeSite 17 }; 18 19 /// <summary> 20 /// This class represents a product in the found by the BootstrapperBuilder in the Path property. 21 /// </summary> 22 [ComVisible(true), GuidAttribute("532BF563-A85D-4088-8048-41F51AC5239F"), ClassInterface(ClassInterfaceType.None)] 23 public class Product : IProduct 24 { 25 private XmlNode _node; 26 private string _productCode; 27 private PackageCollection _packages; 28 private ProductCollection _includes; 29 private List<List<Product>> _dependencies; 30 private ArrayList _missingDependencies; 31 private Hashtable _cultures; 32 private CopyAllFilesType _copyAllPackageFiles; 33 private ProductValidationResults _validationResults; 34 Product()35 public Product() 36 { 37 Debug.Fail("Products are not to be created in this fashion. Please use IBootstrapperBuilder.Products instead."); 38 throw new InvalidOperationException(); 39 } 40 Product(XmlNode node, string code, ProductValidationResults validationResults, string copyAll)41 internal Product(XmlNode node, string code, ProductValidationResults validationResults, string copyAll) 42 { 43 _node = node; 44 _packages = new PackageCollection(); 45 _includes = new ProductCollection(); 46 _dependencies = new List<List<Product>>(); 47 _missingDependencies = new ArrayList(); 48 _productCode = code; 49 _validationResults = validationResults; 50 _cultures = new Hashtable(); 51 if (copyAll == "IfNotHomeSite") 52 _copyAllPackageFiles = CopyAllFilesType.CopyAllFilesIfNotHomeSite; 53 else if (copyAll == "false") 54 _copyAllPackageFiles = CopyAllFilesType.CopyAllFilesFalse; 55 else 56 _copyAllPackageFiles = CopyAllFilesType.CopyAllFilesTrue; 57 } 58 59 internal XmlNode Node 60 { 61 get { return _node; } 62 } 63 64 internal CopyAllFilesType CopyAllPackageFiles 65 { 66 get { return _copyAllPackageFiles; } 67 } 68 69 /// <summary> 70 /// The ProductBuilder representation of this Product 71 /// </summary> 72 public ProductBuilder ProductBuilder 73 { 74 get { return new ProductBuilder(this); } 75 } 76 77 /// <summary> 78 /// A string specifying the unique identifier of this product 79 /// </summary> 80 public string ProductCode 81 { 82 get { return _productCode; } 83 } 84 85 /// <summary> 86 /// A human-readable name for this product 87 /// </summary> 88 public string Name 89 { 90 get 91 { 92 CultureInfo culture = Util.DefaultCultureInfo; 93 Package p = _packages.Package(culture.Name); 94 95 if (p != null) 96 { 97 return p.Name; 98 } 99 100 while (culture != null && culture != CultureInfo.InvariantCulture) 101 { 102 p = _packages.Package(culture.Parent.Name); 103 104 if (p != null) 105 { 106 return p.Name; 107 } 108 109 culture = culture.Parent; 110 } 111 112 if (_packages.Count > 0) 113 { 114 return _packages.Item(0).Name; 115 } 116 117 return _productCode.ToString(); 118 } 119 } 120 121 /// <summary> 122 /// All products which this product also installs 123 /// </summary> 124 public ProductCollection Includes 125 { 126 get { return _includes; } 127 } 128 129 internal List<List<Product>> Dependencies 130 { 131 get { return _dependencies; } 132 } 133 ContainsCulture(string culture)134 internal bool ContainsCulture(string culture) 135 { 136 return _cultures.Contains(culture.ToLowerInvariant()); 137 } 138 ContainsDependencies(List<Product> dependenciesToCheck)139 internal bool ContainsDependencies(List<Product> dependenciesToCheck) 140 { 141 foreach (List<Product> d in _dependencies) 142 { 143 bool found = true; 144 foreach (Product p in d) 145 { 146 bool containedInDependencies = false; 147 foreach (Product pd in dependenciesToCheck) 148 { 149 if (p._productCode == pd._productCode) 150 { 151 containedInDependencies = true; 152 break; 153 } 154 } 155 if (!containedInDependencies) 156 { 157 found = false; 158 break; 159 } 160 } 161 162 if (found) 163 { 164 return true; 165 } 166 } 167 168 return false; 169 } 170 171 internal ArrayList MissingDependencies 172 { 173 get 174 { 175 return _missingDependencies; 176 } 177 } 178 AddPackage(Package package)179 internal void AddPackage(Package package) 180 { 181 if (package == null || String.IsNullOrEmpty(package.Culture)) 182 throw new ArgumentNullException("package"); 183 184 if (!_cultures.Contains(package.Culture.ToLowerInvariant())) 185 { 186 _packages.Add(package); 187 _cultures.Add(package.Culture.ToLowerInvariant(), package); 188 } 189 else 190 { 191 Debug.WriteLine(String.Format(CultureInfo.CurrentCulture, "A package with culture '{0}' has already been added to product '{1}'", package.Culture.ToLowerInvariant(), ProductCode)); 192 } 193 } 194 AddIncludedProduct(Product product)195 internal void AddIncludedProduct(Product product) 196 { 197 _includes.Add(product); 198 } 199 AddDependentProduct(Product product)200 internal void AddDependentProduct(Product product) 201 { 202 List<Product> newDependency = new List<Product>(); 203 newDependency.Add(product); 204 _dependencies.Add(newDependency); 205 } 206 AddMissingDependency(ArrayList productCodes)207 internal void AddMissingDependency(ArrayList productCodes) 208 { 209 bool found = false; 210 foreach (ArrayList md in _missingDependencies) 211 { 212 bool hasAll = true; 213 foreach (string dep in md) 214 { 215 if (!productCodes.Contains(dep)) 216 { 217 hasAll = false; 218 break; 219 } 220 } 221 222 if (hasAll) 223 { 224 found = true; 225 break; 226 } 227 } 228 229 if (!found) 230 { 231 _missingDependencies.Add(productCodes); 232 } 233 } 234 235 internal PackageCollection Packages 236 { 237 get { return _packages; } 238 } 239 GetPackageValidationResults(string culture)240 internal XmlValidationResults GetPackageValidationResults(string culture) 241 { 242 if (_validationResults == null) 243 return null; 244 return _validationResults.PackageResults(culture); 245 } 246 247 internal bool ValidationPassed 248 { 249 get 250 { 251 if (_validationResults == null) 252 return true; 253 return _validationResults.ValidationPassed; 254 } 255 } 256 257 internal ProductValidationResults ValidationResults 258 { 259 get { return _validationResults; } 260 } 261 } 262 } 263