private IEnumerable <InstallItem> FillInNullsOnRequiredProperties(XmlElement[] allItems, PackageMetadataProvider metadata) { var newlyRequiredProps = allItems.Where(i => i.Attribute("type") == "Property" && i.Attribute("action") == "edit" && !string.IsNullOrEmpty(i.Attribute("id")) && i.Element("is_required", "0") == "1" && i.Element("default_value").HasValue()) .ToArray(); if (newlyRequiredProps.Length > 0) { var doc = newlyRequiredProps[0].NewDoc(); var root = doc.Elem("AML"); var idx = 0; foreach (var prop in newlyRequiredProps) { string name; metadata.PropById(prop.Attribute("id"), out name); var typeId = prop.Parent().Parent().Attribute("id"); var typeName = metadata.ItemTypes.Single(i => i.Id == typeId).Name; var script = root.Elem("Item").Attr("type", typeName).Attr("action", "edit").Attr("where", "[" + typeName + "]." + name + " is null"); script.Elem(name, prop.Element("default_value", "")); yield return(InstallItem.FromScript(script, "_Scripts/NewlyRequiredProp (" + (++idx) + ").xml")); } } }
public InstallScript Merge(IPackage baseDir, IPackage compareDir) { var docs = new List <Tuple <XmlDocument, string> >(); var metadata = baseDir.WriteAmlMergeScripts(compareDir, (path, prog) => { ProgressChanged?.Invoke(this, new ProgressChangedEventArgs("Reading files", prog / 2)); var doc = new XmlDocument(); docs.Add(Tuple.Create(doc, path)); return(doc.CreateNavigator().AppendChild()); }); ProgressChanged?.Invoke(this, new ProgressChangedEventArgs("Performing cleanup", 50)); var allItems = docs .Where(d => d.Item1.DocumentElement != null) .SelectMany(d => d.Item1.DocumentElement .DescendantsAndSelf(el => el.LocalName == "Item")) .ToArray(); RemoveDeletesForItemsWithMultipleScripts(allItems); RemoveChangesToSystemProperties(allItems); var installScripts = docs .Where(d => d.Item1.DocumentElement != null) .SelectMany(d => XmlUtils.RootItems(d.Item1.DocumentElement) .Select(i => InstallItem.FromScript(i, d.Item2))) .ToArray(); ProgressChanged?.Invoke(this, new ProgressChangedEventArgs("Processing dependencies", 75)); var lines = (SortDependencies ? _sorter.SortByDependencies(installScripts, metadata) : installScripts).ToList(); lines.RemoveWhere(i => i.Type == InstallType.DependencyCheck); var script = new InstallScript() { Created = DateTime.Now, Creator = Environment.UserName, Title = "MergeScript", Lines = lines }; lines.InsertRange(0, FillInNullsOnRequiredProperties(allItems, metadata)); ProgressChanged?.Invoke(this, new ProgressChangedEventArgs("Processing dependencies", 80)); return(script); }
private static bool TryReadLegacyManifest(IPackageFile manifestFile, IPackage package, ILogger logger, out InstallScript installScript) { installScript = new InstallScript(); var scripts = new List <InstallItem>(); var manifest = new XmlDocument(); using (var manifestStream = manifestFile.Open()) manifest.Load(manifestStream); foreach (var pkg in manifest.DocumentElement.Elements("package")) { if (string.IsNullOrEmpty(installScript.Title)) { installScript.Title = pkg.Attribute("name", ""); } var folderPath = pkg.Attribute("path"); if (folderPath == ".\\") { folderPath = Utils.CleanFileName(pkg.Attribute("name", "")).Replace('.', '\\'); } foreach (var file in package.Files() .Where(f => f.Path.StartsWith(folderPath + "/", StringComparison.OrdinalIgnoreCase) && f.Path.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))) { try { var doc = new XmlDocument(manifest.NameTable); using (var stream = file.Open()) doc.Load(stream); var items = doc.DocumentElement.LocalName == "Item" ? new[] { doc.DocumentElement } : doc.DocumentElement.Elements("Item"); foreach (var item in items) { scripts.Add(InstallItem.FromScript(item, file.Path)); } } catch (Exception ex) { ex.Data["path"] = file.Path; throw; } } } installScript.Lines = scripts; return(CleanKeyedNames(installScript.Lines, logger)); }
public virtual InstallScript Read() { var result = new InstallScript(); XmlDocument doc; var scripts = new List <InstallItem>(); var manifest = new XmlDocument(); string currPath; IEnumerable <string> paths; manifest.Load(GetExistingStream(null)); if (manifest.DocumentElement.HasAttribute("created")) { result.Created = DateTime.Parse(manifest.DocumentElement.GetAttribute("created")); } result.Creator = manifest.DocumentElement.GetAttribute("creator"); result.Description = manifest.DocumentElement.GetAttribute("description"); if (manifest.DocumentElement.HasAttribute("modified")) { result.Modified = DateTime.Parse(manifest.DocumentElement.GetAttribute("modified")); } result.Version = manifest.DocumentElement.GetAttribute("revision"); result.Title = manifest.DocumentElement.GetAttribute("title"); if (manifest.DocumentElement.HasAttribute("website")) { result.Website = new Uri(manifest.DocumentElement.GetAttribute("website")); } foreach (var child in manifest.DocumentElement.ChildNodes.OfType <XmlElement>()) { if (child.LocalName == "Item") { scripts.Add(InstallItem.FromScript(child)); } else { currPath = child.GetAttribute("path"); paths = string.IsNullOrEmpty(currPath) ? Enumerable.Empty <string>() : (currPath == "*" ? GetPaths() : Enumerable.Repeat(currPath, 1)); if (currPath == "*") { result.DependencySorted = false; } foreach (var path in paths) { if (path.EndsWith(".xslt", StringComparison.OrdinalIgnoreCase)) { doc = ReadReport(path); } else { doc = new XmlDocument(manifest.NameTable); var stream = GetExistingStream(path); if (stream == null) { throw new FileNotFoundException("A referenced file was not found in the package", path); } doc.Load(stream); } foreach (var item in doc.DocumentElement.Elements("Item")) { scripts.Add(InstallItem.FromScript(item, path)); } } } } result.Lines = scripts; result.Lines.CleanKeyedNames(); return(result); }
public virtual InstallScript Read() { var result = new InstallScript(); XmlDocument doc; var scripts = new List <InstallItem>(); var manifest = new XmlDocument(); string currPath; IEnumerable <string> paths; manifest.Load(GetExistingStream(null)); if (manifest.DocumentElement.HasAttribute("created")) { result.Created = DateTime.Parse(manifest.DocumentElement.GetAttribute("created")); } result.Creator = manifest.DocumentElement.GetAttribute("creator"); result.Description = manifest.DocumentElement.GetAttribute("description"); if (manifest.DocumentElement.HasAttribute("modified")) { result.Modified = DateTime.Parse(manifest.DocumentElement.GetAttribute("modified")); } result.Version = manifest.DocumentElement.GetAttribute("revision"); result.Title = manifest.DocumentElement.GetAttribute("title"); if (manifest.DocumentElement.HasAttribute("website")) { result.Website = new Uri(manifest.DocumentElement.GetAttribute("website")); } foreach (var child in manifest.DocumentElement.ChildNodes.OfType <XmlElement>()) { if (child.LocalName == "Item") { scripts.Add(InstallItem.FromScript(child)); } else { currPath = child.GetAttribute("path"); paths = string.IsNullOrEmpty(currPath) ? Enumerable.Empty <string>() : (currPath == "*" ? GetPaths() : Enumerable.Repeat(currPath, 1)); if (currPath == "*") { result.DependencySorted = false; } var reportXmlPaths = new HashSet <string>(paths .Where(p => p.EndsWith(".xslt", StringComparison.OrdinalIgnoreCase)) .Select(p => p + ".xml"), StringComparer.OrdinalIgnoreCase); foreach (var path in paths .Where(p => !reportXmlPaths.Contains(p))) { if (path.EndsWith(".xslt", StringComparison.OrdinalIgnoreCase)) { doc = ReadReport(path); } else { try { doc = new XmlDocument(manifest.NameTable); var stream = GetExistingStream(path); if (stream == null) { throw new FileNotFoundException("A referenced file was not found in the package", path); } using (stream) using (var reader = new StreamReader(stream)) { var text = reader.ReadToEnd(); doc.LoadXml(text); } } catch (Exception ex) when(ex is XmlException || ex is IOException) { throw new InvalidOperationException($"Error reading the file {path}: {ex.Message}", ex); } } var items = doc.DocumentElement.LocalName == "Item" ? new[] { doc.DocumentElement } : doc.DocumentElement.Elements("Item"); foreach (var item in items) { scripts.Add(InstallItem.FromScript(item, path)); } } } } result.Lines = scripts; result.Lines.CleanKeyedNames(); return(result); }
private static bool TryReadPackage(IPackageFile manifestFile, IPackage package, ILogger logger, out InstallScript installScript) { installScript = new InstallScript(); var result = true; var scripts = new List <InstallItem>(); var manifest = new XmlDocument(); using (var manifestStream = manifestFile.Open()) manifest.Load(manifestStream); if (manifest.DocumentElement.HasAttribute("created")) { installScript.Created = DateTime.Parse(manifest.DocumentElement.GetAttribute("created")); } installScript.Creator = manifest.DocumentElement.GetAttribute("creator"); installScript.Description = manifest.DocumentElement.GetAttribute("description"); if (manifest.DocumentElement.HasAttribute("modified")) { installScript.Modified = DateTime.Parse(manifest.DocumentElement.GetAttribute("modified")); } installScript.Version = manifest.DocumentElement.GetAttribute("revision"); installScript.Title = manifest.DocumentElement.GetAttribute("title"); if (manifest.DocumentElement.HasAttribute("website")) { installScript.Website = new Uri(manifest.DocumentElement.GetAttribute("website")); } foreach (var child in manifest.DocumentElement.ChildNodes.OfType <XmlElement>()) { if (child.LocalName == "Item") { scripts.Add(InstallItem.FromScript(child)); } else { var currPath = child.GetAttribute("path"); var files = Enumerable.Empty <IPackageFile>(); if (currPath == "*") { files = package.Files(); installScript.DependencySorted = false; } else if (!string.IsNullOrEmpty(currPath)) { if (package.TryAccessFile(currPath, false, out var file)) { files = new[] { file }; } else { result = false; logger.LogError("The file {Path} is referenced in the manifest, but not found in the package.", currPath); continue; } } var reportXmlPaths = new HashSet <string>(files .Where(f => f.Path.EndsWith(".xslt", StringComparison.OrdinalIgnoreCase)) .Select(f => f.Path + ".xml"), StringComparer.OrdinalIgnoreCase); foreach (var file in files .Where(f => !reportXmlPaths.Contains(f.Path))) { try { var doc = new XmlDocument(manifest.NameTable); using (var writer = doc.CreateNavigator().AppendChild()) file.WriteAml(package, writer); var items = doc.DocumentElement.LocalName == "Item" ? new[] { doc.DocumentElement } : doc.DocumentElement.Elements("Item"); foreach (var item in items) { scripts.Add(InstallItem.FromScript(item, file.Path)); } } catch (XmlException ex) { result = false; logger.LogError(ex, "The AML script at {Path} is malformed", file.Path); } catch (Exception ex) { ex.Data["path"] = file.Path; throw; } } } } installScript.Lines = scripts; result = CleanKeyedNames(installScript.Lines, logger) || result; return(result); }