Example #1
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="attributes">The list of available attributes</param>
        /// <param name="container">This is the type of container we are searchig attributes for.</param>
        /// <returns>The attributes matching the <see cref="EdiStructureType"/></returns>
        public static IEnumerable<EdiAttribute> OfType(this IEnumerable<EdiAttribute> attributes, EdiStructureType container) {
            var typesToSearch = new Type[0];
            switch (container) {
                case EdiStructureType.None:
                case EdiStructureType.Interchange:
                    break;
                case EdiStructureType.Group:
                    typesToSearch = new [] { typeof(EdiGroupAttribute) };
                    break;
                case EdiStructureType.Message:
                    typesToSearch = new [] { typeof(EdiMessageAttribute) };
                    break;
                case EdiStructureType.SegmentGroup:
                    typesToSearch = new [] { typeof(EdiSegmentGroupAttribute) };
                    break;
                case EdiStructureType.Segment:
                    typesToSearch = new [] { typeof(EdiSegmentAttribute), typeof(EdiSegmentGroupAttribute) };
                    break;
                case EdiStructureType.Element:
                    typesToSearch = new [] { typeof(EdiElementAttribute) };
                    break;
                default:
                    break;
            }

            return null == typesToSearch ? Enumerable.Empty<EdiAttribute>() : attributes.Where(a => typesToSearch.Contains(a.GetType()));
        }
Example #2
0
 public EdiStructure(EdiStructureType container, object instance, int index, Queue<EdiEntry> cache) {
     ValidationUtils.ArgumentNotNull(instance, "instance");
     _Container = container;
     _Instance = instance;
     _Index = index;
     _Descriptor = typeStore.Get(instance.GetType());
     _CachedReads = cache;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="T:indice.Edi.Serialization.EdiStructure"/> class.
 /// </summary>
 /// <param name="container">Container.</param>
 /// <param name="instance">Instance.</param>
 /// <param name="index">Index.</param>
 /// <param name="cache">Cache.</param>
 public EdiStructure(EdiStructureType container, object instance, int index, Queue <EdiEntry> cache)
 {
     ValidationUtils.ArgumentNotNull(instance, "instance");
     _Container   = container;
     _Instance    = instance;
     _Index       = index;
     _Descriptor  = typeStore.Get(instance.GetType());
     _CachedReads = cache;
 }
Example #4
0
 public EdiStructure(EdiStructureType structureType, EdiStructure parent, EdiPropertyDescriptor property, object instance)
     : this(structureType,
            parent,
            property,
            instance,
            (structureType == EdiStructureType.Element && property.PathInfo.PathInternal.Element.HasIndex) ? property.PathInfo.PathInternal.Element.Index : 0,
            new Queue <EdiEntry>())
 {
 }
Example #5
0
 public EdiStructure(EdiStructureType structureType, EdiStructure parent, EdiPropertyDescriptor property, object instance, int index, Queue <EdiEntry> cache)
 {
     ValidationUtils.ArgumentNotNull(instance, "instance");
     _StructureType      = structureType;
     _Container          = parent;
     _Instance           = instance;
     _Index              = index;
     _Descriptor         = typeStore.Get(instance.GetType());
     _CachedReads        = cache;
     _Conditions         = Descriptor.Attributes.OfType <EdiConditionAttribute>().Concat(property?.Conditions ?? new EdiConditionAttribute[0]).ToArray();
     _ConditionStackMode = _Conditions.Length > 0 && (
         property?.ConditionStackMode == EdiConditionStackMode.Any ||
         Descriptor.Attributes.OfType <EdiAnyAttribute>().Any())
         ? EdiConditionStackMode.Any : EdiConditionStackMode.All;
 }
Example #6
0
        internal bool TryCreateContainer(EdiReader reader, Stack <EdiStructure> stack, EdiStructureType newContainer)
        {
            var index = 0;

            if (stack.Count == 0)
            {
                return(false);
            }

            // clear once upon segment start. This is done here in order to keep any findings for future use
            if (newContainer == EdiStructureType.SegmentGroup || newContainer == EdiStructureType.Segment)
            {
                stack.Peek().CachedReads.Clear();
            }

            if (newContainer == EdiStructureType.SegmentGroup &&
                stack.Peek().StructureType >= EdiStructureType.SegmentGroup)
            {
                // strict hierarchy
                while (stack.Peek().StructureType > newContainer)
                {
                    var previous = stack.Pop(); // close this level
                }
                // nested hierarchy
                var readerSegment = reader.Value;
                foreach (var level in stack)
                {
                    if (!level.IsGroup)
                    {
                        continue;
                    }
                    var groupStart  = level.GroupStart;
                    var sequenceEnd = level.SequenceEnd;
                    if (groupStart.Segment.Equals(readerSegment))
                    {
                        if (PositionMatchesStructure(reader, level, readerSegment as string) ||          // if new occurance of my level or sibling found
                            FindForCurrentSegment(reader, level, EdiStructureType.SegmentGroup) == null) // if cannot advance either.

                        {
                            level.Close(); // Close this level
                            index = level.Index + 1;
                            continue;
                        }
                    }
                    else if (sequenceEnd.HasValue && sequenceEnd.Value.Segment.Equals(readerSegment))
                    {
                        level.Close(); // Close this level
                        continue;
                    }
                    else if (level.GroupMembers.Length > 1 && !level.GroupContains(readerSegment as string))
                    {
                        level.Close(); // Close this level
                        continue;
                    }
                }
                var clearUpTo = stack.Reverse().FirstOrDefault(x => x.IsClosed)?.Container;
                if (clearUpTo != null)
                {
                    while (stack.Peek() != clearUpTo)
                    {
                        stack.Pop();
                    }
                }
            }
            else
            {
                // strict hierarchy
                while (stack.Peek().StructureType >= newContainer)
                {
                    var previous = stack.Pop(); // close this level
                    if (previous.StructureType == newContainer)
                    {
                        index = previous.Index + 1; // seed collection index
                    }
                }
            }

            var current    = stack.Peek();
            var property   = default(EdiPropertyDescriptor);
            var childCache = default(Queue <EdiEntry>);

            switch (newContainer)
            {
            case EdiStructureType.SegmentGroup:
                property = FindForCurrentSegment(reader, current, newContainer);
                break;

            case EdiStructureType.Segment:
                property = FindForCurrentSegment(reader, current, newContainer);
                break;

            case EdiStructureType.Element:
                property = FindForCurrentElement(reader, current, newContainer, out childCache);
                break;

            default:
                property = FindForCurrentLogicalStructure(reader, current, newContainer);
                break;
            }
            if (property == null)
            {
                return(false);
            }
            var propValue = property.Info.GetValue(current.Instance, null);

            if (propValue == null)
            {
                if (property.Info.PropertyType.IsCollectionType())
                {
                    if (property.Info.PropertyType.IsArray)
                    {
                        var initalLength = 0;
                        propValue = Activator.CreateInstance(property.Info.PropertyType, initalLength);
                    }
                    else
                    {
                        var baseType    = typeof(List <>);
                        var genericType = baseType.MakeGenericType(property.Info.PropertyType.GetGenericArguments().First());
                        propValue = Activator.CreateInstance(genericType);
                    }
                }
                else
                {
                    propValue = Activator.CreateInstance(property.Info.PropertyType);
                }
                property.Info.SetValue(current.Instance, propValue);
            }
            if (propValue is IList)
            {
                var itemType = default(Type);
                var item     = default(object);
                if (property.Info.PropertyType.IsArray)
                {
                    itemType = property.Info.PropertyType.GetElementType();
                    item     = Activator.CreateInstance(itemType);
                    var newArray = Array.CreateInstance(itemType, ((IList)propValue).Count + 1);
                    var oldArray = ((Array)propValue);
                    Array.Copy(oldArray, newArray, oldArray.Length);
                    newArray.SetValue(item, newArray.Length - 1);
                    property.Info.SetValue(current.Instance, newArray);
                }
                else
                {
                    itemType = property.Info.PropertyType.GetGenericArguments().First();
                    item     = Activator.CreateInstance(itemType);
                    ((IList)propValue).Add(item);
                }
                propValue = item;
            }
            stack.Push(new EdiStructure(newContainer, current, property, propValue, index, childCache ?? current.CachedReads));
            return(true);
        }
Example #7
0
        /// <summary>
        /// Finds for current element.
        /// </summary>
        /// <returns>The for current element.</returns>
        /// <param name="reader">Reader.</param>
        /// <param name="currentStructure">Current structure.</param>
        /// <param name="newContainerType">New container type.</param>
        private EdiPropertyDescriptor FindForCurrentElement(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType)
        {
            var candidates = currentStructure.GetMatchingProperties(newContainerType);

            if (candidates.Length == 0)
            {
                return(null);
            }
            var property = default(EdiPropertyDescriptor);

            if (reader.TokenType == EdiToken.ElementStart)
            {
                var matches = candidates.Where(p => p.PathInfo.PathInternal.ToString("E").Equals(reader.Path)).ToArray();
                if (matches.Length == 0)
                {
                    property = null;
                }
                else if (matches.Length == 1 && matches[0].ConditionInfo == null)
                {
                    property = matches[0];
                }
                else
                {
                    property = ConditionalMatch(reader, currentStructure, newContainerType, matches);
                }
            }
            return(property);
        }
Example #8
0
        /// <summary>
        /// Conditionals the match.
        /// </summary>
        /// <returns>The match.</returns>
        /// <param name="reader">Reader.</param>
        /// <param name="currentStructure">Current structure.</param>
        /// <param name="newContainerType">New container type.</param>
        /// <param name="matches">Matches.</param>
        private static EdiPropertyDescriptor ConditionalMatch(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType, EdiPropertyDescriptor[] matches)
        {
            if (!matches.All(p => p.ConditionInfo != null))
            {
                throw new EdiException(
                          "More than one properties on type '{0}' have the '{1}' attribute. Please add a 'Condition' attribute to all properties in order to discriminate where each {2} will go."
                          .FormatWith(CultureInfo.InvariantCulture, currentStructure.Descriptor.ClrType.Name, newContainerType, newContainerType));
            }
            if (matches.Select(p => p.Path).Distinct().Count() != 1)
            {
                throw new EdiException("More than one properties on type '{0}' have the '{1}' attribute but the 'Condition' attribute has a different search path declared."
                                       .FormatWith(CultureInfo.InvariantCulture, currentStructure.Descriptor.ClrType.Name, newContainerType));
            }

            var readCache = currentStructure.CachedReads;
            var path      = string.Empty;

            do
            {
                reader.Read();
                path = reader.Path;
                readCache.Enqueue(new EdiEntry(path, reader.TokenType, reader.Value as string));
            } while (reader.TokenType != EdiToken.SegmentStart && matches[0].Path != path);

            var discriminator = reader.ReadAsString();
            var property      = matches.SingleOrDefault(p => p.ConditionInfo.MatchValue == discriminator);

            readCache.Enqueue(new EdiEntry(path, reader.TokenType, discriminator));
            return(property);
        }
Example #9
0
        private static EdiPropertyDescriptor ConditionalMatch(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType, EdiPropertyDescriptor[] candidates)
        {
            if (!candidates.All(p => p.Conditions != null))
            {
                throw new EdiException(
                          "More than one properties on type '{0}' have the '{1}' attribute. Please add a 'Condition' attribute to all properties in order to discriminate where each {2} will go."
                          .FormatWith(CultureInfo.InvariantCulture, currentStructure.Descriptor.ClrType.Name, newContainerType, newContainerType));
            }
            var conditionPaths = candidates.SelectMany(p => p.Conditions.Select(c => c.Path)).Distinct().ToArray();
            //if (conditionPaths.Length != 1) {
            //    throw new EdiException("More than one properties on type '{0}' have the '{1}' attribute but the 'Condition' attribute has a different search path declared."
            //        .FormatWith(CultureInfo.InvariantCulture, currentStructure.Descriptor.ClrType.Name, newContainerType));
            //}
            var cache           = currentStructure.CachedReads;
            var findingsPerPath = new Dictionary <string, string>();

            foreach (var path in conditionPaths)
            {
                // search the cache first.
                var value = default(string);
                var found = false;
                if (cache.Count > 0)
                {
                    var entry = cache.Where(r => r.Path == path).SingleOrDefault();
                    found = !default(EdiEntry).Equals(entry);
                }
                if (!found)
                {
                    // if nothing found search the reader (arvance forward).
                    do
                    {
                        if (reader.Path == path)
                        {
                            value = reader.ReadAsString();
                            cache.Enqueue(new EdiEntry(reader.Path, reader.TokenType, value));
                            found = true;
                            value = reader.Value as string; // if found break;
                            break;
                        }
                        else
                        {
                            reader.Read();
                            cache.Enqueue(new EdiEntry(reader.Path, reader.TokenType, reader.Value as string));
                        }
                    } while (!found || reader.TokenType != EdiToken.SegmentStart);
                }

                if (found)
                {
                    var property = candidates.SingleOrDefault(p => p.PathInfo.PathInternal == path && p.Conditions.Any(c => c.SatisfiedBy(value)));
                    if (property != null)
                    {
                        return(property);
                    }
                }
            }

            return(null);
        }
Example #10
0
        /// <summary>
        /// Tries the create container.
        /// </summary>
        /// <returns><c>true</c>, if create container was tryed, <c>false</c> otherwise.</returns>
        /// <param name="reader">Reader.</param>
        /// <param name="stack">Stack.</param>
        /// <param name="newContainer">New container.</param>
        internal bool TryCreateContainer(EdiReader reader, Stack <EdiStructure> stack, EdiStructureType newContainer)
        {
            var index = 0;

            if (stack.Count == 0)
            {
                return(false);
            }

            if (newContainer == EdiStructureType.SegmentGroup &&
                stack.Peek().Container >= EdiStructureType.SegmentGroup)
            {
                // strict hierarchy
                while (stack.Peek().Container > newContainer)
                {
                    var previous = stack.Pop(); // close this level
                }
                // nested hierarchy
                foreach (var level in stack)
                {
                    if (!level.IsGroup)
                    {
                        continue;
                    }
                    var groupStart  = level.Descriptor.SegmentGroupInfo.StartInternal;
                    var sequenceEnd = level.Descriptor.SegmentGroupInfo.SequenceEndInternal;
                    if (reader.Value.Equals(groupStart.Segment))
                    {
                        level.Close(); // Close this level
                        index = level.Index + 1;
                        break;
                    }
                    else if (reader.Value.Equals(sequenceEnd.Segment))
                    {
                        level.Close(); // Close this level
                        break;
                    }
                }
                if (stack.Any(s => s.IsClosed))
                {
                    var previous = stack.Peek();
                    do
                    {
                        previous = stack.Pop();
                    }while (!previous.IsClosed);
                }
            }
            else
            {
                // strict hierarchy
                while (stack.Peek().Container >= newContainer)
                {
                    var previous = stack.Pop(); // close this level
                    if (previous.Container == newContainer)
                    {
                        index = previous.Index + 1; // seed collection index
                    }
                }
            }

            var current  = stack.Peek();
            var property = default(EdiPropertyDescriptor);

            switch (newContainer)
            {
            case EdiStructureType.SegmentGroup:
                property = FindForCurrentSegment(reader, current, newContainer);
                break;

            case EdiStructureType.Segment:
                property = FindForCurrentSegment(reader, current, newContainer);
                break;

            case EdiStructureType.Element:
                property = FindForCurrentElement(reader, current, newContainer);
                break;

            default:
                property = FindForCurrentLogicalStructure(reader, current, newContainer);
                break;
            }
            if (property == null)
            {
                return(false);
            }
            object propValue = property.Info.GetValue(current.Instance, null);

            if (propValue == null)
            {
                if (property.Info.PropertyType.IsCollectionType())
                {
                    if (property.Info.PropertyType.IsArray)
                    {
                        var initalLength = 0;
                        propValue = Activator.CreateInstance(property.Info.PropertyType, initalLength);
                    }
                    else
                    {
                        var baseType    = typeof(List <>);
                        var genericType = baseType.MakeGenericType(property.Info.PropertyType.GetGenericArguments().First());
                        propValue = Activator.CreateInstance(genericType);
                    }
                }
                else
                {
                    propValue = Activator.CreateInstance(property.Info.PropertyType);
                }
                property.Info.SetValue(current.Instance, propValue);
            }
            if (propValue is IList)
            {
                var itemType = default(Type);
                var item     = default(object);
                if (property.Info.PropertyType.IsArray)
                {
                    itemType = property.Info.PropertyType.GetElementType();
                    item     = Activator.CreateInstance(itemType);
                    var newArray = Array.CreateInstance(itemType, ((IList)propValue).Count + 1);
                    var oldArray = ((Array)propValue);
                    Array.Copy(oldArray, newArray, oldArray.Length);
                    newArray.SetValue(item, newArray.Length - 1);
                    property.Info.SetValue(current.Instance, newArray);
                }
                else
                {
                    itemType = property.Info.PropertyType.GetGenericArguments().First();
                    item     = Activator.CreateInstance(itemType);
                    ((IList)propValue).Add(item);
                }
                propValue = item;
            }
            stack.Push(new EdiStructure(newContainer, propValue, index, current.CachedReads));
            return(true);
        }
Example #11
0
        /// <summary>
        /// Allows the filtering of tokens based on the <see cref="EdiStructureType"/> they represent
        /// instead of the build in way using the corresponding CLR <seealso cref="Type"/>.
        /// </summary>
        /// <param name="attributes">The list of available attributes</param>
        /// <param name="container">This is the type of container we are searchig attributes for.</param>
        /// <returns>The attributes matching the <see cref="EdiStructureType"/></returns>
        public static IEnumerable <EdiAttribute> OfType(this IEnumerable <EdiAttribute> attributes, EdiStructureType container)
        {
            var typesToSearch = new Type[0];

            switch (container)
            {
            case EdiStructureType.None:
            case EdiStructureType.Interchange:
                break;

            case EdiStructureType.Group:
                typesToSearch = new [] { typeof(EdiGroupAttribute) };
                break;

            case EdiStructureType.Message:
                typesToSearch = new [] { typeof(EdiMessageAttribute) };
                break;

            case EdiStructureType.SegmentGroup:
                typesToSearch = new [] { typeof(EdiSegmentGroupAttribute) };
                break;

            case EdiStructureType.Segment:
                typesToSearch = new [] { typeof(EdiSegmentAttribute), typeof(EdiSegmentGroupAttribute) };
                break;

            case EdiStructureType.Element:
                typesToSearch = new [] { typeof(EdiElementAttribute) };
                break;

            default:
                break;
            }

            return(null == typesToSearch?Enumerable.Empty <EdiAttribute>() : attributes.Where(a => typesToSearch.Contains(a.GetType())));
        }
Example #12
0
 private EdiPropertyDescriptor FindForCurrentSegment(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType) {
     currentStructure.CachedReads.Clear();
     var candidates = currentStructure.GetMatchingProperties(newContainerType);
     if (candidates.Length == 0) {
         return null;
     }
     var property = default(EdiPropertyDescriptor);
     if (reader.TokenType == EdiToken.SegmentName) {
         var matches = candidates.Where(p => p.Segment.Equals(reader.Value)).ToArray();
         if (matches.Length == 0) {
             property = null;
         } else if (matches.Length == 1 && matches[0].Conditions == null) {
             property = matches[0];
         } else {
             property = ConditionalMatch(reader, currentStructure, newContainerType, matches);
         }
     }
     return property;
 }
Example #13
0
        public static IEnumerable <EdiAttribute> OfType(this IEnumerable <EdiAttribute> attributes, EdiStructureType container)
        {
            var typeToSearch = default(Type);

            switch (container)
            {
            case EdiStructureType.None:
                break;

            case EdiStructureType.Interchange:
                break;

            case EdiStructureType.Group:
                typeToSearch = typeof(EdiGroupAttribute);
                break;

            case EdiStructureType.Message:
                typeToSearch = typeof(EdiMessageAttribute);
                break;

            case EdiStructureType.Segment:
                typeToSearch = typeof(EdiSegmentAttribute);
                break;

            case EdiStructureType.Element:
                typeToSearch = typeof(EdiElementAttribute);
                break;

            default:
                break;
            }

            return(null == typeToSearch?Enumerable.Empty <EdiAttribute>() : attributes.Where(a => a.GetType().Equals(typeToSearch)));
        }
Example #14
0
 /// <summary>
 /// Creates a <see cref="EdiGeneratedAttribute"/>. Marks a value that the serializer should be generating.
 /// </summary>
 /// <param name="type">The type of an autogenerated value. Count, Position, Index.</param>
 /// <param name="scope">The scope of the autogenerated value. Interchange, Message etc.</param>
 public EdiGeneratedAttribute(EdiGeneratedType type, EdiStructureType scope)
 {
     _Type  = type;
     _Scope = scope;
 }
Example #15
0
        private EdiPropertyDescriptor FindForCurrentSegment(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType)
        {
            var candidates = currentStructure.GetMatchingProperties(newContainerType);

            if (candidates.Length == 0)
            {
                return(null);
            }
            var property = default(EdiPropertyDescriptor);

            if (reader.TokenType == EdiToken.SegmentName || currentStructure.CachedReads.Count > 0)
            {
                var segmentName = reader.TokenType == EdiToken.SegmentName ? reader.Value : ((EdiPath)currentStructure.CachedReads.Peek().Path).Segment;
                var matches     = candidates.Where(p => segmentName.Equals(p.Segment)).ToArray();
                if (matches.Length == 0)
                {
                    property = null;
                }
                else if (matches.Length == 1 && matches[0].Conditions == null)
                {
                    property = matches[0];
                }
                else
                {
                    property = ConditionalMatch(reader, currentStructure, newContainerType, matches);
                }
            }
            return(property);
        }
Example #16
0
        private EdiPropertyDescriptor FindForCurrentLogicalStructure(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType)
        {
            var candidates = currentStructure.GetMatchingProperties(newContainerType);
            var property   = default(EdiPropertyDescriptor);

            if (candidates.Length == 0)
            {
                return(null);
            }
            if (candidates.Length == 1 && candidates[0].Conditions == null)
            {
                property = candidates[0];
            }
            else
            {
                property = ConditionalMatch(reader, currentStructure, newContainerType, candidates);
            }
            return(property);
        }
Example #17
0
 public EdiStructure(EdiStructureType structureType, object instance)
     : this(structureType, null, null, instance, 0, new Queue <EdiEntry>())
 {
 }
Example #18
0
 public EdiStructure(EdiStructureType container, object instance)
     : this(container, instance, 0, new Queue<EdiEntry>()) {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="T:indice.Edi.Serialization.EdiStructure"/> class.
 /// </summary>
 /// <param name="container">Container.</param>
 /// <param name="instance">Instance.</param>
 public EdiStructure(EdiStructureType container, object instance)
     : this(container, instance, 0, new Queue <EdiEntry>())
 {
 }
Example #20
0
 public EdiStructure(EdiStructureType structureType, EdiStructure parent, EdiPropertyDescriptor property, object instance)
     : this(structureType, parent, property, instance, 0, new Queue <EdiEntry>())
 {
 }
Example #21
0
 public EdiPropertyDescriptor[] GetMatchingProperties(EdiStructureType sructureType) =>
     Descriptor.Properties.Where(p => p.Attributes.OfType(sructureType).Any()).ToArray();
Example #22
0
        private EdiPropertyDescriptor FindForCurrentElement(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType, out Queue <EdiEntry> elementReads)
        {
            elementReads = null;
            var candidates = currentStructure.GetMatchingProperties(newContainerType);

            if (candidates.Length == 0)
            {
                return(null);
            }
            var property = default(EdiPropertyDescriptor);

            if (reader.TokenType == EdiToken.ElementStart || currentStructure.CachedReads.Count > 0)
            {
                var elementPath = reader.TokenType == EdiToken.ElementStart ? reader.Path : ((EdiPath)currentStructure.CachedReads.Peek().Path).ToString("E");
                var matches     = candidates.Where(p => p.PathInfo.PathInternal.Equals(elementPath)).ToArray();
                if (matches.Length == 0)
                {
                    property = null;
                }
                else if (matches.Length == 1 && matches[0].Conditions == null)
                {
                    property = matches[0];
                }
                else
                {
                    property = ConditionalMatch(reader, currentStructure, newContainerType, matches);
                }
                if (property != null)
                {
                    elementReads = new Queue <EdiEntry>();
                    var parentCache = currentStructure.CachedReads;
                    while (parentCache.Count > 0 && elementPath == ((EdiPath)parentCache.Peek().Path).ToString("E"))
                    {
                        elementReads.Enqueue(parentCache.Dequeue());
                    }
                    //foreach (var item in currentStructure.CachedReads) {
                    //    if (elementPath == ((EdiPath)item.Path).ToString("E")) {
                    //        elementReads.Enqueue(item);
                    //    }
                    //}
                }
            }
            return(property);
        }
Example #23
0
 public EdiPropertyDescriptor[] GetMatchingProperties(EdiStructureType sructureType) =>
 Descriptor.Properties.Where(p => p.Attributes.OfType(sructureType).Any()).ToArray();
Example #24
0
        private static EdiPropertyDescriptor ConditionalMatch(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType, params EdiPropertyDescriptor[] candidates)
        {
            if (!candidates.All(p => p.Conditions != null))
            {
                throw new EdiException(
                          "More than one properties on type '{0}' have the '{1}' attribute. Please add a 'Condition' attribute to all properties in order to discriminate where each {2} will go."
                          .FormatWith(CultureInfo.InvariantCulture, currentStructure.Descriptor.ClrType.Name, newContainerType, newContainerType));
            }

            var searchResults = SearchForward(reader, currentStructure.CachedReads, candidates.SelectMany(p => p.Conditions.Select(c => c.Path)));
            //if (searchResults.Length != 1) {
            //    throw new EdiException("More than one properties on type '{0}' have the '{1}' attribute but the 'Condition' attribute has a different search path declared."
            //        .FormatWith(CultureInfo.InvariantCulture, currentStructure.Descriptor.ClrType.Name, newContainerType));
            //}
            var property = candidates.SingleOrDefault(p => p.ConditionStackMode == EdiConditionStackMode.All ? p.Conditions.All(c => c.SatisfiedBy(searchResults[c.PathInternal]))
                                                                                                             : p.Conditions.Any(c => c.SatisfiedBy(searchResults[c.PathInternal])));

            if (property != null)
            {
                return(property);
            }
            return(null);
        }
Example #25
0
        internal bool TryCreateContainer(EdiReader reader, Stack <EdiStructure> stack, EdiStructureType newContainer)
        {
            var index = 0;

            if (stack.Count == 0)
            {
                return(false);
            }
            while (stack.Peek().Container >= newContainer)
            {
                var previous = stack.Pop();
                if (previous.Container == newContainer)
                {
                    index = previous.Index + 1;
                }
            }
            var current    = stack.Peek();
            var candidates = current.GetMatchingProperties(newContainer);
            var property   = default(EdiPropertyDescriptor);

            if (newContainer == EdiStructureType.Segment)
            {
                property = FindForCurrentSegment(reader, current, newContainer);
            }
            else if (newContainer == EdiStructureType.Element)
            {
                property = FindForCurrentElement(reader, current, newContainer);
            }
            else
            {
                property = FindForCurrentLogicalStructure(reader, current, newContainer);
            }
            if (property == null)
            {
                return(false);
            }
            object propValue = property.Info.GetValue(current.Instance, null);

            if (propValue == null)
            {
                if (property.Info.PropertyType.IsCollectionType())
                {
                    if (property.Info.PropertyType.IsArray)
                    {
                        var initalLength = 0;
                        propValue = Activator.CreateInstance(property.Info.PropertyType, initalLength);
                    }
                    else
                    {
                        var baseType    = typeof(List <>);
                        var genericType = baseType.MakeGenericType(property.Info.PropertyType.GetGenericArguments().First());
                        propValue = Activator.CreateInstance(genericType);
                    }
                }
                else
                {
                    propValue = Activator.CreateInstance(property.Info.PropertyType);
                }
                property.Info.SetValue(current.Instance, propValue);
            }
            if (propValue is IList)
            {
                var itemType = default(Type);
                var item     = default(object);
                if (property.Info.PropertyType.IsArray)
                {
                    itemType = property.Info.PropertyType.GetElementType();
                    item     = Activator.CreateInstance(itemType);
                    var newArray = Array.CreateInstance(itemType, ((IList)propValue).Count + 1);
                    var oldArray = ((Array)propValue);
                    Array.Copy(oldArray, newArray, oldArray.Length);
                    newArray.SetValue(item, newArray.Length - 1);
                    property.Info.SetValue(current.Instance, newArray);
                }
                else
                {
                    itemType = property.Info.PropertyType.GetGenericArguments().First();
                    item     = Activator.CreateInstance(itemType);
                    ((IList)propValue).Add(item);
                }
                propValue = item;
            }
            stack.Push(new EdiStructure(newContainer, propValue, index, current.CachedReads));
            return(true);
        }