public void ValidateStreamingFragment(JObject ssmd, JObject schema)
        {
            var ex = new MetadataValidationException(typeof(object), "streaming","streaming validation failed","see AggregatedExceptions");

            IEnumerable<JProperty> services = ((JObject)ssmd["services"]).Properties();
            foreach (JProperty service in services)
            {
                JToken svc = service.Value;
                var returnValue = svc["returns"]["$ref"].Value<string>();
                if (returnValue.StartsWith("#."))
                {
                    returnValue = returnValue.Substring(2);
                }
                if (schema["properties"][returnValue] == null)
                {
                    var method = svc["target"].Value<string>()+"."+ svc["channel"].Value<string>();
                    ex.AggregatedExceptions.Add(new MetadataValidationException(typeof(Object), method, "Every service return type must be represented in the json-schema.", "ensure that the return type is represented in the json schema"));

                }
            }

            if(ex.AggregatedExceptions.Count>0)
            {
                throw ex;
            }
        }
        public JObject EmitDtoJson(XmlDocSource xmlDocSource)
        {
            var schemaObj = new JObject();
            var assemblies = xmlDocSource.Dtos.Select(a => a.Assembly).ToArray();

            schemaObj["version"] = xmlDocSource.RouteAssembly.Version;
            var schemaProperties = new JObject();
            schemaObj["properties"] = schemaProperties;

            var types = UtilityExtensions.GetSchemaTypes(assemblies);
            var exception = new MetadataValidationException(typeof (object), "", "Errors generating meta for types", "");
            foreach (Type type in types)
            {
                try
                {

                    var typeNode = type.GetXmlDocTypeNodeWithJSchema();
                    var jschemaXml =
                        JschemaXmlComment.CreateFromXml(typeNode.XPathSelectElement("jschema"));

                    if (jschemaXml.Exclude)
                        continue; //Skip to next type

                    var typeObj = new JObject();
                    typeObj["id"] = type.Name;

                    if (type.IsEnum)
                    {
                        RenderEnum(type, typeObj);
                    }
                    else if (type.IsClass)
                    {
                        RenderType(type, typeObj);
                    }
                    else
                    {
                        throw new NotSupportedException(type.Name + " is not supported ");
                    }

                    ApplyDescription(typeObj, typeNode);

                    if (jschemaXml.DemoValue != null)
                    {
                        typeObj["demoValue"] = jschemaXml.DemoValue;
                    }

                    schemaProperties.Add(type.Name, typeObj);
                }
                catch (MetadataValidationException ex)
                {
                    exception.AggregatedExceptions.Add(ex);
                }

            }

            if (exception.AggregatedExceptions.Count>0)
            {
                throw exception;
            }
            return schemaObj;
        }
        public static void RenderType(Type type, JObject typeObj)
        {
            var typeException = new MetadataValidationException(type,"", "Errors occured generating type meta.","See aggregated exceptions.");
            string typeName = type.Name;

            typeObj["type"] = "object";

            if (type.BaseType != null && type.BaseType != typeof(object))
            {
                typeObj["extends"] = "#." + type.BaseType.Name;
            }

            var properties = new JObject();
            typeObj["properties"] = properties;

            foreach (var propertyInfo in type.GetProperties())
            {
                string memberName = propertyInfo.Name;
                var pnode = type.GetXmlDocPropertyNode(memberName);
                if (pnode != null)
                {
                    var jschemaXml = JschemaXmlComment.CreateFromXml(pnode.XPathSelectElement("jschema"));

                    if (jschemaXml != null)
                    {
                        bool isBaseMember = pnode.Attribute("name").Value != "P:" + type.FullName + "." + propertyInfo.Name;

                        if (!jschemaXml.Exclude && !isBaseMember)
                        {
                            var pobj = new JObject();
                            properties[memberName] = pobj;

                            RenderTypeMeta(pobj, propertyInfo.PropertyType);

                            foreach (var item in jschemaXml.Element.Attributes())
                            {
                                string name = item.Name.ToString();
                                string value = item.Value;
                                ApplyPropertyAttribute(pobj, value, typeName, name);
                            }
                            ApplyDescription(pobj, pnode);

                        }
                    }
                    else
                    {
                        typeException.AggregatedExceptions.Add(new MetadataValidationException(type, memberName, "Member does not have <jschema> element. All DTO properties must have a jschema element", "All DTO properties must have <jschema> element. If you wish to exclude the property use the exclude='true' in jschema"));
                    }
                }
                else
                {
                    typeException.AggregatedExceptions.Add(new MetadataValidationException(type, memberName, "Member is not documented with XML docs. All DTO properties must be documented with XML docs", "Document method with xml documentation as well as jschema element"));
                }
            }

            // #TODO - throw if public fields are present
            foreach (var  field in type.GetFields())
            {
                typeException.AggregatedExceptions.Add(new MetadataValidationException(type, field.Name, "A DTO type must not implement public fields", "Change field to property by adding {get;set;}"));

            }

            if(typeException.AggregatedExceptions.Count>0)
            {
                throw typeException;
            }
        }
 public MetadataGenerationError(MetadataType metadataType, Type type, MetadataValidationException metadataValidationException)
     : this(metadataType, type, metadataValidationException.Message, metadataValidationException.SuggestedSolution)
 {
     MetadataValidationException = metadataValidationException;
 }
        public JObject EmitDtoJson(XmlDocSource xmlDocSource)
        {
            var schemaObj  = new JObject();
            var assemblies = xmlDocSource.Dtos.Select(a => a.Assembly).ToArray();


            schemaObj["version"] = xmlDocSource.RouteAssembly.Version;
            var schemaProperties = new JObject();

            schemaObj["properties"] = schemaProperties;

            var types     = UtilityExtensions.GetSchemaTypes(assemblies);
            var exception = new MetadataValidationException(typeof(object), "", "Errors generating meta for types", "");

            foreach (Type type in types)
            {
                try
                {
                    var typeNode   = type.GetXmlDocTypeNodeWithJSchema();
                    var jschemaXml =
                        JschemaXmlComment.CreateFromXml(typeNode.XPathSelectElement("jschema"));

                    if (jschemaXml.Exclude)
                    {
                        continue; //Skip to next type
                    }
                    var typeObj = new JObject();
                    typeObj["id"] = type.Name;

                    if (type.IsEnum)
                    {
                        RenderEnum(type, typeObj);
                    }
                    else if (type.IsClass)
                    {
                        RenderType(type, typeObj);
                    }
                    else
                    {
                        throw new NotSupportedException(type.Name + " is not supported ");
                    }

                    ApplyDescription(typeObj, typeNode);

                    if (jschemaXml.DemoValue != null)
                    {
                        typeObj["demoValue"] = jschemaXml.DemoValue;
                    }

                    schemaProperties.Add(type.Name, typeObj);
                }
                catch (MetadataValidationException ex)
                {
                    exception.AggregatedExceptions.Add(ex);
                }
            }

            if (exception.AggregatedExceptions.Count > 0)
            {
                throw exception;
            }
            return(schemaObj);
        }
        public static void RenderType(Type type, JObject typeObj)
        {
            var    typeException = new MetadataValidationException(type, "", "Errors occured generating type meta.", "See aggregated exceptions.");
            string typeName      = type.Name;

            typeObj["type"] = "object";

            if (type.BaseType != null && type.BaseType != typeof(object))
            {
                typeObj["extends"] = "#." + type.BaseType.Name;
            }


            var properties = new JObject();

            typeObj["properties"] = properties;

            foreach (var propertyInfo in type.GetProperties())
            {
                string memberName = propertyInfo.Name;
                var    pnode      = type.GetXmlDocPropertyNode(memberName);
                if (pnode != null)
                {
                    var jschemaXml = JschemaXmlComment.CreateFromXml(pnode.XPathSelectElement("jschema"));

                    if (jschemaXml != null)
                    {
                        bool isBaseMember = pnode.Attribute("name").Value != "P:" + type.FullName + "." + propertyInfo.Name;

                        if (!jschemaXml.Exclude && !isBaseMember)
                        {
                            var pobj = new JObject();
                            properties[memberName] = pobj;


                            RenderTypeMeta(pobj, propertyInfo.PropertyType);

                            foreach (var item in jschemaXml.Element.Attributes())
                            {
                                string name  = item.Name.ToString();
                                string value = item.Value;
                                ApplyPropertyAttribute(pobj, value, typeName, name);
                            }
                            ApplyDescription(pobj, pnode);
                        }
                    }
                    else
                    {
                        typeException.AggregatedExceptions.Add(new MetadataValidationException(type, memberName, "Member does not have <jschema> element. All DTO properties must have a jschema element", "All DTO properties must have <jschema> element. If you wish to exclude the property use the exclude='true' in jschema"));
                    }
                }
                else
                {
                    typeException.AggregatedExceptions.Add(new MetadataValidationException(type, memberName, "Member is not documented with XML docs. All DTO properties must be documented with XML docs", "Document method with xml documentation as well as jschema element"));
                }
            }

            // #TODO - throw if public fields are present
            foreach (var field in type.GetFields())
            {
                typeException.AggregatedExceptions.Add(new MetadataValidationException(type, field.Name, "A DTO type must not implement public fields", "Change field to property by adding {get;set;}"));
            }

            if (typeException.AggregatedExceptions.Count > 0)
            {
                throw typeException;
            }
        }