added return types, media types

This commit is contained in:
Tony Tam 2014-09-03 00:38:24 -07:00
parent 812520e29f
commit 6f63ba43ad
9 changed files with 237 additions and 63 deletions

View File

@ -23,7 +23,6 @@ public class Codegen extends DefaultGenerator {
}
}
try{
Swagger swagger = (Swagger) Json.mapper()
.readValue(new File("swagger.json"), Swagger.class);

View File

@ -5,6 +5,7 @@ import com.wordnik.swagger.models.*;
import java.util.*;
public interface CodegenConfig {
Map<String, Object> additionalProperties();
String apiPackage();
String apiFileFolder();
String fileSuffix();
@ -16,7 +17,7 @@ public interface CodegenConfig {
Set<String> reservedWords();
CodegenModel fromModel(String name, ModelImpl model);
CodegenModel fromModel(String name, Model model);
CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation);
Set<String> defaultIncludes();
Map<String, String> typeMapping();

View File

@ -7,8 +7,14 @@ import java.util.*;
public class CodegenOperation {
public String path, operationId,
returnType;
public String path, operationId, returnType, httpMethod, returnBaseType, returnContainer;
public List<Map<String, String>> consumes, produces;
public List<CodegenParameter> allParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> bodyParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> pathParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> queryParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> headerParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> formParams = new ArrayList<CodegenParameter>();
// legacy support
public String nickname;

View File

@ -0,0 +1,5 @@
package com.wordnik.swagger.codegen;
public class CodegenParameter {
public String baseName, paramName, dataType, collectionFormat;
}

View File

@ -2,6 +2,7 @@ package com.wordnik.swagger.codegen;
import com.wordnik.swagger.util.Json;
import com.wordnik.swagger.models.*;
import com.wordnik.swagger.models.parameters.*;
import com.wordnik.swagger.models.properties.*;
import java.util.*;
@ -18,6 +19,7 @@ public class DefaultCodegen {
protected Map<String, String> apiTemplateFiles = new HashMap<String, String>();
protected Map<String, String> modelTemplateFiles = new HashMap<String, String>();
protected String templateDir;
protected Map<String, Object> additionalProperties = new HashMap<String, Object>();
public Set<String> defaultIncludes() {
return defaultIncludes;
@ -58,6 +60,9 @@ public class DefaultCodegen {
public String modelFileFolder() {
return outputFolder + File.separator + modelPackage().replaceAll("\\.", File.separator);
}
public Map<String, Object> additionalProperties() {
return additionalProperties;
}
public void setTemplateDir(String templateDir) {
this.templateDir = templateDir;
@ -166,7 +171,7 @@ public class DefaultCodegen {
}
else {
System.out.println("unhandled property default value");
Json.prettyPrint(p);
// Json.prettyPrint(p);
return "null";
}
}
@ -226,28 +231,40 @@ public class DefaultCodegen {
return initialCaps(name);
}
public CodegenModel fromModel(String name, ModelImpl model) {
public CodegenModel fromModel(String name, Model model) {
CodegenModel m = new CodegenModel();
m.name = name;
m.description = model.getDescription();
m.classname = toModelName(name);
int count = 0;
for(String key: model.getProperties().keySet()) {
Property prop = model.getProperties().get(key);
if(prop == null) {
System.out.println("null property for " + key);
Json.prettyPrint(model.getProperties());
}
else {
CodegenProperty cp = fromProperty(key, prop);
if(cp.complexType != null && !defaultIncludes.contains(cp.complexType)) {
m.imports.add(cp.complexType);
if(model instanceof ArrayModel) {
ArrayModel am = (ArrayModel) model;
ArrayProperty arrayProperty = new ArrayProperty(am.getItems());
CodegenProperty cp = fromProperty(name, arrayProperty);
m.vars.add(cp);
}
else if (model instanceof RefModel) {
}
else {
ModelImpl impl = (ModelImpl) model;
for(String key: impl.getProperties().keySet()) {
Property prop = impl.getProperties().get(key);
if(prop == null) {
System.out.println("null property for " + key);
// Json.prettyPrint(impl.getProperties());
}
else {
CodegenProperty cp = fromProperty(key, prop);
if(cp.complexType != null && !defaultIncludes.contains(cp.complexType)) {
m.imports.add(cp.complexType);
}
m.vars.add(cp);
count += 1;
if(count != impl.getProperties().keySet().size())
cp.hasMore = new Boolean(true);
}
m.vars.add(cp);
count += 1;
if(count != model.getProperties().keySet().size())
cp.hasMore = new Boolean(true);
}
}
return m;
@ -321,6 +338,34 @@ public class DefaultCodegen {
Response methodResponse = null;
if(operation.getConsumes() != null && operation.getConsumes().size() > 0) {
List<Map<String, String>> c = new ArrayList<Map<String, String>>();
int count = 0;
for(String key: operation.getConsumes()) {
Map<String, String> mediaType = new HashMap<String, String>();
mediaType.put("mediaType", key);
count += 1;
if (count < operation.getConsumes().size())
mediaType.put("hasMore", "true");
c.add(mediaType);
}
op.consumes = c;
}
if(operation.getProduces() != null && operation.getProduces().size() > 0) {
List<Map<String, String>> c = new ArrayList<Map<String, String>>();
int count = 0;
for(String key: operation.getProduces()) {
Map<String, String> mediaType = new HashMap<String, String>();
mediaType.put("mediaType", key);
count += 1;
if (count < operation.getProduces().size())
mediaType.put("hasMore", "true");
c.add(mediaType);
}
op.produces = c;
}
if(operation.getResponses() != null) {
for(String responseCode: operation.getResponses().keySet()) {
Response response = operation.getResponses().get(responseCode);
@ -334,11 +379,101 @@ public class DefaultCodegen {
if(methodResponse != null && methodResponse.getSchema() != null) {
CodegenProperty responseModel = fromProperty("response", methodResponse.getSchema());
Json.prettyPrint(responseModel);
Property responseProperty = methodResponse.getSchema();
if(responseProperty instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) responseProperty;
CodegenProperty innerProperty = fromProperty("response", ap.getItems());
op.returnBaseType = innerProperty.datatype;
}
else
op.returnBaseType = responseModel.datatype;
op.returnType = responseModel.datatype;
if(responseModel.isContainer)
op.returnContainer = responseModel.complexType;
}
List<Parameter> parameters = operation.getParameters();
List<CodegenParameter> allParams = new ArrayList<CodegenParameter>();
List<CodegenParameter> bodyParams = new ArrayList<CodegenParameter>();
List<CodegenParameter> pathParams = new ArrayList<CodegenParameter>();
List<CodegenParameter> queryParams = new ArrayList<CodegenParameter>();
List<CodegenParameter> headerParams = new ArrayList<CodegenParameter>();
List<CodegenParameter> cookieParams = new ArrayList<CodegenParameter>();
List<CodegenParameter> formParams = new ArrayList<CodegenParameter>();
if(parameters != null) {
for(Parameter param : parameters) {
CodegenParameter p = new CodegenParameter();
p.baseName = param.getName();
if(param instanceof SerializableParameter) {
SerializableParameter qp = (SerializableParameter) param;
Property property = null;
String collectionFormat = null;
if("array".equals(qp.getType())) {
Property inner = qp.getItems();
property = new ArrayProperty(inner);
collectionFormat = qp.getCollectionFormat();
}
else
property = PropertyBuilder.build(qp.getType(), qp.getFormat(), null);
CodegenProperty model = fromProperty(qp.getName(), property);
p.collectionFormat = collectionFormat;
p.dataType = model.datatype;
p.paramName = qp.getName();
}
else {
BodyParameter bp = (BodyParameter) param;
Model model = bp.getSchema();
if(model instanceof ModelImpl) {
ModelImpl impl = (ModelImpl) model;
CodegenModel cm = fromModel(bp.getName(), impl);
p.dataType = cm.classname;
}
else if(model instanceof ArrayModel) {
// to use the built-in model parsing, we unwrap the ArrayModel
// and get a single property from it
ArrayModel impl = (ArrayModel) model;
CodegenModel cm = fromModel(bp.getName(), impl);
// get the single property
CodegenProperty cp = cm.vars.get(0);
p.dataType = cp.datatype;
}
else{
Model sub = bp.getSchema();
if(sub instanceof RefModel)
p.dataType = ((RefModel)sub).getSimpleRef();
}
p.paramName = bp.getName();
}
allParams.add(p);
if(param instanceof QueryParameter)
queryParams.add(p);
else if(param instanceof PathParameter)
pathParams.add(p);
else if(param instanceof HeaderParameter)
headerParams.add(p);
else if(param instanceof CookieParameter)
cookieParams.add(p);
else if(param instanceof BodyParameter)
bodyParams.add(p);
// else if(param instanceof FormParameter)
// formParams.add(p);
}
}
op.httpMethod = httpMethod.toUpperCase();
op.allParams = allParams;
op.bodyParams = bodyParams;
op.pathParams = pathParams;
op.queryParams = queryParams;
op.headerParams = headerParams;
// op.cookieParams = cookieParams;
op.formParams = formParams;
// legacy support
op.nickname = operationId;

View File

@ -26,7 +26,8 @@ public class DefaultGenerator implements Generator {
Model model = definitions.get(name);
Map<String, Model> modelMap = new HashMap<String, Model>();
modelMap.put(name, model);
Object models = processModels(config, modelMap);
Map<String, Object> models = processModels(config, modelMap);
models.putAll(config.additionalProperties());
for(String templateName: config.modelTemplateFiles().keySet()) {
String suffix = config.modelTemplateFiles().get(templateName);
String filename = config.modelFileFolder() + File.separator + config.toModelFilename(name) + suffix;
@ -44,9 +45,8 @@ public class DefaultGenerator implements Generator {
for(String tag: paths.keySet()) {
List<CodegenOperation> ops = paths.get(tag);
Object tagObject = processOperations(config, tag, ops);
Json.prettyPrint(tagObject);
Map<String, Object> operations = processOperations(config, tag, ops);
operations.putAll(config.additionalProperties());
for(String templateName: config.apiTemplateFiles().keySet()) {
String suffix = config.apiTemplateFiles().get(templateName);
String filename = config.apiFileFolder() + File.separator + config.toApiFilename(tag) + suffix;
@ -56,7 +56,7 @@ public class DefaultGenerator implements Generator {
.defaultValue("")
.compile(template);
writeToFile(filename, tmpl.execute(tagObject));
writeToFile(filename, tmpl.execute(operations));
}
}
@ -66,19 +66,6 @@ public class DefaultGenerator implements Generator {
}
}
public void processOperation(String tag, String resourcePath, String httpMethod, Operation operation, Map<String, List<CodegenOperation>> operations) {
if(tag == null)
tag = "default";
List<CodegenOperation> opList = operations.get(tag);
if(opList == null) {
opList = new ArrayList<CodegenOperation>();
operations.put(tag, opList);
}
CodegenOperation co = config.fromOperation(resourcePath, httpMethod, operation);
opList.add(co);
}
public Map<String, List<CodegenOperation>> groupPaths(Map<String, Path> paths) {
// group by tag, create a Default grouping if none
Map<String, List<CodegenOperation>> ops = new HashMap<String, List<CodegenOperation>>();
@ -86,30 +73,37 @@ public class DefaultGenerator implements Generator {
for(String resourcePath: paths.keySet()) {
Path path = paths.get(resourcePath);
Operation get = path.getGet();
if(get != null) {
tags = get.getTags();
if(tags != null && tags.size() > 0) {
for(String tag: tags) {
processOperation(tag, resourcePath, "get", get, ops);
}
}
else {
processOperation(null, resourcePath, "get", get, ops);
}
}
// List<CodegenOperation> ops = ops
Operation put = path.getPut();
Operation post = path.getPost();
Operation delete = path.getDelete();
Operation patch = path.getPatch();
Operation options = path.getOptions();
processOperation(resourcePath, "get", path.getGet(), ops);
processOperation(resourcePath, "put", path.getPut(), ops);
processOperation(resourcePath, "post", path.getPost(), ops);
processOperation(resourcePath, "delete", path.getDelete(), ops);
processOperation(resourcePath, "patch", path.getPatch(), ops);
processOperation(resourcePath, "options", path.getOptions(), ops);
}
Json.prettyPrint(ops);
// Json.prettyPrint(ops);
return ops;
}
public void processOperation(String resourcePath, String httpMethod, Operation operation, Map<String, List<CodegenOperation>> operations) {
if(operation != null) {
List<String> tags = operation.getTags();
if(tags == null) {
tags = new ArrayList<String>();
tags.add("default");
}
for(String tag: tags) {
List<CodegenOperation> opList = operations.get(tag);
if(opList == null) {
opList = new ArrayList<CodegenOperation>();
operations.put(tag, opList);
}
CodegenOperation co = config.fromOperation(resourcePath, httpMethod, operation);
opList.add(co);
}
}
}
public File writeToFile(String filename, String contents) throws IOException {
System.out.println("writing file " + filename);
File output = new File(filename);
@ -148,6 +142,7 @@ public class DefaultGenerator implements Generator {
objs.put("classname", config.toApiName(tag));
objs.put("operation", ops);
operations.put("operations", objs);
operations.put("package", config.apiPackage());
return operations;
}

View File

@ -15,6 +15,8 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
apiPackage = "com.wordnik.api";
modelPackage = "com.wordnik.model";
additionalProperties.put("invokerPackage", "com.wordnik.common");
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"String",

View File

@ -21,11 +21,11 @@ public class {{classname}} {
public ApiInvoker getInvoker() {
return apiInvoker;
}
public void setBasePath(String basePath) {
this.basePath = basePath;
}
public String getBasePath() {
return basePath;
}
@ -45,7 +45,8 @@ public class {{classname}} {
{{/requiredParamCount}}
// create path and map variables
String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}.replaceAll("\\{" + "{{paramName}}" + "\\}", apiInvoker.escapeString({{{paramName}}}.toString())){{/pathParams}};
String path = "{{path}}".replaceAll("\\{format\\}","json"){{#pathParams}}
.replaceAll("\\{" + "{{paramName}}" + "\\}", apiInvoker.escapeString({{{paramName}}}.toString())){{/pathParams}};
// query params
Map<String, String> queryParams = new HashMap<String, String>();

View File

@ -34,7 +34,10 @@
"description": "List of user object",
"required": false,
"schema": {
"$ref": "#/definitions/User"
"type": "array",
"items": {
"$ref": "#/definitions/User"
}
}
}
],
@ -558,6 +561,33 @@
"description": "Invalid ID supplied"
}
}
},
"delete": {
"tags": [
"pet"
],
"summary": "Deletes a pet",
"description": "",
"operationId": "deletePet",
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "path",
"name": "petId",
"description": "Pet id to delete",
"required": true,
"type": "integer",
"format": "int64"
}
],
"responses": {
"400": {
"description": "Invalid pet value"
}
}
}
}
},