private static string AppendType(ref StringBuilderWrapper sb, MetadataType type, string lastNS, CreateTypeOptions options) { if (type == null || (type.Namespace != null && type.Namespace.StartsWith("System"))) return lastNS; if (type.Namespace != lastNS) { if (lastNS != null) sb.AppendLine("}"); lastNS = type.Namespace; sb.AppendLine(); sb.AppendLine("namespace {0}".Fmt(type.Namespace.SafeToken())); sb.AppendLine("{"); } sb = sb.Indent(); sb.AppendLine(); sb.AppendComments(type.Description); sb.AppendDataContract(type.DataContract); var partial = Config.MakePartial ? "partial " : ""; sb.AppendLine("public {0}class {1}".Fmt(partial, type.Name.SafeToken())); //: BaseClass, Interfaces var inheritsList = new List<string>(); if (type.Inherits != null) inheritsList.Add(Type(type.Inherits, type.InheritsGenericArgs)); if (options.ImplementsFn != null) { var implStr = options.ImplementsFn(); if (!string.IsNullOrEmpty(implStr)) inheritsList.Add(implStr); } var makeExtensible = Config.MakeDataContractsExtensible && type.Inherits == null; if (makeExtensible) inheritsList.Add("IExtensibleDataObject"); if (inheritsList.Count > 0) sb.AppendLine(" : {0}".Fmt(string.Join(", ", inheritsList.ToArray()))); sb.AppendLine("{"); sb = sb.Indent(); sb.AddConstuctor(type, options); sb.AddProperties(type); sb = sb.UnIndent(); sb.AppendLine("}"); sb = sb.UnIndent(); return lastNS; }
public static string GetCode(MetadataTypes metadata, string defaultBaseUrl = null) { Config = metadata.Config; var namespaces = new HashSet<string>(); Config.DefaultNamespaces.Each(x => namespaces.Add(x)); metadata.Types.Each(x => namespaces.Add(x.Namespace)); metadata.Operations.Each(x => namespaces.Add(x.Request.Namespace)); const bool flag = false; Config.AddReturnMarker = flag; Config.MakeVirtual = Config.MakePartial = flag; Config.AddDescriptionAsComments = flag; Config.AddDefaultXmlNamespace = "http://schemas.servicestack.net/dtogen-types"; Config.AddDataContractAttributes = flag; Config.MakeDataContractsExtensible = flag; Config.AddIndexesToDataMembers = flag; Config.InitializeCollections = flag; Config.AddResponseStatus = flag; Config.AddImplicitVersion = null; var sb = new StringBuilderWrapper(new StringBuilder()); sb.AppendLine("/* Options:"); sb.AppendLine("Version: {0}".Fmt(Version)); sb.AppendLine("BaseUrl: {0}".Fmt(Config.BaseUrl ?? defaultBaseUrl)); sb.AppendLine(); sb.AppendLine("ServerVersion: {0}".Fmt(metadata.Version)); sb.AppendLine("MakePartial: {0}".Fmt(Config.MakePartial)); sb.AppendLine("MakeVirtual: {0}".Fmt(Config.MakeVirtual)); sb.AppendLine("AddReturnMarker: {0}".Fmt(Config.AddReturnMarker)); sb.AppendLine("AddDescriptionAsComments: {0}".Fmt(Config.AddDescriptionAsComments)); sb.AppendLine("AddDataContractAttributes: {0}".Fmt(Config.AddDataContractAttributes)); sb.AppendLine("AddDefaultXmlNamespace: {0}".Fmt(Config.AddDefaultXmlNamespace)); sb.AppendLine("MakeDataContractsExtensible: {0}".Fmt(Config.MakeDataContractsExtensible)); sb.AppendLine("AddIndexesToDataMembers: {0}".Fmt(Config.AddIndexesToDataMembers)); sb.AppendLine("InitializeCollections: {0}".Fmt(Config.InitializeCollections)); sb.AppendLine("AddResponseStatus: {0}".Fmt(Config.AddResponseStatus)); sb.AppendLine("AddImplicitVersion: {0}".Fmt(Config.AddImplicitVersion)); sb.AppendLine("DefaultNamespaces: {0}".Fmt(Config.DefaultNamespaces.ToArray().Join(", "))); sb.AppendLine("*/"); sb.AppendLine(); namespaces.ToList().ForEach(x => sb.AppendLine("using {0};".Fmt(x))); if (Config.AddDataContractAttributes && Config.AddDefaultXmlNamespace != null) { sb.AppendLine(); namespaces.Where(x => !Config.DefaultNamespaces.Contains(x)).ToList() .ForEach(x => sb.AppendLine("[assembly: ContractNamespace(\"{0}\", ClrNamespace=\"{1}\")]" .Fmt(Config.AddDefaultXmlNamespace, x))); } sb.AppendLine(); string lastNS = null; sb.AppendLine("#region Operations"); sb.AppendLine(); foreach (var operation in metadata.Operations .OrderBy(x => x.Request.Namespace) .OrderBy(x => x.Request.Name)) { var request = operation.Request; var response = operation.Response; lastNS = AppendType(ref sb, request, lastNS, new CreateTypeOptions { ImplementsFn = () => { if (!Config.AddReturnMarker && !request.ReturnVoidMarker && request.ReturnMarkerGenericArgs == null) return null; if (request.ReturnVoidMarker) return "IReturnVoid"; if (request.ReturnMarkerGenericArgs != null) return Type("IReturn`1", request.ReturnMarkerGenericArgs); return response != null ? Type("IReturn`1", new[] { response.Name }) : null; }, IsRequest = true, }); lastNS = AppendType(ref sb, operation.Response, lastNS, new CreateTypeOptions { IsResponse = true, }); } if (lastNS != null) sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine("#endregion"); sb.AppendLine(); sb.AppendLine(); lastNS = null; sb.AppendLine("#region Types"); sb.AppendLine(); foreach (var type in metadata.Types .OrderBy(x => x.Namespace) .OrderBy(x => x.Name)) { lastNS = AppendType(ref sb, type, lastNS, new CreateTypeOptions { IsType = true }); } if (lastNS != null) sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine("#endregion"); return sb.ToString(); }
public bool AppendDataMember(StringBuilderWrapper sb, MetadataDataMember dmMeta, int dataMemberIndex) { if (dmMeta == null) { if (Config.AddDataContractAttributes) { sb.AppendLine(Config.AddIndexesToDataMembers ? "@DataMember(Order={0})".Fmt(dataMemberIndex) : "@DataMember()"); return(true); } return(false); } var dmArgs = ""; if (dmMeta.Name != null || dmMeta.Order != null || dmMeta.IsRequired != null || dmMeta.EmitDefaultValue != null || Config.AddIndexesToDataMembers) { if (dmMeta.Name != null) { dmArgs = "Name={0}".Fmt(dmMeta.Name.QuotedSafeValue()); } if (dmMeta.Order != null || Config.AddIndexesToDataMembers) { if (dmArgs.Length > 0) { dmArgs += ", "; } dmArgs += "Order={0}".Fmt(dmMeta.Order ?? dataMemberIndex); } if (dmMeta.IsRequired != null) { if (dmArgs.Length > 0) { dmArgs += ", "; } dmArgs += "IsRequired={0}".Fmt(dmMeta.IsRequired.ToString().ToLower()); } if (dmMeta.EmitDefaultValue != null) { if (dmArgs.Length > 0) { dmArgs += ", "; } dmArgs += "EmitDefaultValue={0}".Fmt(dmMeta.EmitDefaultValue.ToString().ToLower()); } dmArgs = "({0})".Fmt(dmArgs); } sb.AppendLine("@DataMember{0}".Fmt(dmArgs)); if (dmMeta.Name != null) { sb.AppendLine("@SerializedName(\"{0}\")".Fmt(dmMeta.Name)); } return(true); }
public void AddProperties(StringBuilderWrapper sb, MetadataType type, bool includeResponseStatus, bool addPropertyAccessors, string settersReturnType) { var wasAdded = false; var sbAccessors = new StringBuilderWrapper(new StringBuilder()); if (addPropertyAccessors) { sbAccessors.AppendLine(); sbAccessors = sbAccessors.Indent().Indent(); } var dataMemberIndex = 1; if (type.Properties != null) { foreach (var prop in type.Properties) { if (wasAdded) { sb.AppendLine(); } var propType = Type(prop.Type, prop.GenericArgs); var fieldName = prop.Name.SafeToken().PropertyStyle(); var accessorName = fieldName.ToPascalCase(); wasAdded = AppendDataMember(sb, prop.DataMember, dataMemberIndex++); wasAdded = AppendAttributes(sb, prop.Attributes) || wasAdded; if (!fieldName.IsKeyWord()) { sb.AppendLine("public {0} {1} = null;".Fmt(propType, fieldName)); } else { var originalName = fieldName; fieldName = Char.ToUpper(fieldName[0]) + fieldName.SafeSubstring(1); sb.AppendLine("@SerializedName(\"{0}\") public {1} {2} = null;".Fmt(originalName, propType, fieldName)); } if (addPropertyAccessors) { sbAccessors.AppendPropertyAccessor(propType, fieldName, accessorName, settersReturnType); } } } if (includeResponseStatus) { if (wasAdded) { sb.AppendLine(); } AppendDataMember(sb, null, dataMemberIndex++); sb.AppendLine("public ResponseStatus {0} = null;".Fmt(typeof(ResponseStatus).Name.PropertyStyle())); if (addPropertyAccessors) { sbAccessors.AppendPropertyAccessor("ResponseStatus", "ResponseStatus", settersReturnType); } } if (sbAccessors.Length > 0) { sb.AppendLine(sbAccessors.ToString().TrimEnd()); //remove last \n } }
private string AppendType(ref StringBuilderWrapper sb, MetadataType type, string lastNS, CreateTypeOptions options) { sb = sb.Indent(); sb.AppendLine(); AppendComments(sb, type.Description); if (type.Routes != null) { AppendAttributes(sb, type.Routes.ConvertAll(x => x.ToMetadataAttribute())); } AppendAttributes(sb, type.Attributes); AppendDataContract(sb, type.DataContract); var typeName = Type(type.Name, type.GenericArgs); if (type.IsEnum.GetValueOrDefault()) { sb.AppendLine("public static enum {0}".Fmt(typeName)); sb.AppendLine("{"); sb = sb.Indent(); if (type.EnumNames != null) { var hasIntValue = false; for (var i = 0; i < type.EnumNames.Count; i++) { var name = type.EnumNames[i]; var value = type.EnumValues != null ? type.EnumValues[i] : null; var delim = i == type.EnumNames.Count - 1 ? ";" : ","; var serializeAs = JsConfig.TreatEnumAsInteger || (type.Attributes.Safe().Any(x => x.Name == "Flags")) ? "@SerializedName(\"{0}\") ".Fmt(value) : ""; sb.AppendLine(value == null ? "{0}{1}".Fmt(name.ToPascalCase(), delim) : serializeAs + "{0}({1}){2}".Fmt(name.ToPascalCase(), value, delim)); hasIntValue = hasIntValue || value != null; } if (hasIntValue) { sb.AppendLine(); sb.AppendLine("private final int value;"); sb.AppendLine("{0}(final int intValue) {{ value = intValue; }}".Fmt(typeName)); sb.AppendLine("public int getValue() { return value; }"); } } sb = sb.UnIndent(); sb.AppendLine("}"); } else { var defType = type.IsInterface() ? "interface" : "class"; var extends = new List <string>(); //: BaseClass, Interfaces if (type.Inherits != null) { extends.Add(Type(type.Inherits).InheritedType()); } string responseTypeExpression = null; var interfaces = new List <string>(); if (options.ImplementsFn != null) { var implStr = options.ImplementsFn(); if (!string.IsNullOrEmpty(implStr)) { interfaces.Add(implStr); if (implStr.StartsWith("IReturn<")) { var parts = implStr.SplitOnFirst('<'); var returnType = parts[1].Substring(0, parts[1].Length - 1); //Can't get .class from Generic Type definition responseTypeExpression = returnType.Contains("<") ? "new TypeToken<{0}>(){{}}.getType()".Fmt(returnType) : "{0}.class".Fmt(returnType); } } if (!type.Implements.IsEmpty()) { foreach (var interfaceRef in type.Implements) { interfaces.Add(Type(interfaceRef)); } } } var extend = extends.Count > 0 ? " extends " + extends[0] : ""; if (interfaces.Count > 0) { extend += " implements " + string.Join(", ", interfaces.ToArray()); } var addPropertyAccessors = Config.AddPropertyAccessors && !type.IsInterface(); var settersReturnType = addPropertyAccessors && Config.SettersReturnThis ? typeName : null; sb.AppendLine("public static {0} {1}{2}".Fmt(defType, typeName, extend)); sb.AppendLine("{"); sb = sb.Indent(); var addVersionInfo = Config.AddImplicitVersion != null && options.IsRequest; if (addVersionInfo) { sb.AppendLine("public Integer {0} = {1};".Fmt("Version".PropertyStyle(), Config.AddImplicitVersion)); if (addPropertyAccessors) { sb.AppendPropertyAccessor("Integer", "Version", settersReturnType); } } AddProperties(sb, type, includeResponseStatus: Config.AddResponseStatus && options.IsResponse && type.Properties.Safe().All(x => x.Name != typeof(ResponseStatus).Name), addPropertyAccessors: addPropertyAccessors, settersReturnType: settersReturnType); if (responseTypeExpression != null) { sb.AppendLine("private static Object responseType = {0};".Fmt(responseTypeExpression)); sb.AppendLine("public Object getResponseType() { return responseType; }"); } sb = sb.UnIndent(); sb.AppendLine("}"); } sb = sb.UnIndent(); return(lastNS); }
public string GetCode(MetadataTypes metadata, IRequest request) { var namespaces = Config.GetDefaultNamespaces(metadata); metadata.RemoveIgnoredTypesForNet(Config); if (Config.GlobalNamespace == null) { metadata.Types.Each(x => namespaces.Add(x.Namespace)); metadata.Operations.Each(x => namespaces.Add(x.Request.Namespace)); } else { namespaces.Add(Config.GlobalNamespace); } Func <string, string> defaultValue = k => request.QueryString[k].IsNullOrEmpty() ? "'''" : "'"; var sb = new StringBuilderWrapper(new StringBuilder()); sb.AppendLine("' Options:"); sb.AppendLine("'Date: {0}".Fmt(DateTime.Now.ToString("s").Replace("T", " "))); sb.AppendLine("'Version: {0}".Fmt(Env.ServiceStackVersion)); sb.AppendLine("'BaseUrl: {0}".Fmt(Config.BaseUrl)); sb.AppendLine("'"); sb.AppendLine("{0}GlobalNamespace: {1}".Fmt(defaultValue("GlobalNamespace"), Config.GlobalNamespace)); sb.AppendLine("{0}MakePartial: {1}".Fmt(defaultValue("MakePartial"), Config.MakePartial)); sb.AppendLine("{0}MakeVirtual: {1}".Fmt(defaultValue("MakeVirtual"), Config.MakeVirtual)); sb.AppendLine("{0}MakeDataContractsExtensible: {1}".Fmt(defaultValue("MakeDataContractsExtensible"), Config.MakeDataContractsExtensible)); sb.AppendLine("{0}AddReturnMarker: {1}".Fmt(defaultValue("AddReturnMarker"), Config.AddReturnMarker)); sb.AppendLine("{0}AddDescriptionAsComments: {1}".Fmt(defaultValue("AddDescriptionAsComments"), Config.AddDescriptionAsComments)); sb.AppendLine("{0}AddDataContractAttributes: {1}".Fmt(defaultValue("AddDataContractAttributes"), Config.AddDataContractAttributes)); sb.AppendLine("{0}AddIndexesToDataMembers: {1}".Fmt(defaultValue("AddIndexesToDataMembers"), Config.AddIndexesToDataMembers)); sb.AppendLine("{0}AddGeneratedCodeAttributes: {1}".Fmt(defaultValue("AddGeneratedCodeAttributes"), Config.AddGeneratedCodeAttributes)); sb.AppendLine("{0}AddResponseStatus: {1}".Fmt(defaultValue("AddResponseStatus"), Config.AddResponseStatus)); sb.AppendLine("{0}AddImplicitVersion: {1}".Fmt(defaultValue("AddImplicitVersion"), Config.AddImplicitVersion)); sb.AppendLine("{0}InitializeCollections: {1}".Fmt(defaultValue("InitializeCollections"), Config.InitializeCollections)); sb.AppendLine("{0}IncludeTypes: {1}".Fmt(defaultValue("IncludeTypes"), Config.IncludeTypes.Safe().ToArray().Join(", "))); sb.AppendLine("{0}ExcludeTypes: {1}".Fmt(defaultValue("ExcludeTypes"), Config.ExcludeTypes.Safe().ToArray().Join(", "))); sb.AppendLine("{0}AddDefaultXmlNamespace: {1}".Fmt(defaultValue("AddDefaultXmlNamespace"), Config.AddDefaultXmlNamespace)); //sb.AppendLine("{0}DefaultNamespaces: {1}".Fmt(defaultValue("DefaultNamespaces"), Config.DefaultNamespaces.ToArray().Join(", "))); sb.AppendLine(); namespaces.Where(x => !string.IsNullOrEmpty(x)) .Each(x => sb.AppendLine("Imports {0}".Fmt(x))); if (Config.AddGeneratedCodeAttributes) { sb.AppendLine("Imports System.CodeDom.Compiler"); } if (Config.AddDataContractAttributes && Config.AddDefaultXmlNamespace != null) { sb.AppendLine(); namespaces.Where(x => !Config.DefaultNamespaces.Contains(x)).ToList() .ForEach(x => sb.AppendLine("<Assembly: ContractNamespace(\"{0}\", ClrNamespace:=\"{1}\")>" .Fmt(Config.AddDefaultXmlNamespace, x))); } sb.AppendLine(); sb.AppendLine("Namespace Global"); sb = sb.Indent(); string lastNS = null; var existingTypes = new HashSet <string>(); var requestTypes = metadata.Operations.Select(x => x.Request).ToHashSet(); var requestTypesMap = metadata.Operations.ToSafeDictionary(x => x.Request); var responseTypes = metadata.Operations .Where(x => x.Response != null) .Select(x => x.Response).ToHashSet(); var types = metadata.Types.ToHashSet(); var allTypes = new List <MetadataType>(); allTypes.AddRange(requestTypes); allTypes.AddRange(responseTypes); allTypes.AddRange(types); allTypes.RemoveAll(x => x.IgnoreType(Config)); var orderedTypes = allTypes .OrderBy(x => x.Namespace) .ThenBy(x => x.Name); foreach (var type in orderedTypes) { var fullTypeName = type.GetFullName(); if (requestTypes.Contains(type)) { if (!existingTypes.Contains(fullTypeName)) { MetadataType response = null; MetadataOperationType operation; if (requestTypesMap.TryGetValue(type, out operation)) { response = operation.Response; } lastNS = AppendType(ref sb, type, lastNS, allTypes, new CreateTypeOptions { ImplementsFn = () => { if (!Config.AddReturnMarker && !type.ReturnVoidMarker && type.ReturnMarkerTypeName == null) { return(null); } if (type.ReturnVoidMarker) { return("IReturnVoid"); } if (type.ReturnMarkerTypeName != null) { return(Type("IReturn`1", new[] { Type(type.ReturnMarkerTypeName) })); } return(response != null ? Type("IReturn`1", new[] { Type(response.Name, response.GenericArgs) }) : null); }, IsRequest = true, }); existingTypes.Add(fullTypeName); } } else if (responseTypes.Contains(type)) { if (!existingTypes.Contains(fullTypeName) && !Config.IgnoreTypesInNamespaces.Contains(type.Namespace)) { lastNS = AppendType(ref sb, type, lastNS, allTypes, new CreateTypeOptions { IsResponse = true, }); existingTypes.Add(fullTypeName); } } else if (types.Contains(type) && !existingTypes.Contains(fullTypeName)) { lastNS = AppendType(ref sb, type, lastNS, allTypes, new CreateTypeOptions { IsType = true }); existingTypes.Add(fullTypeName); } } if (lastNS != null) { sb.AppendLine("End Namespace"); } sb = sb.UnIndent(); sb.AppendLine("End Namespace"); sb.AppendLine(); return(sb.ToString()); }
private string AppendType(ref StringBuilderWrapper sb, MetadataType type, string lastNS, List <MetadataType> allTypes, CreateTypeOptions options) { if (type.IsNested.GetValueOrDefault() && !options.IsNestedType) { return(lastNS); } var ns = Config.GlobalNamespace ?? type.Namespace; if (ns != lastNS) { if (lastNS != null) { sb.AppendLine("End Namespace"); } lastNS = ns; sb.AppendLine(); sb.AppendLine("Namespace {0}".Fmt(ns.SafeToken())); //sb.AppendLine("{"); } sb = sb.Indent(); sb.AppendLine(); AppendComments(sb, type.Description); if (type.Routes != null) { AppendAttributes(sb, type.Routes.ConvertAll(x => x.ToMetadataAttribute())); } AppendAttributes(sb, type.Attributes); AppendDataContract(sb, type.DataContract); if (Config.AddGeneratedCodeAttributes) { sb.AppendLine("<GeneratedCode(\"AddServiceStackReference\", \"{0}\")>".Fmt(Env.VersionString)); } if (type.IsEnum.GetValueOrDefault()) { sb.AppendLine("Public Enum {0}".Fmt(Type(type.Name, type.GenericArgs))); //sb.AppendLine("{"); sb = sb.Indent(); if (type.EnumNames != null) { for (var i = 0; i < type.EnumNames.Count; i++) { var name = type.EnumNames[i]; var value = type.EnumValues != null ? type.EnumValues[i] : null; sb.AppendLine(value == null ? "{0}".Fmt(name) : "{0} = {1}".Fmt(name, value)); } } sb = sb.UnIndent(); sb.AppendLine("End Enum"); } else { var partial = Config.MakePartial && !type.IsInterface() ? "Partial " : ""; var defType = type.IsInterface() ? "Interface" : "Class"; sb.AppendLine("Public {0}{1} {2}".Fmt(partial, defType, Type(type.Name, type.GenericArgs))); //: BaseClass, Interfaces if (type.Inherits != null) { sb.AppendLine(" Inherits {0}".Fmt(Type(type.Inherits, includeNested: true))); } var implements = new List <string>(); if (options.ImplementsFn != null) { var implStr = options.ImplementsFn(); if (!string.IsNullOrEmpty(implStr)) { implements.Add(implStr); } if (!type.Implements.IsEmpty()) { type.Implements.Each(x => implements.Add(Type(x))); } } var makeExtensible = Config.MakeDataContractsExtensible && type.Inherits == null; if (makeExtensible) { implements.Add("IExtensibleDataObject"); } if (implements.Count > 0) { foreach (var x in implements) { sb.AppendLine(" Implements {0}".Fmt(x)); } } //sb.AppendLine("{"); sb = sb.Indent(); AddConstuctor(sb, type, options); AddProperties(sb, type, includeResponseStatus: Config.AddResponseStatus && options.IsResponse && type.Properties.Safe().All(x => x.Name != typeof(ResponseStatus).Name)); foreach (var innerTypeRef in type.InnerTypes.Safe()) { var innerType = allTypes.FirstOrDefault(x => x.Name == innerTypeRef.Name); if (innerType == null) { continue; } sb = sb.UnIndent(); AppendType(ref sb, innerType, lastNS, allTypes, new CreateTypeOptions { IsNestedType = true }); sb = sb.Indent(); } sb = sb.UnIndent(); sb.AppendLine(type.IsInterface() ? "End Interface" : "End Class"); } sb = sb.UnIndent(); return(lastNS); }