Skip to content

Instantly share code, notes, and snippets.

Created February 2, 2014 19:28
Show Gist options
  • Save anonymous/8773475 to your computer and use it in GitHub Desktop.
Save anonymous/8773475 to your computer and use it in GitHub Desktop.
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