예제 #1
0
        private static bool CleanKeyedNames(IEnumerable <InstallItem> lines, ILogger logger)
        {
            var groups = lines.Where(l => l.Type == InstallType.Create)
                         .GroupBy(l => $"{l.Reference.Unique}|{l.Reference.Type}");
            var result = true;

            foreach (var duplicate in groups.Where(g => g.Skip(1).Any()))
            {
                result = false;
                logger.LogError("The package has duplicate entries for creating {Type} {Name} with ID {ID} at {Paths}", duplicate.First().Reference.Type, duplicate.First().Reference.KeyedName, duplicate.First().Reference.Unique, duplicate.Select(i => i.Path));
            }

            var existing = groups
                           .ToDictionary(g => g.Key, g => g.First());
            InstallItem item;

            foreach (var line in lines.Where(l => l.Type == InstallType.Script))
            {
                if (existing.TryGetValue(line.InstalledId, out item))
                {
                    line.Reference.KeyedName = InstallItem.RenderAttributes(line.Script, item.Reference.KeyedName);
                }
            }

            return(result);
        }
예제 #2
0
        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"));
                }
            }
        }
예제 #3
0
        public static InstallItem FromWarning(ItemReference itemRef, string warning)
        {
            var result = new InstallItem();

            result._itemRef = itemRef;
            result._name    = warning;
            result.Type     = InstallType.Warning;
            return(result);
        }
예제 #4
0
        private void WriteReport(InstallItem line, string path)
        {
            var dataFile = "<Result><Item></Item></Result>";

            using (var writer = new StreamWriter(GetNewStream(path)))
            {
                var aml = new StringBuilder();

                using (var amlWriter = new System.IO.StringWriter(aml))
                {
                    using (var xml = new ConfigurableXmlWriter(amlWriter))
                    {
                        xml.ElementProcessor = (prefix, localName, ns, w) =>
                        {
                            if (localName == "xsl_stylesheet")
                            {
                                return(ProcessState.DontRender);
                            }
                            return(ProcessState.RenderAll);
                        };

                        xml.WriteStartElement("AML");
                        line.Script.WriteTo(xml);
                        xml.WriteEndElement();
                    }
                }

                writer.WriteLine(_reportStart);
                writer.WriteLine(aml);
                writer.WriteLine(_reportEnd);

                var xsltElem = line.Script.SelectSingleNode(".//xsl_stylesheet") as XmlElement;
                if (xsltElem != null)
                {
                    var xslt      = xsltElem.InnerText;
                    var dataStart = xslt.IndexOf(_reportDataStart);
                    var dataEnd   = xslt.IndexOf(_reportDataEnd);
                    if (dataStart >= 0 && dataEnd >= 0)
                    {
                        dataFile = xslt.Substring(dataStart + _reportDataStart.Length, dataEnd - dataStart - _reportDataStart.Length).Trim();
                        xslt     = xslt.Substring(0, dataStart).Trim() + Environment.NewLine + xslt.Substring(dataEnd + _reportDataEnd.Length).Trim();
                    }
                    else
                    {
                        dataFile = xsltElem.Parent().Element("report_query", "<Result><Item></Item></Result>");
                    }
                    dataFile = XmlUtils.RemoveComments(dataFile);

                    writer.WriteLine(xslt);
                }
            }

            using (var writer = new StreamWriter(GetNewStream(path + ".xml")))
            {
                writer.Write(dataFile);
            }
        }
예제 #5
0
        private int DefaultInstallOrder(InstallItem line)
        {
            var itemRef = line.Reference;

            if (line.Reference.Type == InstallItem.ScriptType)
            {
                itemRef = ItemReference.FromElement(line.Script);
            }
            return(DefaultInstallOrder(itemRef));
        }
예제 #6
0
        public static string FilePath(this InstallItem line, HashSet <string> existingPaths, string extension = ".xml")
        {
            var folder  = line.Type == InstallType.Script ? "_Scripts" : line.Reference.Type;
            var newPath = folder + "\\" + Utils.CleanFileName(line.Reference.KeyedName ?? line.Reference.Unique) + extension;

            if (existingPaths.Contains(newPath))
            {
                newPath = folder + "\\" + Utils.CleanFileName((line.Reference.KeyedName ?? "") + "_" + line.Reference.Unique) + extension;
            }
            return(newPath);
        }
예제 #7
0
 private string GetPath(InstallItem line, HashSet <string> existingPaths)
 {
     if (line.Reference.Type == "Report" && line.Type != InstallType.Script)
     {
         return(line.FilePath(existingPaths, ".xslt"));
     }
     else
     {
         return(line.FilePath(existingPaths));
     }
 }
예제 #8
0
        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);
        }
예제 #9
0
        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));
        }
예제 #10
0
        public static InstallItem FromDependency(ItemReference itemRef)
        {
            var result = new InstallItem();

            result._itemRef = itemRef;
            result._elem    = new XmlDocument().CreateElement("Item");
            result._elem.SetAttribute("type", result._itemRef.Type);
            if (result._itemRef.Unique.IsGuid())
            {
                result._elem.SetAttribute("id", result._itemRef.Unique);
            }
            else
            {
                result._elem.SetAttribute("where", result._itemRef.Unique);
            }
            result._elem.SetAttribute("action", "get");
            result._elem.SetAttribute("_dependency_check", "1");
            result._elem.SetAttribute("_keyed_name", result._itemRef.KeyedName);
            result.Type = InstallType.DependencyCheck;
            return(result);
        }
예제 #11
0
        public static void CleanKeyedNames(this IEnumerable <InstallItem> lines)
        {
            var groups = lines.Where(l => l.Type == InstallType.Create)
                         .GroupBy(l => l.Reference.Unique);
            var duplicates = groups.Where(g => g.Skip(1).Any()).ToArray();

            if (duplicates.Length > 0)
            {
                throw new InvalidOperationException("The package has duplicate entries for the following items: " + duplicates.GroupConcat(", ", g => g.Key));
            }
            var existing = groups
                           .ToDictionary(g => g.Key, g => g.First());
            InstallItem item;

            foreach (var line in lines.Where(l => l.Type == InstallType.Script))
            {
                if (existing.TryGetValue(line.InstalledId, out item))
                {
                    line.Reference.KeyedName = InstallItem.RenderAttributes(line.Script, item.Reference.KeyedName);
                }
            }
        }
예제 #12
0
 public static InstallItem FromDependency(ItemReference itemRef)
 {
   var result = new InstallItem();
   result._itemRef = itemRef;
   result._elem = new XmlDocument().CreateElement("Item");
   result._elem.SetAttribute("type", result._itemRef.Type);
   if (result._itemRef.Unique.IsGuid())
   {
     result._elem.SetAttribute("id", result._itemRef.Unique);
   }
   else
   {
     result._elem.SetAttribute("where", result._itemRef.Unique);
   }
   result._elem.SetAttribute("action", "get");
   result._elem.SetAttribute("_dependency_check", "1");
   result._elem.SetAttribute("_keyed_name", result._itemRef.KeyedName);
   result._type = InstallType.DependencyCheck;
   return result;
 }
예제 #13
0
        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);
        }
예제 #14
0
 public static InstallItem FromWarning(ItemReference itemRef, string warning)
 {
   var result = new InstallItem();
   result._itemRef = itemRef;
   result._name = warning;
   result._type = InstallType.Warning;
   return result;
 }
예제 #15
0
    public static InstallItem FromScript(XmlElement elem
      , Func<XmlElement, string> keyedNameGetter = null)
    {

      var result = new InstallItem();
      result._elem = elem;
      result._itemRef = ItemReference.FromFullItem(elem, true);
      if (result._itemRef.Type.IsGuid())
      {
        result.InstalledId = result._itemRef.Type;
      }
      else
      {
        result.InstalledId = elem.Attribute("id", "");
      }

      if (elem.HasAttribute("_dependency_check"))
      {
        result._type = InstallType.DependencyCheck;
      }
      else if (elem.HasAttribute("action"))
      {
        switch (elem.Attributes["action"].Value)
        {
          case "add":
          case "merge":
          case "create":
            result._type = InstallType.Create;
            break;
          case "ActivateActivity":
          case "AddItem":
          case "AddHistory":
          case "ApplyUpdate":
          case "BuildProcessReport":
          case "CancelWorkflow":
          case "checkImportedItemType":
          case "closeWorkflow":
          case "copy":
          case "copyAsIs":
          case "copyAsNew":
          case "delete":
          case "edit":
          case "EmailItem":
          case "EvaluateActivity":
          case "exportItemType":
          case "get":
          case "getItemAllVersions":
          case "getAffectedItems":
          case "getItemConfig":
          case "getItemLastVersion":
          case "getItemNextStates":
          case "getItemRelationships":
          case "GetItemRepeatConfig":
          case "getItemWhereUsed":
          case "GetMappedPath":
          case "getPermissions":
          case "getRelatedItem":
          case "GetUpdateInfo":
          case "instantiateWorkflow":
          case "lock":
          case "New Workflow Map":
          case "PromoteItem":
          case "purge":
          case "recache":
          case "replicate":
          case "resetAllItemsAccess":
          case "resetItemAccess":
          case "resetLifecycle":
          case "setDefaultLifecycle":
          case "skip":
          case "startWorkflow":
          case "unlock":
          case "update":
          case "ValidateWorkflowMap":
          case "version":
            if ((elem.Attributes["type"].Value != "Form" && elem.Attributes["type"].Value != "View")
              || elem.Attributes["action"].Value != "delete")
              result._dependencies = Enumerable.Repeat(result._itemRef, 1);
            result._itemRef = new ItemReference(ScriptType, result._itemRef.ToString() + " " + Utils.GetChecksum(Encoding.UTF8.GetBytes(elem.OuterXml)))
            {
              KeyedName = RenderAttributes(elem)
            };
            result._type = InstallType.Script;
            break;
          default:
            result._dependencies = Enumerable.Repeat(new ItemReference("Method", "[Method].[name] = '" + elem.Attributes["action"].Value + "'")
            {
              KeyedName = elem.Attributes["action"].Value
            }, 1);
            result._itemRef = new ItemReference(ScriptType, result._itemRef.ToString() + " " + Utils.GetChecksum(Encoding.UTF8.GetBytes(elem.OuterXml)))
            {
              KeyedName = RenderAttributes(elem)
            };
            result._type = InstallType.Script;
            break;
        }
      }

      if (elem.Attribute(XmlFlags.Attr_IsScript) == "1")
      {
        if (string.IsNullOrEmpty(result._itemRef.KeyedName))
        {
          result._itemRef.KeyedName = RenderAttributes(elem);
        }
        result._type = InstallType.Script;
      }
      return result;
    }
예제 #16
0
        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);
        }
예제 #17
0
        public static InstallItem FromScript(XmlElement elem
                                             , Func <XmlElement, string> keyedNameGetter = null)
        {
            var result = new InstallItem();

            result._elem    = elem;
            result._itemRef = ItemReference.FromFullItem(elem, true);
            if (result._itemRef.Type.IsGuid())
            {
                result.InstalledId = result._itemRef.Type;
            }
            else
            {
                result.InstalledId = elem.Attribute("id", "");
            }

            if (elem.HasAttribute("_dependency_check"))
            {
                result.Type = InstallType.DependencyCheck;
            }
            else if (elem.HasAttribute("action"))
            {
                switch (elem.Attributes["action"].Value)
                {
                case "add":
                case "merge":
                case "create":
                    result.Type = InstallType.Create;
                    break;

                case "ActivateActivity":
                case "AddItem":
                case "AddHistory":
                case "ApplyUpdate":
                case "BuildProcessReport":
                case "CancelWorkflow":
                case "checkImportedItemType":
                case "closeWorkflow":
                case "copy":
                case "copyAsIs":
                case "copyAsNew":
                case "delete":
                case "edit":
                case "EmailItem":
                case "EvaluateActivity":
                case "exportItemType":
                case "get":
                case "getItemAllVersions":
                case "getAffectedItems":
                case "getItemConfig":
                case "getItemLastVersion":
                case "getItemNextStates":
                case "getItemRelationships":
                case "GetItemRepeatConfig":
                case "getItemWhereUsed":
                case "GetMappedPath":
                case "getPermissions":
                case "getRelatedItem":
                case "GetUpdateInfo":
                case "instantiateWorkflow":
                case "lock":
                case "New Workflow Map":
                case "PromoteItem":
                case "purge":
                case "recache":
                case "replicate":
                case "resetAllItemsAccess":
                case "resetItemAccess":
                case "resetLifecycle":
                case "setDefaultLifecycle":
                case "skip":
                case "startWorkflow":
                case "unlock":
                case "update":
                case "ValidateWorkflowMap":
                case "version":
                    if ((elem.Attributes["type"].Value != "Form" && elem.Attributes["type"].Value != "View") ||
                        elem.Attributes["action"].Value != "delete")
                    {
                        result._dependencies = Enumerable.Repeat(result._itemRef, 1);
                    }

                    result._itemRef = new ItemReference(ScriptType, result._itemRef + " " + Utils.GetChecksum(Encoding.UTF8.GetBytes(elem.OuterXml)))
                    {
                        KeyedName = RenderAttributes(elem)
                    };
                    result.Type = InstallType.Script;
                    break;

                default:
                    result._dependencies = Enumerable.Repeat(new ItemReference("Method", "[Method].[name] = '" + elem.Attributes["action"].Value + "'")
                    {
                        KeyedName = elem.Attributes["action"].Value
                    }, 1);
                    result._itemRef = new ItemReference(ScriptType, result._itemRef + " " + Utils.GetChecksum(Encoding.UTF8.GetBytes(elem.OuterXml)))
                    {
                        KeyedName = RenderAttributes(elem)
                    };
                    result.Type = InstallType.Script;
                    break;
                }
            }

            if (elem.Attribute(XmlFlags.Attr_IsScript) == "1")
            {
                if (string.IsNullOrEmpty(result._itemRef.KeyedName))
                {
                    result._itemRef.KeyedName = RenderAttributes(elem);
                }
                result.Type = InstallType.Script;
            }
            return(result);
        }
예제 #18
0
 /// <summary>
 /// Determine the dependencies of an install item script
 /// </summary>
 public void AddReferenceAndDependencies(InstallItem installItem)
 {
     AddReferenceAndDependencies(installItem.Script, installItem.Reference, installItem.CoreDependencies);
 }
예제 #19
0
        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);
        }
예제 #20
0
    private void WriteReport(InstallItem line, string path)
    {
      var dataFile = "<Result><Item></Item></Result>";

      using (var writer = new StreamWriter(GetNewStream(path)))
      {
        var aml = new StringBuilder();

        using (var amlWriter = new System.IO.StringWriter(aml))
        {
          using (var xml = new ConfigurableXmlWriter(amlWriter))
          {
            xml.ElementProcessor = (prefix, localName, ns, w) =>
            {
              if (localName == "xsl_stylesheet") return ProcessState.DontRender;
              return ProcessState.RenderAll;
            };

            xml.WriteStartElement("AML");
            line.Script.WriteTo(xml);
            xml.WriteEndElement();
          }
        }

        writer.WriteLine(_reportStart);
        writer.WriteLine(aml);
        writer.WriteLine(_reportEnd);

        var xsltElem = line.Script.SelectSingleNode(".//xsl_stylesheet") as XmlElement;
        if (xsltElem != null)
        {
          var xslt = xsltElem.InnerText;
          var dataStart = xslt.IndexOf(_reportDataStart);
          var dataEnd = xslt.IndexOf(_reportDataEnd);
          if (dataStart >= 0 && dataEnd >= 0)
          {
            dataFile = xslt.Substring(dataStart + _reportDataStart.Length, dataEnd - dataStart - _reportDataStart.Length).Trim();
            xslt = xslt.Substring(0, dataStart).Trim() + Environment.NewLine + xslt.Substring(dataEnd + _reportDataEnd.Length).Trim();
          }
          else
          {
            dataFile = xsltElem.Parent().Element("report_query", "<Result><Item></Item></Result>");
          }

          writer.WriteLine(xslt);
        }
      }

      using (var writer = new StreamWriter(GetNewStream(path + ".xml")))
      {
        writer.Write(dataFile);
      }
    }
예제 #21
0
        internal IEnumerable <InstallItem> GetDependencyList(DependencyAnalyzer dependAnalyzer
                                                             , IEnumerable <InstallItem> values, out CycleState cycleState)
        {
            cycleState = CycleState.NoCycle;
            var lookup = (from i in values
                          group i by i.Reference into refGroup
                          select refGroup)
                         .ToDictionary(i => i.Key, i => (IEnumerable <InstallItem>)i);

            IEnumerable <ItemReference> sorted = null;
            IList <ItemReference>       cycle  = new List <ItemReference>()
            {
                null
            };
            List <XmlNode> refs;

            // Bias the install order initially to try and help the dependency sort properly handle anything
            // where explicit dependencies don't exist.  Then, perform the dependency sort.
            var initialSort = lookup.Keys
                              .OrderBy(DefaultInstallOrder)
                              .ThenBy(i => i.Type.ToLowerInvariant())
                              .ThenBy(i => i.Unique)
                              .ToList();

            sorted = initialSort.DependencySort <ItemReference>(d =>
            {
                IEnumerable <InstallItem> res = null;
                if (lookup.TryGetValue(d, out res))
                {
                    return(res.SelectMany(r =>
                    {
                        var ii = r as InstallItem;
                        if (ii == null)
                        {
                            return Enumerable.Empty <ItemReference>();
                        }
                        return dependAnalyzer.GetDependencies(ii.Reference);
                    }));
                }

                return(Enumerable.Empty <ItemReference>());
            }, ref cycle, false);

            // Attempt to remove cycles by identifying a Relationships tag in one of the cycles
            // and moving the Relationships to the top level
            if (cycle.Count > 0 && (cycle[0] != null || cycle.Count > 1))
            {
                cycleState = CycleState.UnresolvedCycle;
                for (int i = (cycle[0] == null ? 2 : 1); i < cycle.Count; i++)
                {
                    refs = dependAnalyzer.GetReferences(cycle[i - 1], cycle[i]).ToList();
                    if (refs.Count == 1)
                    {
                        var relTag = refs[0].Parents().FirstOrDefault(e => e.LocalName == "Relationships");
                        if (relTag != null)
                        {
                            var parentTag = refs[0].Parents().Last(e => e.LocalName == "Item").Parent();
                            foreach (var child in relTag.Elements().ToList())
                            {
                                child.Detach();
                                parentTag.AppendChild(child);
                                var sourceId = (XmlElement)child.AppendChild(child.OwnerDocument.CreateElement("source_id"));
                                sourceId.SetAttribute("type", relTag.Parent().Attribute("type"));
                                sourceId.SetAttribute("keyed_name", relTag.Parent().Attribute("_keyed_name"));
                                sourceId.InnerText = relTag.Parent().Attribute("id");
                            }
                            relTag.Detach();
                            cycleState = CycleState.ResolvedCycle;
                            //return Enumerable.Empty<InstallItem>();
                        }
                    }
                }
            }

            var result = new List <InstallItem>();
            IEnumerable <InstallItem> items = null;

            foreach (var sort in sorted)
            {
                if (lookup.TryGetValue(sort, out items))
                {
                    foreach (var item in items)
                    {
                        result.Add(item);
                    }
                }
                else
                {
                    result.Add(InstallItem.FromDependency(sort));
                }
            }

            return(result);
        }
예제 #22
0
 private static bool IsDelete(InstallItem item)
 {
     return(item.Type == InstallType.Script && item.Name.Split(' ').Contains("Delete"));
 }