private string CreateName(IClass @class) { if (Names.ContainsKey(@class)) { return(Names[@class]); } if (@class.IsClass(Rdf.List)) { return(CreateListName(@class)); } if (@class.IsClass(@class.Context.Mappings.MappingFor <ICollection>().Classes.First().Uri)) { return(CreateCollectionName(@class)); } if (@class.Id is BlankId) { foreach (var superClass in @class.SubClassOf) { var result = Names[@class] = CreateName(superClass.AsEntity <IClass>()); Namespaces[@class] = CreateNamespace(superClass.AsEntity <IClass>()); return(result); } } ParseUri(@class); return(Names[@class]); }
internal static IEnumerable <Rdfs.IResource> GetUniqueIdentifierType(this IClass @class) { return((from supportedProperty in @class.SupportedProperties let property = supportedProperty.Property where property.Is(RomanticWeb.Vocabularies.Owl.InverseFunctionalProperty) select property.Range).FirstOrDefault() ?? new Rdfs.IResource[0]); }
private string AnalyzeProperty(IClass supportedClass, ISupportedProperty property, out string typeName, out string getter, out string attributes) { var propertyName = (!String.IsNullOrEmpty(property.Property.Label) ? property.Property.Label : CreateName(property.Property.AsEntity <IResource>())); typeName = AnalyzePropertyType(property); attributes = String.Empty; bool singleValue = typeName.IndexOf("<") == -1; if ((!property.Writeable) && (!singleValue)) { var targetType = Regex.Replace( Regex.Replace(typeName, "ICollection|IList(?=<)", "List"), "System.Collections.IList", typeof(ArrayList).FullName); attributes = String.Format("private {0} _{1} = new {2}();{3}{3} ", typeName, propertyName.ToLowerCamelCase(), targetType, Environment.NewLine); } if ((_hydraUriParser != null) && (_hydraUriParser.IsApplicable(property.Property.Id.Uri) == UriParserCompatibility.None)) { attributes += String.Format("[RomanticWeb.Mapping.Attributes.{0}(\"{1}\")]", (singleValue ? "Property" : "Collection"), property.Property.Id); } getter = ((!property.Writeable) && (!singleValue) ? String.Format(" get {{ return _{0}; }} ", propertyName.ToLowerCamelCase()) : " get;" + (property.Writeable ? String.Empty : " ")); return(propertyName); }
private void BuildDescription(DescriptionContext context, IClass specializationType) { Uri graphUri = _namedGraphSelectorFactory.NamedGraphSelector.SelectGraph(specializationType.Id, null, null); context.ApiDocumentation.SupportedClasses.Add(specializationType); var description = _descriptionBuilder.BuildDescriptor(); foreach (OperationInfo <Verb> operation in description.Operations) { IIriTemplate template; var operationDefinition = BuildOperation(context, operation, out template); IResource operationOwner = DetermineOperationOwner(operation, context, specializationType); if (template != null) { ITemplatedLink templatedLink = context.ApiDocumentation.Context.Create <ITemplatedLink>(template.Id.Uri.AbsoluteUri.Replace("#template", "#withTemplate")); templatedLink.SupportedOperations.Add(operationDefinition); context.ApiDocumentation.Context.Store.ReplacePredicateValues( operationOwner.Id, Node.ForUri(templatedLink.Id.Uri), () => new[] { Node.ForUri(template.Id.Uri) }, graphUri, CultureInfo.InvariantCulture); } else { (operationOwner is ISupportedOperationsOwner ? ((ISupportedOperationsOwner)operationOwner).SupportedOperations : operationOwner.Operations).Add(operationDefinition); } } }
private static Rdfs.IProperty GetMappingProperty(DescriptionContext context, ParameterInfo parameter) { IClass description = context[context.Type]; Rdfs.IProperty resultCandidate = null; IResource parameterType = null; foreach (var supportedProperty in description.SupportedProperties) { if (StringComparer.OrdinalIgnoreCase.Equals(supportedProperty.Property.Label, parameter.Name)) { return(supportedProperty.Property); } if (parameterType == null) { parameterType = (context.ContainsType(parameter.ParameterType) ? context[parameter.ParameterType] : context.BuildTypeDescription()); } if (supportedProperty.Property.Range.Any(range => (range.Id == parameterType.Id) || ((range is IClass) && (((IClass)range).SubClassOf.Any(subClass => subClass.Id == parameterType.Id))))) { resultCandidate = supportedProperty.Property; } } return(resultCandidate); }
private string AnalyzeType(IClass @class, out string @namespace, IList <string> validMediaTypes = null) { if (validMediaTypes != null) { validMediaTypes.AddRange(@class.MediaTypes); } var name = CreateName(@class); @namespace = CreateNamespace(@class); return(name); }
/// <inheritdoc /> public IClass BuildTypeDescription(DescriptionContext context, out bool requiresRdf) { if (context == null) { throw new ArgumentNullException("context"); } if (context.ContainsType(context.Type)) { return(context.BuildTypeDescription(out requiresRdf)); } if (System.Reflection.TypeExtensions.IsEnumerable(context.Type)) { if (context.Type.IsList()) { return(CreateListDefinition(context, out requiresRdf, context.Type.IsGenericList())); } return(CreateCollectionDefinition(context, out requiresRdf, context.Type.IsGenericEnumerable())); } requiresRdf = false; Type itemType = context.Type.GetItemType(); if (TypeDescriptions.ContainsKey(itemType)) { return(BuildDatatypeDescription(context, TypeDescriptions[itemType])); } var classUri = itemType.MakeUri(); if (typeof(IEntity).IsAssignableFrom(itemType)) { classUri = context.ApiDocumentation.Context.Mappings.MappingFor(itemType).Classes.Select(item => item.Uri).FirstOrDefault() ?? classUri; requiresRdf = true; } IClass result = context.ApiDocumentation.Context.Create <IClass>(classUri); result.Label = itemType.MakeTypeName(false, true); result.Description = _xmlDocProvider.GetDescription(itemType); if (typeof(EntityId).IsAssignableFrom(itemType)) { context.Describe(result, requiresRdf); return(result); } context.Prescribe(result, requiresRdf); SetupProperties(context.ForType(itemType), result); context.Describe(result, requiresRdf); return(result); }
private string AnalyzeOperations(IClass supportedClass, IDictionary <string, string> classes) { var operations = new StringBuilder(1024); var supportedOperations = supportedClass.GetSupportedOperations(); foreach (var operationDescriptor in supportedOperations) { AnalyzeOperation(supportedClass, operationDescriptor.Operation, operationDescriptor.IriTemplate, operations, classes); } return(operations.ToString()); }
private string AnalyzePropertyType(ISupportedProperty property) { var propertyTypeNamespace = "System"; var propertyTypeName = "Object"; if (!property.Property.Range.Any()) { return(String.Format("{0}.{1}", propertyTypeNamespace, propertyTypeName)); } IClass propertyType = property.Property.Range.First().AsEntity <IClass>(); propertyTypeName = CreateName(propertyType); propertyTypeNamespace = CreateNamespace(propertyType); return(String.Format("{0}.{1}", propertyTypeNamespace, propertyTypeName)); }
private string CreateListName(IClass @class) { IRestriction itemTypeRestriction; IEntity itemType = null; @class.SuperClasses().Any(restriction => (restriction.Is(Owl.Restriction)) && ((itemTypeRestriction = restriction.AsEntity <IRestriction>()).OnProperty != null) && (itemTypeRestriction.OnProperty.Id == Rdf.first) && ((itemType = itemTypeRestriction.AllValuesFrom) != null)); if (itemType != null) { Namespaces[@class] = typeof(IList <>).Namespace; return(Names[@class] = String.Format("IList<{0}>", CreateName(itemType.AsEntity <IClass>()))); } Namespaces[@class] = typeof(IList).Namespace; return(Names[@class] = "IList"); }
private string CreateCollectionName(IClass @class) { IRestriction itemTypeRestriction; IEntity itemType = null; @class.SuperClasses().Any(restriction => (restriction.Is(Owl.Restriction)) && ((itemTypeRestriction = restriction.AsEntity <IRestriction>()).OnProperty != null) && (AbsoluteUriComparer.Default.Equals(itemTypeRestriction.OnProperty.Id.Uri, @class.Context.Mappings.MappingFor <ICollection>().PropertyFor("Members").Uri)) && ((itemType = itemTypeRestriction.AllValuesFrom) != null)); if (itemType != null) { Namespaces[@class] = typeof(IEnumerable <>).Namespace; return(Names[@class] = String.Format("ICollection<{0}>", CreateName(itemType.AsEntity <IClass>()))); } Namespaces[@class] = typeof(ICollection).Namespace; return(Names[@class] = "ICollection"); }
/// <inheritdoc /> public IClass SubClass(DescriptionContext context, IClass @class, Type contextTypeOverride = null) { if (context == null) { throw new ArgumentNullException("context"); } if (@class == null) { throw new ArgumentNullException("class"); } IClass result = context.ApiDocumentation.Context.Create <IClass>(@class.CreateBlankId()); result.SubClassOf.Add(@class); return(result); }
private bool AnalyzeTemplate(ref string template, IEnumerable <IIriTemplateMapping> mappings, StringBuilder parameters, StringBuilder uriArguments) { bool expectContentRangeHeader = false; bool isContentRangeHeaderParameterAdded = false; foreach (var mapping in mappings) { bool isMultipleValueMapping = Regex.IsMatch(template, mapping.Variable + "\\*[,}]"); var variableName = mapping.Variable.ToLowerCamelCase(); var templateSafeVariableName = Regex.Replace(variableName, "\\W", match => String.Join(String.Empty, match.Value.Select(@char => "%" + Convert.ToUInt32(@char).ToString("X")))); var safeVariableName = Regex.Replace(variableName, "\\W", "_"); template = template.Replace(mapping.Variable, templateSafeVariableName); IClass expected = null; if (mapping.Property != null) { expectContentRangeHeader |= (mapping.Property.Id.Uri.ToString() == DescriptionBuildingServerBahaviorAttributeVisitor <PropertyInfo> .OData + "$skip") || (mapping.Property.Id.Uri.ToString() == DescriptionBuildingServerBahaviorAttributeVisitor <PropertyInfo> .OData + "$take"); if ((mapping.Property.Range.Any()) && ((expected = mapping.Property.Range.First().AsEntity <IClass>()) != null) && (expected.Id is BlankId) && (expected.SubClassOf.Any())) { expected = expected.SubClassOf.First().AsEntity <IClass>(); } } var @namespace = "System"; var name = "Object"; if (expected != null) { @namespace = CreateNamespace(expected); name = CreateName(expected); } if ((expectContentRangeHeader) && (!isContentRangeHeaderParameterAdded)) { parameters.Insert(0, "out System.Int32 totalEntities, "); uriArguments.AppendFormat(" uriArguments[\"totalEntities\"] = totalEntities = 0;{0}", Environment.NewLine); isContentRangeHeaderParameterAdded = true; } parameters.AppendFormat(isMultipleValueMapping ? "System.Collections.Generic.IEnumerable<{0}.{1}> {2}, " : "{0}.{1} {2}, ", @namespace, name, safeVariableName); uriArguments.AppendFormat(" uriArguments[\"{1}\"] = {0};{2}", safeVariableName, templateSafeVariableName, Environment.NewLine); } return(isContentRangeHeaderParameterAdded); }
/// <summary>Builds an API description.</summary> /// <param name="apiDocumentation">API documentation.</param> /// <param name="profiles">Requested media type profiles.</param> public void BuildDescription(IApiDocumentation apiDocumentation, IEnumerable <Uri> profiles) { if (apiDocumentation == null) { throw new ArgumentNullException("apiDocumentation"); } if (SpecializationType == typeof(object)) { return; } var typeDescriptionBuilder = GetTypeDescriptionBuilder(profiles); var context = DescriptionContext.ForType(apiDocumentation, SpecializationType, typeDescriptionBuilder); IClass specializationType = context.BuildTypeDescription(); BuildDescription(context, specializationType); }
private IClass CreateEnumerableDefinition(DescriptionContext context, Uri baseType, out bool requiresRdf, out Type itemType, bool isGeneric = true) { itemType = null; requiresRdf = false; if (!isGeneric) { return(context.ApiDocumentation.Context.Create <IClass>(baseType)); } itemType = context.Type.GetItemType(); IClass result = context.ApiDocumentation.Context.Create <IClass>(context.Type.MakeUri()); result.Label = context.Type.MakeTypeName(false, true); result.Description = _xmlDocProvider.GetDescription(context.Type); result.SubClassOf.Add(context.ApiDocumentation.Context.Create <IClass>(baseType)); requiresRdf |= context.RequiresRdf(itemType); context.Describe(result, requiresRdf); return(result); }
private string AnalyzeProperties(IClass supportedClass) { var properties = new StringBuilder(512); foreach (var property in supportedClass.SupportedProperties) { string typeName; string getter; string attributes; string propertyName = AnalyzeProperty(supportedClass, property, out typeName, out getter, out attributes); properties.AppendFormat( PropertyTemplate, propertyName, property.Readable ? getter : String.Empty, property.Writeable ? " set; " : String.Empty, typeName, (propertyName == "Id" ? "new " : String.Empty), attributes); } return(properties.ToString()); }
private void SetupProperties(DescriptionContext context, IClass @class) { if (context.IsTypeComplete(context.Type)) { if (@class == context[context.Type]) { return; } foreach (var property in context[context.Type].SupportedProperties) { @class.SupportedProperties.Add(property); } } else { var properties = context.Type.GetProperties(typeof(IEntity)); foreach (var property in properties) { @class.SupportedProperties.Add(BuildSupportedProperty(context, @class, context.Type, property)); } } }
internal static bool IsGenericRdfList(this IClass @class, out IResource itemRestriction) { bool result = false; itemRestriction = null; foreach (var superClass in @class.SubClassOf) { if (superClass.IsClass(Rdf.List)) { result = true; } IRestriction restriction; if ((superClass.Is(RomanticWeb.Vocabularies.Owl.Restriction)) && ((restriction = superClass.AsEntity <IRestriction>()).OnProperty != null) && (restriction.OnProperty.Id == Rdf.first) && (restriction.AllValuesFrom != null) && (restriction.AllValuesFrom.Is(RomanticWeb.Vocabularies.Rdfs.Resource))) { itemRestriction = restriction.AllValuesFrom.AsEntity <IResource>(); } } return(result); }
/// <inheritdoc /> public IDictionary<string, string> CreateCode(IClass supportedClass) { var name = CreateName(supportedClass); var @namespace = CreateNamespace(supportedClass); var result = new Dictionary<string, string>(); var properties = AnalyzeProperties(supportedClass).Replace("\r\n \r\n", "\r\n"); var operations = AnalyzeOperations(supportedClass, result); var mapping = String.Empty; if ((_hydraUriParser != null) && (_hydraUriParser.IsApplicable(supportedClass.Id.Uri) == UriParserCompatibility.None)) { mapping = String.Format("\r\n [RomanticWeb.Mapping.Attributes.Class(\"{0}\")]", supportedClass.Id); } var classProperties = Regex.Replace(properties.Replace("public new ", "public "), "\\[[^\\]]+\\]\r\n ", String.Empty); var interfaceProperties = Regex.Replace(Regex.Replace(properties.Replace(" public ", " "), " private[^\r\n]*", String.Empty), "get { return _[^;]+; } ", "get;"); if (interfaceProperties.Length > 0) { interfaceProperties = Regex.Replace(interfaceProperties, "(" + Environment.NewLine + "){3,}", Environment.NewLine + Environment.NewLine).Substring(Environment.NewLine.Length); } result[name + ".cs"] = String.Format(EntityClassTemplate, @namespace, name, classProperties, interfaceProperties, mapping).Replace("{\r\n\r\n", "{\r\n"); result[name + "Client.cs"] = String.Format(ClientClassTemplate, @namespace, name, operations); return result; }
internal IResource DetermineOperationOwner(OperationInfo <Verb> operation, DescriptionContext context, IClass specializationType) { IResource result = specializationType; PropertyInfo matchingProperty; if ((!typeof(IReadController <,>).IsAssignableFromSpecificGeneric(_descriptionBuilder.BuildDescriptor().ControllerType)) || ((matchingProperty = operation.UnderlyingMethod.MatchesPropertyOf(context.Type, typeof(IControlledEntity <>).GetProperties().First().Name)) == null)) { return(result); } var propertyId = context.TypeDescriptionBuilder.GetSupportedPropertyId(matchingProperty, context.Type); return(context.ApiDocumentation.Context.Load <ISupportedProperty>(propertyId)); }
// TODO: Add support for header out parameters like totalItems. private void AnalyzeOperation(IClass supportedClass, IOperation operation, IIriTemplate template, StringBuilder operations, IDictionary<string, string> classes) { foreach (var method in operation.Method) { var bodyArguments = new StringBuilder(256); var uriArguments = new StringBuilder(256); var parameters = new StringBuilder(256); var accept = new StringBuilder(256); var contentType = new StringBuilder(256); var returns = "void"; var operationName = CreateName(operation, method); var uri = operation.Id.Uri.ToRelativeUri().ToString(); var returnedType = String.Empty; var isReturns = String.Empty; bool isContentRangeHeaderParameterAdded = false; if (template != null) { uri = template.Template; isContentRangeHeaderParameterAdded = AnalyzeTemplate(ref uri, template.Mappings, parameters, uriArguments); } AnalyzeBody(operation.Expects, parameters, bodyArguments, contentType, operation.MediaTypes); if (parameters.Length > 2) { parameters.Remove(parameters.Length - 2, 2); } if (operation.Returns.Any()) { isReturns = "var result = "; returns = AnalyzeResult(operationName, operation.Returns, classes, accept, operation.MediaTypes); returnedType = String.Format("<{0}>", returns); } if (accept.Length == 0) { accept.Append(" var accept = new string[0];"); } if (contentType.Length == 0) { contentType.Append(" var contentType = new string[0];"); } var isStatic = ((operation.Expects.Any(expected => expected == supportedClass)) && (method == "POST") ? " static" : String.Empty); operations.AppendFormat( OperationTemplate, isStatic, returns, operationName, parameters, method, uri, uriArguments, bodyArguments, isReturns, returnedType, accept, contentType, (isContentRangeHeaderParameterAdded ? " totalEntities = (int)uriArguments[\"totalEntities\"];" + Environment.NewLine : String.Empty), (isReturns.Length > 0 ? " return result;" + Environment.NewLine : String.Empty)); } }
private string AnalyzeType(IClass @class, out string @namespace, IList<string> validMediaTypes = null) { if (validMediaTypes != null) { validMediaTypes.AddRange(@class.MediaTypes); } var name = CreateName(@class); @namespace = CreateNamespace(@class); return name; }
private string AnalyzeProperty(IClass supportedClass, ISupportedProperty property, out string typeName, out string getter, out string attributes) { var propertyName = (!String.IsNullOrEmpty(property.Property.Label) ? property.Property.Label : CreateName(property.Property.AsEntity<IResource>())); typeName = AnalyzePropertyType(property); attributes = String.Empty; bool singleValue = typeName.IndexOf("<") == -1; if ((!property.Writeable) && (!singleValue)) { var targetType = Regex.Replace( Regex.Replace(typeName, "ICollection|IList(?=<)", "List"), "System.Collections.IList", typeof(ArrayList).FullName); attributes = String.Format("private {0} _{1} = new {2}();{3}{3} ", typeName, propertyName.ToLowerCamelCase(), targetType, Environment.NewLine); } if ((_hydraUriParser != null) && (_hydraUriParser.IsApplicable(property.Property.Id.Uri) == UriParserCompatibility.None)) { attributes += String.Format("[RomanticWeb.Mapping.Attributes.{0}(\"{1}\")]", (singleValue ? "Property" : "Collection"), property.Property.Id); } getter = ((!property.Writeable) && (!singleValue) ? String.Format(" get {{ return _{0}; }} ", propertyName.ToLowerCamelCase()) : " get;" + (property.Writeable ? String.Empty : " ")); return propertyName; }
private string AnalyzeOperations(IClass supportedClass, IDictionary<string, string> classes) { var operations = new StringBuilder(1024); var supportedOperations = supportedClass.GetSupportedOperations(); foreach (var operationDescriptor in supportedOperations) { AnalyzeOperation(supportedClass, operationDescriptor.Operation, operationDescriptor.IriTemplate, operations, classes); } return operations.ToString(); }
private string CreateName(IClass @class) { if (Names.ContainsKey(@class)) { return Names[@class]; } if (@class.IsClass(Rdf.List)) { return CreateListName(@class); } if (@class.IsClass(@class.Context.Mappings.MappingFor<ICollection>().Classes.First().Uri)) { return CreateCollectionName(@class); } if (@class.Id is BlankId) { foreach (var superClass in @class.SubClassOf) { var result = Names[@class] = CreateName(superClass.AsEntity<IClass>()); Namespaces[@class] = CreateNamespace(superClass.AsEntity<IClass>()); return result; } } ParseUri(@class); return Names[@class]; }
private string AnalyzeProperties(IClass supportedClass) { var properties = new StringBuilder(512); foreach (var property in supportedClass.SupportedProperties) { string typeName; string getter; string attributes; string propertyName = AnalyzeProperty(supportedClass, property, out typeName, out getter, out attributes); properties.AppendFormat( PropertyTemplate, propertyName, property.Readable ? getter : String.Empty, property.Writeable ? " set; " : String.Empty, typeName, (propertyName == "Id" ? "new " : String.Empty), attributes); } return properties.ToString(); }
private string CreateListName(IClass @class) { IRestriction itemTypeRestriction; IEntity itemType = null; @class.SuperClasses().Any(restriction => (restriction.Is(Owl.Restriction)) && ((itemTypeRestriction = restriction.AsEntity<IRestriction>()).OnProperty != null) && (itemTypeRestriction.OnProperty.Id == Rdf.first) && ((itemType = itemTypeRestriction.AllValuesFrom) != null)); if (itemType != null) { Namespaces[@class] = typeof(IList<>).Namespace; return Names[@class] = String.Format("IList<{0}>", CreateName(itemType.AsEntity<IClass>())); } Namespaces[@class] = typeof(IList).Namespace; return Names[@class] = "IList"; }
private string CreateCollectionName(IClass @class) { IRestriction itemTypeRestriction; IEntity itemType = null; @class.SuperClasses().Any(restriction => (restriction.Is(Owl.Restriction)) && ((itemTypeRestriction = restriction.AsEntity<IRestriction>()).OnProperty != null) && (AbsoluteUriComparer.Default.Equals(itemTypeRestriction.OnProperty.Id.Uri, @class.Context.Mappings.MappingFor<ICollection>().PropertyFor("Members").Uri)) && ((itemType = itemTypeRestriction.AllValuesFrom) != null)); if (itemType != null) { Namespaces[@class] = typeof(IEnumerable<>).Namespace; return Names[@class] = String.Format("ICollection<{0}>", CreateName(itemType.AsEntity<IClass>())); } Namespaces[@class] = typeof(ICollection).Namespace; return Names[@class] = "ICollection"; }
private void BuildDescription(DescriptionContext context, IClass specializationType) { Uri graphUri = _namedGraphSelectorFactory.NamedGraphSelector.SelectGraph(specializationType.Id, null, null); context.ApiDocumentation.SupportedClasses.Add(specializationType); var description = _descriptionBuilder.BuildDescriptor(); foreach (OperationInfo<Verb> operation in description.Operations) { IIriTemplate template; var operationDefinition = BuildOperation(context, operation, out template); IResource operationOwner = DetermineOperationOwner(operation, context, specializationType); if (template != null) { ITemplatedLink templatedLink = context.ApiDocumentation.Context.Create<ITemplatedLink>(template.Id.Uri.AbsoluteUri.Replace("#template", "#withTemplate")); templatedLink.SupportedOperations.Add(operationDefinition); context.ApiDocumentation.Context.Store.ReplacePredicateValues( operationOwner.Id, Node.ForUri(templatedLink.Id.Uri), () => new[] { Node.ForUri(template.Id.Uri) }, graphUri, CultureInfo.InvariantCulture); } else { (operationOwner is ISupportedOperationsOwner ? ((ISupportedOperationsOwner)operationOwner).SupportedOperations : operationOwner.Operations).Add(operationDefinition); } } }
internal IResource DetermineOperationOwner(OperationInfo<Verb> operation, DescriptionContext context, IClass specializationType) { IResource result = specializationType; PropertyInfo matchingProperty; if ((!typeof(IReadController<,>).IsAssignableFromSpecificGeneric(_descriptionBuilder.BuildDescriptor().ControllerType)) || ((matchingProperty = operation.UnderlyingMethod.MatchesPropertyOf(context.Type, typeof(IControlledEntity<>).GetProperties().First().Name)) == null)) { return result; } var propertyId = context.TypeDescriptionBuilder.GetSupportedPropertyId(matchingProperty, context.Type); return context.ApiDocumentation.Context.Load<ISupportedProperty>(propertyId); }
// TODO: Add support for header out parameters like totalItems. private void AnalyzeOperation(IClass supportedClass, IOperation operation, IIriTemplate template, StringBuilder operations, IDictionary <string, string> classes) { foreach (var method in operation.Method) { var bodyArguments = new StringBuilder(256); var uriArguments = new StringBuilder(256); var parameters = new StringBuilder(256); var accept = new StringBuilder(256); var contentType = new StringBuilder(256); var returns = "void"; var operationName = CreateName(operation, method); var uri = operation.Id.Uri.ToRelativeUri().ToString(); var returnedType = String.Empty; var isReturns = String.Empty; bool isContentRangeHeaderParameterAdded = false; if (template != null) { uri = template.Template; isContentRangeHeaderParameterAdded = AnalyzeTemplate(ref uri, template.Mappings, parameters, uriArguments); } AnalyzeBody(operation.Expects, parameters, bodyArguments, contentType, operation.MediaTypes); if (parameters.Length > 2) { parameters.Remove(parameters.Length - 2, 2); } if (operation.Returns.Any()) { isReturns = "var result = "; returns = AnalyzeResult(operationName, operation.Returns, classes, accept, operation.MediaTypes); returnedType = String.Format("<{0}>", returns); } if (accept.Length == 0) { accept.Append(" var accept = new string[0];"); } if (contentType.Length == 0) { contentType.Append(" var contentType = new string[0];"); } var isStatic = ((operation.Expects.Any(expected => expected == supportedClass)) && (method == "POST") ? " static" : String.Empty); operations.AppendFormat( OperationTemplate, isStatic, returns, operationName, parameters, method, uri, uriArguments, bodyArguments, isReturns, returnedType, accept, contentType, (isContentRangeHeaderParameterAdded ? " totalEntities = (int)uriArguments[\"totalEntities\"];" + Environment.NewLine : String.Empty), (isReturns.Length > 0 ? " return result;" + Environment.NewLine : String.Empty)); } }
/// <inheritdoc /> public IClass SubClass(DescriptionContext context, IClass @class, Type contextTypeOverride = null) { if (context == null) { throw new ArgumentNullException("context"); } if (@class == null) { throw new ArgumentNullException("class"); } IClass result = context.ApiDocumentation.Context.Create<IClass>(@class.CreateBlankId()); result.SubClassOf.Add(@class); return result; }
private ISupportedProperty BuildSupportedProperty(DescriptionContext context, IClass @class, Type declaringType, PropertyInfo property) { var propertyId = GetSupportedPropertyId(property, declaringType); var propertyUri = (!typeof(IEntity).IsAssignableFrom(context.Type) ? @class.Id.Uri.AddName(property.Name) : context.ApiDocumentation.Context.Mappings.MappingFor(context.Type).PropertyFor(property.Name).Uri); var result = context.ApiDocumentation.Context.Create<ISupportedProperty>(propertyId); result.Readable = property.CanRead; result.Writeable = property.CanWrite; result.Required = (property.PropertyType.IsValueType) || (property.GetCustomAttribute<RequiredAttribute>() != null); var isKeyProperty = (property.GetCustomAttribute<KeyAttribute>() != null) || (property.ImplementsGeneric(typeof(IControlledEntity<>), "Key")); result.Property = (isKeyProperty ? context.ApiDocumentation.Context.Create<IInverseFunctionalProperty>(propertyUri) : context.ApiDocumentation.Context.Create<IProperty>(propertyUri)); result.Property.Label = property.Name; result.Property.Description = _xmlDocProvider.GetDescription(property); result.Property.Domain.Add(@class); IClass propertyType; var itemPropertyType = (System.Reflection.TypeExtensions.IsEnumerable(property.PropertyType) ? property.PropertyType : property.PropertyType.GetItemType()); if (!context.ContainsType(itemPropertyType)) { bool requiresRdf; var childContext = context.ForType(itemPropertyType); propertyType = BuildTypeDescription(childContext, out requiresRdf); childContext.Describe(propertyType, requiresRdf); } else { propertyType = context[itemPropertyType]; } result.Property.Range.Add(propertyType); if ((System.Reflection.TypeExtensions.IsEnumerable(property.PropertyType)) && (property.PropertyType != typeof(byte[]))) { return result; } @class.SubClassOf.Add(@class.CreateRestriction(result.Property, 1u)); return result; }
private ISupportedProperty BuildSupportedProperty(DescriptionContext context, IClass @class, Type declaringType, PropertyInfo property) { var propertyId = GetSupportedPropertyId(property, declaringType); var propertyUri = (!typeof(IEntity).IsAssignableFrom(context.Type) ? @class.Id.Uri.AddName(property.Name) : context.ApiDocumentation.Context.Mappings.MappingFor(context.Type).PropertyFor(property.Name).Uri); var result = context.ApiDocumentation.Context.Create <ISupportedProperty>(propertyId); result.Readable = property.CanRead; result.Writeable = property.CanWrite; result.Required = (property.PropertyType.IsValueType) || (property.GetCustomAttribute <RequiredAttribute>() != null); var isKeyProperty = (property.GetCustomAttribute <KeyAttribute>() != null) || (property.ImplementsGeneric(typeof(IControlledEntity <>), "Key")); result.Property = (isKeyProperty ? context.ApiDocumentation.Context.Create <IInverseFunctionalProperty>(propertyUri) : context.ApiDocumentation.Context.Create <IProperty>(propertyUri)); result.Property.Label = property.Name; result.Property.Description = _xmlDocProvider.GetDescription(property); result.Property.Domain.Add(@class); IClass propertyType; var itemPropertyType = (System.Reflection.TypeExtensions.IsEnumerable(property.PropertyType) ? property.PropertyType : property.PropertyType.GetItemType()); if (!context.ContainsType(itemPropertyType)) { bool requiresRdf; var childContext = context.ForType(itemPropertyType); propertyType = BuildTypeDescription(childContext, out requiresRdf); childContext.Describe(propertyType, requiresRdf); } else { propertyType = context[itemPropertyType]; } result.Property.Range.Add(propertyType); if ((System.Reflection.TypeExtensions.IsEnumerable(property.PropertyType)) && (property.PropertyType != typeof(byte[]))) { return(result); } @class.SubClassOf.Add(@class.CreateRestriction(result.Property, 1u)); return(result); }