private string GetContentType(ContentTypeAttribute contentTypeAttribute, TDataExchangeFormat dataExchangeFormat) { string contentType = null; if (contentTypeAttribute != null) { contentType = string.Concat(contentTypeAttribute.ContentType, "+", dataExchangeFormat.ToString().ToLower()); } else { contentType = string.Concat("application/", dataExchangeFormat.ToString()); } return contentType; }
private string GetContentType(ContentTypeAttribute contentTypeAttribute, TDataExchangeFormat dataExchangeFormat) { string contentType = null; if (contentTypeAttribute != null) { contentType = string.Concat(contentTypeAttribute.ContentType, "+", dataExchangeFormat.ToString().ToLower()); } else { contentType = string.Concat("application/", dataExchangeFormat.ToString()); } return(contentType); }
private string GetPropertyTypeName(Type propertyType, TDataExchangeFormat format) { // JSON: string integer number boolean object array // XML: string integer decimal boolean date time string propertyTypeName = propertyType.Name; if (propertyTypeName.StartsWith("Nullable`")) { propertyTypeName = ((TypeInfo)propertyType).DeclaredFields.ToArray()[1].FieldType.Name; } if (propertyTypeName.Equals("String")) { propertyTypeName = "string"; } else if (propertyTypeName.Equals("Int32") || propertyTypeName.Equals("Int64")) { propertyTypeName = "integer"; } else if (propertyTypeName.Equals("Float") || propertyTypeName.Equals("Double")) { if (format == TDataExchangeFormat.Json) { propertyTypeName = "number"; } else { propertyTypeName = "decimal"; } } else if (propertyTypeName.Equals("Boolean")) { propertyTypeName = "boolean"; } else if (propertyTypeName.StartsWith("List`")) { propertyTypeName = "array"; } else { //Console.WriteLine("GetPropertyType: skipped " + propertyTypeName); propertyTypeName = "object"; } return(propertyTypeName); }
public static TDataExchangeFormat GetDataExchangeFormatFromContentType(string contentType) { TDataExchangeFormat format = TDataExchangeFormat.None; if (contentType.Equals("application/x-www-form-urlencoded")) { format = TDataExchangeFormat.FormUrlEncoded; } else if (contentType.EndsWith("+json")) { format = TDataExchangeFormat.Json; } else if (contentType.EndsWith("+xml")) { format = TDataExchangeFormat.Xml; } return(format); }
public string GetExampleContent(Type classType, MethodInfo methodInfo, TMessageType exampleType, string mimeType, TDataExchangeFormat dataExchangeFormat) { string content = null; Example example = GetExample(classType, methodInfo, exampleType, mimeType); if (example != null) { example.Content.TryGetValue(dataExchangeFormat, out content); } return content; }
public string GetExampleContent(Type classType, MethodInfo methodInfo, TMessageType exampleType, string mimeType, TDataExchangeFormat dataExchangeFormat) { string content = null; Example example = GetExample(classType, methodInfo, exampleType, mimeType); if (example != null) { example.Content.TryGetValue(dataExchangeFormat, out content); } return(content); }
private object GetSchemaKey(Type objectType, TDataExchangeFormat dataExchangeFormat) { return string.Concat(objectType.Name, dataExchangeFormat.ToString()); }
private void WriteBody(StreamWriter writer, ExampleStore exampleStore, ResourceNode node, TDataExchangeFormat dataExchangeFormat, string contentType, TMessageType messageType, Type bodyObjectType, int indent) { writer.WriteLine(string.Concat(GetIndentString(indent), contentType, ":")); if (SerialisationUtils.IsStandardDataExchangeFormat(dataExchangeFormat)) { writer.WriteLine(string.Concat(GetIndentString(indent + 1), "schema: ", GetSchemaKey(bodyObjectType, dataExchangeFormat))); } WriteExample(writer, exampleStore, node.Class, node.Method, contentType, messageType, dataExchangeFormat, indent + 1); }
private void WriteExample(StreamWriter writer, ExampleStore exampleStore, Type classType, MethodInfo methodInfo, string contentType, TMessageType exampleType, TDataExchangeFormat dataExchangeFormat, int indent) { string exampleText = exampleStore.GetExampleContent(classType, methodInfo, exampleType, contentType, dataExchangeFormat); if (exampleText != null) { writer.WriteLine(string.Concat(GetIndentString(indent), "example: |")); List<string> lines = SerialisationUtils.SplitLines(exampleText); foreach (string line in lines) { writer.WriteLine(string.Concat(GetIndentString(indent + 1), line)); } } else if (dataExchangeFormat != TDataExchangeFormat.Xml) { SerialisationLog.Warning(string.Concat("No example for ", classType.Name, ".", methodInfo.Name, " ", dataExchangeFormat, " ", exampleType.ToString().ToLower())); } }
private void WriteMethod(StreamWriter writer, ResourceNode node, DocumentationHeaderSettings headerSettings, SchemaStore schemaStore, ExampleStore exampleStore, int indent) { MethodDocumentationAttribute attribute = node.Method.GetCustomAttributes <MethodDocumentationAttribute>().FirstOrDefault(); if (node.AllowsAnonymous()) { string securitySchemes = "null"; if (attribute != null && attribute.AllowMultipleSecuritySchemes) { securitySchemes = string.Concat(securitySchemes, ", oauth_2_0"); } writer.WriteLine(string.Concat(GetIndentString(indent + 1), "securedBy: [", securitySchemes, "]")); } if (attribute != null) { if (attribute.Summary != null) { writer.WriteLine(string.Concat(GetIndentString(indent + 1), "description: |")); writer.WriteLine(string.Concat(GetIndentString(indent + 2), attribute.Summary)); Example example = exampleStore.GetExample(node.Class, node.Method, ""); if (example != null) { writer.WriteLine(GetIndentString(indent + 2)); writer.WriteLine(string.Concat(GetIndentString(indent + 2), "For more information, go to ", headerSettings.RepositoryFilesURI, "/", example.DocFilename, "#", example.DocHeading)); } else if (attribute.RequestTypes != null) { SerialisationLog.Warning(string.Concat("No example to retrieve link to more information for ", node.Class.Name, ".", node.Method.Name)); } } else { SerialisationLog.Warning(string.Concat("No summary for ", node.Class.Name, ".", node.Method.Name)); } if (attribute.ResponseTypes != null && attribute.ResponseTypes.Any(r => r.GetProperties().Any(p => p.PropertyType == typeof(PageInfo)))) { writer.WriteLine(string.Concat(GetIndentString(indent + 1), "queryParameters: ")); foreach (KeyValuePair <string, Dictionary <string, string> > field in headerSettings.PagingFields) { writer.WriteLine(string.Concat(GetIndentString(indent + 2), field.Key, ":")); writer.WriteLine(string.Concat(GetIndentString(indent + 3), "displayName: ", field.Value["displayName"])); writer.WriteLine(string.Concat(GetIndentString(indent + 3), "description: ", field.Value["description"])); writer.WriteLine(string.Concat(GetIndentString(indent + 3), "type: ", field.Value["type"])); writer.WriteLine(string.Concat(GetIndentString(indent + 3), "required: ", field.Value["required"])); } } if (attribute.RequestTypes != null) { writer.WriteLine(string.Concat(GetIndentString(indent + 1), "body: ")); foreach (Type requestType in attribute.RequestTypes) { ContentTypeAttribute contentTypeAttribute = requestType.GetCustomAttributes <ContentTypeAttribute>().FirstOrDefault(); if (contentTypeAttribute == null) { SerialisationLog.Warning(string.Concat("No ContentTypeAttribute for ", requestType.FullName)); } if (attribute.RequestTypeNames != null) { foreach (string contentType in attribute.RequestTypeNames) { TDataExchangeFormat dataExchangeFormat = SerialisationUtils.GetDataExchangeFormatFromContentType(contentType); if (dataExchangeFormat != TDataExchangeFormat.None) { WriteBody(writer, exampleStore, node, dataExchangeFormat, contentType, TMessageType.Request, requestType, indent + 2); } else { SerialisationLog.Warning(string.Concat("No supported data exchange format for ", contentType)); } } } else { foreach (TDataExchangeFormat dataExchangeFormat in Enum.GetValues(typeof(TDataExchangeFormat))) { if (SerialisationUtils.IsStandardDataExchangeFormat(dataExchangeFormat)) { string contentType = GetContentType(contentTypeAttribute, dataExchangeFormat); WriteBody(writer, exampleStore, node, dataExchangeFormat, contentType, TMessageType.Request, requestType, indent + 2); } } } } } writer.WriteLine(string.Concat(GetIndentString(indent + 1), "responses:")); HttpStatusCode[] statusCodes = attribute.StatusCodes; if (node.Class.GetCustomAttributes <AuthorizeAttribute>().FirstOrDefault() != null) { statusCodes = statusCodes.Concat(new[] { HttpStatusCode.Unauthorized, HttpStatusCode.Forbidden }).ToArray(); } foreach (HttpStatusCode statusCode in statusCodes) { writer.WriteLine(string.Concat(GetIndentString(indent + 2), (int)statusCode, ":")); WriteDefaultDescription(writer, headerSettings, statusCode, indent + 3); if (SerialisationUtils.IsSuccessStatusCode(statusCode) && attribute.ResponseTypes != null) { writer.WriteLine(string.Concat(GetIndentString(indent + 3), "body:")); foreach (Type responseType in attribute.ResponseTypes) { ContentTypeAttribute contentTypeAttribute = responseType.GetCustomAttributes <ContentTypeAttribute>().FirstOrDefault(); if (contentTypeAttribute == null) { SerialisationLog.Warning(string.Concat("No ContentTypeAttribute for ", responseType.FullName)); } foreach (TDataExchangeFormat dataExchangeFormat in Enum.GetValues(typeof(TDataExchangeFormat))) { if (SerialisationUtils.IsStandardDataExchangeFormat(dataExchangeFormat)) { string contentType = GetContentType(contentTypeAttribute, dataExchangeFormat); WriteBody(writer, exampleStore, node, dataExchangeFormat, contentType, TMessageType.Response, responseType, indent + 4); } } } } } } else { SerialisationLog.Warning(string.Concat("No method-level documentation for ", node.Class.Name, ".", node.Method.Name)); } }
private string GetPropertyTypeName(Type propertyType, TDataExchangeFormat format) { // JSON: string integer number boolean object array // XML: string integer decimal boolean date time string propertyTypeName = propertyType.Name; if (propertyTypeName.StartsWith("Nullable`")) { propertyTypeName = ((TypeInfo)propertyType).DeclaredFields.ToArray()[1].FieldType.Name; } if (propertyTypeName.Equals("String")) { propertyTypeName = "string"; } else if (propertyTypeName.Equals("Int32") || propertyTypeName.Equals("Int64")) { propertyTypeName = "integer"; } else if (propertyTypeName.Equals("Float") || propertyTypeName.Equals("Double")) { if (format == TDataExchangeFormat.Json) propertyTypeName = "number"; else propertyTypeName = "decimal"; } else if (propertyTypeName.Equals("Boolean")) { propertyTypeName = "boolean"; } else if (propertyTypeName.StartsWith("List`")) { propertyTypeName = "array"; } else { //Console.WriteLine("GetPropertyType: skipped " + propertyTypeName); propertyTypeName = "object"; } return propertyTypeName; }
public static bool IsStandardDataExchangeFormat(TDataExchangeFormat dataExchangeFormat) { return dataExchangeFormat == TDataExchangeFormat.Json || dataExchangeFormat == TDataExchangeFormat.Xml; }
public void ReadExamples(string baseDirectory, string filename, ResourceNode resourceTree) { Example currentExample = null; StringBuilder currentExampleBody = null; TDataExchangeFormat currentExampleFormat = TDataExchangeFormat.None; bool inExample = false; string lastHeading = null; bool generateXml = true; foreach (string line in File.ReadLines(filename)) { string trimmed = line.Trim(); if (trimmed.StartsWith("#")) { lastHeading = trimmed.Replace("#", "").Trim().Replace(" ", "-").ToLower(); } else if (trimmed.StartsWith("[]: [!generateXml]")) { generateXml = false; } if (trimmed.StartsWith("```")) { if (currentExample != null) { string exampleFormat = trimmed.Substring("```".Length); if (exampleFormat.Equals(TDataExchangeFormat.Json.ToString().ToLower())) { currentExampleFormat = TDataExchangeFormat.Json; inExample = true; } else if (exampleFormat.Equals(FORM_EXAMPLE)) { currentExampleFormat = TDataExchangeFormat.FormUrlEncoded; inExample = true; } else if (inExample && exampleFormat.Length == 0) { if (currentExampleFormat == TDataExchangeFormat.FormUrlEncoded) { currentExample.Content.Add(currentExampleFormat, currentExampleBody.ToString()); } else { currentExample.Content.Add(TDataExchangeFormat.Json, currentExampleBody.ToString()); if (generateXml) { currentExample.Content.Add(TDataExchangeFormat.Xml, JsonToXml(currentExample, resourceTree, currentExampleBody.ToString())); } } currentExample = null; inExample = false; generateXml = true; } } } else { if (inExample) { if (line.Trim().Length > 0) { currentExampleBody.Append(line);// string.Concat(line, "\r\n")); } } else { MatchCollection matches = EXAMPLE_NAME_REGEX.Matches(trimmed); if (matches.Count == 1) { string fullExampleName = matches[0].Value; string prefix = "[]: ["; string suffix = "]"; string withoutSquareBrackets = fullExampleName.Substring(prefix.Length, matches[0].Value.Length - prefix.Length - suffix.Length); string[] parts = withoutSquareBrackets.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); string className = parts[0]; string methodName = parts[1]; string mimeType = trimmed.Substring(fullExampleName.Length); if (mimeType.Length > 0) { if (mimeType.StartsWith("[") && mimeType.EndsWith("]")) { mimeType = mimeType.Substring(1, mimeType.Length - 2); } else { SerialisationLog.Warning(string.Concat("Invalid mimetype on example tag: ", trimmed, " in ", filename)); mimeType = ""; } } if (resourceTree.Find(className, methodName) != null) { TMessageType messageType = (TMessageType)Enum.Parse(typeof(TMessageType), parts[2]); string exampleFilename = filename.Substring(baseDirectory.Length); currentExample = new Example(exampleFilename, lastHeading, className, methodName, messageType, mimeType); currentExampleBody = new StringBuilder(); string key = string.Concat(currentExample.ClassName, currentExample.MethodName, currentExample.ExampleType.ToString(), mimeType); if (!_Examples.ContainsKey(key)) { _Examples.Add(key, currentExample); } else { SerialisationLog.Error(string.Concat("An example already exists for ", currentExample.ClassName, ".", currentExample.MethodName, ".", currentExample.ExampleType.ToString(), "files: [", currentExample.DocFilename, ", ", _Examples[key].DocFilename, "]")); } } else { SerialisationLog.Error(string.Concat("The method ", className, ".", methodName, " in ", filename, " does not exist")); } } } } } }
public static bool IsStandardDataExchangeFormat(TDataExchangeFormat dataExchangeFormat) { return(dataExchangeFormat == TDataExchangeFormat.Json || dataExchangeFormat == TDataExchangeFormat.Xml); }
private void WriteExample(StreamWriter writer, ExampleStore exampleStore, Type classType, MethodInfo methodInfo, string contentType, TMessageType exampleType, TDataExchangeFormat dataExchangeFormat, int indent) { string exampleText = exampleStore.GetExampleContent(classType, methodInfo, exampleType, contentType, dataExchangeFormat); if (exampleText != null) { writer.WriteLine(string.Concat(GetIndentString(indent), "example: |")); List <string> lines = SerialisationUtils.SplitLines(exampleText); foreach (string line in lines) { writer.WriteLine(string.Concat(GetIndentString(indent + 1), line)); } } else if (dataExchangeFormat != TDataExchangeFormat.Xml) { SerialisationLog.Warning(string.Concat("No example for ", classType.Name, ".", methodInfo.Name, " ", dataExchangeFormat, " ", exampleType.ToString().ToLower())); } }
private object GetSchemaKey(Type objectType, TDataExchangeFormat dataExchangeFormat) { return(string.Concat(objectType.Name, dataExchangeFormat.ToString())); }