public async Task <InstallScript> ConvertManifestXml(XmlDocument doc, string name) { ExportProcessor.EnsureSystemData(_conn, ref _itemTypes); foreach (var elem in doc.ElementsByXPath("//Item[@action='add']").ToList()) { elem.SetAttribute("action", "merge"); } ItemType itemType; foreach (var elem in doc.ElementsByXPath("//Item[@type and @id]").ToList()) { if (_itemTypes.TryGetValue(elem.Attribute("type", "").ToLowerInvariant(), out itemType) && itemType.IsVersionable) { elem.SetAttribute(XmlFlags.Attr_ConfigId, elem.Attribute("id")); elem.SetAttribute("where", string.Format("[{0}].[config_id] = '{1}'", itemType.Name.Replace(' ', '_'), elem.Attribute("id"))); elem.RemoveAttribute("id"); } } var result = new InstallScript() { Title = name }; await _exportTools.Export(result, doc).ConfigureAwait(false); return(result); }
public void Write(InstallScript script) { using (var xml = XmlTextWriter.Create(_path, _settings)) { xml.WriteStartElement("imports"); xml.WriteStartElement("package"); xml.WriteAttributeString("name", script.Title); if (script.Title.StartsWith("com.aras.innovator")) { if (script.Title.StartsWith("com.aras.innovator.solution.")) { _baseFolderPath = Utils.CleanFileName(script.Title).Substring(28).Replace('.', '\\') + "\\Import"; xml.WriteAttributeString("path", _baseFolderPath); } else { _baseFolderPath = Utils.CleanFileName(script.Title).Replace('.', '\\'); xml.WriteAttributeString("path", ".\\"); } } else { _baseFolderPath = Utils.CleanFileName(script.Title) + "\\Import"; xml.WriteAttributeString("path", _baseFolderPath); } xml.WriteEndElement(); xml.WriteEndElement(); } _baseFolderPath = Path.Combine(Path.GetDirectoryName(_path), _baseFolderPath); XmlWriter writer; var existingPaths = new HashSet <string>(); string newPath; foreach (var line in script.Lines.Where(l => l.Type == InstallType.Create || l.Type == InstallType.Script)) { newPath = line.FilePath(existingPaths); writer = GetWriter(newPath); try { writer.WriteStartElement("AML"); line.Script.WriteTo(writer); writer.WriteEndElement(); writer.Flush(); } finally { writer.Close(); } existingPaths.Add(newPath); } }
public async Task Initialize(InstallScript script) { _script = script; _lines = (_script.DependencySorted ? (_script.Lines ?? Enumerable.Empty <InstallItem>()) : (await _sorter.SortByDependencies(script.Lines, _conn).ConfigureAwait(false)) .Where(l => l.Type != InstallType.DependencyCheck) ).Where(l => l.Script != null && l.Type != InstallType.Warning).ToList(); _currLine = -1; }
public void Write(InstallScript script) { using (var xml = XmlTextWriter.Create(_path, _settings)) { xml.WriteStartElement("imports"); xml.WriteStartElement("package"); xml.WriteAttributeString("name", script.Title); if (script.Title.StartsWith("com.aras.innovator")) { if (script.Title.StartsWith("com.aras.innovator.solution.")) { _baseFolderPath = Utils.CleanFileName(script.Title).Substring(28).Replace('.', '\\') + "\\Import"; xml.WriteAttributeString("path", _baseFolderPath); } else { _baseFolderPath = Utils.CleanFileName(script.Title).Replace('.', '\\'); xml.WriteAttributeString("path", ".\\"); } } else { _baseFolderPath = Utils.CleanFileName(script.Title) + "\\Import"; xml.WriteAttributeString("path", _baseFolderPath); } xml.WriteEndElement(); xml.WriteEndElement(); } _baseFolderPath = Path.Combine(Path.GetDirectoryName(_path), _baseFolderPath); XmlWriter writer; var existingPaths = new HashSet<string>(); string newPath; foreach (var line in script.Lines.Where(l => l.Type == InstallType.Create || l.Type == InstallType.Script)) { newPath = line.FilePath(existingPaths); writer = GetWriter(newPath); try { writer.WriteStartElement("AML"); line.Script.WriteTo(writer); writer.WriteEndElement(); writer.Flush(); } finally { writer.Close(); } existingPaths.Add(newPath); } }
public async Task Initialize(InstallScript script) { _log.Length = 0; _script = script; _lines = (_script.DependencySorted ? _script.Lines : (await ExportProcessor.SortByDependencies(script.Lines, _conn)) .Where(l => l.Type != InstallType.DependencyCheck) ).Where(l => l.Script != null && l.Type != InstallType.Warning).ToList(); _currLine = -1; }
public override void Write(InstallScript script) { _package.PackageProperties.Created = script.Created; _package.PackageProperties.Creator = script.Creator; _package.PackageProperties.Description = script.Description; _package.PackageProperties.Modified = script.Modified; _package.PackageProperties.Revision = script.Version; _package.PackageProperties.Title = script.Title; if (script.Website != null) _package.PackageProperties.Identifier = script.Website.ToString(); base.Write(script); }
public static PackageMetadataProvider FromScript(InstallScript script) { var metadata = new PackageMetadataProvider() { Title = script.Title }; metadata.AddRange(script.Lines .Where(l => l.Type != InstallType.DependencyCheck && l.Type != InstallType.Warning) .Select(l => ElementFactory.Local.FromXml(l.Script).AssertItem())); return(metadata); }
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 override void Write(InstallScript script) { _package.PackageProperties.Created = script.Created; _package.PackageProperties.Creator = script.Creator; _package.PackageProperties.Description = script.Description; _package.PackageProperties.Modified = script.Modified; _package.PackageProperties.Revision = script.Version; _package.PackageProperties.Title = script.Title; if (script.Website != null) { _package.PackageProperties.Identifier = script.Website.ToString(); } base.Write(script); }
public static bool TryRead(this IPackage package, ILogger logger, out InstallScript installScript) { using (SharedUtils.StartActivity("Package.TryRead", "Read an Innovator Package from disk")) { var manifestFile = package.Manifest(false); if (manifestFile.Path.EndsWith(".mf", StringComparison.OrdinalIgnoreCase)) { return(TryReadLegacyManifest(manifestFile, package, logger, out installScript)); } else { return(TryReadPackage(manifestFile, package, logger, out installScript)); } } }
public InstallScript ConvertManifestXml(XmlDocument doc, string name) { ExportProcessor.EnsureSystemData(_conn, ref _itemTypes); foreach (var elem in doc.ElementsByXPath("//Item[@action='add']").ToList()) { elem.SetAttribute("action", "merge"); } ItemType itemType; foreach (var elem in doc.ElementsByXPath("//Item[@type and @id]").ToList()) { if (_itemTypes.TryGetValue(elem.Attribute("type", "").ToLowerInvariant(), out itemType) && itemType.IsVersionable) { elem.SetAttribute(XmlFlags.Attr_ConfigId, elem.Attribute("id")); elem.SetAttribute("where", string.Format("[{0}].[config_id] = '{1}'", itemType.Name.Replace(' ', '_'), elem.Attribute("id"))); elem.RemoveAttribute("id"); } } var result = new InstallScript(); result.Title = name; _exportTools.Export(result, doc); return result; }
public bool Write(InstallScript script, Func <string, DatabasePackageAction> errorHandler = null, Action <int, string> reportProgress = null) { var cont = true; var typeGroups = from l in script.Lines where l.Type == InstallType.Create group l by l.Reference.Type into typeGroup select typeGroup; var cnt = typeGroups.Count(); var idx = 0; var packageGroups = new HashSet <string>(); string currPackageId = null; while (cont) { IEnumerable <IReadOnlyItem> elements; foreach (var typeGroup in typeGroups) { if (reportProgress != null) { reportProgress((int)(idx * 50.0 / cnt), string.Format("Checking for existing package elements ({0} of {1}) ", idx + 1, cnt)); } if (typeGroup.First().Reference.Unique.IsGuid()) { elements = _conn.Apply("<Item type=\"PackageElement\" action=\"get\" select=\"element_id,name,source_id\"><element_type>" + typeGroup.Key + "</element_type><element_id condition=\"in\">'" + typeGroup.Select(i => i.Reference.Unique).Aggregate((p, c) => p + "','" + c) + "'</element_id></Item>").Items(); } else { elements = _conn.Apply("<Item type=\"PackageElement\" action=\"get\" select=\"element_id,name,source_id\"><element_type>" + typeGroup.Key + "</element_type><element_id condition=\"in\">(select id from innovator.[" + typeGroup.Key.Replace(' ', '_') + "] where " + typeGroup.Select(i => i.Reference.Unique).Aggregate((p, c) => p + " or " + c) + ")</element_id></Item>").Items(); } packageGroups.UnionWith(elements.Select(e => e.SourceId().Value)); idx++; } var packages = _conn.Apply("<Item type=\"PackageDefinition\" action=\"get\" select=\"name\"><id condition=\"in\">(select SOURCE_ID FROM innovator.PACKAGEGROUP where id in ('" + packageGroups.Aggregate((p, c) => p + "','" + c) + "'))</id></Item>").Items(); currPackageId = packages.Where(p => p.Property("name").Value == script.Title).SingleOrDefault().Id(); cont = false; if (packages.Any(p => p.Property("name").Value != script.Title)) { if (errorHandler != null) { var packageList = (from p in packages where p.Property("name").Value != script.Title select p.Property("name").Value) .Aggregate((p, c) => p + ", " + c); switch (errorHandler("The package cannot be created because one or more elements exist in the packages: " + packageList)) { case DatabasePackageAction.TryAgain: cont = true; break; case DatabasePackageAction.RemoveElementsFromPackages: foreach (var typeGroup in typeGroups) { if (reportProgress != null) { reportProgress((int)(idx * 50.0 / cnt), string.Format("Removing package elements ({0} of {1}) ", idx + 1, cnt)); } if (typeGroup.First().Reference.Unique.IsGuid()) { elements = _conn.Apply("<Item type=\"PackageElement\" action=\"purge\" where=\"[PackageElement].[element_type] = '" + typeGroup.Key + "' and [PackageElement].[element_id] in ('" + typeGroup.Select(i => i.Reference.Unique).Aggregate((p, c) => p + "','" + c) + "')\" />").Items(); } else { elements = _conn.Apply("<Item type=\"PackageElement\" action=\"purge\" where=\"[PackageElement].[element_type] = '" + typeGroup.Key + "' and [PackageElement].[element_id] in (select id from innovator.[" + typeGroup.Key.Replace(' ', '_') + "] where " + typeGroup.Select(i => i.Reference.Unique).Aggregate((p, c) => p + " or " + c) + ")\" />").Items(); } idx++; } break; default: return(false); } } else { return(false); } } } // Try one more time to get the package if (string.IsNullOrEmpty(currPackageId)) { var packages = _conn.Apply("<Item type=\"PackageDefinition\" action=\"get\" select=\"name\"><name>" + script.Title + "</name></Item>"); currPackageId = packages.AssertItem().Id(); } // Add the package if (string.IsNullOrEmpty(currPackageId)) { var packages = _conn.Apply("<Item type=\"PackageDefinition\" action=\"add\" ><name>" + script.Title + "</name></Item>", true); currPackageId = packages.AssertItem().Id(); } string groupId; foreach (var typeGroup in typeGroups) { if (reportProgress != null) { reportProgress((int)(50 + idx * 50.0 / cnt), string.Format("Adding package elements of type ({0} of {1}) ", idx + 1, cnt)); } groupId = _conn.Apply("<Item type=\"PackageGroup\" action=\"merge\" where=\"[PackageGroup].[source_id] = '" + currPackageId + "' and [PackageGroup].[name] = '" + typeGroup.Key + "'\"><name>" + typeGroup.Key + "</name></Item>", true).AssertItem().Id(); foreach (var elem in typeGroup) { _conn.Apply("<Item type=\"PackageElement\" action=\"merge\" where=\"[PackageElement].[source_id] = '" + groupId + "' and [PackageElement].[element_id] = '" + (elem.InstalledId ?? elem.Reference.Unique) + "'\">" + "<element_type>" + typeGroup.Key + "</element_type>" + "<element_id>" + (elem.InstalledId ?? elem.Reference.Unique) + "</element_id>" + "<source_id>" + groupId + "</source_id>" + "<name>" + elem.Reference.KeyedName + "</name></Item>").AssertNoError(); } idx++; } return(true); }
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); }
public virtual void Write(InstallScript script) { string newPath; var existingPaths = new HashSet <string>(); // Record the import order var settings = new XmlWriterSettings() { OmitXmlDeclaration = true, Indent = true, IndentChars = " " }; using (var manifestStream = GetNewStream(null)) { using (var manifestWriter = XmlWriter.Create(manifestStream, settings)) { manifestWriter.WriteStartElement("Import"); if (script.Created.HasValue) { manifestWriter.WriteAttributeString("created", script.Created.Value.ToString("s")); } manifestWriter.WriteAttributeString("creator", script.Creator); manifestWriter.WriteAttributeString("description", script.Description); if (script.Modified.HasValue) { manifestWriter.WriteAttributeString("modified", script.Modified.Value.ToString("s")); } manifestWriter.WriteAttributeString("revision", script.Version); manifestWriter.WriteAttributeString("title", script.Title); if (script.Website != null) { manifestWriter.WriteAttributeString("website", script.Website.ToString()); } foreach (var line in script.Lines) { if (line.Type == InstallType.Warning) { // Do nothing } else if (line.Type == InstallType.DependencyCheck) { line.Script.WriteTo(manifestWriter); } else { if (line.Reference.Type == "Report" && line.Type != InstallType.Script) { newPath = line.FilePath(existingPaths, ".xslt"); WriteReport(line, newPath); } else { newPath = line.FilePath(existingPaths); using (var stream = GetNewStream(newPath)) { using (var writer = GetWriter(stream)) { writer.WriteStartElement("AML"); line.Script.WriteTo(writer); writer.WriteEndElement(); } } } existingPaths.Add(newPath); manifestWriter.WriteStartElement("Path"); manifestWriter.WriteAttributeString("path", newPath); manifestWriter.WriteEndElement(); } } manifestWriter.WriteEndElement(); } } }
public bool Write(InstallScript script, Func<string, DatabasePackageAction> errorHandler = null, Action<int, string> reportProgress = null) { var cont = true; var typeGroups = from l in script.Lines where l.Type == InstallType.Create group l by l.Reference.Type into typeGroup select typeGroup; var cnt = typeGroups.Count(); var idx = 0; var packageGroups = new HashSet<string>(); string currPackageId = null; while (cont) { IEnumerable<IReadOnlyItem> elements; foreach (var typeGroup in typeGroups) { if (reportProgress != null) reportProgress((int)(idx * 50.0 / cnt), string.Format("Checking for existing package elements ({0} of {1}) ", idx + 1, cnt)); if (typeGroup.First().Reference.Unique.IsGuid()) { elements = _conn.Apply("<Item type=\"PackageElement\" action=\"get\" select=\"element_id,name,source_id\"><element_type>" + typeGroup.Key + "</element_type><element_id condition=\"in\">'" + typeGroup.Select(i => i.Reference.Unique).Aggregate((p, c) => p + "','" + c) + "'</element_id></Item>").Items(); } else { elements = _conn.Apply("<Item type=\"PackageElement\" action=\"get\" select=\"element_id,name,source_id\"><element_type>" + typeGroup.Key + "</element_type><element_id condition=\"in\">(select id from innovator.[" + typeGroup.Key.Replace(' ', '_') + "] where " + typeGroup.Select(i => i.Reference.Unique).Aggregate((p, c) => p + " or " + c) + ")</element_id></Item>").Items(); } packageGroups.UnionWith(elements.Select(e => e.SourceId().Value)); idx++; } var packages = _conn.Apply("<Item type=\"PackageDefinition\" action=\"get\" select=\"name\"><id condition=\"in\">(select SOURCE_ID FROM innovator.PACKAGEGROUP where id in ('" + packageGroups.Aggregate((p, c) => p + "','" + c) + "'))</id></Item>").Items(); currPackageId = packages.Where(p => p.Property("name").Value == script.Title).SingleOrDefault().Id(); cont = false; if (packages.Any(p => p.Property("name").Value != script.Title)) { if (errorHandler != null) { var packageList = (from p in packages where p.Property("name").Value != script.Title select p.Property("name").Value) .Aggregate((p, c) => p + ", " + c); switch (errorHandler("The package cannot be created because one or more elements exist in the packages: " + packageList)) { case DatabasePackageAction.TryAgain: cont = true; break; case DatabasePackageAction.RemoveElementsFromPackages: foreach (var typeGroup in typeGroups) { if (reportProgress != null) reportProgress((int)(idx * 50.0 / cnt), string.Format("Removing package elements ({0} of {1}) ", idx + 1, cnt)); if (typeGroup.First().Reference.Unique.IsGuid()) { elements = _conn.Apply("<Item type=\"PackageElement\" action=\"purge\" where=\"[PackageElement].[element_type] = '" + typeGroup.Key + "' and [PackageElement].[element_id] in ('" + typeGroup.Select(i => i.Reference.Unique).Aggregate((p, c) => p + "','" + c) + "')\" />").Items(); } else { elements = _conn.Apply("<Item type=\"PackageElement\" action=\"purge\" where=\"[PackageElement].[element_type] = '" + typeGroup.Key + "' and [PackageElement].[element_id] in (select id from innovator.[" + typeGroup.Key.Replace(' ', '_') + "] where " + typeGroup.Select(i => i.Reference.Unique).Aggregate((p, c) => p + " or " + c) + ")\" />").Items(); } idx++; } break; default: return false; } } else { return false; } } } // Try one more time to get the package if (string.IsNullOrEmpty(currPackageId)) { var packages = _conn.Apply("<Item type=\"PackageDefinition\" action=\"get\" select=\"name\"><name>" + script.Title + "</name></Item>"); currPackageId = packages.AssertItem().Id(); } // Add the package if (string.IsNullOrEmpty(currPackageId)) { var packages = _conn.Apply("<Item type=\"PackageDefinition\" action=\"add\" ><name>" + script.Title + "</name></Item>", true); currPackageId = packages.AssertItem().Id(); } string groupId; foreach (var typeGroup in typeGroups) { if (reportProgress != null) reportProgress((int)(50 + idx * 50.0 / cnt), string.Format("Adding package elements of type ({0} of {1}) ", idx + 1, cnt)); groupId = _conn.Apply("<Item type=\"PackageGroup\" action=\"merge\" where=\"[PackageGroup].[source_id] = '" + currPackageId + "' and [PackageGroup].[name] = '" + typeGroup.Key + "'\"><name>" + typeGroup.Key + "</name></Item>", true).AssertItem().Id(); foreach (var elem in typeGroup) { _conn.Apply("<Item type=\"PackageElement\" action=\"merge\" where=\"[PackageElement].[source_id] = '" + groupId + "' and [PackageElement].[element_id] = '" + (elem.InstalledId ?? elem.Reference.Unique) + "'\">" + "<element_type>" + typeGroup.Key + "</element_type>" + "<element_id>" + (elem.InstalledId ?? elem.Reference.Unique) + "</element_id>" + "<source_id>" + groupId + "</source_id>" + "<name>" + elem.Reference.KeyedName + "</name></Item>").AssertNoError(); } idx++; } return true; }
/// <summary> /// Fill an install script with exports of the items in the XmlDocument /// </summary> public void Export(InstallScript script, XmlDocument doc , HashSet<ItemReference> warnings = null, bool checkDependencies = true) { try { _metadata.Wait(); FixPolyItemReferences(doc); FixPolyItemListReferences(doc); FixForeignProperties(doc); FixCyclicalWorkflowLifeCycleRefs(doc); FixCyclicalWorkflowItemTypeRefs(doc); RemoveEmptyRelationshipTags(doc); RemoveVersionableRelIds(doc); SortRelationshipTags(doc); MoveFormRefsInline(doc, (script.Lines ?? Enumerable.Empty<InstallItem>()).Where(l => l.Type == InstallType.Create || l.Type == InstallType.Script)); // Sort the resulting nodes as appropriate ReportProgress(98, "Sorting the results"); XmlNode itemNode = doc.DocumentElement; while (itemNode != null && itemNode.LocalName != "Item") itemNode = itemNode.Elements().FirstOrDefault(); if (itemNode == null) throw new InvalidOperationException(); //TODO: Give better error information here (e.g. interpret an error item if present) IEnumerable<InstallItem> results = null; if (checkDependencies) { int loops = 0; CycleState state = CycleState.ResolvedCycle; while (loops < 10 && state == CycleState.ResolvedCycle) { // Only reset if this is not a rescan if (script.Lines != null) { _dependAnalyzer.Reset(from l in script.Lines where l.Type == InstallType.Create || l.Type == InstallType.Script select l.Reference); } else { _dependAnalyzer.Reset(); } var newInstallItems = (from e in itemNode.ParentNode.Elements() where e.LocalName == "Item" && e.HasAttribute("type") select InstallItem.FromScript(e)).ToList(); foreach (var newInstallItem in newInstallItems) { _dependAnalyzer.GatherDependencies(newInstallItem.Script, newInstallItem.Reference, newInstallItem.CoreDependencies); } _dependAnalyzer.CleanDependencies(); results = GetDependencyList(_dependAnalyzer , (script.Lines ?? Enumerable.Empty<InstallItem>()).Concat(newInstallItems) , out state).ToList(); loops++; } } else { var newInstallItems = (from e in itemNode.ParentNode.Elements() where e.LocalName == "Item" && e.HasAttribute("type") select InstallItem.FromScript(e)).ToList(); //foreach (var item in newInstallItems) //{ // item.Script.SetAttribute(XmlFlags.Attr_DependenciesAnalyzed, "1"); //} results = (script.Lines ?? Enumerable.Empty<InstallItem>()) .Concat(newInstallItems).ToList(); } if (warnings == null) warnings = new HashSet<ItemReference>(); warnings.ExceptWith(results.Select(r => r.Reference)); script.Lines = warnings.Select(w => InstallItem.FromWarning(w, w.KeyedName)) .Concat(results.Where(r => r.Type == InstallType.DependencyCheck || r.Type == InstallType.Warning)) .OrderBy(r => r.Name) .ToList() .Concat(results.Where(r => r.Type != InstallType.DependencyCheck && r.Type != InstallType.Warning)) .ToList(); RemoveInjectedDependencies(doc); this.OnActionComplete(new ActionCompleteEventArgs()); } catch (Exception ex) { this.OnActionComplete(new ActionCompleteEventArgs() { Exception = ex }); } }
public virtual void Write(InstallScript script) { string newPath; var existingPaths = new HashSet<string>(); // Record the import order var settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; settings.Indent = true; settings.IndentChars = " "; using (var manifestStream = GetNewStream(null)) { using (var manifestWriter = XmlWriter.Create(manifestStream, settings)) { manifestWriter.WriteStartElement("Import"); if (script.Created.HasValue) manifestWriter.WriteAttributeString("created", script.Created.Value.ToString("s")); manifestWriter.WriteAttributeString("creator", script.Creator); manifestWriter.WriteAttributeString("description", script.Description); if (script.Modified.HasValue) manifestWriter.WriteAttributeString("modified", script.Modified.Value.ToString("s")); manifestWriter.WriteAttributeString("revision", script.Version); manifestWriter.WriteAttributeString("title", script.Title); if (script.Website != null) manifestWriter.WriteAttributeString("website", script.Website.ToString()); foreach (var line in script.Lines) { if (line.Type == InstallType.Warning) { // Do nothing } else if (line.Type == InstallType.DependencyCheck) { line.Script.WriteTo(manifestWriter); } else { if (line.Reference.Type == "Report" && line.Type != InstallType.Script) { newPath = line.FilePath(existingPaths, ".xslt"); WriteReport(line, newPath); } else { newPath = line.FilePath(existingPaths); using (var stream = GetNewStream(newPath)) { using (var writer = GetWriter(stream)) { writer.WriteStartElement("AML"); line.Script.WriteTo(writer); writer.WriteEndElement(); } } } existingPaths.Add(newPath); manifestWriter.WriteStartElement("Path"); manifestWriter.WriteAttributeString("path", newPath); manifestWriter.WriteEndElement(); } } manifestWriter.WriteEndElement(); } } }
/// <summary> /// Removes all the properties that reference the given item /// </summary> public void RemoveReferences(InstallScript script, ItemReference itemRef) { var nodes = _dependAnalyzer.RemoveDependencyReferences(itemRef); script.Lines = script.Lines.Where(l => !(l.Type == InstallType.Create || l.Type == InstallType.Script) || !nodes.Contains(l.Script)).ToList(); }
public static IEnumerable<InstallItemDiff> GetDiffs(InstallScript left, InstallScript right) { return GetDiffs(left.Lines, right.Lines); }
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); }
/// <summary> /// Fill an install script with exports of the specified items /// </summary> public void Export(InstallScript script, IEnumerable<ItemReference> items , bool checkDependencies = true) { ReportProgress(0, "Loading system data"); _metadata.Wait(); var uniqueItems = new HashSet<ItemReference>(items); if (script.Lines != null) uniqueItems.ExceptWith(script.Lines.Select(l => l.Reference)); var itemList = uniqueItems.ToList(); ItemType metaData; var outputDoc = new XmlDocument(); outputDoc.AppendChild(outputDoc.CreateElement("AML")); XmlElement queryElem; var whereClause = new StringBuilder(); ConvertPolyItemReferencesToActualType(itemList); string itemType; var groups = itemList.PagedGroupBy(i => new { Type = i.Type, Levels = i.Levels }, 25); foreach (var typeItems in groups) { whereClause.Length = 0; itemType = typeItems.Key.Type; // For versionable item types, get the latest generation if (_metadata.ItemTypeByName(typeItems.Key.Type.ToLowerInvariant(), out metaData) && metaData.IsVersionable) { queryElem = outputDoc.CreateElement("Item") .Attr("action", "get") .Attr("type", typeItems.Key.Type); if (typeItems.Any(i => i.Unique.IsGuid())) { whereClause.Append("[") .Append(typeItems.Key.Type.Replace(' ', '_')) .Append("].[config_id] in (select config_id from innovator.[") .Append(typeItems.Key.Type.Replace(' ', '_')) .Append("] where id in ('") .Append(typeItems.Where(i => i.Unique.IsGuid()).Select(i => i.Unique).Aggregate((p, c) => p + "','" + c)) .Append("'))"); } if (typeItems.Any(i => !i.Unique.IsGuid())) { whereClause.AppendSeparator(" or ", typeItems.Where(i => !i.Unique.IsGuid()).Select(i => i.Unique).Aggregate((p, c) => p + " or " + c)); } queryElem.SetAttribute("where", whereClause.ToString()); } else if (typeItems.Key.Type == "ItemType") { // Make sure relationship item types aren't accidentally added queryElem = outputDoc.CreateElement("Item").Attr("action", "get").Attr("type", typeItems.Key.Type); if (typeItems.Any(i => i.Unique.IsGuid())) { whereClause.Append("[ItemType].[id] in ('") .Append(typeItems.Where(i => i.Unique.IsGuid()).Select(i => i.Unique).Aggregate((p, c) => p + "','" + c)) .Append("')"); } if (typeItems.Any(i => !i.Unique.IsGuid())) { whereClause.AppendSeparator(" or ", typeItems.Where(i => !i.Unique.IsGuid()).Select(i => i.Unique).Aggregate((p, c) => p + " or " + c)); } queryElem.SetAttribute("where", "(" + whereClause.ToString() + ") and [ItemType].[is_relationship] = '0'"); SetQueryAttributes(queryElem, typeItems.Key.Type, typeItems.Key.Levels, typeItems); outputDoc.DocumentElement.AppendChild(queryElem); queryElem = outputDoc.CreateElement("Item") .Attr("action", "get") .Attr("type", "RelationshipType") .Attr("where", "[RelationshipType].[relationship_id] in (select id from innovator.[ItemType] where " + whereClause.ToString() + ")"); itemType = "RelationshipType"; } else if (typeItems.Key.Type == "List") { // Filter out auto-generated lists for polymorphic item types queryElem = outputDoc.CreateElement("Item") .Attr("action", "get") .Attr("type", typeItems.Key.Type); if (typeItems.Any(i => i.Unique.IsGuid())) { whereClause.Append("[List].[id] in ('") .Append(typeItems.Where(i => i.Unique.IsGuid()).Select(i => i.Unique).Aggregate((p, c) => p + "','" + c)) .Append("')"); } if (typeItems.Any(i => !i.Unique.IsGuid())) { whereClause.AppendSeparator(" or ", typeItems.Where(i => !i.Unique.IsGuid()).Select(i => i.Unique).Aggregate((p, c) => p + " or " + c)); } queryElem.SetAttribute("where", "(" + whereClause.ToString() + @") and not [List].[id] in ( select l.id from innovator.LIST l inner join innovator.PROPERTY p on l.id = p.DATA_SOURCE and p.name = 'itemtype' inner join innovator.ITEMTYPE it on it.id = p.SOURCE_ID and it.IMPLEMENTATION_TYPE = 'polymorphic' )"); } else { queryElem = outputDoc.CreateElement("Item") .Attr("action", "get") .Attr("type", typeItems.Key.Type); if (typeItems.Any(i => i.Unique.IsGuid())) { whereClause.Append("[") .Append(typeItems.Key.Type.Replace(' ', '_')) .Append("].[id] in ('") .Append(typeItems.Where(i => i.Unique.IsGuid()).Select(i => i.Unique).Aggregate((p, c) => p + "','" + c)) .Append("')"); } if (typeItems.Any(i => !i.Unique.IsGuid())) { whereClause.AppendSeparator(" or ", typeItems.Where(i => !i.Unique.IsGuid()).Select(i => i.Unique).Aggregate((p, c) => p + " or " + c)); } queryElem.SetAttribute("where", whereClause.ToString()); } SetQueryAttributes(queryElem, itemType, typeItems.Key.Levels, typeItems); outputDoc.DocumentElement.AppendChild(queryElem); } try { ReportProgress(0, "Loading system data"); FixFederatedRelationships(outputDoc.DocumentElement); var result = ExecuteExportQuery(ref outputDoc, items); // Add warnings for embedded relationships var warnings = new HashSet<ItemReference>(); ItemReference warning; foreach (var relType in result.ElementsByXPath("/Result/Item[@type='ItemType']/Relationships/Item[@type='RelationshipType']")) { warning = ItemReference.FromFullItem(relType as XmlElement, true); warning.KeyedName = "* Possible missing relationship: " + warning.KeyedName; warnings.Add(warning); } //RemoveRelatedItems(result, items); //CleanUpSystemProps(result.DocumentElement.Elements(), items, false); FixPolyItemReferences(result); FloatVersionableRefs(result); var doc = TransformResults(ref result); NormalizeClassStructure(doc); FixFormFieldsPointingToSystemProperties(doc); ExpandSystemIdentities(doc); RemoveVersionableRelIds(doc); //TODO: Replace references to poly item lists Export(script, doc, warnings, checkDependencies); CleanUpSystemProps(doc.DocumentElement.Elements(), items.ToDictionary(i => i), true); ConvertFloatProps(doc); RemoveKeyedNameAttributes(doc.DocumentElement); if (string.IsNullOrWhiteSpace(script.Title)) { if (script.Lines.Count(l => l.Type == InstallType.Create) == 1) { script.Title = script.Lines.Single(l => l.Type == InstallType.Create).Reference.ToString(); } else if (items.Count() == 1) { script.Title = items.First().ToString(); } } // Rename the FileTypes and identities to make comparing easier ItemReference newRef; foreach (var line in script.Lines.Where(l => l.Reference.Type == "FileType" || l.Reference.Type == "Identity")) { newRef = ItemReference.FromFullItem(line.Script.DescendantsAndSelf(e => e.LocalName == "Item").First(), true); if (newRef.Type == line.Reference.Type && !String.Equals(newRef.KeyedName, line.Reference.KeyedName)) { line.Reference.KeyedName = newRef.KeyedName; } } } catch (Exception ex) { this.OnActionComplete(new ActionCompleteEventArgs() { Exception = ex }); } }
public virtual void Write(InstallScript script) { var existingPaths = new HashSet <string>(); // Record the import order var settings = new XmlWriterSettings() { OmitXmlDeclaration = true, Indent = true, IndentChars = " " }; using (var manifestStream = GetNewStream(null)) { using (var manifestWriter = XmlWriter.Create(manifestStream, settings)) { manifestWriter.WriteStartElement("Import"); if (script.Created.HasValue) { manifestWriter.WriteAttributeString("created", script.Created.Value.ToString("s")); } manifestWriter.WriteAttributeString("creator", script.Creator); manifestWriter.WriteAttributeString("description", script.Description); if (script.Modified.HasValue) { manifestWriter.WriteAttributeString("modified", script.Modified.Value.ToString("s")); } manifestWriter.WriteAttributeString("revision", script.Version); manifestWriter.WriteAttributeString("title", script.Title); if (script.Website != null) { manifestWriter.WriteAttributeString("website", script.Website.ToString()); } // Achieve consistent file names regardless of the ordering. foreach (var line in script.Lines) { line.Path = GetPath(line, existingPaths); } existingPaths.UnionWith(script.Lines.Select(l => l.Path)); foreach (var group in script.Lines.GroupBy(l => l.Path).Where(g => g.Skip(1).Any())) { foreach (var line in group.OrderBy(l => l.Reference.Unique).Skip(1)) { line.Path = GetPath(line, existingPaths); } } foreach (var line in script.Lines) { if (line.Type == InstallType.Warning) { // Do nothing } else if (line.Type == InstallType.DependencyCheck) { line.Script.WriteTo(manifestWriter); } else { manifestWriter.WriteStartElement("Path"); manifestWriter.WriteAttributeString("path", line.Path); manifestWriter.WriteEndElement(); } } manifestWriter.WriteEndElement(); Action <InstallItem> writeFunc = line => { if (line.Reference.Type == "Report" && line.Type != InstallType.Script) { WriteReport(line, line.Path); } else { using (var stream = GetNewStream(line.Path)) { using (var writer = GetWriter(stream)) { writer.WriteStartElement("AML"); line.Script.WriteTo(writer); writer.WriteEndElement(); } } } }; var scriptLines = script.Lines.Where(l => l.Type != InstallType.Warning && l.Type != InstallType.DependencyCheck); if (_parallel) { Parallel.ForEach(scriptLines, writeFunc); } else { foreach (var line in scriptLines) { writeFunc(line); } } } } }
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); doc.Load(GetExistingStream(path)); } foreach (var item in doc.DocumentElement.Elements("Item")) { scripts.Add(InstallItem.FromScript(item)); } } } } result.Lines = scripts; result.Lines.CleanKeyedNames(); return result; }
public static IEnumerable <InstallItemDiff> GetDiffs(InstallScript left, InstallScript right) { return(GetDiffs(left.Lines, right.Lines)); }
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); }