Created
February 2, 2014 19:28
-
-
Save anonymous/8773475 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using ServiceStack.Api.Swagger; | |
using ServiceStack.Common.Web; | |
using ServiceStack.ServiceHost; | |
using ServiceStack.ServiceInterface; | |
using System; | |
using System.IO; | |
using System.IO.Compression; | |
namespace web.services | |
{ | |
public class ExtJsService | |
{ | |
[Restrict(VisibleInternalOnly = true)] | |
[Route("/extjs/javascript", "GET")] | |
public class ExtJavascriptGetRequest : IReturn<string> | |
{ | |
} | |
[Restrict(VisibleInternalOnly = true)] | |
[Route("/extjs/metadata", "GET")] | |
public class ExtMetaDataGetRequest : IReturn<string> | |
{ | |
} | |
public class DevelopmentService : Service | |
{ | |
private const string extjsDefaultNameSpace = "MyApp"; | |
private const string extjsStoreTemplate = @"Ext.define('{0}', {{ | |
extend: 'Ext.data.Store', | |
requires: [ | |
'{1}', | |
'Ext.data.proxy.Ajax', | |
'Ext.data.reader.Json' | |
], | |
constructor: function(cfg) {{ | |
var me = this; | |
cfg = cfg || {{}}; | |
me.callParent([Ext.apply({{ | |
model: '{2}', | |
storeId: '{3}', | |
proxy: {{ | |
type: 'ajax', | |
url: '{4}', | |
reader: {{ | |
type: 'json' | |
}} | |
}} | |
}}, cfg)]); | |
}} | |
}});"; | |
private const string extjsModelTemplate = @"Ext.define('{0}', {{ | |
extend: 'Ext.data.Model', | |
requires: [ | |
'Ext.data.Field' | |
], | |
fields: [ | |
{1} | |
] | |
}});"; | |
private const string extjsModelMetadataTemplate = @"{{ | |
""type"": ""Ext.data.Model"", | |
""reference"": {{ | |
""name"": ""items"", | |
""type"": ""array"" | |
}}, | |
""codeClass"": null, | |
""userConfig"": {{ | |
""designer|userClassName"": ""{0}"" | |
}}, | |
""designerId"": ""{1}"", | |
""cn"": [ | |
{2} | |
] | |
}}"; | |
private const string extjsStoreMetadataTemplate = @"{{ | |
""type"": ""jsonstore"", | |
""reference"": {{ | |
""name"": ""items"", | |
""type"": ""array"" | |
}}, | |
""codeClass"": null, | |
""userConfig"": {{ | |
""designer|userClassName"": ""{0}"", | |
""model"": ""{1}"", | |
""storeId"": ""{2}"" | |
}}, | |
""designerId"": ""{3}"", | |
""cn"": [ | |
{{ | |
""type"": ""Ext.data.proxy.Ajax"", | |
""reference"": {{ | |
""name"": ""proxy"", | |
""type"": ""object"" | |
}}, | |
""codeClass"": null, | |
""userConfig"": {{ | |
""url"": ""{4}"" | |
}}, | |
""designerId"": ""{5}"", | |
""cn"": [ | |
{{ | |
""type"": ""Ext.data.reader.Json"", | |
""reference"": {{ | |
""name"": ""reader"", | |
""type"": ""object"" | |
}}, | |
""codeClass"": null, | |
""designerId"": ""{6}"" | |
}} | |
] | |
}} | |
] | |
}}"; | |
private ResourceResponse GetResourceResponse() | |
{ | |
var resources = new ResourceRequest() | |
{ | |
Name = "api" | |
}; | |
return (ResourceResponse)base.ResolveService<SwaggerApiService>().Get(resources); | |
} | |
private string SanitzeModelName(string modelName) | |
{ | |
string ret = string.Empty; | |
if (!string.IsNullOrEmpty(modelName)) | |
{ | |
ret = modelName | |
.Replace("List[", string.Empty) | |
.Replace("]", string.Empty); | |
if (ret.ToLower() == "byte") | |
{ | |
ret = string.Empty; | |
} | |
} | |
return ret; | |
} | |
private string MakeJavascriptModel(ResourceResponse resource, MethodDescription api) | |
{ | |
string result = string.Empty; | |
string modelName = SanitzeModelName(api.Operations[0].ResponseClass); | |
result += "// " + api.Description + Environment.NewLine + Environment.NewLine; | |
SwaggerModel model; | |
if (resource.Models.TryGetValue(modelName, out model)) | |
{ | |
string properties = string.Empty; | |
foreach (var prop in model.Properties) | |
{ | |
properties += | |
" {" + Environment.NewLine + | |
" mapping : " + "'" + prop.Key + "'," + Environment.NewLine + | |
" name : " + "'" + prop.Key + "'," + Environment.NewLine + | |
" type : " + "'" + prop.Value.Type + "'" + Environment.NewLine + | |
" }," + Environment.NewLine; | |
} | |
properties = properties.TrimEnd().Remove(properties.TrimEnd().Length - 1); | |
result += string.Format(extjsModelTemplate, | |
extjsDefaultNameSpace + ".model." + model.Id, | |
properties | |
); | |
result += Environment.NewLine + Environment.NewLine; | |
} | |
return result; | |
} | |
private string MakeJavascriptStore(MethodDescription api) | |
{ | |
var result = string.Empty; | |
var modelName = SanitzeModelName(api.Operations[0].ResponseClass); | |
result += string.Format(extjsStoreTemplate, | |
extjsDefaultNameSpace + ".store." + api.Operations[0].Nickname, | |
extjsDefaultNameSpace + ".model." + modelName, | |
extjsDefaultNameSpace + ".model." + modelName, | |
api.Operations[0].Nickname, | |
api.Path | |
); | |
return result; | |
} | |
private string MakeMetaDataModel(ResourceResponse resource, MethodDescription api, out string fileName) | |
{ | |
var result = string.Empty; | |
fileName = string.Empty; | |
var modelName = SanitzeModelName(api.Operations[0].ResponseClass); | |
SwaggerModel model; | |
if (resource.Models.TryGetValue(modelName, out model)) | |
{ | |
string properties = string.Empty; | |
foreach (var prop in model.Properties) | |
{ | |
properties += @" { | |
""type"": ""Ext.data.Field"", | |
""reference"": { | |
""name"": ""fields"", | |
""type"": ""array"" | |
}, | |
""codeClass"": null, | |
""userConfig"": "; | |
properties += | |
"{" + Environment.NewLine + | |
" \"mapping\" : " + "\"" + prop.Key + "\"," + Environment.NewLine + | |
" \"name\" : " + "\"" + prop.Key + "\"," + Environment.NewLine + | |
" \"type\" : " + "\"" + prop.Value.Type + "\"" + Environment.NewLine + | |
" }," + Environment.NewLine; | |
properties += @" ""designerId"": """ + Guid.NewGuid() + @""" | |
}," + Environment.NewLine; | |
} | |
properties = properties.TrimEnd().Remove(properties.TrimEnd().Length - 1); | |
result += string.Format(extjsModelMetadataTemplate, | |
model.Id, | |
Guid.NewGuid(), | |
properties | |
); | |
result += Environment.NewLine + Environment.NewLine; | |
fileName = model.Id; | |
} | |
return result; | |
} | |
private string MakeMetadataStore(MethodDescription api, out string fileName) | |
{ | |
var result = string.Empty; | |
var modelName = SanitzeModelName(api.Operations[0].ResponseClass); | |
result += string.Format(extjsStoreMetadataTemplate, | |
api.Operations[0].Nickname, | |
modelName, | |
api.Operations[0].Nickname, | |
Guid.NewGuid(), | |
api.Path, | |
Guid.NewGuid(), | |
Guid.NewGuid() | |
); | |
fileName = api.Operations[0].Nickname; | |
return result; | |
} | |
public object Get(ExtJavascriptGetRequest request) | |
{ | |
var resource = GetResourceResponse(); | |
var result = string.Empty; | |
foreach (var api in resource.Apis) | |
{ | |
// models | |
result += MakeJavascriptModel(resource, api); | |
result += Environment.NewLine + Environment.NewLine; | |
// stores | |
result += MakeJavascriptStore(api); | |
result += Environment.NewLine + Environment.NewLine + Environment.NewLine + Environment.NewLine; | |
} | |
return result; | |
} | |
public object Get(ExtMetaDataGetRequest request) | |
{ | |
var resource = GetResourceResponse(); | |
string fileName = string.Empty; | |
var stream = new MemoryStream(); | |
using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true)) | |
{ | |
foreach (var api in resource.Apis) | |
{ | |
// model | |
var modelMetadata = MakeMetaDataModel(resource, api, out fileName); | |
if (!string.IsNullOrEmpty(fileName)) | |
{ | |
var modelEntry = archive.CreateEntry(Path.Combine("model", fileName)); | |
var modleWriter = new StreamWriter(modelEntry.Open()); | |
modleWriter.Write(modelMetadata); | |
modleWriter.Close(); | |
} | |
// store | |
var storeMetadata = MakeMetadataStore(api, out fileName); | |
if (!string.IsNullOrEmpty(fileName)) | |
{ | |
var storeEntry = archive.CreateEntry(Path.Combine("store", fileName)); | |
var storeWriter = new StreamWriter(storeEntry.Open()); | |
storeWriter.Write(storeMetadata); | |
storeWriter.Close(); | |
} | |
} | |
} | |
base.Response.AddHeader("Content-Disposition", "attachment; filename=" + "metadata.zip"); | |
return new HttpResult(stream, "application/octet-stream"); | |
} | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment