private void VerifyContentLinks(HtmlString html, string path, ContentLinkType contentType, ILookup <string, string> lookup)
        {
            var xmlDoc = new XmlDocument();
            var doc    = xmlDoc.CreateDocumentFragment();

            doc.InnerXml = html.ToString();

            var childNodes   = doc.ChildNodes.Cast <XmlNode>().Where(n => !(n is XmlWhitespace)).ToList();
            var expectedList = lookup[path];

            Assert.Equal(expectedList.Count(), childNodes.Count);

            foreach (var pair in childNodes.Zip(expectedList, Tuple.Create))
            {
                var node     = pair.Item1;
                var expected = pair.Item2;

                if (contentType == ContentLinkType.Javascript)
                {
                    Assert.Equal("script", node.Name);
                    Assert.Equal(2, node.Attributes.Count);

                    Assert.Equal("text/javascript", node.Attributes.GetNamedItem("type").Value);
                    Assert.Equal(expected, node.Attributes.GetNamedItem("src").Value);
                }
                else
                {
                    Assert.Equal("link", node.Name);
                    Assert.Equal(2, node.Attributes.Count);

                    Assert.Equal("stylesheet", node.Attributes.GetNamedItem("rel").Value);
                    Assert.Equal(expected, node.Attributes.GetNamedItem("href").Value);
                }
            }
        }
Esempio n. 2
0
        // This constructor exists for better factorization of code in AssetDependencies. 
        // It should not be turned into public as AssetItem is not valid.
        internal AssetLink(IContentReference reference, ContentLinkType type)
        {
            if (reference == null) throw new ArgumentNullException("reference");

            Item = null;
            this.type = type;
            this.reference = reference;
        }
Esempio n. 3
0
        /// <summary>
        /// Create an asset dependency of type <paramref name="type"/> and pointing to <paramref name="item"/>
        /// </summary>
        /// <param name="item">The item the dependency is pointing to</param>
        /// <param name="type">The type of the dependency between the items</param>
        public AssetLink(AssetItem item, ContentLinkType type)
        {
            if (item == null) throw new ArgumentNullException("item");

            Item = item;
            this.type = type;
            reference = item.ToReference();
        }
Esempio n. 4
0
        // This constructor exists for better factorization of code in AssetDependencies.
        // It should not be turned into public as AssetItem is not valid.
        internal AssetLink(IReference reference, ContentLinkType type)
        {
            if (reference == null)
            {
                throw new ArgumentNullException("reference");
            }

            Item           = null;
            this.type      = type;
            this.reference = reference;
        }
Esempio n. 5
0
        /// <summary>
        /// Create an asset dependency of type <paramref name="type"/> and pointing to <paramref name="item"/>
        /// </summary>
        /// <param name="item">The item the dependency is pointing to</param>
        /// <param name="type">The type of the dependency between the items</param>
        public AssetLink(AssetItem item, ContentLinkType type)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            Item      = item;
            this.type = type;
            reference = item.ToReference();
        }
Esempio n. 6
0
        /// <summary>
        ///   Create an asset dependency of a specified <paramref name="type"/> pointing to an asset <paramref name="item"/>.
        /// </summary>
        /// <param name="item">The item the dependency is pointing to.</param>
        /// <param name="type">The type of the dependency between the items.</param>
        public AssetLink(AssetItem item, ContentLinkType type)
        {
            if (item is null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            Item           = item;
            Type           = type;
            assetReference = item.ToReference();
        }
        /// <inheritdoc />
        public AssetDependencies ComputeDependencies(AssetId assetId, AssetDependencySearchOptions dependenciesOptions = AssetDependencySearchOptions.All,
                                                     ContentLinkType linkTypes = ContentLinkType.Reference, HashSet <AssetId> visited = null)
        {
            bool recursive = dependenciesOptions.HasFlag(AssetDependencySearchOptions.Recursive);

            if (visited is null && recursive)
            {
                visited = new HashSet <AssetId>();
            }

            //var clock = Stopwatch.StartNew();

            lock (Initialize())
            {
                if (!Dependencies.TryGetValue(assetId, out AssetDependencies dependencies))
                {
                    return(null);
                }

                dependencies = new AssetDependencies(dependencies.Item);

                int inCount = 0, outCount = 0;

                if (dependenciesOptions.HasFlag(AssetDependencySearchOptions.In))
                {
                    CollectInputReferences(dependencies, assetId, visited, recursive, linkTypes, ref inCount);
                }

                if (dependenciesOptions.HasFlag(AssetDependencySearchOptions.Out))
                {
                    visited?.Clear();
                    CollectOutputReferences(dependencies, assetId, visited, recursive, linkTypes, ref outCount);
                }

                //Console.WriteLine("Time to compute dependencies: {0}ms in: {1} out:{2}", clock.ElapsedMilliseconds, inCount, outCount);

                return(dependencies);
            }
        }
Esempio n. 8
0
        /// <inheritdoc />
        public List <AssetItem> FindAssetInheritances(AssetId assetId, AssetInheritanceSearchOptions searchOptions = AssetInheritanceSearchOptions.All)
        {
            var list = new List <AssetItem>();

            lock (Initialize())
            {
                ContentLinkType searchType = 0;
                if ((searchOptions & AssetInheritanceSearchOptions.Base) != 0)
                {
                    searchType |= ContentLinkType.Inheritance;
                }
                if ((searchOptions & AssetInheritanceSearchOptions.Composition) != 0)
                {
                    searchType |= ContentLinkType.CompositionInheritance;
                }

                AssetDependencies dependencies;
                if (Dependencies.TryGetValue(assetId, out dependencies))
                {
                    list.AddRange(dependencies.LinksOut.Where(p => (p.Type & searchType) != 0).Select(p => p.Item.Clone(true)));
                }
            }
            return(list);
        }
Esempio n. 9
0
 /// <summary>
 /// Adds a link going to the provided element.
 /// </summary>
 /// <param name="toItem">The element the link is going to</param>
 /// <param name="contentLinkType">The type of link</param>
 /// <param name="cloneAssetItem">Indicate if the <see cref="AssetItem"/> should be cloned or not</param>
 /// <exception cref="ArgumentException">A link to this element already exists</exception>
 public void AddLinkOut(AssetItem toItem, ContentLinkType contentLinkType, bool cloneAssetItem)
 {
     AddLink(ref children, new AssetLink(toItem, contentLinkType), cloneAssetItem);
 }
Esempio n. 10
0
 /// <summary>
 /// Adds a broken link out.
 /// </summary>
 /// <param name="reference">the reference to the missing element</param>
 /// <param name="contentLinkType">The type of link</param>
 /// <exception cref="ArgumentException">A broken link to this element already exists</exception>
 public void AddBrokenLinkOut(IReference reference, ContentLinkType contentLinkType)
 {
     AddLink(ref missingChildren, new AssetLink(reference, contentLinkType));
 }
Esempio n. 11
0
        private AssetLink RemoveLink(ref Dictionary<Guid, AssetLink> dictionary, Guid id, ContentLinkType type)
        {
            if (dictionary == null || !dictionary.ContainsKey(id))
                throw new ArgumentException("There is currently no link between elements '{0}' and '{1}'".ToFormat(item.Id, id));

            var oldLink = dictionary[id];
            var newLink = oldLink;

            newLink.Type &= ~type;
            oldLink.Type &= type;

            if(newLink.Type == 0)
                dictionary.Remove(id);

            if (dictionary.Count == 0)
                dictionary = null;

            return oldLink;
        }
Esempio n. 12
0
 /// <summary>
 /// Adds a link going into the element.
 /// </summary>
 /// <param name="fromItem">The element the link is coming from</param>
 /// <param name="contentLinkType">The type of link</param>
 /// <exception cref="ArgumentException">A link from this element already exists</exception>
 public void AddLinkIn(AssetItem fromItem, ContentLinkType contentLinkType)
 {
     AddLink(ref parents, new AssetLink(fromItem, contentLinkType));
 }
Esempio n. 13
0
 /// <summary>
 /// Adds a link going to the provided element.
 /// </summary>
 /// <param name="toItem">The element the link is going to</param>
 /// <param name="contentLinkType">The type of link</param>
 /// <exception cref="ArgumentException">A link to this element already exists</exception>
 public void AddLinkOut(AssetItem toItem, ContentLinkType contentLinkType)
 {
     AddLink(ref children, new AssetLink(toItem, contentLinkType));
 }
Esempio n. 14
0
        private void CollectInputReferences(AssetDependencies dependencyRoot, AssetId assetId, HashSet <AssetId> visited, bool recursive, ContentLinkType linkTypes, ref int count)
        {
            if (visited != null)
            {
                if (visited.Contains(assetId))
                {
                    return;
                }

                visited.Add(assetId);
            }

            count++;

            AssetDependencies dependencies;

            Dependencies.TryGetValue(assetId, out dependencies);
            if (dependencies != null)
            {
                foreach (var pair in dependencies.LinksIn)
                {
                    if ((linkTypes & pair.Type) != 0)
                    {
                        dependencyRoot.AddLinkIn(pair);

                        if (visited != null && recursive)
                        {
                            CollectInputReferences(dependencyRoot, pair.Item.Id, visited, true, linkTypes, ref count);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Computes the dependencies for the specified asset.
        /// </summary>
        /// <param name="assetId">The asset id.</param>
        /// <param name="dependenciesOptions">The dependencies options.</param>
        /// <param name="linkTypes">The type of links to visit while computing the dependencies</param>
        /// <param name="visited">The list of element already visited.</param>
        /// <returns>The dependencies, or null if the object is not tracked.</returns>
        public AssetDependencies ComputeDependencies(AssetId assetId, AssetDependencySearchOptions dependenciesOptions = AssetDependencySearchOptions.All, ContentLinkType linkTypes = ContentLinkType.All, HashSet<AssetId> visited = null)
        {
            bool recursive = (dependenciesOptions & AssetDependencySearchOptions.Recursive) != 0;
            if (visited == null && recursive)
                visited = new HashSet<AssetId>();

            //var clock = Stopwatch.StartNew();

            lock (Initialize())
            {
                AssetDependencies dependencies;
                if (!Dependencies.TryGetValue(assetId, out dependencies))
                    return null;

                dependencies = new AssetDependencies(dependencies.Item);

                int inCount = 0, outCount = 0;

                if ((dependenciesOptions & AssetDependencySearchOptions.In) != 0)
                {
                    CollectInputReferences(dependencies, assetId, visited, recursive, linkTypes, ref inCount);
                }

                if ((dependenciesOptions & AssetDependencySearchOptions.Out) != 0)
                {
                    visited?.Clear();
                    CollectOutputReferences(dependencies, assetId, visited, recursive, linkTypes, ref outCount);
                }

                //Console.WriteLine("Time to compute dependencies: {0}ms in: {1} out:{2}", clock.ElapsedMilliseconds, inCount, outCount);

                return dependencies;
            }

        }
        private void CollectInputReferences(AssetDependencies dependencyRoot, AssetId assetId, HashSet<AssetId> visited, bool recursive, ContentLinkType linkTypes, ref int count)
        {
            if (visited != null)
            {
                if (visited.Contains(assetId))
                    return;

                visited.Add(assetId);
            }

            count++;

            AssetDependencies dependencies;
            Dependencies.TryGetValue(assetId, out dependencies);
            if (dependencies != null)
            {
                foreach (var pair in dependencies.LinksIn)
                {
                    if ((linkTypes & pair.Type) != 0)
                    {
                        dependencyRoot.AddLinkIn(pair);

                        if (visited != null && recursive)
                        {
                            CollectInputReferences(dependencyRoot, pair.Item.Id, visited, true, linkTypes, ref count);
                        }
                    }
                }
            }
        }
Esempio n. 17
0
 /// <summary>
 /// Adds a broken link out.
 /// </summary>
 /// <param name="reference">the reference to the missing element</param>
 /// <param name="contentLinkType">The type of link</param>
 /// <exception cref="ArgumentException">A broken link to this element already exists</exception>
 public void AddBrokenLinkOut(IReference reference, ContentLinkType contentLinkType)
 {
     AddLink(ref missingChildren, new AssetLink(reference, contentLinkType));
 }
Esempio n. 18
0
 /// <summary>
 /// Adds a link going into the element.
 /// </summary>
 /// <param name="fromItem">The element the link is coming from</param>
 /// <param name="contentLinkType">The type of link</param>
 /// <exception cref="ArgumentException">A link from this element already exists</exception>
 public void AddLinkIn(AssetItem fromItem, ContentLinkType contentLinkType)
 {
     AddLink(ref parents, new AssetLink(fromItem, contentLinkType));
 }
Esempio n. 19
0
 /// <summary>
 /// Adds a link going into the element.
 /// </summary>
 /// <param name="fromItem">The element the link is coming from</param>
 /// <param name="contentLinkType">The type of link</param>
 /// <param name="cloneAssetItem">Indicate if the <see cref="AssetItem"/> should be cloned or not</param>
 /// <exception cref="ArgumentException">A link from this element already exists</exception>
 public void AddLinkIn(AssetItem fromItem, ContentLinkType contentLinkType, bool cloneAssetItem)
 {
     AddLink(ref parents, new AssetLink(fromItem, contentLinkType), cloneAssetItem);
 }
        private void CollectOutputReferences(AssetDependencies dependencyRoot, AssetId assetId, HashSet<AssetId> visited, bool recursive, ContentLinkType linkTypes, ref int count)
        {
            if (visited != null)
            {
                if (visited.Contains(assetId))
                    return;

                visited.Add(assetId);
            }

            count++;

            var dependencies = CalculateDependencies(assetId);
            if (dependencies == null)
                return;

            // Add missing references
            foreach (var missingRef in dependencies.BrokenLinksOut)
            {
                dependencyRoot.AddBrokenLinkOut(missingRef);
            }

            // Add output references
            foreach (var child in dependencies.LinksOut)
            {
                if ((linkTypes & child.Type) != 0)
                {
                    dependencyRoot.AddLinkOut(child);

                    if (visited != null && recursive)
                    {
                        CollectOutputReferences(dependencyRoot, child.Item.Id, visited, true, linkTypes, ref count);
                    }
                }
            }
        }
Esempio n. 21
0
 /// <summary>
 /// Adds a link going to the provided element.
 /// </summary>
 /// <param name="toItem">The element the link is going to</param>
 /// <param name="contentLinkType">The type of link</param>
 /// <exception cref="ArgumentException">A link to this element already exists</exception>
 public void AddLinkOut(AssetItem toItem, ContentLinkType contentLinkType)
 {
     AddLink(ref children, new AssetLink(toItem, contentLinkType));
 }
Esempio n. 22
0
        /// <summary>
        /// Computes the dependencies for the specified asset.
        /// </summary>
        /// <param name="assetItem">The asset item.</param>
        /// <param name="dependenciesOptions">The dependencies options.</param>
        /// <param name="linkTypes">The type of links to visit while computing the dependencies</param>
        /// <param name="visited">The list of element already visited.</param>
        /// <returns>The dependencies.</returns>
        public AssetDependencies ComputeDependencies(AssetItem assetItem, AssetDependencySearchOptions dependenciesOptions = AssetDependencySearchOptions.All, ContentLinkType linkTypes = ContentLinkType.All, HashSet <Guid> visited = null)
        {
            if (assetItem == null)
            {
                throw new ArgumentNullException(nameof(assetItem));
            }
            bool recursive = (dependenciesOptions & AssetDependencySearchOptions.Recursive) != 0;

            if (visited == null && recursive)
            {
                visited = new HashSet <Guid>();
            }

            //var clock = Stopwatch.StartNew();

            lock (Initialize())
            {
                var dependencies = new AssetDependencies(assetItem);

                int inCount = 0, outCount = 0;

                if ((dependenciesOptions & AssetDependencySearchOptions.In) != 0)
                {
                    CollectInputReferences(dependencies, assetItem, visited, recursive, linkTypes, ref inCount);
                }

                if ((dependenciesOptions & AssetDependencySearchOptions.Out) != 0)
                {
                    visited?.Clear();
                    CollectOutputReferences(dependencies, assetItem, visited, recursive, linkTypes, ref outCount);
                }

                //Console.WriteLine("Time to compute dependencies: {0}ms in: {1} out:{2}", clock.ElapsedMilliseconds, inCount, outCount);

                return(dependencies);
            }
        }
Esempio n. 23
0
        private AssetLink RemoveLink(ref Dictionary <AssetId, AssetLink> dictionary, AssetId id, ContentLinkType type)
        {
            if (dictionary == null || !dictionary.ContainsKey(id))
            {
                throw new ArgumentException("There is currently no link between elements '{0}' and '{1}'".ToFormat(item.Id, id));
            }

            var oldLink = dictionary[id];
            var newLink = oldLink;

            newLink.Type &= ~type;
            oldLink.Type &= type;

            if (newLink.Type == 0)
            {
                dictionary.Remove(id);
            }

            if (dictionary.Count == 0)
            {
                dictionary = null;
            }

            return(oldLink);
        }
        private void VerifyContentLinks(IHtmlContent html, string path, ContentLinkType contentType, ILookup<string, string> lookup)
        {
            var xmlDoc = new XmlDocument();
            var doc = xmlDoc.CreateDocumentFragment();

            using (var writer = new StringWriter())
            {
                html.WriteTo(writer, HtmlEncoder.Default);
                doc.InnerXml = writer.ToString();
            }

            var childNodes = doc.ChildNodes.Cast<XmlNode>().Where(n => !(n is XmlWhitespace)).ToList();
            var expectedList = lookup[path];

            Assert.Equal(expectedList.Count(), childNodes.Count);

            foreach (var pair in childNodes.Zip(expectedList, Tuple.Create))
            {
                var node = pair.Item1;
                var expected = pair.Item2;

                if (contentType == ContentLinkType.Javascript)
                {
                    Assert.Equal("script", node.Name);
                    Assert.Equal(2, node.Attributes.Count);

                    Assert.Equal("text/javascript", node.Attributes.GetNamedItem("type").Value);
                    Assert.Equal(expected, node.Attributes.GetNamedItem("src").Value);
                }
                else
                {
                    Assert.Equal("link", node.Name);
                    Assert.Equal(2, node.Attributes.Count);

                    Assert.Equal("stylesheet", node.Attributes.GetNamedItem("rel").Value);
                    Assert.Equal(expected, node.Attributes.GetNamedItem("href").Value);
                }
            }
        }
Esempio n. 25
0
 //
 // This constructor exists for better factorization of code in AssetDependencies.
 // It should not be turned into public as AssetItem is not valid.
 //
 internal AssetLink(IReference reference, ContentLinkType type)
 {
     Item           = null;
     Type           = type;
     assetReference = reference ?? throw new ArgumentNullException(nameof(reference));
 }
Esempio n. 26
0
 /// <summary>
 /// Adds a link going into the element.
 /// </summary>
 /// <param name="fromItem">The element the link is coming from</param>
 /// <param name="contentLinkType">The type of link</param>
 /// <param name="cloneAssetItem">Indicate if the <see cref="AssetItem"/> should be cloned or not</param>
 /// <exception cref="ArgumentException">A link from this element already exists</exception>
 public void AddLinkIn(AssetItem fromItem, ContentLinkType contentLinkType, bool cloneAssetItem)
 {
     AddLink(ref parents, new AssetLink(fromItem, contentLinkType), cloneAssetItem);
 }
Esempio n. 27
0
        private void CollectOutputReferences(AssetDependencies dependencyRoot, AssetId assetId, HashSet <AssetId> visited, bool recursive, ContentLinkType linkTypes, ref int count)
        {
            if (visited != null)
            {
                if (visited.Contains(assetId))
                {
                    return;
                }

                visited.Add(assetId);
            }

            count++;

            var dependencies = CalculateDependencies(assetId);

            if (dependencies == null)
            {
                return;
            }

            // Add missing references
            foreach (var missingRef in dependencies.BrokenLinksOut)
            {
                dependencyRoot.AddBrokenLinkOut(missingRef);
            }

            // Add output references
            foreach (var child in dependencies.LinksOut)
            {
                if ((linkTypes & child.Type) != 0)
                {
                    dependencyRoot.AddLinkOut(child);

                    if (visited != null && recursive)
                    {
                        CollectOutputReferences(dependencyRoot, child.Item.Id, visited, true, linkTypes, ref count);
                    }
                }
            }
        }
Esempio n. 28
0
 /// <summary>
 /// Adds a link going to the provided element.
 /// </summary>
 /// <param name="toItem">The element the link is going to</param>
 /// <param name="contentLinkType">The type of link</param>
 /// <param name="cloneAssetItem">Indicate if the <see cref="AssetItem"/> should be cloned or not</param>
 /// <exception cref="ArgumentException">A link to this element already exists</exception>
 public void AddLinkOut(AssetItem toItem, ContentLinkType contentLinkType, bool cloneAssetItem)
 {
     AddLink(ref children, new AssetLink(toItem, contentLinkType), cloneAssetItem);
 }