Example #1
0
        private object Aggregate(object[] args, string name)
        {
            object result;
            string predicate = args.First().ToString();
            var    values    = args.Skip(1).ToArray();
            var    query     = (IQueryable <object>) this.Select(predicate, values);
            object firstItem = query.FirstOrDefault();

            if (firstItem == null)
            {
                result = new DynamicNull();
            }
            else
            {
                var types = from i in query
                            group i by i.GetType() into g
                                where g.Key != typeof(DynamicNull)
                            orderby g.Count() descending
                            select new { g, Instances = g.Count() };
                var dominantType = types.First().g.Key;
                //remove items that are not the dominant type
                //e.g. string,string,string,string,false[DynamicNull],string
                var itemsOfDominantTypeOnly = query.ToList();
                itemsOfDominantTypeOnly.RemoveAll(item => !item.GetType().IsAssignableFrom(dominantType));
                if (dominantType == typeof(string))
                {
                    throw new ArgumentException("Can only use aggregate methods on properties which are numeric");
                }
                else if (dominantType == typeof(int))
                {
                    List <int> data = (List <int>)itemsOfDominantTypeOnly.Cast <int>().ToList();
                    return(Aggregate <int>(data, name));
                }
                else if (dominantType == typeof(decimal))
                {
                    List <decimal> data = (List <decimal>)itemsOfDominantTypeOnly.Cast <decimal>().ToList();
                    return(Aggregate <decimal>(data, name));
                }
                else if (dominantType == typeof(bool))
                {
                    throw new ArgumentException("Can only use aggregate methods on properties which are numeric or datetime");
                }
                else if (dominantType == typeof(DateTime))
                {
                    if (name != "Min" || name != "Max")
                    {
                        throw new ArgumentException("Can only use aggregate min or max methods on properties which are datetime");
                    }
                    List <DateTime> data = (List <DateTime>)itemsOfDominantTypeOnly.Cast <DateTime>().ToList();
                    return(Aggregate <DateTime>(data, name));
                }
                else
                {
                    result = query.ToList();
                }
            }
            return(result);
        }
Example #2
0
        public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
        {
            int index = (int)indexes[0];

            try
            {
                result = this.Items.ElementAt(index);
                return(true);
            }
            catch (IndexOutOfRangeException)
            {
                result = new DynamicNull();
                return(true);
            }
        }
Example #3
0
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            var name = binder.Name;

            if (name == "Where")
            {
                string predicate = args.First().ToString();
                var    values    = args.Skip(1).ToArray();
                result = new DynamicNodeList(this.Where <DynamicNode>(predicate, values).ToList());
                return(true);
            }
            if (name == "OrderBy")
            {
                result = new DynamicNodeList(this.OrderBy <DynamicNode>(args.First().ToString()).ToList());
                return(true);
            }
            if (name == "InGroupsOf")
            {
                int groupSize = 0;
                if (int.TryParse(args.First().ToString(), out groupSize))
                {
                    result = this.InGroupsOf <DynamicNode>(groupSize);
                    return(true);
                }
                result = new DynamicNull();
                return(true);
            }
            if (name == "GroupedInto")
            {
                int groupCount = 0;
                if (int.TryParse(args.First().ToString(), out groupCount))
                {
                    result = this.GroupedInto <DynamicNode>(groupCount);
                    return(true);
                }
                result = new DynamicNull();
                return(true);
            }
            if (name == "GroupBy")
            {
                result = this.GroupBy <DynamicNode>(args.First().ToString());
                return(true);
            }
            if (name == "Average" || name == "Min" || name == "Max" || name == "Sum")
            {
                result = Aggregate(args, name);
                return(true);
            }
            if (name == "Union")
            {
                if ((args.First() as IEnumerable <DynamicNode>) != null)
                {
                    result = new DynamicNodeList(this.Items.Union(args.First() as IEnumerable <DynamicNode>));
                    return(true);
                }
                if ((args.First() as DynamicNodeList) != null)
                {
                    result = new DynamicNodeList(this.Items.Union((args.First() as DynamicNodeList).Items));
                    return(true);
                }
            }
            if (name == "Except")
            {
                if ((args.First() as IEnumerable <DynamicNode>) != null)
                {
                    result = new DynamicNodeList(this.Items.Except(args.First() as IEnumerable <DynamicNode>, new DynamicNodeIdEqualityComparer()));
                    return(true);
                }
                if ((args.First() as DynamicNodeList) != null)
                {
                    result = new DynamicNodeList(this.Items.Except((args.First() as DynamicNodeList).Items, new DynamicNodeIdEqualityComparer()));
                    return(true);
                }
            }
            if (name == "Intersect")
            {
                if ((args.First() as IEnumerable <DynamicNode>) != null)
                {
                    result = new DynamicNodeList(this.Items.Intersect(args.First() as IEnumerable <DynamicNode>, new DynamicNodeIdEqualityComparer()));
                    return(true);
                }
                if ((args.First() as DynamicNodeList) != null)
                {
                    result = new DynamicNodeList(this.Items.Intersect((args.First() as DynamicNodeList).Items, new DynamicNodeIdEqualityComparer()));
                    return(true);
                }
            }
            if (name == "Distinct")
            {
                result = new DynamicNodeList(this.Items.Distinct(new DynamicNodeIdEqualityComparer()));
                return(true);
            }
            if (name == "Pluck" || name == "Select")
            {
                result = Pluck(args);
                return(true);
            }
            try
            {
                //Property?
                result = Items.GetType().InvokeMember(binder.Name,
                                                      System.Reflection.BindingFlags.Instance |
                                                      System.Reflection.BindingFlags.Public |
                                                      System.Reflection.BindingFlags.NonPublic |
                                                      System.Reflection.BindingFlags.GetProperty,
                                                      null,
                                                      Items,
                                                      args);
                return(true);
            }
            catch (MissingMethodException)
            {
                try
                {
                    //Static or Instance Method?
                    result = Items.GetType().InvokeMember(binder.Name,
                                                          System.Reflection.BindingFlags.Instance |
                                                          System.Reflection.BindingFlags.Public |
                                                          System.Reflection.BindingFlags.NonPublic |
                                                          System.Reflection.BindingFlags.Static |
                                                          System.Reflection.BindingFlags.InvokeMethod,
                                                          null,
                                                          Items,
                                                          args);
                    return(true);
                }
                catch (MissingMethodException)
                {
                    try
                    {
                        result = ExecuteExtensionMethod(args, name, false);
                        return(true);
                    }
                    catch (TargetInvocationException)
                    {
                        //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();
                        return(true);
                    }

                    catch
                    {
                        result = null;
                        return(false);
                    }
                }
            }
            catch
            {
                result = null;
                return(false);
            }
        }
Example #4
0
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            var name = binder.Name;

            if (name == "Where")
            {
                string predicate = args.First().ToString();
                var    values    = args.Skip(1).ToArray();
                result = new DynamicNodeList(this.Where <DynamicNode>(predicate, values).ToList());
                return(true);
            }
            if (name == "OrderBy")
            {
                result = new DynamicNodeList(this.OrderBy <DynamicNode>(args.First().ToString()).ToList());
                return(true);
            }
            if (name == "Pluck" || name == "Select")
            {
                string predicate = args.First().ToString();
                var    values    = args.Skip(1).ToArray();
                var    query     = (IQueryable <object>) this.Select(predicate, values);
                object firstItem = query.FirstOrDefault();
                if (firstItem == null)
                {
                    result = new DynamicNull();
                }
                else
                {
                    var types = from i in query
                                group i by i.GetType() into g
                                orderby g.Count() descending
                                select new { g, Instances = g.Count() };
                    var dominantType = types.First().g.Key;
                    //remove items that are not the dominant type
                    //e.g. string,string,string,string,false[DynamicNull],string
                    var itemsOfDominantTypeOnly = query.ToList();
                    itemsOfDominantTypeOnly.RemoveAll(item => !item.GetType().IsAssignableFrom(dominantType));
                    if (dominantType == typeof(string))
                    {
                        result = (List <string>)itemsOfDominantTypeOnly.Cast <string>().ToList();
                    }
                    else if (dominantType == typeof(int))
                    {
                        result = (List <int>)itemsOfDominantTypeOnly.Cast <int>().ToList();
                    }
                    else if (dominantType == typeof(decimal))
                    {
                        result = (List <decimal>)itemsOfDominantTypeOnly.Cast <decimal>().ToList();
                    }
                    else if (dominantType == typeof(bool))
                    {
                        result = (List <bool>)itemsOfDominantTypeOnly.Cast <bool>().ToList();
                    }
                    else if (dominantType == typeof(DateTime))
                    {
                        result = (List <DateTime>)itemsOfDominantTypeOnly.Cast <DateTime>().ToList();
                    }
                    else
                    {
                        result = query.ToList();
                    }
                }
                return(true);
            }
            try
            {
                //Property?
                result = Items.GetType().InvokeMember(binder.Name,
                                                      System.Reflection.BindingFlags.Instance |
                                                      System.Reflection.BindingFlags.Public |
                                                      System.Reflection.BindingFlags.NonPublic |
                                                      System.Reflection.BindingFlags.GetProperty,
                                                      null,
                                                      Items,
                                                      args);
                return(true);
            }
            catch (MissingMethodException)
            {
                try
                {
                    //Static or Instance Method?
                    result = Items.GetType().InvokeMember(binder.Name,
                                                          System.Reflection.BindingFlags.Instance |
                                                          System.Reflection.BindingFlags.Public |
                                                          System.Reflection.BindingFlags.NonPublic |
                                                          System.Reflection.BindingFlags.Static |
                                                          System.Reflection.BindingFlags.InvokeMethod,
                                                          null,
                                                          Items,
                                                          args);
                    return(true);
                }
                catch (MissingMethodException)
                {
                    try
                    {
                        result = ExecuteExtensionMethod(args, name, false);
                        return(true);
                    }
                    catch (TargetInvocationException)
                    {
                        //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();
                        return(true);
                    }

                    catch
                    {
                        result = null;
                        return(false);
                    }
                }
            }
            catch
            {
                result = null;
                return(false);
            }
        }
Example #5
0
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            var firstArg = args.FirstOrDefault();

            //this is to check for 'DocumentTypeAlias' vs 'NodeTypeAlias' for compatibility
            if (firstArg != null && firstArg.ToString().InvariantStartsWith("DocumentTypeAlias"))
            {
                firstArg = "NodeTypeAlias" + firstArg.ToString().Substring("DocumentTypeAlias".Length);
            }

            var name = binder.Name;

            if (name == "Single")
            {
                string predicate = firstArg == null ? "" : firstArg.ToString();
                var    values    = predicate.IsNullOrWhiteSpace() ? new object[] { } : args.Skip(1).ToArray();
                var    single    = this.Single <DynamicNode>(predicate, values);
                result = new DynamicNode(single);
                return(true);
            }
            if (name == "SingleOrDefault")
            {
                string predicate = firstArg == null ? "" : firstArg.ToString();
                var    values    = predicate.IsNullOrWhiteSpace() ? new object[] { } : args.Skip(1).ToArray();
                var    single    = this.SingleOrDefault <DynamicNode>(predicate, values);
                if (single == null)
                {
                    result = new DynamicNull();
                }
                else
                {
                    result = new DynamicNode(single);
                }
                return(true);
            }
            if (name == "First")
            {
                string predicate = firstArg == null ? "" : firstArg.ToString();
                var    values    = predicate.IsNullOrWhiteSpace() ? new object[] { } : args.Skip(1).ToArray();
                var    first     = this.First <DynamicNode>(predicate, values);
                result = new DynamicNode(first);
                return(true);
            }
            if (name == "FirstOrDefault")
            {
                string predicate = firstArg == null ? "" : firstArg.ToString();
                var    values    = predicate.IsNullOrWhiteSpace() ? new object[] { } : args.Skip(1).ToArray();
                var    first     = this.FirstOrDefault <DynamicNode>(predicate, values);
                if (first == null)
                {
                    result = new DynamicNull();
                }
                else
                {
                    result = new DynamicNode(first);
                }
                return(true);
            }
            if (name == "Last")
            {
                string predicate = firstArg == null ? "" : firstArg.ToString();
                var    values    = predicate.IsNullOrWhiteSpace() ? new object[] { } : args.Skip(1).ToArray();
                var    last      = this.Last <DynamicNode>(predicate, values);
                result = new DynamicNode(last);
                return(true);
            }
            if (name == "LastOrDefault")
            {
                string predicate = firstArg == null ? "" : firstArg.ToString();
                var    values    = predicate.IsNullOrWhiteSpace() ? new object[] { } : args.Skip(1).ToArray();
                var    last      = this.LastOrDefault <DynamicNode>(predicate, values);
                if (last == null)
                {
                    result = new DynamicNull();
                }
                else
                {
                    result = new DynamicNode(last);
                }
                return(true);
            }
            if (name == "Where")
            {
                string predicate = firstArg.ToString();
                var    values    = args.Skip(1).ToArray();
                result = new DynamicNodeList(this.Where <DynamicNode>(predicate, values).ToList());
                return(true);
            }
            if (name == "OrderBy")
            {
                result = new DynamicNodeList(this.OrderBy <DynamicNode>(firstArg.ToString()).ToList());
                return(true);
            }
            if (name == "Take")
            {
                result = new DynamicNodeList(this.Take((int)firstArg));
                return(true);
            }
            if (name == "Skip")
            {
                result = new DynamicNodeList(this.Skip((int)firstArg));
                return(true);
            }
            if (name == "InGroupsOf")
            {
                int groupSize = 0;
                if (int.TryParse(firstArg.ToString(), out groupSize))
                {
                    result = this.InGroupsOf <DynamicNode>(groupSize);
                    return(true);
                }
                result = new DynamicNull();
                return(true);
            }
            if (name == "GroupedInto")
            {
                int groupCount = 0;
                if (int.TryParse(firstArg.ToString(), out groupCount))
                {
                    result = this.GroupedInto <DynamicNode>(groupCount);
                    return(true);
                }
                result = new DynamicNull();
                return(true);
            }
            if (name == "GroupBy")
            {
                result = this.GroupBy <DynamicNode>(firstArg.ToString());
                return(true);
            }
            if (name == "Average" || name == "Min" || name == "Max" || name == "Sum")
            {
                result = Aggregate(args, name);
                return(true);
            }
            if (name == "Union")
            {
                if ((firstArg as IEnumerable <DynamicNode>) != null)
                {
                    result = new DynamicNodeList(this.Items.Union(firstArg as IEnumerable <DynamicNode>));
                    return(true);
                }
                if ((firstArg as DynamicNodeList) != null)
                {
                    result = new DynamicNodeList(this.Items.Union((firstArg as DynamicNodeList).Items));
                    return(true);
                }
            }
            if (name == "Except")
            {
                if ((firstArg as IEnumerable <DynamicNode>) != null)
                {
                    result = new DynamicNodeList(this.Items.Except(firstArg as IEnumerable <DynamicNode>, new DynamicNodeIdEqualityComparer()));
                    return(true);
                }
                if ((firstArg as DynamicNodeList) != null)
                {
                    result = new DynamicNodeList(this.Items.Except((firstArg as DynamicNodeList).Items, new DynamicNodeIdEqualityComparer()));
                    return(true);
                }
            }
            if (name == "Intersect")
            {
                if ((firstArg as IEnumerable <DynamicNode>) != null)
                {
                    result = new DynamicNodeList(this.Items.Intersect(firstArg as IEnumerable <DynamicNode>, new DynamicNodeIdEqualityComparer()));
                    return(true);
                }
                if ((firstArg as DynamicNodeList) != null)
                {
                    result = new DynamicNodeList(this.Items.Intersect((firstArg as DynamicNodeList).Items, new DynamicNodeIdEqualityComparer()));
                    return(true);
                }
            }
            if (name == "Distinct")
            {
                result = new DynamicNodeList(this.Items.Distinct(new DynamicNodeIdEqualityComparer()));
                return(true);
            }
            if (name == "Pluck" || name == "Select")
            {
                result = Pluck(args);
                return(true);
            }
            try
            {
                //Property?
                result = Items.GetType().InvokeMember(binder.Name,
                                                      System.Reflection.BindingFlags.Instance |
                                                      System.Reflection.BindingFlags.Public |
                                                      System.Reflection.BindingFlags.GetProperty,
                                                      null,
                                                      Items,
                                                      args);
                return(true);
            }
            catch (MissingMethodException)
            {
                try
                {
                    //Static or Instance Method?
                    result = Items.GetType().InvokeMember(binder.Name,
                                                          System.Reflection.BindingFlags.Instance |
                                                          System.Reflection.BindingFlags.Public |
                                                          System.Reflection.BindingFlags.Static |
                                                          System.Reflection.BindingFlags.InvokeMethod,
                                                          null,
                                                          Items,
                                                          args);
                    return(true);
                }
                catch (MissingMethodException)
                {
                    try
                    {
                        result = ExecuteExtensionMethod(args, name, false);
                        return(true);
                    }
                    catch (TargetInvocationException)
                    {
                        //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();
                        return(true);
                    }

                    catch
                    {
                        result = null;
                        return(false);
                    }
                }
            }
            catch
            {
                result = null;
                return(false);
            }
        }
Example #6
0
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            var name = binder.Name;

            result = null; //this will never be returned

            if (name == "ChildrenAsList" || name == "Children")
            {
                result = GetChildrenAsList;
                return(true);
            }
            bool propertyExists = false;

            if (n != null)
            {
                var data = n.GetProperty(name, out propertyExists);
                // check for nicer support of Pascal Casing EVEN if alias is camelCasing:
                if (data == null && name.Substring(0, 1).ToUpper() == name.Substring(0, 1) && !propertyExists)
                {
                    data = n.GetProperty(name.Substring(0, 1).ToLower() + name.Substring((1)), out propertyExists);
                }

                if (data != null)
                {
                    result = data.Value;
                    //special casing for true/false properties
                    //int/decimal are handled by ConvertPropertyValueByDataType
                    //fallback is stringT

                    Guid dataType = ContentType.GetDataType(n.NodeTypeAlias, data.Alias);

                    //convert the string value to a known type
                    return(ConvertPropertyValueByDataType(ref result, name, dataType));
                }

                //check if the alias is that of a child type
                var typeChildren = n.ChildrenAsList
                                   .Where(x => MakePluralName(x.NodeTypeAlias) == name || x.NodeTypeAlias == name);
                if (typeChildren.Any())
                {
                    result = new DynamicNodeList(typeChildren);
                    return(true);
                }

                try
                {
                    result = n.GetType().InvokeMember(binder.Name,
                                                      System.Reflection.BindingFlags.GetProperty |
                                                      System.Reflection.BindingFlags.Instance |
                                                      System.Reflection.BindingFlags.Public |
                                                      System.Reflection.BindingFlags.NonPublic,
                                                      null,
                                                      n,
                                                      null);
                    return(true);
                }
                catch
                {
                    //result = null;
                    //return false;
                }
            }

            //if property access, type lookup and member invoke all failed
            //at this point, we're going to return null
            //instead, we return a DynamicNull - see comments in that file
            //this will let things like Model.ChildItem work and return nothing instead of crashing
            if (!propertyExists && result == null)
            {
                //.Where explictly checks for this type
                //and will make it false
                //which means backwards equality (&& property != true) will pass
                //forwwards equality (&& property or && property == true) will fail
                result = new DynamicNull();
                return(true);
            }
            return(true);
        }