示例#1
0
        private string BuildPropertyPath(PropertyTraversalPath sourcePath, List <PropertyTraversalPath> parameters, bool targetIsArray)
        {
            if (sourcePath == null)
            {
                return("source");
            }

            var parameter = GetParameterThatIsSubPath(sourcePath, parameters);

            var subPath = sourcePath.SubPath(parameter);

            // TODO - will need to be greatly expanded to handle arrays/collections/choice etc

            if (subPath == null || !subPath.Any())
            {
                return(parameter.Name);
            }

            var propPath = parameter.Name;

            if (parameter.IsArray && !targetIsArray)
            {
                propPath += ".First()";
            }
            foreach (var item in subPath)
            {
                propPath += "?." + AppendPropertyPath(item, targetIsArray);
            }

            return(propPath);
        }
示例#2
0
        public void Resolve(Dictionary <int, TypeMapping> existingTypeMappings, Type rootSourceType, Type rootTargetType, SchemaItem rootSourceSchemaItem, SchemaItem rootTargetSchemaItem,
                            Mapping mapping)
        {
            foreach (var itemMapping in mapping.SchemaItemMappings)
            {
                if (itemMapping.SourceSchemaItemId.HasValue)
                {
                    if (itemMapping.SourceSchemaItem.IsRoot)
                    {
                        itemMapping.SourcePath = new PropertyTraversalPath()
                        {
                            RootType = rootSourceType
                        };
                    }
                    else
                    {
                        itemMapping.SourcePath = PathManipulation.GetClrPropertyPathFromPath(rootSourceType, itemMapping.SourceSchemaItem.Path, 1);
                    }
                }

                if (!existingTypeMappings.ContainsKey(itemMapping.TargetSchemaItem.key))
                {
                    PropertyTraversalPath targetPath = null;
                    if (!itemMapping.TargetSchemaItem.IsRoot)
                    {
                        targetPath = PathManipulation.GetClrPropertyPathFromPath(rootTargetType, itemMapping.TargetSchemaItem.Path, 1);
                    }
                    existingTypeMappings.Add(itemMapping.TargetSchemaItem.key, new TypeMapping {
                        TargetPath = targetPath, Mappings = new List <SchemaItemMapping>()
                    });
                }
                existingTypeMappings[itemMapping.TargetSchemaItem.key].Mappings.Add(itemMapping);
            }

            if (!existingTypeMappings.ContainsKey(rootTargetSchemaItem.key))
            {
                var rootTm = new TypeMapping()
                {
                    Mappings = new List <SchemaItemMapping>()
                    {
                        new SchemaItemMapping()
                        {
                            SourceSchemaItem = rootSourceSchemaItem, SourceSchemaItemId = rootSourceSchemaItem.key, SourcePath = new PropertyTraversalPath()
                            {
                                RootType = rootSourceType
                            }, TargetSchemaItem = rootTargetSchemaItem, TargetSchemaItemId = rootTargetSchemaItem.key, Action = new SchemaItemMappingAction()
                            {
                                Id = MappingAction.Transform
                            }
                        }
                    }
                };
                existingTypeMappings.Add(rootTargetSchemaItem.key, rootTm);
            }
        }
示例#3
0
        private PropertyTraversalPath GetParameterThatIsSubPath(PropertyTraversalPath sourcePath, List <PropertyTraversalPath> parameters)
        {
            var ordered = parameters.Where(a => a.Path != null).OrderByDescending(a => a.Path.Count);

            foreach (var parameter in ordered)
            {
                if (parameter.RootType == sourcePath.RootType && sourcePath.Path.Any(a => a.Property == parameter.Property))
                {
                    return(parameter);
                }
            }

            return(parameters.FirstOrDefault(a => a.RootType == sourcePath.RootType));
        }
        private static PropertyTraversalPath AddTraversal(List <SchemaItem> path, int index, PropertyTraversalPath traversalPath,
                                                          PropertyInfo prop)
        {
            traversalPath.Path.Add(new PropertyTraversal()
            {
                Property = prop
            });

            if (index == path.Count - 1)
            {
                return(traversalPath);
            }
            else
            {
                return(GetClrPropertyPathFromPathInternal(prop.PropertyType, path, index + 1, traversalPath));
            }
        }
        private static PropertyTraversalPath GetClrPropertyPathFromPathInternal(Type type, List <SchemaItem> path, int index, PropertyTraversalPath traversalPath)
        {
            Log("Working out path " + PathAsString(path));

            var item = path[index];

            var parent = path[index - 1];

            if (parent.Occurrance.Max == null)
            {
                if (index == path.Count - 1)
                {
                    return(traversalPath);
                }
                else
                {
                    if (type.IsArray)
                    {
                        return(GetClrPropertyPathFromPathInternal(type.GetElementType(), path, index + 1, traversalPath));
                    }
                    else
                    {
                        // assume a collection
                        return(GetClrPropertyPathFromPathInternal(type.GetGenericArguments().First(), path, index + 1, traversalPath));
                    }
                }
            }
            else
            {
                var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);

                if (item.title == ChoiceItemName)
                {
                    // TODO - assumes the choice element will be named 'item'
                    var prop = props.FirstOrDefault(a => a.Name.Equals("Item", StringComparison.InvariantCultureIgnoreCase));
                    if (prop != null)
                    {
                        return(AddChoiceTraversal(path, index, traversalPath, prop));
                    }
                }
                else
                {
                    Log("Looking for property named " + item.title); // "choose one of" == choice. Need to

                    var prop = props.FirstOrDefault(a => a.Name.Equals(item.title, StringComparison.InvariantCultureIgnoreCase));
                    if (prop != null)
                    {
                        return(AddTraversal(path, index, traversalPath, prop));
                    }

                    // if there are clashes NJsonSchema adds a '1' etc to the end of the type name
                    // TODO - consider searching for more numbers?
                    prop = props.FirstOrDefault(a => a.Name.Equals(item.title + "1", StringComparison.InvariantCultureIgnoreCase));
                    if (prop != null)
                    {
                        return(AddTraversal(path, index, traversalPath, prop));
                    }
                }

                throw new InvalidOperationException("traversal not found for " + item.title);
            }
        }
        private static PropertyTraversalPath AddChoiceTraversal(List <SchemaItem> path, int index, PropertyTraversalPath traversalPath,
                                                                PropertyInfo prop)
        {
            var attribs = Attribute.GetCustomAttributes(prop, typeof(XmlElementAttribute)).Select(a => (XmlElementAttribute)a).ToList();
            var child   = path[index + 1];
            var attrib  = attribs.First(a => a.ElementName == child.title);

            traversalPath.Path.Add(new PropertyTraversal()
            {
                Property = prop, ChoiceInfo = new ChoiceInfo {
                    ElementAttribute = attrib
                }
            });

            if (index == path.Count - 2)
            {
                return(traversalPath);
            }
            else
            {
                // +2 here because we've effectively skipped over the 'choice' element and gone straight to the child
                return(GetClrPropertyPathFromPathInternal(attrib.Type, path, index + 2, traversalPath));
            }
        }