示例#1
0
        /**
         * Recursively walk the spec input tree.
         */
        private static List <CardinalitySpec> CreateChildren(JObject rawSpec)
        {
            var children   = new List <CardinalitySpec>();
            var actualKeys = new HashSet <string>();

            foreach (var kv in rawSpec)
            {
                CardinalitySpec childSpec;
                if (kv.Value.Type == JTokenType.Object)
                {
                    childSpec = new CardinalityCompositeSpec(kv.Key, (JObject)kv.Value);
                }
                else
                {
                    childSpec = new CardinalityLeafSpec(kv.Key, kv.Value);
                }

                string childCanonicalString = childSpec.GetPathElement().GetCanonicalForm();

                if (actualKeys.Contains(childCanonicalString))
                {
                    throw new ArgumentException(nameof(rawSpec),
                                                "Duplicate canonical CardinalityTransform key found : " + childCanonicalString);
                }

                actualKeys.Add(childCanonicalString);

                children.Add(childSpec);
            }

            return(children);
        }
示例#2
0
        private readonly IReadOnlyList <CardinalitySpec> _computedChildren;              // children that are regex matches against the input data

        public CardinalityCompositeSpec(string rawKey, JObject spec) :
            base(rawKey)
        {
            var literals = new Dictionary <string, CardinalitySpec>();
            var computed = new List <CardinalitySpec>();

            _specialChild = null;

            // self check
            if (GetPathElement().GetType() == typeof(AtPathElement))
            {
                throw new SpecException("@ CardinalityTransform key, can not have children.");
            }

            List <CardinalitySpec> children = CreateChildren(spec);

            if (children.Count == 0)
            {
                throw new SpecException("Shift CardinalitySpec format error : CardinalitySpec line with empty {} as value is not valid.");
            }

            foreach (CardinalitySpec child in children)
            {
                var childPe = child.GetPathElement();
                literals[childPe.RawKey] = child;

                if (childPe is LiteralPathElement)
                {
                    literals[childPe.RawKey] = child;
                }
                // special is it is "@"
                else if (childPe is AtPathElement)
                {
                    if (child is CardinalityLeafSpec cls)
                    {
                        _specialChild = cls;
                    }
                    else
                    {
                        throw new SpecException("@ CardinalityTransform key, can not have children.");
                    }
                }
                // star
                else
                {
                    computed.Add(child);
                }
            }

            // Only the computed children need to be sorted
            computed.Sort(computedKeysComparator);
            computed.TrimExcess();
            _literalChildren  = literals;
            _computedChildren = computed.AsReadOnly();
        }