Esempio n. 1
0
        /**
         * Parse the dotNotation of the RHS.
         */
        public static List <IPathElement> ParseDotNotationRHS(string dotNotation)
        {
            string        fixedNotation = SpecStringParser.FixLeadingBracketSugar(dotNotation);
            List <string> pathStrs      = SpecStringParser.ParseDotNotation(new List <string>(), fixedNotation.GetEnumerator(), dotNotation);

            return(ParseList(pathStrs, dotNotation));
        }
Esempio n. 2
0
        public Filtr(JToken spec)
        {
            if (spec == null)
            {
                throw new SpecException("Filtr expected a spec of Map type, got 'null'.");
            }
            if (!(spec is JObject dic))
            {
                throw new SpecException("Filtr expected a spec of Map type, got " + spec.GetType().Name);
            }

            _rootSpec = new FiltrCompositeSpec(null);
            foreach (var kv in dic)
            {
                List <string> pathStrs   = SpecStringParser.ParseDotNotation(new List <string>(), kv.Key.GetEnumerator(), kv.Key);
                var           parentSpec = _rootSpec;
                foreach (var pathStr in pathStrs)
                {
                    var pathElement = RemovrSpec.Parse(pathStr);
                    if (!parentSpec.Children.TryGetValue(pathElement.RawKey, out var childSpec))
                    {
                        childSpec = new FiltrCompositeSpec(pathElement);
                        parentSpec.Children.Add(pathElement.RawKey, childSpec);
                    }
                    parentSpec = childSpec;
                }
                if (!(kv.Value is JObject filterSpec))
                {
                    throw new SpecException($"Filtr object filter specification must be a JSON object (found {kv.Value.Type})");
                }
                var propFilters = new List <KeyValuePair <string, JToken> >();
                foreach (var filterKv in filterSpec)
                {
                    if (filterKv.Value.Type == JTokenType.Array || filterKv.Value.Type == JTokenType.Object)
                    {
                        throw new SpecException($"Filter object filter specification must be a simple JSON value (string, number or null)");
                    }
                    propFilters.Add(new KeyValuePair <string, JToken>(filterKv.Key, filterKv.Value));
                }
                parentSpec.Filters.Add(new FiltrLeafSpec(propFilters.AsReadOnly()));
            }
        }
Esempio n. 3
0
        /**
         * Visible for Testing.
         *
         * Inspects the key in a particular order to determine the correct sublass of
         *  PathElement to create.
         *
         * @param origKey string that should represent a single PathElement
         * @return a concrete implementation of PathElement
         */
        public static IPathElement ParseSingleKeyLHS(string origKey)
        {
            string elementKey;   // the string to use to actually make Elements
            string keyToInspect; // the string to use to determine which kind of Element to create

            if (origKey.Contains("\\"))
            {
                // only do the extra work of processing for escaped chars, if there is one.
                keyToInspect = SpecStringParser.RemoveEscapedValues(origKey);
                elementKey   = SpecStringParser.RemoveEscapeChars(origKey);
            }
            else
            {
                keyToInspect = origKey;
                elementKey   = origKey;
            }

            //// LHS single values
            if ("@" == keyToInspect)
            {
                return(new AtPathElement(elementKey));
            }
            else if ("*" == keyToInspect)
            {
                return(new StarAllPathElement(elementKey));
            }
            else if (keyToInspect.StartsWith("["))
            {
                if (StringTools.CountMatches(keyToInspect, "[") != 1 || StringTools.CountMatches(keyToInspect, "]") != 1)
                {
                    throw new SpecException("Invalid key:" + origKey + " has too many [] references.");
                }

                return(new ArrayPathElement(elementKey));
            }
            //// LHS multiple values
            else if (keyToInspect.StartsWith("@") || keyToInspect.Contains("@("))
            {
                // The traspose path element gets the origKey so that it has it's escapes.
                return(TransposePathElement.Parse(origKey));
            }
            else if (keyToInspect.Contains("@"))
            {
                throw new SpecException("Invalid key:" + origKey + " can not have an @ other than at the front.");
            }
            else if (keyToInspect.Contains("$"))
            {
                return(new DollarPathElement(elementKey));
            }
            else if (keyToInspect.Contains("["))
            {
                if (StringTools.CountMatches(keyToInspect, "[") != 1 || StringTools.CountMatches(keyToInspect, "]") != 1)
                {
                    throw new SpecException("Invalid key:" + origKey + " has too many [] references.");
                }

                return(new ArrayPathElement(elementKey));
            }
            else if (keyToInspect.Contains("&"))
            {
                if (keyToInspect.Contains("*"))
                {
                    throw new SpecException("Invalid key:" + origKey + ", Can't mix * with & ) ");
                }
                return(new AmpPathElement(elementKey));
            }
            else if (keyToInspect.Contains("*"))
            {
                int numOfStars = StringTools.CountMatches(keyToInspect, "*");

                if (numOfStars == 1)
                {
                    return(new StarSinglePathElement(elementKey));
                }
                else if (numOfStars == 2)
                {
                    return(new StarDoublePathElement(elementKey));
                }
                else
                {
                    return(new StarRegexPathElement(elementKey));
                }
            }
            else if (keyToInspect.Contains("#"))
            {
                return(new HashPathElement(elementKey));
            }
            else
            {
                return(new LiteralPathElement(elementKey));
            }
        }