示例#1
0
        /**
         * Creates an empty map/list, as required by spec, in the parent map/list at given key/index
         *
         * @param keyOrIndex of the parent object to create
         * @param walkedPath containing the parent object
         * @param opMode     to determine if this write operation is allowed
         * @return newly created object
         */
        public JToken Create(string keyOrIndex, WalkedPath walkedPath, OpMode opMode)
        {
            object parent           = walkedPath.LastElement().TreeRef;
            int?   origSizeOptional = walkedPath.LastElement().OrigSize;

            if (!Int32.TryParse(keyOrIndex, out int index))
            {
                index = -1;
            }
            JToken value = null;

            if (parent is JObject map && opMode.IsApplicable(map, keyOrIndex))
            {
                map[keyOrIndex] = value = CreateValue();
            }
        public override void ProcessList(IOrderedCompositeSpec spec, JArray inputList, WalkedPath walkedPath, JObject output, JObject context)
        {
            int?originalSize = walkedPath.LastElement().OrigSize;

            foreach (var kv in spec.GetLiteralChildren())
            {
                JToken subInputOptional = null;
                // If the data is an Array, but the spec keys are Non-Integer Strings,
                //  we are annoyed, but we don't stop the whole transform.
                // Just this part of the Transform won't work.
                if (Int32.TryParse(kv.Key, out int keyInt) &&
                    keyInt >= 0 && keyInt < inputList.Count)
                {
                    // if the input in not available in the list use null or else get value,
                    // then lookup and place a default value as defined in spec there
                    JToken subInput = inputList[keyInt];
                    if ((subInput != null && subInput.Type != JTokenType.Null) |
                        !originalSize.HasValue || keyInt < originalSize.Value)
                    {
                        subInputOptional = subInput;
                    }
                }
                kv.Value.Apply(kv.Key, subInputOptional, walkedPath, output, context);
            }
        }
        public override void ProcessList(IOrderedCompositeSpec spec, JArray inputList, WalkedPath walkedPath, JObject output, JObject context)
        {
            int?originalSize = walkedPath.LastElement().OrigSize;

            foreach (var kv in spec.GetLiteralChildren())
            {
                // If the data is an Array, but the spec keys are Non-Integer Strings,
                //  we are annoyed, but we don't stop the whole transform.
                // Just this part of the Transform won't work.
                if (Int32.TryParse(kv.Key, out int keyInt) &&
                    // Do not work if the index is outside of the input list
                    keyInt < inputList.Count)
                {
                    // XXX: does this make sense? can you have a literal null in JArray?
                    JToken subInput = inputList[keyInt];
                    JToken subInputOptional;
                    if (subInput == null && originalSize.HasValue && keyInt >= originalSize.Value)
                    {
                        subInputOptional = null;
                    }
                    else
                    {
                        subInputOptional = subInput;
                    }

                    kv.Value.Apply(kv.Key, subInputOptional, walkedPath, output, context);
                }
            }
        }
示例#4
0
        public MatchedElement Match(string dataKey, WalkedPath walkedPath)
        {
            int?origSizeOptional = walkedPath.LastElement().OrigSize;

            if (origSizeOptional.HasValue)
            {
                return(new ArrayMatchedElement(dataKey, origSizeOptional.Value));
            }
            else
            {
                return(new MatchedElement(dataKey));
            }
        }
        public MatchedElement Match(string dataKey, WalkedPath walkedPath)
        {
            string evaled = Evaluate(walkedPath);

            if (evaled == dataKey)
            {
                int?origSizeOptional = walkedPath.LastElement().OrigSize;
                if (origSizeOptional.HasValue)
                {
                    return(new ArrayMatchedElement(evaled, origSizeOptional.Value));
                }
                else
                {
                    return(null);
                }
            }
            return(null);
        }
        /**
         * If this Spec matches the inputKey, then perform one step in the Shiftr parallel treewalk.
         *
         * Step one level down the input "tree" by carefully handling the List/Map nature the input to
         *  get the "one level down" data.
         *
         * Step one level down the Spec tree by carefully and efficiently applying our children to the
         *  "one level down" data.
         *
         * @return true if this this spec "handles" the inputKey such that no sibling specs need to see it
         */
        public override bool Apply(string inputKey, JToken inputOptional, WalkedPath walkedPath, JObject output, JObject context)
        {
            MatchedElement thisLevel = _pathElement.Match(inputKey, walkedPath);

            if (thisLevel == null)
            {
                return(false);
            }

            // If we are a TransposePathElement, try to swap the "input" with what we lookup from the Transpose
            if (_pathElement is TransposePathElement tpe)
            {
                // Note the data found may not be a string, thus we have to call the special objectEvaluate
                // Optional, because the input data could have been a valid null.
                var optional = tpe.ObjectEvaluate(walkedPath);
                if (optional == null)
                {
                    return(false);
                }
                inputOptional = optional;
            }

            // add ourselves to the path, so that our children can reference us
            walkedPath.Add(inputOptional, thisLevel);

            // Handle any special / key based children first, but don't have them block anything
            foreach (ShiftrSpec subSpec in _specialChildren)
            {
                subSpec.Apply(inputKey, inputOptional, walkedPath, output, context);
            }

            // Handle the rest of the children
            _executionStrategy.Process(this, inputOptional, walkedPath, output, context);

            // We are done, so remove ourselves from the walkedPath
            walkedPath.RemoveLast();

            // we matched so increment the matchCount of our parent
            walkedPath.LastElement().MatchedElement.IncrementHashCount();
            return(true);
        }
        public override void ProcessList(IOrderedCompositeSpec spec, JArray inputList, WalkedPath walkedPath, JObject output, JObject context)
        {
            int?originalSize = walkedPath.LastElement().OrigSize;

            for (int index = 0; index < inputList.Count; index++)
            {
                JToken subInput  = inputList[index];
                string subKeyStr = index.ToString();
                JToken subInputOptional;
                if (subInput == null && originalSize.HasValue && index >= originalSize.Value)
                {
                    subInputOptional = null;
                }
                else
                {
                    subInputOptional = subInput;
                }

                ApplyKeyToComputed(spec.GetComputedChildren(), walkedPath, output, subKeyStr, subInputOptional, context);
            }
        }
        /**
         * If this Spec matches the inputkey, then do the work of outputting data and return true.
         *
         * @return true if this this spec "handles" the inputkey such that no sibling specs need to see it
         */
        public override bool Apply(string inputKey, JToken inputOptional, WalkedPath walkedPath, JObject output, JObject context)
        {
            JToken         input     = inputOptional;
            MatchedElement thisLevel = _pathElement.Match(inputKey, walkedPath);

            if (thisLevel == null)
            {
                return(false);
            }

            JToken data;
            bool   realChild = false; // by default don't block further Shiftr matches

            if (_pathElement is DollarPathElement ||
                _pathElement is HashPathElement)
            {
                // The data is already encoded in the thisLevel object created by the pathElement.match called above
                data = thisLevel.GetCanonicalForm();
            }
            else if (_pathElement is AtPathElement)
            {
                // The data is our parent's data
                data = input;
            }
            else if (_pathElement is TransposePathElement tpe)
            {
                // We try to walk down the tree to find the value / data we want

                // Note the data found may not be a string, thus we have to call the special objectEvaluate
                var evaledData = tpe.ObjectEvaluate(walkedPath);
                if (evaledData != null)
                {
                    data = evaledData;
                }
                else
                {
                    // if we could not find the value we want looking down the tree, bail
                    return(false);
                }
            }
            else
            {
                // the data is the input
                data = input;
                // tell our parent that we matched and no further processing for this inputKey should be done
                realChild = true;
            }

            // Add our the LiteralPathElement for this level, so that write path References can use it as &(0,0)
            walkedPath.Add(input, thisLevel);

            // Write out the data
            foreach (PathEvaluatingTraversal outputPath in _shiftrWriters)
            {
                outputPath.Write(data, output, walkedPath);
            }

            walkedPath.RemoveLast();

            if (realChild)
            {
                // we were a "real" child, so increment the matchCount of our parent
                walkedPath.LastElement().MatchedElement.IncrementHashCount();
            }

            return(realChild);
        }
 public MatchedElement Match(string dataKey, WalkedPath walkedPath)
 {
     return(walkedPath.LastElement().MatchedElement);  // copy what our parent was so that write keys of &0 and &1 both work.
 }