From 7175860ae06e27ed78d03cd555386ec003fa7b23 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Sat, 18 Aug 2012 11:03:30 +0600 Subject: [PATCH] Added tests for dynamic node to select children based on the child doc type names including pluralized names and added support for checking with case insensitivity. Example. CurrentPage.NewsItems where NewsItem is a child doc type alias. Found one reason why the old dynamic node has performance issues and have added a note, just need to do more reseearch to make sure my findings are correct. Changed over all of the new DynamicNode classes to be DynamicDocument instead. --- src/Umbraco.Core/Dynamics/ClassFactory.cs | 2 +- .../{DynamicNode.cs => DynamicDocument.cs} | 285 +++++++----------- ...s => DynamicDocumentDataSourceResolver.cs} | 6 +- ...s => DynamicDocumentIdEqualityComparer.cs} | 6 +- ...amicNodeList.cs => DynamicDocumentList.cs} | 92 +++--- ...ring.cs => DynamicDocumentListOrdering.cs} | 154 +++++----- ...NodeWalker.cs => DynamicDocumentWalker.cs} | 54 ++-- src/Umbraco.Core/Dynamics/DynamicGrouping.cs | 10 +- src/Umbraco.Core/Dynamics/DynamicQueryable.cs | 60 ++-- src/Umbraco.Core/Dynamics/ExpressionParser.cs | 56 ++-- src/Umbraco.Core/Dynamics/ExtensionMethods.cs | 8 +- src/Umbraco.Core/Dynamics/Grouping.cs | 12 +- ...ource.cs => IDynamicDocumentDataSource.cs} | 3 +- src/Umbraco.Core/Dynamics/Signature.cs | 24 +- src/Umbraco.Core/StringExtensions.cs | 42 +++ src/Umbraco.Core/Umbraco.Core.csproj | 14 +- src/Umbraco.Tests/DynamicNodeTests.cs | 58 ++-- src/Umbraco.Tests/TestHelpers/BaseWebTest.cs | 4 +- .../DefaultDynamicDocumentDataSource.cs | 21 ++ .../DefaultDynamicNodeDataSource.cs | 54 ---- src/Umbraco.Web/Umbraco.Web.csproj | 2 +- src/Umbraco.Web/WebBootManager.cs | 2 +- .../RazorDynamicNode/DynamicNode.cs | 6 + 23 files changed, 476 insertions(+), 499 deletions(-) rename src/Umbraco.Core/Dynamics/{DynamicNode.cs => DynamicDocument.cs} (82%) rename src/Umbraco.Core/Dynamics/{DynamicNodeDataSourceResolver.cs => DynamicDocumentDataSourceResolver.cs} (64%) rename src/Umbraco.Core/Dynamics/{DynamicNodeIdEqualityComparer.cs => DynamicDocumentIdEqualityComparer.cs} (74%) rename src/Umbraco.Core/Dynamics/{DynamicNodeList.cs => DynamicDocumentList.cs} (79%) rename src/Umbraco.Core/Dynamics/{DynamicNodeListOrdering.cs => DynamicDocumentListOrdering.cs} (59%) rename src/Umbraco.Core/Dynamics/{DynamicNodeWalker.cs => DynamicDocumentWalker.cs} (75%) rename src/Umbraco.Core/Dynamics/{IDynamicNodeDataSource.cs => IDynamicDocumentDataSource.cs} (81%) create mode 100644 src/Umbraco.Web/DefaultDynamicDocumentDataSource.cs delete mode 100644 src/Umbraco.Web/DefaultDynamicNodeDataSource.cs diff --git a/src/Umbraco.Core/Dynamics/ClassFactory.cs b/src/Umbraco.Core/Dynamics/ClassFactory.cs index 9ed1897f17..8edd9839d5 100644 --- a/src/Umbraco.Core/Dynamics/ClassFactory.cs +++ b/src/Umbraco.Core/Dynamics/ClassFactory.cs @@ -47,7 +47,7 @@ namespace Umbraco.Core.Dynamics Type type; if (!classes.TryGetValue(signature, out type)) { - type = CreateDynamicClass(signature.properties); + type = CreateDynamicClass(signature.Properties); classes.Add(signature, type); } return type; diff --git a/src/Umbraco.Core/Dynamics/DynamicNode.cs b/src/Umbraco.Core/Dynamics/DynamicDocument.cs similarity index 82% rename from src/Umbraco.Core/Dynamics/DynamicNode.cs rename to src/Umbraco.Core/Dynamics/DynamicDocument.cs index 357252ca80..6111092c8f 100644 --- a/src/Umbraco.Core/Dynamics/DynamicNode.cs +++ b/src/Umbraco.Core/Dynamics/DynamicDocument.cs @@ -11,7 +11,7 @@ using System.Xml.Linq; namespace Umbraco.Core.Dynamics { - internal class DynamicNode : DynamicObject + internal class DynamicDocument : DynamicObject { #region consts // these are private readonlys as const can't be Guids @@ -23,11 +23,11 @@ namespace Umbraco.Core.Dynamics #endregion private readonly DynamicBackingItem _backingItem; - private DynamicNodeList _cachedChildren; + private DynamicDocumentList _cachedChildren; - internal DynamicNodeList OwnerList { get; set; } + internal DynamicDocumentList OwnerList { get; set; } - public DynamicNode(DynamicBackingItem n) + public DynamicDocument(DynamicBackingItem n) { if (n == null) throw new ArgumentNullException("n"); _backingItem = n; @@ -51,7 +51,7 @@ namespace Umbraco.Core.Dynamics // } // throw new ArgumentException("Cannot instantiate a DynamicNode without an id"); //} - public DynamicNode(IDocument node) + public DynamicDocument(IDocument node) { if (node == null) throw new ArgumentNullException("node"); _backingItem = new DynamicBackingItem(node); @@ -67,7 +67,7 @@ namespace Umbraco.Core.Dynamics // } // throw new ArgumentException("Cannot instantiate a DynamicNode without an id"); //} - public DynamicNode() + public DynamicDocument() { //Empty constructor for a special case with Generic Methods } @@ -77,65 +77,65 @@ namespace Umbraco.Core.Dynamics return this; } - public DynamicNode Up() + public DynamicDocument Up() { - return DynamicNodeWalker.Up(this); + return DynamicDocumentWalker.Up(this); } - public DynamicNode Up(int number) + public DynamicDocument Up(int number) { - return DynamicNodeWalker.Up(this, number); + return DynamicDocumentWalker.Up(this, number); } - public DynamicNode Up(string nodeTypeAlias) + public DynamicDocument Up(string nodeTypeAlias) { - return DynamicNodeWalker.Up(this, nodeTypeAlias); + return DynamicDocumentWalker.Up(this, nodeTypeAlias); } - public DynamicNode Down() + public DynamicDocument Down() { - return DynamicNodeWalker.Down(this); + return DynamicDocumentWalker.Down(this); } - public DynamicNode Down(int number) + public DynamicDocument Down(int number) { - return DynamicNodeWalker.Down(this, number); + return DynamicDocumentWalker.Down(this, number); } - public DynamicNode Down(string nodeTypeAlias) + public DynamicDocument Down(string nodeTypeAlias) { - return DynamicNodeWalker.Down(this, nodeTypeAlias); + return DynamicDocumentWalker.Down(this, nodeTypeAlias); } - public DynamicNode Next() + public DynamicDocument Next() { - return DynamicNodeWalker.Next(this); + return DynamicDocumentWalker.Next(this); } - public DynamicNode Next(int number) + public DynamicDocument Next(int number) { - return DynamicNodeWalker.Next(this, number); + return DynamicDocumentWalker.Next(this, number); } - public DynamicNode Next(string nodeTypeAlias) + public DynamicDocument Next(string nodeTypeAlias) { - return DynamicNodeWalker.Next(this, nodeTypeAlias); + return DynamicDocumentWalker.Next(this, nodeTypeAlias); } - public DynamicNode Previous() + public DynamicDocument Previous() { - return DynamicNodeWalker.Previous(this); + return DynamicDocumentWalker.Previous(this); } - public DynamicNode Previous(int number) + public DynamicDocument Previous(int number) { - return DynamicNodeWalker.Previous(this, number); + return DynamicDocumentWalker.Previous(this, number); } - public DynamicNode Previous(string nodeTypeAlias) + public DynamicDocument Previous(string nodeTypeAlias) { - return DynamicNodeWalker.Previous(this, nodeTypeAlias); + return DynamicDocumentWalker.Previous(this, nodeTypeAlias); } - public DynamicNode Sibling(int number) + public DynamicDocument Sibling(int number) { - return DynamicNodeWalker.Sibling(this, number); + return DynamicDocumentWalker.Sibling(this, number); } - public DynamicNode Sibling(string nodeTypeAlias) + public DynamicDocument Sibling(string nodeTypeAlias) { - return DynamicNodeWalker.Sibling(this, nodeTypeAlias); + return DynamicDocumentWalker.Sibling(this, nodeTypeAlias); } - private DynamicNodeList GetChildren() + private DynamicDocumentList GetChildren() { if (_cachedChildren == null) { @@ -143,12 +143,12 @@ namespace Umbraco.Core.Dynamics //testing if (!children.Any() && _backingItem.Id == 0) { - _cachedChildren = new DynamicNodeList(new List { new DynamicNode(this._backingItem) }); + _cachedChildren = new DynamicDocumentList(new List { new DynamicDocument(this._backingItem) }); } else { - _cachedChildren = new DynamicNodeList(_backingItem.Children.Select(x => new DynamicNode(x))); - } + _cachedChildren = new DynamicDocumentList(_backingItem.Children.Select(x => new DynamicDocument(x))); + } } return _cachedChildren; } @@ -283,7 +283,7 @@ namespace Umbraco.Core.Dynamics try { var prop = _backingItem.GetUserProperty(name); - + return (prop != null); } catch (Exception) @@ -298,7 +298,7 @@ namespace Umbraco.Core.Dynamics try { //Property? - result = typeof(DynamicNode).InvokeMember(binder.Name, + result = typeof(DynamicDocument).InvokeMember(binder.Name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | @@ -313,7 +313,7 @@ namespace Umbraco.Core.Dynamics try { //Static or Instance Method? - result = typeof(DynamicNode).InvokeMember(binder.Name, + result = typeof(DynamicDocument).InvokeMember(binder.Name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | @@ -359,10 +359,10 @@ namespace Umbraco.Core.Dynamics { object result = null; - MethodInfo methodToExecute = ExtensionMethodFinder.FindExtensionMethod(typeof(IEnumerable), args, name, false); + MethodInfo methodToExecute = ExtensionMethodFinder.FindExtensionMethod(typeof(IEnumerable), args, name, false); if (methodToExecute == null) { - methodToExecute = ExtensionMethodFinder.FindExtensionMethod(typeof(DynamicNodeList), args, name, false); + methodToExecute = ExtensionMethodFinder.FindExtensionMethod(typeof(DynamicDocumentList), args, name, false); } if (methodToExecute != null) { @@ -379,13 +379,13 @@ namespace Umbraco.Core.Dynamics //{ // result = new DynamicNodeList((IEnumerable)result); //} - if (result is IEnumerable) + if (result is IEnumerable) { - result = new DynamicNodeList((IEnumerable)result); + result = new DynamicDocumentList((IEnumerable)result); } if (result is DynamicBackingItem) { - result = new DynamicNode((DynamicBackingItem)result); + result = new DynamicDocument((DynamicBackingItem)result); } } return result; @@ -484,7 +484,7 @@ namespace Umbraco.Core.Dynamics name = name.Substring(1, name.Length - 1); recursive = true; } - var userProperty = _backingItem.GetUserProperty(name, recursive); + var userProperty = _backingItem.GetUserProperty(name, recursive); //check for a user defined property @@ -500,7 +500,7 @@ namespace Umbraco.Core.Dynamics } //contextAlias is the node which the property data was returned from - var dataType = DynamicNodeDataSourceResolver.Current.DataSource.GetDataType(userProperty.DocumentTypeAlias, userProperty.Alias); + var dataType = DynamicDocumentDataSourceResolver.Current.DataSource.GetDataType(userProperty.DocumentTypeAlias, userProperty.Alias); //HttpContext.Current.Trace.Write(string.Format("RazorDynamicNode got datatype {0} for {1} on {2}", dataType, data.Alias, data.ContextAlias)); //HttpContext.Current.Trace.Write(string.Format("Checking for a RazorDataTypeModel for data type guid {0}...", dataType)); @@ -585,25 +585,13 @@ namespace Umbraco.Core.Dynamics // I'm pretty sure this means that if we have a 'Home' document type as the current type and it has children types that are for example called 'NewsPage' then // we can actually do this in the query: CurrentPage.NewsPages (plural) or CurrentPage.NewsPage (non-plural) and it will return the children of that type. - var typeChildren = _backingItem.Children; - if (typeChildren != null) + var filteredTypeChildren = _backingItem.Children + .Where(x => x.NodeTypeAlias.InvariantEquals(name) || x.NodeTypeAlias.MakePluralName().InvariantEquals(name)) + .ToArray(); + if (filteredTypeChildren.Any()) { - var filteredTypeChildren = typeChildren.Where(x => - { - var ancestorAliases = DynamicNodeDataSourceResolver.Current.DataSource.GetAncestorOrSelfNodeTypeAlias(x); - if (ancestorAliases == null) - { - return false; - } - return ancestorAliases.Any(alias => alias == name || MakePluralName(alias) == name); - }).ToArray(); - - if (filteredTypeChildren.Any()) - { - result = new DynamicNodeList(filteredTypeChildren.Select(x => new DynamicNode(x))); - return true; - } - + result = new DynamicDocumentList(filteredTypeChildren.Select(x => new DynamicDocument(x))); + return true; } //lastly, we'll try to get the property from the document object's member properties using reflection @@ -862,67 +850,26 @@ namespace Umbraco.Core.Dynamics // return null; //} - //this is from SqlMetal and just makes it a bit of fun to allow pluralisation - private static string MakePluralName(string name) - { - if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("ss", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase))) - { - name = name + "es"; - return name; - } - if ((name.EndsWith("y", StringComparison.OrdinalIgnoreCase) && (name.Length > 1)) && !IsVowel(name[name.Length - 2])) - { - name = name.Remove(name.Length - 1, 1); - name = name + "ies"; - return name; - } - if (!name.EndsWith("s", StringComparison.OrdinalIgnoreCase)) - { - name = name + "s"; - } - return name; - } - - private static bool IsVowel(char c) - { - switch (c) - { - case 'O': - case 'U': - case 'Y': - case 'A': - case 'E': - case 'I': - case 'o': - case 'u': - case 'y': - case 'a': - case 'e': - case 'i': - return true; - } - return false; - } - public DynamicNode AncestorOrSelf() + public DynamicDocument AncestorOrSelf() { //TODO: Why is this query like this?? return AncestorOrSelf(node => node.Level == 1); } - public DynamicNode AncestorOrSelf(int level) + public DynamicDocument AncestorOrSelf(int level) { return AncestorOrSelf(node => node.Level == level); } - public DynamicNode AncestorOrSelf(string nodeTypeAlias) + public DynamicDocument AncestorOrSelf(string nodeTypeAlias) { return AncestorOrSelf(node => node.NodeTypeAlias == nodeTypeAlias); } - public DynamicNode AncestorOrSelf(Func func) + public DynamicDocument AncestorOrSelf(Func func) { var node = this; while (node != null) { if (func(node)) return node; - DynamicNode parent = node.Parent; + DynamicDocument parent = node.Parent; if (parent != null) { if (this != parent) @@ -941,15 +888,15 @@ namespace Umbraco.Core.Dynamics } return node; } - public DynamicNodeList AncestorsOrSelf(Func func) + public DynamicDocumentList AncestorsOrSelf(Func func) { - var ancestorList = new List(); + var ancestorList = new List(); var node = this; ancestorList.Add(node); while (node != null) { if (node.Level == 1) break; - DynamicNode parent = node.Parent; + DynamicDocument parent = node.Parent; if (parent != null) { if (this != parent) @@ -971,50 +918,50 @@ namespace Umbraco.Core.Dynamics } } ancestorList.Reverse(); - return new DynamicNodeList(ancestorList); + return new DynamicDocumentList(ancestorList); } - public DynamicNodeList AncestorsOrSelf() + public DynamicDocumentList AncestorsOrSelf() { return AncestorsOrSelf(n => true); } - public DynamicNodeList AncestorsOrSelf(string nodeTypeAlias) + public DynamicDocumentList AncestorsOrSelf(string nodeTypeAlias) { return AncestorsOrSelf(n => n.NodeTypeAlias == nodeTypeAlias); } - public DynamicNodeList AncestorsOrSelf(int level) + public DynamicDocumentList AncestorsOrSelf(int level) { return AncestorsOrSelf(n => n.Level <= level); } - public DynamicNodeList Descendants(string nodeTypeAlias) + public DynamicDocumentList Descendants(string nodeTypeAlias) { return Descendants(p => p.NodeTypeAlias == nodeTypeAlias); } - public DynamicNodeList Descendants(int level) + public DynamicDocumentList Descendants(int level) { return Descendants(p => p.Level >= level); } - public DynamicNodeList Descendants() + public DynamicDocumentList Descendants() { return Descendants(n => true); } - public DynamicNodeList Descendants(Func func) + public DynamicDocumentList Descendants(Func func) { var flattenedNodes = this._backingItem.Children.Map(func, (DynamicBackingItem n) => n.Children); - return new DynamicNodeList(flattenedNodes.ToList().ConvertAll(dynamicBackingItem => new DynamicNode(dynamicBackingItem))); + return new DynamicDocumentList(flattenedNodes.ToList().ConvertAll(dynamicBackingItem => new DynamicDocument(dynamicBackingItem))); } - public DynamicNodeList DescendantsOrSelf(int level) + public DynamicDocumentList DescendantsOrSelf(int level) { return DescendantsOrSelf(p => p.Level >= level); } - public DynamicNodeList DescendantsOrSelf(string nodeTypeAlias) + public DynamicDocumentList DescendantsOrSelf(string nodeTypeAlias) { return DescendantsOrSelf(p => p.NodeTypeAlias == nodeTypeAlias); } - public DynamicNodeList DescendantsOrSelf() + public DynamicDocumentList DescendantsOrSelf() { return DescendantsOrSelf(p => true); } - public DynamicNodeList DescendantsOrSelf(Func func) + public DynamicDocumentList DescendantsOrSelf(Func func) { if (this._backingItem != null) { @@ -1024,30 +971,30 @@ namespace Umbraco.Core.Dynamics thisNode.Add(this._backingItem); } var flattenedNodes = this._backingItem.Children.Map(func, (DynamicBackingItem n) => n.Children); - return new DynamicNodeList(thisNode.Concat(flattenedNodes).ToList().ConvertAll(dynamicBackingItem => new DynamicNode(dynamicBackingItem))); + return new DynamicDocumentList(thisNode.Concat(flattenedNodes).ToList().ConvertAll(dynamicBackingItem => new DynamicDocument(dynamicBackingItem))); } - return new DynamicNodeList(Enumerable.Empty()); + return new DynamicDocumentList(Enumerable.Empty()); } - public DynamicNodeList Ancestors(int level) + public DynamicDocumentList Ancestors(int level) { return Ancestors(n => n.Level <= level); } - public DynamicNodeList Ancestors(string nodeTypeAlias) + public DynamicDocumentList Ancestors(string nodeTypeAlias) { return Ancestors(n => n.NodeTypeAlias == nodeTypeAlias); } - public DynamicNodeList Ancestors() + public DynamicDocumentList Ancestors() { return Ancestors(n => true); } - public DynamicNodeList Ancestors(Func func) + public DynamicDocumentList Ancestors(Func func) { - var ancestorList = new List(); + var ancestorList = new List(); var node = this; while (node != null) { if (node.Level == 1) break; - DynamicNode parent = node.Parent; + DynamicDocument parent = node.Parent; if (parent != null) { if (this != parent) @@ -1069,15 +1016,15 @@ namespace Umbraco.Core.Dynamics } } ancestorList.Reverse(); - return new DynamicNodeList(ancestorList); + return new DynamicDocumentList(ancestorList); } - public DynamicNode Parent + public DynamicDocument Parent { get - { + { if (_backingItem.Parent != null) { - return new DynamicNode(_backingItem.Parent); + return new DynamicDocument(_backingItem.Parent); } if (_backingItem != null && _backingItem.Id == 0) { @@ -1088,7 +1035,7 @@ namespace Umbraco.Core.Dynamics } //private readonly Lazy _razorLibrary = new Lazy(() => new RazorLibraryCore(null)); - + public int TemplateId { get { return _backingItem.TemplateId; } @@ -1107,7 +1054,7 @@ namespace Umbraco.Core.Dynamics { get { - + var umbracoNaviHide = _backingItem.GetUserProperty("umbracoNaviHide"); if (umbracoNaviHide != null) { @@ -1195,7 +1142,7 @@ namespace Umbraco.Core.Dynamics // get { if (_n == null) return null; return _n.Children; } //} - public IEnumerable Children + public IEnumerable Children { get { return GetChildren(); } } @@ -1232,7 +1179,7 @@ namespace Umbraco.Core.Dynamics { var prop = GetPropertyValue(alias, recursive); return !prop.IsNullOrWhiteSpace() ? prop : fallback; - } + } #endregion @@ -1294,11 +1241,11 @@ namespace Umbraco.Core.Dynamics { //var list = this.Parent.Children.Select(n => new DynamicNode(n)); var list = this.Parent.Children; - this.OwnerList = new DynamicNodeList(list); + this.OwnerList = new DynamicDocumentList(list); } if (this.OwnerList != null) { - List container = this.OwnerList.Items.ToList(); + List container = this.OwnerList.Items.ToList(); int currentIndex = container.FindIndex(n => n.Id == this.Id); if (currentIndex != -1) { @@ -1513,99 +1460,99 @@ namespace Umbraco.Core.Dynamics { return IsHelper(n => n.Index() % 2 == 1, valueIfTrue, valueIfFalse); } - public bool IsEqual(DynamicNode other) + public bool IsEqual(DynamicDocument other) { return IsHelper(n => n.Id == other.Id); } - public HtmlString IsEqual(DynamicNode other, string valueIfTrue) + public HtmlString IsEqual(DynamicDocument other, string valueIfTrue) { return IsHelper(n => n.Id == other.Id, valueIfTrue); } - public HtmlString IsEqual(DynamicNode other, string valueIfTrue, string valueIfFalse) + public HtmlString IsEqual(DynamicDocument other, string valueIfTrue, string valueIfFalse) { return IsHelper(n => n.Id == other.Id, valueIfTrue, valueIfFalse); } - public bool IsNotEqual(DynamicNode other) + public bool IsNotEqual(DynamicDocument other) { return IsHelper(n => n.Id != other.Id); } - public HtmlString IsNotEqual(DynamicNode other, string valueIfTrue) + public HtmlString IsNotEqual(DynamicDocument other, string valueIfTrue) { return IsHelper(n => n.Id != other.Id, valueIfTrue); } - public HtmlString IsNotEqual(DynamicNode other, string valueIfTrue, string valueIfFalse) + public HtmlString IsNotEqual(DynamicDocument other, string valueIfTrue, string valueIfFalse) { return IsHelper(n => n.Id != other.Id, valueIfTrue, valueIfFalse); } - public bool IsDescendant(DynamicNode other) + public bool IsDescendant(DynamicDocument other) { var ancestors = this.Ancestors(); return IsHelper(n => ancestors.Items.Find(ancestor => ancestor.Id == other.Id) != null); } - public HtmlString IsDescendant(DynamicNode other, string valueIfTrue) + public HtmlString IsDescendant(DynamicDocument other, string valueIfTrue) { var ancestors = this.Ancestors(); return IsHelper(n => ancestors.Items.Find(ancestor => ancestor.Id == other.Id) != null, valueIfTrue); } - public HtmlString IsDescendant(DynamicNode other, string valueIfTrue, string valueIfFalse) + public HtmlString IsDescendant(DynamicDocument other, string valueIfTrue, string valueIfFalse) { var ancestors = this.Ancestors(); return IsHelper(n => ancestors.Items.Find(ancestor => ancestor.Id == other.Id) != null, valueIfTrue, valueIfFalse); } - public bool IsDescendantOrSelf(DynamicNode other) + public bool IsDescendantOrSelf(DynamicDocument other) { var ancestors = this.AncestorsOrSelf(); return IsHelper(n => ancestors.Items.Find(ancestor => ancestor.Id == other.Id) != null); } - public HtmlString IsDescendantOrSelf(DynamicNode other, string valueIfTrue) + public HtmlString IsDescendantOrSelf(DynamicDocument other, string valueIfTrue) { var ancestors = this.AncestorsOrSelf(); return IsHelper(n => ancestors.Items.Find(ancestor => ancestor.Id == other.Id) != null, valueIfTrue); } - public HtmlString IsDescendantOrSelf(DynamicNode other, string valueIfTrue, string valueIfFalse) + public HtmlString IsDescendantOrSelf(DynamicDocument other, string valueIfTrue, string valueIfFalse) { var ancestors = this.AncestorsOrSelf(); return IsHelper(n => ancestors.Items.Find(ancestor => ancestor.Id == other.Id) != null, valueIfTrue, valueIfFalse); } - public bool IsAncestor(DynamicNode other) + public bool IsAncestor(DynamicDocument other) { var descendants = this.Descendants(); return IsHelper(n => descendants.Items.Find(descendant => descendant.Id == other.Id) != null); } - public HtmlString IsAncestor(DynamicNode other, string valueIfTrue) + public HtmlString IsAncestor(DynamicDocument other, string valueIfTrue) { var descendants = this.Descendants(); return IsHelper(n => descendants.Items.Find(descendant => descendant.Id == other.Id) != null, valueIfTrue); } - public HtmlString IsAncestor(DynamicNode other, string valueIfTrue, string valueIfFalse) + public HtmlString IsAncestor(DynamicDocument other, string valueIfTrue, string valueIfFalse) { var descendants = this.Descendants(); return IsHelper(n => descendants.Items.Find(descendant => descendant.Id == other.Id) != null, valueIfTrue, valueIfFalse); } - public bool IsAncestorOrSelf(DynamicNode other) + public bool IsAncestorOrSelf(DynamicDocument other) { var descendants = this.DescendantsOrSelf(); return IsHelper(n => descendants.Items.Find(descendant => descendant.Id == other.Id) != null); } - public HtmlString IsAncestorOrSelf(DynamicNode other, string valueIfTrue) + public HtmlString IsAncestorOrSelf(DynamicDocument other, string valueIfTrue) { var descendants = this.DescendantsOrSelf(); return IsHelper(n => descendants.Items.Find(descendant => descendant.Id == other.Id) != null, valueIfTrue); } - public HtmlString IsAncestorOrSelf(DynamicNode other, string valueIfTrue, string valueIfFalse) + public HtmlString IsAncestorOrSelf(DynamicDocument other, string valueIfTrue, string valueIfFalse) { var descendants = this.DescendantsOrSelf(); return IsHelper(n => descendants.Items.Find(descendant => descendant.Id == other.Id) != null, valueIfTrue, valueIfFalse); } - public bool IsHelper(Func test) + public bool IsHelper(Func test) { return test(this); } - public HtmlString IsHelper(Func test, string valueIfTrue) + public HtmlString IsHelper(Func test, string valueIfTrue) { return IsHelper(test, valueIfTrue, string.Empty); } - public HtmlString IsHelper(Func test, string valueIfTrue, string valueIfFalse) + public HtmlString IsHelper(Func test, string valueIfTrue, string valueIfFalse) { return test(this) ? new HtmlString(valueIfTrue) : new HtmlString(valueIfFalse); } @@ -1624,9 +1571,9 @@ namespace Umbraco.Core.Dynamics public bool Where(string predicate) { //Totally gonna cheat here - var dynamicNodeList = new DynamicNodeList(); + var dynamicNodeList = new DynamicDocumentList(); dynamicNodeList.Add(this); - var filtered = dynamicNodeList.Where(predicate); + var filtered = dynamicNodeList.Where(predicate); if (Queryable.Count(filtered) == 1) { //this node matches the predicate diff --git a/src/Umbraco.Core/Dynamics/DynamicNodeDataSourceResolver.cs b/src/Umbraco.Core/Dynamics/DynamicDocumentDataSourceResolver.cs similarity index 64% rename from src/Umbraco.Core/Dynamics/DynamicNodeDataSourceResolver.cs rename to src/Umbraco.Core/Dynamics/DynamicDocumentDataSourceResolver.cs index 4db42564f4..654af1e4c0 100644 --- a/src/Umbraco.Core/Dynamics/DynamicNodeDataSourceResolver.cs +++ b/src/Umbraco.Core/Dynamics/DynamicDocumentDataSourceResolver.cs @@ -7,11 +7,11 @@ namespace Umbraco.Core.Dynamics /// and currently the business logic part of Umbraco is still in the legacy project and we don't want to move that to the core so in the /// meantime until the new APIs are made, we need to have this data source in place with a resolver which is set in the web project. /// - internal class DynamicNodeDataSourceResolver : SingleObjectResolverBase + internal class DynamicDocumentDataSourceResolver : SingleObjectResolverBase { - public IDynamicNodeDataSource DataSource { get; private set; } + public IDynamicDocumentDataSource DataSource { get; private set; } - public DynamicNodeDataSourceResolver(IDynamicNodeDataSource dataSource) + public DynamicDocumentDataSourceResolver(IDynamicDocumentDataSource dataSource) { DataSource = dataSource; } diff --git a/src/Umbraco.Core/Dynamics/DynamicNodeIdEqualityComparer.cs b/src/Umbraco.Core/Dynamics/DynamicDocumentIdEqualityComparer.cs similarity index 74% rename from src/Umbraco.Core/Dynamics/DynamicNodeIdEqualityComparer.cs rename to src/Umbraco.Core/Dynamics/DynamicDocumentIdEqualityComparer.cs index 9d5110dfcd..8ad63cea5d 100644 --- a/src/Umbraco.Core/Dynamics/DynamicNodeIdEqualityComparer.cs +++ b/src/Umbraco.Core/Dynamics/DynamicDocumentIdEqualityComparer.cs @@ -3,10 +3,10 @@ using System.Collections.Generic; namespace Umbraco.Core.Dynamics { - internal class DynamicNodeIdEqualityComparer : EqualityComparer + internal class DynamicDocumentIdEqualityComparer : EqualityComparer { - public override bool Equals(DynamicNode x, DynamicNode y) + public override bool Equals(DynamicDocument x, DynamicDocument y) { //Check whether the compared objects reference the same data. if (Object.ReferenceEquals(x, y)) return true; @@ -20,7 +20,7 @@ namespace Umbraco.Core.Dynamics } - public override int GetHashCode(DynamicNode obj) + public override int GetHashCode(DynamicDocument obj) { if (Object.ReferenceEquals(obj, null)) return 0; diff --git a/src/Umbraco.Core/Dynamics/DynamicNodeList.cs b/src/Umbraco.Core/Dynamics/DynamicDocumentList.cs similarity index 79% rename from src/Umbraco.Core/Dynamics/DynamicNodeList.cs rename to src/Umbraco.Core/Dynamics/DynamicDocumentList.cs index 089ff3ad2b..9fe878d929 100644 --- a/src/Umbraco.Core/Dynamics/DynamicNodeList.cs +++ b/src/Umbraco.Core/Dynamics/DynamicDocumentList.cs @@ -9,17 +9,17 @@ using System.Reflection; namespace Umbraco.Core.Dynamics { - internal class DynamicNodeList : DynamicObject, IEnumerable + internal class DynamicDocumentList : DynamicObject, IEnumerable { - internal List Items { get; set; } + internal List Items { get; set; } - public DynamicNodeList() + public DynamicDocumentList() { - Items = new List(); + Items = new List(); } - public DynamicNodeList(IEnumerable items) + public DynamicDocumentList(IEnumerable items) { - List list = items.ToList(); + List list = items.ToList(); list.ForEach(node => node.OwnerList = this); Items = list; } @@ -31,9 +31,9 @@ namespace Umbraco.Core.Dynamics // Items = list; //} - public DynamicNodeList(IEnumerable items) + public DynamicDocumentList(IEnumerable items) { - List list = items.Select(x => new DynamicNode(x)).ToList(); + List list = items.Select(x => new DynamicDocument(x)).ToList(); list.ForEach(node => node.OwnerList = this); Items = list; } @@ -58,12 +58,12 @@ namespace Umbraco.Core.Dynamics { string predicate = args.First().ToString(); var values = args.Skip(1).ToArray(); - result = new DynamicNodeList(this.Where(predicate, values).ToList()); + result = new DynamicDocumentList(this.Where(predicate, values).ToList()); return true; } if (name == "OrderBy") { - result = new DynamicNodeList(this.OrderBy(args.First().ToString()).ToList()); + result = new DynamicDocumentList(this.OrderBy(args.First().ToString()).ToList()); return true; } if (name == "InGroupsOf") @@ -71,7 +71,7 @@ namespace Umbraco.Core.Dynamics int groupSize = 0; if (int.TryParse(args.First().ToString(), out groupSize)) { - result = this.InGroupsOf(groupSize); + result = this.InGroupsOf(groupSize); return true; } result = new DynamicNull(); @@ -82,7 +82,7 @@ namespace Umbraco.Core.Dynamics int groupCount = 0; if (int.TryParse(args.First().ToString(), out groupCount)) { - result = this.GroupedInto(groupCount); + result = this.GroupedInto(groupCount); return true; } result = new DynamicNull(); @@ -90,7 +90,7 @@ namespace Umbraco.Core.Dynamics } if (name == "GroupBy") { - result = this.GroupBy(args.First().ToString()); + result = this.GroupBy(args.First().ToString()); return true; } if (name == "Average" || name == "Min" || name == "Max" || name == "Sum") @@ -100,46 +100,46 @@ namespace Umbraco.Core.Dynamics } if (name == "Union") { - if ((args.First() as IEnumerable) != null) + if ((args.First() as IEnumerable) != null) { - result = new DynamicNodeList(this.Items.Union(args.First() as IEnumerable)); + result = new DynamicDocumentList(this.Items.Union(args.First() as IEnumerable)); return true; } - if ((args.First() as DynamicNodeList) != null) + if ((args.First() as DynamicDocumentList) != null) { - result = new DynamicNodeList(this.Items.Union((args.First() as DynamicNodeList).Items)); + result = new DynamicDocumentList(this.Items.Union((args.First() as DynamicDocumentList).Items)); return true; } } if (name == "Except") { - if ((args.First() as IEnumerable) != null) + if ((args.First() as IEnumerable) != null) { - result = new DynamicNodeList(this.Items.Except(args.First() as IEnumerable, new DynamicNodeIdEqualityComparer())); + result = new DynamicDocumentList(this.Items.Except(args.First() as IEnumerable, new DynamicDocumentIdEqualityComparer())); return true; } - if ((args.First() as DynamicNodeList) != null) + if ((args.First() as DynamicDocumentList) != null) { - result = new DynamicNodeList(this.Items.Except((args.First() as DynamicNodeList).Items, new DynamicNodeIdEqualityComparer())); + result = new DynamicDocumentList(this.Items.Except((args.First() as DynamicDocumentList).Items, new DynamicDocumentIdEqualityComparer())); return true; } } if (name == "Intersect") { - if ((args.First() as IEnumerable) != null) + if ((args.First() as IEnumerable) != null) { - result = new DynamicNodeList(this.Items.Intersect(args.First() as IEnumerable, new DynamicNodeIdEqualityComparer())); + result = new DynamicDocumentList(this.Items.Intersect(args.First() as IEnumerable, new DynamicDocumentIdEqualityComparer())); return true; } - if ((args.First() as DynamicNodeList) != null) + if ((args.First() as DynamicDocumentList) != null) { - result = new DynamicNodeList(this.Items.Intersect((args.First() as DynamicNodeList).Items, new DynamicNodeIdEqualityComparer())); + result = new DynamicDocumentList(this.Items.Intersect((args.First() as DynamicDocumentList).Items, new DynamicDocumentIdEqualityComparer())); return true; } } if (name == "Distinct") { - result = new DynamicNodeList(this.Items.Distinct(new DynamicNodeIdEqualityComparer())); + result = new DynamicDocumentList(this.Items.Distinct(new DynamicDocumentIdEqualityComparer())); return true; } if (name == "Pluck" || name == "Select") @@ -189,7 +189,7 @@ namespace Umbraco.Core.Dynamics //We do this to enable error checking of Razor Syntax when a method e.g. ElementAt(2) is used. //When the Script is tested, there's no Children which means ElementAt(2) is invalid (IndexOutOfRange) //Instead, we are going to return an empty DynamicNode. - result = new DynamicNode(); + result = new DynamicDocument(); return true; } @@ -353,14 +353,14 @@ namespace Umbraco.Core.Dynamics { object result = null; - MethodInfo methodToExecute = ExtensionMethodFinder.FindExtensionMethod(typeof(IEnumerable), args, name, false); + MethodInfo methodToExecute = ExtensionMethodFinder.FindExtensionMethod(typeof(IEnumerable), args, name, false); if (methodToExecute == null) { - methodToExecute = ExtensionMethodFinder.FindExtensionMethod(typeof(DynamicNodeList), args, name, false); + methodToExecute = ExtensionMethodFinder.FindExtensionMethod(typeof(DynamicDocumentList), args, name, false); } if (methodToExecute != null) { - if (methodToExecute.GetParameters().First().ParameterType == typeof(DynamicNodeList)) + if (methodToExecute.GetParameters().First().ParameterType == typeof(DynamicDocumentList)) { var genericArgs = (new[] { this }).Concat(args); result = methodToExecute.Invoke(null, genericArgs.ToArray()); @@ -379,15 +379,15 @@ namespace Umbraco.Core.Dynamics { if (result is IEnumerable) { - result = new DynamicNodeList((IEnumerable)result); + result = new DynamicDocumentList((IEnumerable)result); } - if (result is IEnumerable) + if (result is IEnumerable) { - result = new DynamicNodeList((IEnumerable)result); + result = new DynamicDocumentList((IEnumerable)result); } if (result is INode) { - result = new DynamicNode((IDocument)result); + result = new DynamicDocument((IDocument)result); } } return result; @@ -422,9 +422,9 @@ namespace Umbraco.Core.Dynamics return new DynamicGrouping( this .Items - .Select((node, index) => new KeyValuePair(index, node)) + .Select((node, index) => new KeyValuePair(index, node)) .GroupBy(kv => (object)(kv.Key / groupSize)) - .Select(item => new Grouping() + .Select(item => new Grouping() { Key = item.Key, Elements = item.Select(inner => inner.Value) @@ -435,9 +435,9 @@ namespace Umbraco.Core.Dynamics return new DynamicGrouping( this .Items - .Select((node, index) => new KeyValuePair(index, node)) + .Select((node, index) => new KeyValuePair(index, node)) .GroupBy(kv => (object)(kv.Key / groupSize)) - .Select(item => new Grouping() + .Select(item => new Grouping() { Key = item.Key, Elements = item.Select(inner => inner.Value) @@ -450,17 +450,17 @@ namespace Umbraco.Core.Dynamics return DynamicQueryable.Select(Items.AsQueryable(), predicate, values); } - public void Add(DynamicNode node) + public void Add(DynamicDocument document) { - node.OwnerList = this; - this.Items.Add(node); + document.OwnerList = this; + this.Items.Add(document); } - public void Remove(DynamicNode node) + public void Remove(DynamicDocument document) { - if (this.Items.Contains(node)) + if (this.Items.Contains(document)) { - node.OwnerList = null; - this.Items.Remove(node); + document.OwnerList = null; + this.Items.Remove(document); } } public bool IsNull() @@ -472,7 +472,7 @@ namespace Umbraco.Core.Dynamics return true; } - public IEnumerator GetEnumerator() + public IEnumerator GetEnumerator() { return Items.GetEnumerator(); } diff --git a/src/Umbraco.Core/Dynamics/DynamicNodeListOrdering.cs b/src/Umbraco.Core/Dynamics/DynamicDocumentListOrdering.cs similarity index 59% rename from src/Umbraco.Core/Dynamics/DynamicNodeListOrdering.cs rename to src/Umbraco.Core/Dynamics/DynamicDocumentListOrdering.cs index bcbd3458bb..3d408db28b 100644 --- a/src/Umbraco.Core/Dynamics/DynamicNodeListOrdering.cs +++ b/src/Umbraco.Core/Dynamics/DynamicDocumentListOrdering.cs @@ -5,15 +5,15 @@ using System.Linq.Expressions; namespace Umbraco.Core.Dynamics { - internal static class DynamicNodeListOrdering + internal static class DynamicDocumentListOrdering { - private static TOut Reduce(Func func, DynamicNode node) + private static TOut Reduce(Func func, DynamicDocument document) { - var value = func(node); - while (value is Func) + var value = func(document); + while (value is Func) { - value = (value as Func)(node); + value = (value as Func)(document); } //when you're sorting a list of properties //and one of those properties doesn't exist, it will come back as DynamicNull @@ -37,209 +37,209 @@ namespace Umbraco.Core.Dynamics } return (TOut)value; } - public static IOrderedQueryable OrderBy(object source, object key) + public static IOrderedQueryable OrderBy(object source, object key) { - IEnumerable typedSource = source as IEnumerable; + IEnumerable typedSource = source as IEnumerable; LambdaExpression lambda = key as LambdaExpression; //if the lambda we have returns an actual property, not a dynamic one, //then the TOut of the func will be the actual type, not object //Func func = (Func)lambda.Compile(); var func = lambda.Compile(); var TOut = func.GetType().GetGenericArguments()[1]; - IOrderedQueryable result = null; - if (TOut == typeof(Func)) + IOrderedQueryable result = null; + if (TOut == typeof(Func)) { - result = (IOrderedQueryable)typedSource - .OrderBy(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .OrderBy(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(object)) { - result = (IOrderedQueryable)typedSource - .OrderBy(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .OrderBy(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(bool)) { - result = (IOrderedQueryable)typedSource - .OrderBy(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .OrderBy(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(decimal)) { - result = (IOrderedQueryable)typedSource - .OrderBy(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .OrderBy(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(int)) { - result = (IOrderedQueryable)typedSource - .OrderBy(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .OrderBy(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(string)) { - result = (IOrderedQueryable)typedSource - .OrderBy(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .OrderBy(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(DateTime)) { - result = (IOrderedQueryable)typedSource - .OrderBy(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .OrderBy(x => Reduce(func as Func, x)) .AsQueryable(); } return result; } - public static IOrderedQueryable ThenBy(object source, object key) + public static IOrderedQueryable ThenBy(object source, object key) { - IOrderedQueryable typedSource = source as IOrderedQueryable; + IOrderedQueryable typedSource = source as IOrderedQueryable; LambdaExpression lambda = key as LambdaExpression; var func = lambda.Compile(); var TOut = func.GetType().GetGenericArguments()[1]; - IOrderedQueryable result = null; - if (TOut == typeof(Func)) + IOrderedQueryable result = null; + if (TOut == typeof(Func)) { - result = (IOrderedQueryable)typedSource - .ThenBy(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .ThenBy(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(object)) { - result = (IOrderedQueryable)typedSource - .ThenBy(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .ThenBy(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(bool)) { - result = (IOrderedQueryable)typedSource - .ThenBy(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .ThenBy(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(decimal)) { - result = (IOrderedQueryable)typedSource - .ThenBy(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .ThenBy(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(int)) { - result = (IOrderedQueryable)typedSource - .ThenBy(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .ThenBy(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(string)) { - result = (IOrderedQueryable)typedSource - .ThenBy(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .ThenBy(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(DateTime)) { - result = (IOrderedQueryable)typedSource - .ThenBy(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .ThenBy(x => Reduce(func as Func, x)) .AsQueryable(); } return result; } - public static IOrderedQueryable OrderByDescending(object source, object key) + public static IOrderedQueryable OrderByDescending(object source, object key) { - IEnumerable typedSource = source as IEnumerable; + IEnumerable typedSource = source as IEnumerable; LambdaExpression lambda = key as LambdaExpression; var func = lambda.Compile(); var TOut = func.GetType().GetGenericArguments()[1]; - IOrderedQueryable result = null; - if (TOut == typeof(Func)) + IOrderedQueryable result = null; + if (TOut == typeof(Func)) { - result = (IOrderedQueryable)typedSource - .OrderByDescending(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .OrderByDescending(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(object)) { - result = (IOrderedQueryable)typedSource - .OrderByDescending(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .OrderByDescending(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(bool)) { - result = (IOrderedQueryable)typedSource - .OrderByDescending(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .OrderByDescending(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(decimal)) { - result = (IOrderedQueryable)typedSource - .OrderByDescending(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .OrderByDescending(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(int)) { - result = (IOrderedQueryable)typedSource - .OrderByDescending(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .OrderByDescending(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(string)) { - result = (IOrderedQueryable)typedSource - .OrderByDescending(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .OrderByDescending(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(DateTime)) { - result = (IOrderedQueryable)typedSource - .OrderByDescending(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .OrderByDescending(x => Reduce(func as Func, x)) .AsQueryable(); } return result; } - public static IOrderedQueryable ThenByDescending(object source, object key) + public static IOrderedQueryable ThenByDescending(object source, object key) { - IOrderedQueryable typedSource = source as IOrderedQueryable; + IOrderedQueryable typedSource = source as IOrderedQueryable; LambdaExpression lambda = key as LambdaExpression; var func = lambda.Compile(); var TOut = func.GetType().GetGenericArguments()[1]; - IOrderedQueryable result = null; - if (TOut == typeof(Func)) + IOrderedQueryable result = null; + if (TOut == typeof(Func)) { - result = (IOrderedQueryable)typedSource - .ThenByDescending(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .ThenByDescending(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(object)) { - result = (IOrderedQueryable)typedSource - .ThenByDescending(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .ThenByDescending(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(bool)) { - result = (IOrderedQueryable)typedSource - .ThenByDescending(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .ThenByDescending(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(decimal)) { - result = (IOrderedQueryable)typedSource - .ThenByDescending(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .ThenByDescending(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(int)) { - result = (IOrderedQueryable)typedSource - .ThenByDescending(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .ThenByDescending(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(string)) { - result = (IOrderedQueryable)typedSource - .ThenByDescending(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .ThenByDescending(x => Reduce(func as Func, x)) .AsQueryable(); } if (TOut == typeof(DateTime)) { - result = (IOrderedQueryable)typedSource - .ThenByDescending(x => Reduce(func as Func, x)) + result = (IOrderedQueryable)typedSource + .ThenByDescending(x => Reduce(func as Func, x)) .AsQueryable(); } return result; diff --git a/src/Umbraco.Core/Dynamics/DynamicNodeWalker.cs b/src/Umbraco.Core/Dynamics/DynamicDocumentWalker.cs similarity index 75% rename from src/Umbraco.Core/Dynamics/DynamicNodeWalker.cs rename to src/Umbraco.Core/Dynamics/DynamicDocumentWalker.cs index 1f5feda4dd..3a1ca1398d 100644 --- a/src/Umbraco.Core/Dynamics/DynamicNodeWalker.cs +++ b/src/Umbraco.Core/Dynamics/DynamicDocumentWalker.cs @@ -4,13 +4,13 @@ using System.Linq; namespace Umbraco.Core.Dynamics { - internal static class DynamicNodeWalker + internal static class DynamicDocumentWalker { - public static DynamicNode Up(this DynamicNode context) + public static DynamicDocument Up(this DynamicDocument context) { return context.Up(0); } - public static DynamicNode Up(this DynamicNode context, int number) + public static DynamicDocument Up(this DynamicDocument context, int number) { if (number == 0) { @@ -22,7 +22,7 @@ namespace Umbraco.Core.Dynamics return context; } } - public static DynamicNode Up(this DynamicNode context, string nodeTypeAlias) + public static DynamicDocument Up(this DynamicDocument context, string nodeTypeAlias) { if (string.IsNullOrEmpty(nodeTypeAlias)) { @@ -35,34 +35,34 @@ namespace Umbraco.Core.Dynamics } } - public static DynamicNode Down(this DynamicNode context) + public static DynamicDocument Down(this DynamicDocument context) { return context.Down(0); } - public static DynamicNode Down(this DynamicNode context, int number) + public static DynamicDocument Down(this DynamicDocument context, int number) { - var children = new DynamicNodeList(context.Children); + var children = new DynamicDocumentList(context.Children); if (number == 0) { return children.Items.First(); } else { - DynamicNode working = context; + DynamicDocument working = context; while (number-- >= 0) { working = children.Items.First(); - children = new DynamicNodeList(working.Children); + children = new DynamicDocumentList(working.Children); } return working; } } - public static DynamicNode Down(this DynamicNode context, string nodeTypeAlias) + public static DynamicDocument Down(this DynamicDocument context, string nodeTypeAlias) { if (string.IsNullOrEmpty(nodeTypeAlias)) { - var children = new DynamicNodeList(context.Children); + var children = new DynamicDocumentList(context.Children); return children.Items.First(); } else @@ -70,17 +70,17 @@ namespace Umbraco.Core.Dynamics return context.Descendants(nodeTypeAlias).Items.FirstOrDefault(); } } - public static DynamicNode Next(this DynamicNode context) + public static DynamicDocument Next(this DynamicDocument context) { return context.Next(0); } - public static DynamicNode Next(this DynamicNode context, int number) + public static DynamicDocument Next(this DynamicDocument context, int number) { if (context.OwnerList == null && context.Parent != null) { //var list = context.Parent.Children.Select(n => new DynamicNode(n)); var list = context.Parent.Children; - context.OwnerList = new DynamicNodeList(list); + context.OwnerList = new DynamicDocumentList(list); } if (context.OwnerList != null) { @@ -100,13 +100,13 @@ namespace Umbraco.Core.Dynamics throw new ArgumentNullException(string.Format("Node {0} has been orphaned and doesn't belong to a DynamicNodeList", context.Id)); } } - public static DynamicNode Sibling(this DynamicNode context, int number) + public static DynamicDocument Sibling(this DynamicDocument context, int number) { if (context.OwnerList == null && context.Parent != null) { //var list = context.Parent.Children.Select(n => new DynamicNode(n)); var list = context.Parent.Children; - context.OwnerList = new DynamicNodeList(list); + context.OwnerList = new DynamicDocumentList(list); } if (context.OwnerList != null) { @@ -126,13 +126,13 @@ namespace Umbraco.Core.Dynamics throw new ArgumentNullException(string.Format("Node {0} has been orphaned and doesn't belong to a DynamicNodeList", context.Id)); } } - public static DynamicNode Sibling(this DynamicNode context, string nodeTypeAlias) + public static DynamicDocument Sibling(this DynamicDocument context, string nodeTypeAlias) { if (context.OwnerList == null && context.Parent != null) { //var list = context.Parent.Children.Select(n => new DynamicNode(n)); var list = context.Parent.Children; - context.OwnerList = new DynamicNodeList(list); + context.OwnerList = new DynamicDocumentList(list); } if (context.OwnerList != null) { @@ -166,13 +166,13 @@ namespace Umbraco.Core.Dynamics throw new ArgumentNullException(string.Format("Node {0} has been orphaned and doesn't belong to a DynamicNodeList", context.Id)); } } - public static DynamicNode Next(this DynamicNode context, string nodeTypeAlias) + public static DynamicDocument Next(this DynamicDocument context, string nodeTypeAlias) { if (context.OwnerList == null && context.Parent != null) { //var list = context.Parent.Children.Select(n => new DynamicNode(n)); var list = context.Parent.Children; - context.OwnerList = new DynamicNodeList(list); + context.OwnerList = new DynamicDocumentList(list); } if (context.OwnerList != null) { @@ -197,21 +197,21 @@ namespace Umbraco.Core.Dynamics throw new ArgumentNullException(string.Format("Node {0} has been orphaned and doesn't belong to a DynamicNodeList", context.Id)); } } - public static DynamicNode Previous(this DynamicNode context) + public static DynamicDocument Previous(this DynamicDocument context) { return context.Previous(0); } - public static DynamicNode Previous(this DynamicNode context, int number) + public static DynamicDocument Previous(this DynamicDocument context, int number) { if (context.OwnerList == null && context.Parent != null) { //var list = context.Parent.Children.Select(n => new DynamicNode(n)); var list = context.Parent.Children; - context.OwnerList = new DynamicNodeList(list); + context.OwnerList = new DynamicDocumentList(list); } if (context.OwnerList != null) { - List container = context.OwnerList.Items.ToList(); + List container = context.OwnerList.Items.ToList(); int currentIndex = container.FindIndex(n => n.Id == context.Id); if (currentIndex != -1) { @@ -227,17 +227,17 @@ namespace Umbraco.Core.Dynamics throw new ArgumentNullException(string.Format("Node {0} has been orphaned and doesn't belong to a DynamicNodeList", context.Id)); } } - public static DynamicNode Previous(this DynamicNode context, string nodeTypeAlias) + public static DynamicDocument Previous(this DynamicDocument context, string nodeTypeAlias) { if (context.OwnerList == null && context.Parent != null) { //var list = context.Parent.Children.Select(n => new DynamicNode(n)); var list = context.Parent.Children; - context.OwnerList = new DynamicNodeList(list); + context.OwnerList = new DynamicDocumentList(list); } if (context.OwnerList != null) { - List container = context.OwnerList.Items.ToList(); + List container = context.OwnerList.Items.ToList(); int currentIndex = container.FindIndex(n => n.Id == context.Id); if (currentIndex != -1) { diff --git a/src/Umbraco.Core/Dynamics/DynamicGrouping.cs b/src/Umbraco.Core/Dynamics/DynamicGrouping.cs index f5e51e414a..5d932869fc 100644 --- a/src/Umbraco.Core/Dynamics/DynamicGrouping.cs +++ b/src/Umbraco.Core/Dynamics/DynamicGrouping.cs @@ -6,14 +6,14 @@ namespace Umbraco.Core.Dynamics { internal class DynamicGrouping : IEnumerable { - public IEnumerable> Inner; + public IEnumerable> Inner; public DynamicGrouping OrderBy(string expression) { return this; } - public DynamicGrouping(DynamicNodeList list, string groupBy) + public DynamicGrouping(DynamicDocumentList list, string groupBy) { Inner = list @@ -21,7 +21,7 @@ namespace Umbraco.Core.Dynamics .Select(node => { string predicate = groupBy; - var internalList = new DynamicNodeList(new DynamicNode[] { node }); + var internalList = new DynamicDocumentList(new DynamicDocument[] { node }); var query = (IQueryable)internalList.Select(predicate, new object[] { }); var key = query.FirstOrDefault(); return new @@ -32,13 +32,13 @@ namespace Umbraco.Core.Dynamics }) .Where(item => item.Key != null) .GroupBy(item => item.Key) - .Select(item => new Grouping() + .Select(item => new Grouping() { Key = item.Key, Elements = item.Select(inner => inner.Node) }); } - public DynamicGrouping(IEnumerable> source) + public DynamicGrouping(IEnumerable> source) { this.Inner = source; } diff --git a/src/Umbraco.Core/Dynamics/DynamicQueryable.cs b/src/Umbraco.Core/Dynamics/DynamicQueryable.cs index 76b0dc07bc..aadb6d3a98 100644 --- a/src/Umbraco.Core/Dynamics/DynamicQueryable.cs +++ b/src/Umbraco.Core/Dynamics/DynamicQueryable.cs @@ -21,22 +21,22 @@ namespace Umbraco.Core.Dynamics if (source == null) throw new ArgumentNullException("source"); if (predicate == null) throw new ArgumentNullException("predicate"); LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, typeof(bool), predicate, true, values); - if (lambda.Parameters.Count > 0 && lambda.Parameters[0].Type == typeof(DynamicNode)) + if (lambda.Parameters.Count > 0 && lambda.Parameters[0].Type == typeof(DynamicDocument)) { //source list is DynamicNode and the lambda returns a Func - IQueryable typedSource = source as IQueryable; + IQueryable typedSource = source as IQueryable; var compiledFunc = lambda.Compile(); - Func func = null; - Func boolFunc = null; - if (compiledFunc is Func) + Func func = null; + Func boolFunc = null; + if (compiledFunc is Func) { - func = (Func)compiledFunc; + func = (Func)compiledFunc; } - if (compiledFunc is Func) + if (compiledFunc is Func) { - boolFunc = (Func)compiledFunc; + boolFunc = (Func)compiledFunc; } - return typedSource.Where(delegate(DynamicNode node) + return typedSource.Where(delegate(DynamicDocument node) { object value = -1; //value = func(node); @@ -46,13 +46,13 @@ namespace Umbraco.Core.Dynamics if (func != null) { var firstFuncResult = func(node); - if (firstFuncResult is Func) + if (firstFuncResult is Func) { - value = (firstFuncResult as Func)(node); + value = (firstFuncResult as Func)(node); } - if (firstFuncResult is Func) + if (firstFuncResult is Func) { - value = (firstFuncResult as Func)(node); + value = (firstFuncResult as Func)(node); } if (firstFuncResult is bool) { @@ -86,28 +86,28 @@ namespace Umbraco.Core.Dynamics } } - public static IQueryable Select(this IQueryable source, string selector, params object[] values) + public static IQueryable Select(this IQueryable source, string selector, params object[] values) { if (source == null) throw new ArgumentNullException("source"); if (selector == null) throw new ArgumentNullException("selector"); LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, typeof(object), selector, false, values); - if (lambda.Parameters.Count > 0 && lambda.Parameters[0].Type == typeof(DynamicNode)) + if (lambda.Parameters.Count > 0 && lambda.Parameters[0].Type == typeof(DynamicDocument)) { //source list is DynamicNode and the lambda returns a Func - IQueryable typedSource = source as IQueryable; + IQueryable typedSource = source as IQueryable; var compiledFunc = lambda.Compile(); - Func func = null; - if (compiledFunc is Func) + Func func = null; + if (compiledFunc is Func) { - func = (Func)compiledFunc; + func = (Func)compiledFunc; } - return typedSource.Select(delegate(DynamicNode node) + return typedSource.Select(delegate(DynamicDocument node) { object value = null; value = func(node); - if (value is Func) + if (value is Func) { - var innerValue = (value as Func)(node); + var innerValue = (value as Func)(node); return innerValue; } return value; @@ -133,7 +133,7 @@ namespace Umbraco.Core.Dynamics if (source == null) throw new ArgumentNullException("source"); if (ordering == null) throw new ArgumentNullException("ordering"); - IQueryable typedSource = source as IQueryable; + IQueryable typedSource = source as IQueryable; if (!ordering.Contains(",")) { bool descending = false; @@ -149,10 +149,10 @@ namespace Umbraco.Core.Dynamics } LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, typeof(object), ordering, false, values); - if (lambda.Parameters.Count > 0 && lambda.Parameters[0].Type == typeof(DynamicNode)) + if (lambda.Parameters.Count > 0 && lambda.Parameters[0].Type == typeof(DynamicDocument)) { //source list is DynamicNode and the lambda returns a Func - Func func = (Func)lambda.Compile(); + Func func = (Func)lambda.Compile(); //get the values out var query = typedSource.ToList().ConvertAll(item => new { node = item, key = EvaluateDynamicNodeFunc(item, func) }); if (query.Count == 0) @@ -214,7 +214,7 @@ namespace Umbraco.Core.Dynamics //reroute each stacked Expression.Call into our own methods that know how to deal //with DynamicNode queryExpr = Expression.Call( - typeof(DynamicNodeListOrdering), + typeof(DynamicDocumentListOrdering), o.Ascending ? methodAsc : methodDesc, null, queryExpr, @@ -246,13 +246,13 @@ namespace Umbraco.Core.Dynamics return null; } } - private static object EvaluateDynamicNodeFunc(DynamicNode node, Func func) + private static object EvaluateDynamicNodeFunc(DynamicDocument document, Func func) { object value = -1; - var firstFuncResult = func(node); - if (firstFuncResult is Func) + var firstFuncResult = func(document); + if (firstFuncResult is Func) { - value = (firstFuncResult as Func)(node); + value = (firstFuncResult as Func)(document); } if (firstFuncResult.GetType().IsValueType || firstFuncResult is string) { diff --git a/src/Umbraco.Core/Dynamics/ExpressionParser.cs b/src/Umbraco.Core/Dynamics/ExpressionParser.cs index 87158069fd..e041dcc6ec 100644 --- a/src/Umbraco.Core/Dynamics/ExpressionParser.cs +++ b/src/Umbraco.Core/Dynamics/ExpressionParser.cs @@ -507,7 +507,7 @@ namespace Umbraco.Core.Dynamics (expr as LambdaExpression).Parameters.CopyTo(parameters, 0); var invokedExpr = Expression.Invoke(expr, parameters); var not = Expression.Not(Expression.TypeAs(invokedExpr, typeof(Nullable))); - expr = Expression.Lambda>( + expr = Expression.Lambda>( Expression.Condition( Expression.Property(not, "HasValue"), Expression.Property(not, "Value"), @@ -854,11 +854,11 @@ namespace Umbraco.Core.Dynamics Expression[] args = ParseArgumentList(); MethodBase mb; LambdaExpression instanceAsString = null; - ParameterExpression instanceExpression = Expression.Parameter(typeof(DynamicNode), "instance"); + ParameterExpression instanceExpression = Expression.Parameter(typeof(DynamicDocument), "instance"); if (type.IsGenericType && type != typeof(string)) { var typeArgs = type.GetGenericArguments(); - if (typeArgs[0] == typeof(DynamicNode)) + if (typeArgs[0] == typeof(DynamicDocument)) { if (instance != null && instance is LambdaExpression) { @@ -929,14 +929,14 @@ namespace Umbraco.Core.Dynamics //this will invoke TryGetMember (but wrapped in an expression tree) //so that when it's evaluated, DynamicNode should be supported - ParameterExpression instanceExpression = Expression.Parameter(typeof(DynamicNode), "instance"); + ParameterExpression instanceExpression = Expression.Parameter(typeof(DynamicDocument), "instance"); ParameterExpression convertDynamicNullToBooleanFalse = Expression.Parameter(typeof(bool), "convertDynamicNullToBooleanFalse"); ParameterExpression result = Expression.Parameter(typeof(object), "result"); ParameterExpression binder = Expression.Variable(typeof(DynamicQueryableGetMemberBinder), "binder"); ParameterExpression ignoreCase = Expression.Variable(typeof(bool), "ignoreCase"); ConstructorInfo getMemberBinderConstructor = typeof(DynamicQueryableGetMemberBinder).GetConstructor(new Type[] { typeof(string), typeof(bool) }); LabelTarget blockReturnLabel = Expression.Label(typeof(object)); - MethodInfo method = typeof(DynamicNode).GetMethod("TryGetMember"); + MethodInfo method = typeof(DynamicDocument).GetMethod("TryGetMember"); BlockExpression block = Expression.Block( typeof(object), @@ -957,10 +957,10 @@ namespace Umbraco.Core.Dynamics Expression.Return(blockReturnLabel, result), Expression.Label(blockReturnLabel, Expression.Constant(-2, typeof(object))) ); - LambdaExpression lax = Expression.Lambda>(block, instanceExpression); + LambdaExpression lax = Expression.Lambda>(block, instanceExpression); return lax; } - if (typeof(Func).IsAssignableFrom(type)) + if (typeof(Func).IsAssignableFrom(type)) { //accessing a property off an already resolved DynamicNode TryGetMember call //e.g. uBlogsyPostDate.Date @@ -969,8 +969,8 @@ namespace Umbraco.Core.Dynamics ParameterExpression result = Expression.Parameter(typeof(object), "result"); ParameterExpression idParam = Expression.Parameter(typeof(string), "id"); ParameterExpression lambdaResult = Expression.Parameter(typeof(object), "lambdaResult"); - ParameterExpression lambdaInstanceExpression = Expression.Parameter(typeof(DynamicNode), "lambdaInstanceExpression"); - ParameterExpression instanceExpression = Expression.Parameter(typeof(Func), "instance"); + ParameterExpression lambdaInstanceExpression = Expression.Parameter(typeof(DynamicDocument), "lambdaInstanceExpression"); + ParameterExpression instanceExpression = Expression.Parameter(typeof(Func), "instance"); LabelTarget blockReturnLabel = Expression.Label(typeof(object)); BlockExpression block = Expression.Block( @@ -989,7 +989,7 @@ namespace Umbraco.Core.Dynamics Expression.Return(blockReturnLabel, result), Expression.Label(blockReturnLabel, Expression.Constant(-2, typeof(object))) ); - LambdaExpression lax = Expression.Lambda>(block, lambdaInstanceExpression); + LambdaExpression lax = Expression.Lambda>(block, lambdaInstanceExpression); return lax; } } @@ -1048,11 +1048,11 @@ namespace Umbraco.Core.Dynamics switch (methodReturnType.Name) { case "String": - return Expression.Lambda>(block, instanceExpression); + return Expression.Lambda>(block, instanceExpression); case "Int32": - return Expression.Lambda>(block, instanceExpression); + return Expression.Lambda>(block, instanceExpression); case "Boolean": - return Expression.Lambda>(block, instanceExpression); + return Expression.Lambda>(block, instanceExpression); } return Expression.Call(instance, (MethodInfo)method, args); } @@ -1090,8 +1090,8 @@ namespace Umbraco.Core.Dynamics Expression.Return(cblockReturnLabel, cresult), Expression.Label(cblockReturnLabel, Expression.Constant(null, typeof(string)))); - LambdaExpression lax2 = Expression.Lambda>(cblock, instanceExpression); - var expression = Expression.Lambda>(cblock, instanceExpression); + LambdaExpression lax2 = Expression.Lambda>(cblock, instanceExpression); + var expression = Expression.Lambda>(cblock, instanceExpression); return expression; } @@ -1408,7 +1408,7 @@ namespace Umbraco.Core.Dynamics //if the type of the expression is a func - invokable returning object, //we are going to return it here, because we can get the real value when we actually have the instance //if (typeof(Func).IsAssignableFrom(expr.Type)) return expr; - if (expr is LambdaExpression && ((LambdaExpression)expr).Parameters.Count > 0 && ((LambdaExpression)expr).Parameters[0].Type == typeof(DynamicNode)) + if (expr is LambdaExpression && ((LambdaExpression)expr).Parameters.Count > 0 && ((LambdaExpression)expr).Parameters[0].Type == typeof(DynamicDocument)) { return expr; } @@ -1687,12 +1687,12 @@ namespace Umbraco.Core.Dynamics UnaryExpression unboxedLeft = null, unboxedRight = null; ParameterExpression[] parameters = null; - if (left is LambdaExpression && (left as LambdaExpression).Type.GetGenericArguments().First() == typeof(DynamicNode)) + if (left is LambdaExpression && (left as LambdaExpression).Type.GetGenericArguments().First() == typeof(DynamicDocument)) { leftIsLambda = true; } - if (right is LambdaExpression && (right as LambdaExpression).Type.GetGenericArguments().First() == typeof(DynamicNode)) + if (right is LambdaExpression && (right as LambdaExpression).Type.GetGenericArguments().First() == typeof(DynamicDocument)) { rightIsLambda = true; } @@ -1746,11 +1746,11 @@ namespace Umbraco.Core.Dynamics if (expressionType == ExpressionType.AndAlso) { - return ExpressionExtensions.And(left as Expression>, right as Expression>); + return ExpressionExtensions.And(left as Expression>, right as Expression>); } if (expressionType == ExpressionType.OrElse) { - return ExpressionExtensions.Or(left as Expression>, right as Expression>); + return ExpressionExtensions.Or(left as Expression>, right as Expression>); } } @@ -1781,11 +1781,11 @@ namespace Umbraco.Core.Dynamics //left is invoked and unboxed to right's TOut, right was not boxed if (expressionType == ExpressionType.AndAlso) { - return ExpressionExtensions.And(right as Expression>, Expression.Lambda>(unboxedLeft, parameters) as Expression>); + return ExpressionExtensions.And(right as Expression>, Expression.Lambda>(unboxedLeft, parameters) as Expression>); } if (expressionType == ExpressionType.OrElse) { - return ExpressionExtensions.And(right as Expression>, Expression.Lambda>(unboxedLeft, parameters) as Expression>); + return ExpressionExtensions.And(right as Expression>, Expression.Lambda>(unboxedLeft, parameters) as Expression>); } } else @@ -1802,11 +1802,11 @@ namespace Umbraco.Core.Dynamics //right is invoked and unboxed to left's TOut, left was not boxed if (expressionType == ExpressionType.AndAlso) { - return ExpressionExtensions.And(left as Expression>, Expression.Lambda>(unboxedRight, parameters) as Expression>); + return ExpressionExtensions.And(left as Expression>, Expression.Lambda>(unboxedRight, parameters) as Expression>); } if (expressionType == ExpressionType.OrElse) { - return ExpressionExtensions.And(left as Expression>, Expression.Lambda>(unboxedRight, parameters) as Expression>); + return ExpressionExtensions.And(left as Expression>, Expression.Lambda>(unboxedRight, parameters) as Expression>); } } @@ -1877,7 +1877,7 @@ namespace Umbraco.Core.Dynamics break; case ExpressionType.Modulo: binaryExpression = Expression.Modulo(finalLeft, finalRight); - return (Expression.Lambda>(binaryExpression, parameters)); + return (Expression.Lambda>(binaryExpression, parameters)); case ExpressionType.AndAlso: if ((leftIsLambda && rightIsLambda && sequenceEqual) || (!leftIsLambda && !rightIsLambda)) { @@ -1885,7 +1885,7 @@ namespace Umbraco.Core.Dynamics } else { - return (Expression.Lambda>(Expression.AndAlso(finalLeft, finalRight), parameters)); + return (Expression.Lambda>(Expression.AndAlso(finalLeft, finalRight), parameters)); } case ExpressionType.OrElse: if (leftIsLambda && rightIsLambda && sequenceEqual || (!leftIsLambda && !rightIsLambda)) @@ -1894,7 +1894,7 @@ namespace Umbraco.Core.Dynamics } else { - return (Expression.Lambda>(Expression.OrElse(finalLeft, finalRight), parameters)); + return (Expression.Lambda>(Expression.OrElse(finalLeft, finalRight), parameters)); } default: return Expression.Equal(left, right); @@ -1902,7 +1902,7 @@ namespace Umbraco.Core.Dynamics if (leftIsLambda || rightIsLambda) { var body = Expression.Condition(Expression.TypeEqual(innerLeft, right.Type), binaryExpression, Expression.Constant(false)); - return Expression.Lambda>(body, parameters); + return Expression.Lambda>(body, parameters); } else { diff --git a/src/Umbraco.Core/Dynamics/ExtensionMethods.cs b/src/Umbraco.Core/Dynamics/ExtensionMethods.cs index ce394098e0..e2879b115f 100644 --- a/src/Umbraco.Core/Dynamics/ExtensionMethods.cs +++ b/src/Umbraco.Core/Dynamics/ExtensionMethods.cs @@ -32,7 +32,7 @@ namespace Umbraco.Core.Dynamics } - public static DynamicNodeList Random(this DynamicNodeList all, int min, int max) + public static DynamicDocumentList Random(this DynamicDocumentList all, int min, int max) { //get a random number generator Random r = new Random(); @@ -41,13 +41,13 @@ namespace Umbraco.Core.Dynamics //Call the other method return Random(all, Number); } - public static DynamicNodeList Random(this DynamicNodeList all, int max) + public static DynamicDocumentList Random(this DynamicDocumentList all, int max) { //Randomly order the items in the set by a Guid, Take the correct number, and return this wrapped in a new DynamicNodeList - return new DynamicNodeList(all.Items.OrderBy(x => Guid.NewGuid()).Take(max)); + return new DynamicDocumentList(all.Items.OrderBy(x => Guid.NewGuid()).Take(max)); } - public static DynamicNode Random(this DynamicNodeList all) + public static DynamicDocument Random(this DynamicDocumentList all) { return all.Items.OrderBy(x => Guid.NewGuid()).First(); } diff --git a/src/Umbraco.Core/Dynamics/Grouping.cs b/src/Umbraco.Core/Dynamics/Grouping.cs index fcf693c65b..72e6504188 100644 --- a/src/Umbraco.Core/Dynamics/Grouping.cs +++ b/src/Umbraco.Core/Dynamics/Grouping.cs @@ -13,7 +13,7 @@ namespace Umbraco.Core.Dynamics public IEnumerator GetEnumerator() { - var temp = new DynamicNodeList(Elements.Cast()); + var temp = new DynamicDocumentList(Elements.Cast()); return (IEnumerator)temp.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() @@ -21,7 +21,7 @@ namespace Umbraco.Core.Dynamics return (IEnumerator)GetEnumerator(); } - public DynamicNodeList OrderBy(string ordering) + public DynamicDocumentList OrderBy(string ordering) { bool descending = false; if (ordering.IndexOf(" descending", StringComparison.CurrentCultureIgnoreCase) >= 0) @@ -37,21 +37,21 @@ namespace Umbraco.Core.Dynamics if (!descending) { - return new DynamicNodeList(Elements.OrderBy(item => + return new DynamicDocumentList(Elements.OrderBy(item => { object key = null; (item as DynamicObject).TryGetMember(new DynamicQueryableGetMemberBinder(ordering, false), out key); return key; - }).Cast()); + }).Cast()); } else { - return new DynamicNodeList(Elements.OrderByDescending(item => + return new DynamicDocumentList(Elements.OrderByDescending(item => { object key = null; (item as DynamicObject).TryGetMember(new DynamicQueryableGetMemberBinder(ordering, false), out key); return key; - }).Cast()); + }).Cast()); } } } diff --git a/src/Umbraco.Core/Dynamics/IDynamicNodeDataSource.cs b/src/Umbraco.Core/Dynamics/IDynamicDocumentDataSource.cs similarity index 81% rename from src/Umbraco.Core/Dynamics/IDynamicNodeDataSource.cs rename to src/Umbraco.Core/Dynamics/IDynamicDocumentDataSource.cs index 8841f82881..a130e834f4 100644 --- a/src/Umbraco.Core/Dynamics/IDynamicNodeDataSource.cs +++ b/src/Umbraco.Core/Dynamics/IDynamicDocumentDataSource.cs @@ -8,9 +8,8 @@ namespace Umbraco.Core.Dynamics /// and currently the business logic part of Umbraco is still in the legacy project and we don't want to move that to the core so in the /// meantime until the new APIs are made, we need to have this data source in place with a resolver which is set in the web project. /// - internal interface IDynamicNodeDataSource + internal interface IDynamicDocumentDataSource { - IEnumerable GetAncestorOrSelfNodeTypeAlias(DynamicBackingItem node); Guid GetDataType(string contentTypeAlias, string propertyTypeAlias); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Dynamics/Signature.cs b/src/Umbraco.Core/Dynamics/Signature.cs index 48c44796f4..cececc502d 100644 --- a/src/Umbraco.Core/Dynamics/Signature.cs +++ b/src/Umbraco.Core/Dynamics/Signature.cs @@ -6,36 +6,36 @@ namespace Umbraco.Core.Dynamics { internal class Signature : IEquatable { - public DynamicProperty[] properties; - public int hashCode; + public DynamicProperty[] Properties { get; set; } + public int HashCode { get; set; } public Signature(IEnumerable properties) { - this.properties = properties.ToArray(); - hashCode = 0; - foreach (DynamicProperty p in properties) + this.Properties = properties.ToArray(); + HashCode = 0; + foreach (DynamicProperty p in this.Properties) { - hashCode ^= p.Name.GetHashCode() ^ p.Type.GetHashCode(); + HashCode ^= p.Name.GetHashCode() ^ p.Type.GetHashCode(); } } public override int GetHashCode() { - return hashCode; + return HashCode; } public override bool Equals(object obj) { - return obj is Signature ? Equals((Signature)obj) : false; + return obj is Signature && Equals((Signature)obj); } public bool Equals(Signature other) { - if (properties.Length != other.properties.Length) return false; - for (int i = 0; i < properties.Length; i++) + if (Properties.Length != other.Properties.Length) return false; + for (int i = 0; i < Properties.Length; i++) { - if (properties[i].Name != other.properties[i].Name || - properties[i].Type != other.properties[i].Type) return false; + if (Properties[i].Name != other.Properties[i].Name || + Properties[i].Type != other.Properties[i].Type) return false; } return true; } diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs index 81cb40cb9f..30634e75d1 100644 --- a/src/Umbraco.Core/StringExtensions.cs +++ b/src/Umbraco.Core/StringExtensions.cs @@ -18,6 +18,48 @@ namespace Umbraco.Core /// public static class StringExtensions { + //this is from SqlMetal and just makes it a bit of fun to allow pluralisation + public static string MakePluralName(this string name) + { + if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("ss", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase))) + { + name = name + "es"; + return name; + } + if ((name.EndsWith("y", StringComparison.OrdinalIgnoreCase) && (name.Length > 1)) && !IsVowel(name[name.Length - 2])) + { + name = name.Remove(name.Length - 1, 1); + name = name + "ies"; + return name; + } + if (!name.EndsWith("s", StringComparison.OrdinalIgnoreCase)) + { + name = name + "s"; + } + return name; + } + + public static bool IsVowel(this char c) + { + switch (c) + { + case 'O': + case 'U': + case 'Y': + case 'A': + case 'E': + case 'I': + case 'o': + case 'u': + case 'y': + case 'a': + case 'e': + case 'i': + return true; + } + return false; + } + /// /// Trims the specified value from a string; accepts a string input whereas the in-built implementation only accepts char or char[]. /// diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 047e795895..a708eca4d3 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -66,12 +66,12 @@ - - - - - - + + + + + + @@ -85,7 +85,7 @@ - + diff --git a/src/Umbraco.Tests/DynamicNodeTests.cs b/src/Umbraco.Tests/DynamicNodeTests.cs index 1645ec6b8c..e525f16d2d 100644 --- a/src/Umbraco.Tests/DynamicNodeTests.cs +++ b/src/Umbraco.Tests/DynamicNodeTests.cs @@ -19,29 +19,48 @@ namespace Umbraco.Tests { base.Initialize(); - DynamicNodeDataSourceResolver.Current = new DynamicNodeDataSourceResolver( - new TestDynamicNodeDataSource()); + DynamicDocumentDataSourceResolver.Current = new DynamicDocumentDataSourceResolver( + new TestDynamicDocumentDataSource()); } public override void TearDown() { base.TearDown(); - DynamicNodeDataSourceResolver.Reset(); + DynamicDocumentDataSourceResolver.Reset(); } - private DynamicNode GetDynamicNode(int id) + private DynamicDocument GetDynamicNode(int id) { var template = Template.MakeNew("test", new User(0)); var ctx = GetUmbracoContext("/test", template); var contentStore = new XmlPublishedContentStore(); var doc = contentStore.GetDocumentById(ctx, id); Assert.IsNotNull(doc); - var dynamicNode = new DynamicNode(doc); + var dynamicNode = new DynamicDocument(doc); Assert.IsNotNull(dynamicNode); return dynamicNode; } + [Test] + public void Get_Children_With_Pluralized_Alias() + { + var dynamicNode = GetDynamicNode(1173); + var asDynamic = dynamicNode.AsDynamic(); + + Action doAssert = d => + { + Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(d)); + var casted = (IEnumerable)d; + Assert.AreEqual(2, casted.Count()); + }; + + doAssert(asDynamic.Homes); //pluralized alias + doAssert(asDynamic.homes); //pluralized alias + doAssert(asDynamic.CustomDocuments); //pluralized alias + doAssert(asDynamic.customDocuments); //pluralized alias + } + [Test] public void GetPropertyValue_Non_Reflected() { @@ -99,11 +118,11 @@ namespace Umbraco.Tests var childrenAsList = asDynamic.ChildrenAsList; //test ChildrenAsList too Assert.IsTrue(TypeHelper.IsTypeAssignableFrom(childrenAsList)); - var castChildren = (IEnumerable)children; - Assert.AreEqual(2, castChildren.Count()); + var castChildren = (IEnumerable)children; + Assert.AreEqual(4, castChildren.Count()); - var castChildrenAsList = (IEnumerable)childrenAsList; - Assert.AreEqual(2, castChildrenAsList.Count()); + var castChildrenAsList = (IEnumerable)childrenAsList; + Assert.AreEqual(4, castChildrenAsList.Count()); } [Test] @@ -129,7 +148,7 @@ namespace Umbraco.Tests Assert.IsNotNull(result); - var list = (IEnumerable)result; + var list = (IEnumerable)result; Assert.AreEqual(3, list.Count()); Assert.IsTrue(list.Select(x => x.Id).ContainsAll(new[] { 1174, 1173, 1046 })); } @@ -144,7 +163,7 @@ namespace Umbraco.Tests Assert.IsNotNull(result); - var list = (IEnumerable)result; + var list = (IEnumerable)result; Assert.AreEqual(2, list.Count()); Assert.IsTrue(list.Select(x => x.Id).ContainsAll(new[] { 1173, 1046 })); } @@ -159,8 +178,8 @@ namespace Umbraco.Tests Assert.IsNotNull(result); - var list = (IEnumerable)result; - Assert.AreEqual(5, list.Count()); + var list = (IEnumerable)result; + Assert.AreEqual(7, list.Count()); Assert.IsTrue(list.Select(x => x.Id).ContainsAll(new[] { 1046, 1173, 1174, 1176, 1175 })); } @@ -174,8 +193,8 @@ namespace Umbraco.Tests Assert.IsNotNull(result); - var list = (IEnumerable)result; - Assert.AreEqual(4, list.Count()); + var list = (IEnumerable)result; + Assert.AreEqual(6, list.Count()); Assert.IsTrue(list.Select(x => x.Id).ContainsAll(new[] { 1173, 1174, 1176, 1175 })); } @@ -221,7 +240,7 @@ namespace Umbraco.Tests [Test] public void Next_Without_Sibling() { - var dynamicNode = GetDynamicNode(1176); + var dynamicNode = GetDynamicNode(1178); var asDynamic = dynamicNode.AsDynamic(); Assert.IsNull(asDynamic.Next()); @@ -251,13 +270,8 @@ namespace Umbraco.Tests #region Classes used in test - private class TestDynamicNodeDataSource : IDynamicNodeDataSource + private class TestDynamicDocumentDataSource : IDynamicDocumentDataSource { - public IEnumerable GetAncestorOrSelfNodeTypeAlias(DynamicBackingItem node) - { - return Enumerable.Empty(); - } - public Guid GetDataType(string contentTypeAlias, string propertyTypeAlias) { //just return an empty Guid since we don't want to match anything currently. diff --git a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs index 296150a31a..5d1642f6bc 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs @@ -83,11 +83,13 @@ namespace Umbraco.Tests.TestHelpers + + - + "; } diff --git a/src/Umbraco.Web/DefaultDynamicDocumentDataSource.cs b/src/Umbraco.Web/DefaultDynamicDocumentDataSource.cs new file mode 100644 index 0000000000..fda20606a2 --- /dev/null +++ b/src/Umbraco.Web/DefaultDynamicDocumentDataSource.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using Umbraco.Core.Dynamics; +using umbraco.cms.businesslogic; + +namespace Umbraco.Web +{ + + /// + /// This exists only because we want Dynamics in the Core project but DynamicNode has references to ContentType to run some queries + /// and currently the business logic part of Umbraco is still in the legacy project and we don't want to move that to the core so in the + /// meantime until the new APIs are made, we need to have this data source in place with a resolver which is set in the web project. + /// + internal class DefaultDynamicDocumentDataSource : IDynamicDocumentDataSource + { + public Guid GetDataType(string contentTypeAlias, string propertyTypeAlias) + { + return ContentType.GetDataType(contentTypeAlias, propertyTypeAlias); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/DefaultDynamicNodeDataSource.cs b/src/Umbraco.Web/DefaultDynamicNodeDataSource.cs deleted file mode 100644 index d7f4387c10..0000000000 --- a/src/Umbraco.Web/DefaultDynamicNodeDataSource.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Collections.Generic; -using Umbraco.Core.Dynamics; -using umbraco.cms.businesslogic; - -namespace Umbraco.Web -{ - - /// - /// This exists only because we want Dynamics in the Core project but DynamicNode has references to ContentType to run some queries - /// and currently the business logic part of Umbraco is still in the legacy project and we don't want to move that to the core so in the - /// meantime until the new APIs are made, we need to have this data source in place with a resolver which is set in the web project. - /// - internal class DefaultDynamicNodeDataSource : IDynamicNodeDataSource - { - public IEnumerable GetAncestorOrSelfNodeTypeAlias(DynamicBackingItem node) - { - var list = new List(); - if (node != null) - { - if (node.Type == DynamicBackingItemType.Content) - { - //find the doctype node, so we can walk it's parent's tree- not the working.parent content tree - CMSNode working = ContentType.GetByAlias(node.NodeTypeAlias); - while (working != null) - { - if ((working as ContentType) != null) - { - list.Add((working as ContentType).Alias); - } - try - { - working = working.Parent; - } - catch (ArgumentException) - { - break; - } - } - } - else - { - return null; - } - } - return list; - } - - public Guid GetDataType(string contentTypeAlias, string propertyTypeAlias) - { - return ContentType.GetDataType(contentTypeAlias, propertyTypeAlias); - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 88f8627dae..d37b782430 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -239,7 +239,7 @@ Properties\SolutionInfo.cs - + diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index 7b86a78f10..d7327ee7ed 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -160,7 +160,7 @@ namespace Umbraco.Web //This exists only because the new business logic classes aren't created yet and we want Dynamics in the Core project, //see the note in the DynamicNodeDataSourceResolver.cs class - DynamicNodeDataSourceResolver.Current = new DynamicNodeDataSourceResolver(new DefaultDynamicNodeDataSource()); + DynamicDocumentDataSourceResolver.Current = new DynamicDocumentDataSourceResolver(new DefaultDynamicDocumentDataSource()); } } diff --git a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs index 2ac11ce535..3d18226674 100644 --- a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs +++ b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs @@ -411,6 +411,12 @@ namespace umbraco.MacroEngines CMSNode working = ContentType.GetByAlias(node.NodeTypeAlias); while (working != null) { + //NOTE: I'm not sure if anyone has ever tested this but if you get working.Parent it will return a CMSNode and + // it will never be castable to a 'ContentType' object + // pretty sure the only reason why this method works for the one place that it is used is that it returns + // the current node's alias which is all that is actually requried, this is just added overhead for no + // reason + if ((working as ContentType) != null) { list.Add((working as ContentType).Alias);