From 812520e29fab87999fd4e8401d572cb92b8b27ef Mon Sep 17 00:00:00 2001 From: Tony Tam Date: Mon, 1 Sep 2014 13:31:01 -0700 Subject: [PATCH] added support for models, partial for ops --- .../com/wordnik/swagger/codegen/Codegen.java | 20 +- .../swagger/codegen/CodegenConfig.java | 28 ++- .../wordnik/swagger/codegen/CodegenModel.java | 1 + .../swagger/codegen/CodegenOperation.java | 15 ++ .../swagger/codegen/CodegenProperty.java | 9 +- .../swagger/codegen/DefaultCodegen.java | 215 +++++++++++++++--- .../swagger/codegen/DefaultGenerator.java | 92 +++++++- .../wordnik/swagger/codegen/JavaCodegen.java | 14 -- .../com/wordnik/swagger/codegen/Person.java | 13 -- .../codegen/languages/JavaClientCodegen.java | 61 +++++ .../codegen/languages/ObjcClientCodegen.java | 136 +++++++++++ src/main/resources/Java/api.mustache | 2 +- src/main/resources/Java/model.mustache | 37 ++- src/main/resources/objc/model-body.mustache | 40 ++-- swagger.json | 85 ++++--- 15 files changed, 605 insertions(+), 163 deletions(-) create mode 100644 src/main/java/com/wordnik/swagger/codegen/CodegenOperation.java delete mode 100644 src/main/java/com/wordnik/swagger/codegen/JavaCodegen.java delete mode 100644 src/main/java/com/wordnik/swagger/codegen/Person.java create mode 100644 src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java create mode 100644 src/main/java/com/wordnik/swagger/codegen/languages/ObjcClientCodegen.java diff --git a/src/main/java/com/wordnik/swagger/codegen/Codegen.java b/src/main/java/com/wordnik/swagger/codegen/Codegen.java index 54cd8e3a1bdb..b62a8f40d926 100644 --- a/src/main/java/com/wordnik/swagger/codegen/Codegen.java +++ b/src/main/java/com/wordnik/swagger/codegen/Codegen.java @@ -1,5 +1,6 @@ package com.wordnik.swagger.codegen; +import com.wordnik.swagger.codegen.languages.*; import com.wordnik.swagger.models.Swagger; import com.wordnik.swagger.util.Json; @@ -7,15 +8,28 @@ import java.io.File; public class Codegen extends DefaultGenerator { public static void main(String[] args) { - JavaCodegen config = new JavaCodegen(); - config.setTemplateDir("src/main/resources/Java"); + CodegenConfig config = null; + if(args != null && args.length > 0) { + String lang = args[0]; + if("java".equals(lang)) { + JavaClientCodegen javaConfig = new JavaClientCodegen(); + javaConfig.setTemplateDir("src/main/resources/Java"); + config = javaConfig; + } + else if ("objc".equals(lang)) { + ObjcClientCodegen objcConfig = new ObjcClientCodegen(); + objcConfig.setTemplateDir("src/main/resources/objc"); + config = objcConfig; + } + } + try{ Swagger swagger = (Swagger) Json.mapper() .readValue(new File("swagger.json"), Swagger.class); new Codegen() - .config(new JavaCodegen()) + .config(config) .generate(swagger); } catch (Exception e) { diff --git a/src/main/java/com/wordnik/swagger/codegen/CodegenConfig.java b/src/main/java/com/wordnik/swagger/codegen/CodegenConfig.java index 498bb419cebf..e33fcf29121d 100644 --- a/src/main/java/com/wordnik/swagger/codegen/CodegenConfig.java +++ b/src/main/java/com/wordnik/swagger/codegen/CodegenConfig.java @@ -1,20 +1,30 @@ package com.wordnik.swagger.codegen; -import com.wordnik.swagger.models.ModelImpl; +import com.wordnik.swagger.models.*; import java.util.*; public interface CodegenConfig { - CodegenModel fromModel(String name, ModelImpl model); - String modelPackage(); - Set defaultIncludes(); - Map typeMapping(); - Set reservedWords(); - Map importMapping(); String apiPackage(); + String apiFileFolder(); String fileSuffix(); String templateDir(); - Map modelTemplateFiles(); - String toModelFilename(String name); String modelFileFolder(); + String modelPackage(); + String toApiName(String name); + String toModelName(String name); + + Set reservedWords(); + + CodegenModel fromModel(String name, ModelImpl model); + CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation); + Set defaultIncludes(); + Map typeMapping(); + Map importMapping(); + Map apiTemplateFiles(); + Map modelTemplateFiles(); + + String toApiFilename(String name); + String toModelFilename(String name); + String toModelImport(String name); } diff --git a/src/main/java/com/wordnik/swagger/codegen/CodegenModel.java b/src/main/java/com/wordnik/swagger/codegen/CodegenModel.java index 1010949be806..b774ea5450eb 100644 --- a/src/main/java/com/wordnik/swagger/codegen/CodegenModel.java +++ b/src/main/java/com/wordnik/swagger/codegen/CodegenModel.java @@ -9,4 +9,5 @@ class CodegenModel { public String name, classname, description; public String defaultValue; public List vars = new ArrayList(); + public Set imports = new HashSet(); } \ No newline at end of file diff --git a/src/main/java/com/wordnik/swagger/codegen/CodegenOperation.java b/src/main/java/com/wordnik/swagger/codegen/CodegenOperation.java new file mode 100644 index 000000000000..9c826389340c --- /dev/null +++ b/src/main/java/com/wordnik/swagger/codegen/CodegenOperation.java @@ -0,0 +1,15 @@ +package com.wordnik.swagger.codegen; + +import com.wordnik.swagger.models.*; +import com.wordnik.swagger.models.properties.*; + +import java.util.*; + + +public class CodegenOperation { + public String path, operationId, + returnType; + + // legacy support + public String nickname; +} diff --git a/src/main/java/com/wordnik/swagger/codegen/CodegenProperty.java b/src/main/java/com/wordnik/swagger/codegen/CodegenProperty.java index 662e6c9700cb..f9ee0655d294 100644 --- a/src/main/java/com/wordnik/swagger/codegen/CodegenProperty.java +++ b/src/main/java/com/wordnik/swagger/codegen/CodegenProperty.java @@ -6,6 +6,11 @@ import com.wordnik.swagger.models.properties.*; import java.util.*; public class CodegenProperty { - public String getter, setter, description, datatype, name, min, max, defaultValue; + public String baseName, complexType, getter, setter, description, datatype, name, + min, max, defaultValue; + public Double minimum, maximum, exclusiveMinimum, exclusiveMaximum; + public Boolean hasMore = null, required = null; + public boolean isPrimitiveType, isContainer, isNotContainer; + public List _enum; public Map allowableValues; -} \ No newline at end of file +} diff --git a/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java b/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java index e6d76675463b..e6ed76840118 100644 --- a/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java +++ b/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java @@ -1,5 +1,6 @@ package com.wordnik.swagger.codegen; +import com.wordnik.swagger.util.Json; import com.wordnik.swagger.models.*; import com.wordnik.swagger.models.properties.*; @@ -7,15 +8,16 @@ import java.util.*; import java.io.File; public class DefaultCodegen { - String outputFolder = ""; - Set defaultIncludes; - Map typeMapping; - Set reservedWords; - Map importMapping; - String modelPackage = "", apiPackage, fileSuffix; - Map apiTemplateFiles = new HashMap(); - Map modelTemplateFiles = new HashMap(); - String templateDir; + protected String outputFolder = ""; + protected Set defaultIncludes = new HashSet(); + protected Map typeMapping = new HashMap(); + protected Set reservedWords = new HashSet(); + protected Set languageSpecificPrimitives = new HashSet(); + protected Map importMapping = new HashMap(); + protected String modelPackage = "", apiPackage = "", fileSuffix; + protected Map apiTemplateFiles = new HashMap(); + protected Map modelTemplateFiles = new HashMap(); + protected String templateDir; public Set defaultIncludes() { return defaultIncludes; @@ -26,6 +28,9 @@ public class DefaultCodegen { public Set reservedWords() { return reservedWords; } + public Set languageSpecificPrimitives() { + return languageSpecificPrimitives; + } public Map importMapping() { return importMapping; } @@ -41,9 +46,15 @@ public class DefaultCodegen { public String templateDir() { return templateDir; } + public Map apiTemplateFiles() { + return apiTemplateFiles; + } public Map modelTemplateFiles() { return modelTemplateFiles; } + public String apiFileFolder() { + return outputFolder + File.separator + apiPackage().replaceAll("\\.", File.separator); + } public String modelFileFolder() { return outputFolder + File.separator + modelPackage().replaceAll("\\.", File.separator); } @@ -52,26 +63,38 @@ public class DefaultCodegen { this.templateDir = templateDir; } + public String toApiFilename(String name) { + return initialCaps(name); + } + public String toModelFilename(String name) { return name; } + public String toVarName(String name) { + return name; + } + + public String toModelImport(String name) { + return modelPackage() + "." + name; + } + public DefaultCodegen() { defaultIncludes = new HashSet( - Arrays.asList("double", - "int", - "long", - "short", - "char", - "float", - "String", - "boolean", - "Boolean", - "Double", - "Integer", - "Long", - "Float") - ); + Arrays.asList("double", + "int", + "long", + "short", + "char", + "float", + "String", + "boolean", + "Boolean", + "Double", + "Integer", + "Long", + "Float") + ); typeMapping = new HashMap(); typeMapping.put("Array", "List"); @@ -82,6 +105,7 @@ public class DefaultCodegen { typeMapping.put("int", "Integer"); typeMapping.put("float", "Float"); typeMapping.put("number", "BigDecimal"); + typeMapping.put("DateTime", "Date"); typeMapping.put("long", "Long"); typeMapping.put("short", "Short"); typeMapping.put("char", "String"); @@ -137,13 +161,20 @@ public class DefaultCodegen { return "null"; else if (p instanceof ArrayProperty) { ArrayProperty ap = (ArrayProperty) p; - String inner = toDeclaredType(ap.getItems()); - return "ArrayList<" + inner + ">() "; + String inner = getSwaggerType(ap.getItems()); + return "new ArrayList<" + inner + ">() "; + } + else { + System.out.println("unhandled property default value"); + Json.prettyPrint(p); + return "null"; } - return null; } - public String toDeclaredType(Property p) { + /** + * returns the swagger type for the property + **/ + public String getSwaggerType(Property p) { String datatype = null; if(p instanceof StringProperty) datatype = "string"; @@ -152,7 +183,7 @@ public class DefaultCodegen { else if(p instanceof DateProperty) datatype = "date"; else if(p instanceof DateTimeProperty) - datatype = "dateTime"; + datatype = "DateTime"; else if (p instanceof DoubleProperty) datatype = "double"; else if (p instanceof FloatProperty) @@ -163,6 +194,12 @@ public class DefaultCodegen { datatype = "long"; else if (p instanceof MapProperty) datatype = "map"; + else if (p instanceof RefProperty) { + RefProperty r = (RefProperty)p; + datatype = r.get$ref(); + if(datatype.indexOf("#/definitions/") == 0) + datatype = datatype.substring("#/definitions/".length()); + } else { if(p != null) datatype = p.getType(); @@ -170,15 +207,48 @@ public class DefaultCodegen { return datatype; } + public String initialCaps(String name) { + return Character.toUpperCase(name.charAt(0)) + name.substring(1); + } + + public String getTypeDeclaration(Property p) { + String swaggerType = getSwaggerType(p); + if(typeMapping.containsKey(swaggerType)) + return typeMapping.get(swaggerType); + return swaggerType; + } + + public String toApiName(String name) { + return initialCaps(name); + } + + public String toModelName(String name) { + return initialCaps(name); + } + public CodegenModel fromModel(String name, ModelImpl model) { CodegenModel m = new CodegenModel(); m.name = name; m.description = model.getDescription(); - m.classname = name; + m.classname = toModelName(name); + int count = 0; for(String key: model.getProperties().keySet()) { Property prop = model.getProperties().get(key); - m.vars.add(fromProperty(key, prop)); + 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); + } + m.vars.add(cp); + count += 1; + if(count != model.getProperties().keySet().size()) + cp.hasMore = new Boolean(true); + } } return m; } @@ -186,19 +256,92 @@ public class DefaultCodegen { public CodegenProperty fromProperty(String name, Property p) { CodegenProperty property = new CodegenProperty(); - property.name = name; - + property.name = toVarName(name); + property.baseName = name; + property.description = p.getDescription(); property.getter = "get" + name.substring(0, 1).toUpperCase() + name.substring(1); property.setter = "set" + name.substring(0, 1).toUpperCase() + name.substring(1); property.defaultValue = toDefaultValue(p); - String datatype = toDeclaredType(p); + property.required = p.getRequired(); - if(typeMapping.containsKey(datatype)) { - property.datatype = typeMapping.get(datatype); + String type = getSwaggerType(p); + + if(p instanceof AbstractNumericProperty) { + AbstractNumericProperty np = (AbstractNumericProperty) p; + property.minimum = np.getMinimum(); + property.maximum = np.getMaximum(); + property.exclusiveMinimum = np.getExclusiveMinimum(); + property.exclusiveMaximum = np.getExclusiveMaximum(); + + // legacy support + Map allowableValues = new HashMap(); + if(np.getMinimum() != null) + allowableValues.put("min", np.getMinimum()); + if(np.getMaximum() != null) + allowableValues.put("max", np.getMaximum()); + property.allowableValues = allowableValues; + } + + if(p instanceof StringProperty) { + StringProperty sp = (StringProperty) p; + if(sp.getEnum() != null) { + List _enum = sp.getEnum(); + property._enum = _enum; + + // legacy support + Map allowableValues = new HashMap(); + allowableValues.put("values", _enum); + property.allowableValues = allowableValues; + } + } + + property.datatype = getTypeDeclaration(p); + + if(languageSpecificPrimitives().contains(type)) { + property.isPrimitiveType = true; } else - property.datatype = datatype; + property.complexType = type; + if(p instanceof ArrayProperty) + property.isContainer = true; + else + property.isNotContainer = true; return property; } + + public CodegenOperation fromOperation(String path, String httpMethod, Operation operation){ + CodegenOperation op = new CodegenOperation(); + + String operationId = operation.getOperationId(); + if(operationId == null) + operationId = "fixme"; + op.path = path; + op.operationId = operationId; + + Response methodResponse = null; + + if(operation.getResponses() != null) { + for(String responseCode: operation.getResponses().keySet()) { + Response response = operation.getResponses().get(responseCode); + if("200".equals(responseCode)) { + methodResponse = response; + } + } + if(methodResponse == null && operation.getResponses().keySet().contains("default")) + methodResponse = operation.getResponses().get("default"); + } + + if(methodResponse != null && methodResponse.getSchema() != null) { + CodegenProperty responseModel = fromProperty("response", methodResponse.getSchema()); + Json.prettyPrint(responseModel); + op.returnType = responseModel.datatype; + } + + + // legacy support + op.nickname = operationId; + + return op; + } } \ No newline at end of file diff --git a/src/main/java/com/wordnik/swagger/codegen/DefaultGenerator.java b/src/main/java/com/wordnik/swagger/codegen/DefaultGenerator.java index d1f8eaad17eb..8a084ecd1a8c 100644 --- a/src/main/java/com/wordnik/swagger/codegen/DefaultGenerator.java +++ b/src/main/java/com/wordnik/swagger/codegen/DefaultGenerator.java @@ -20,8 +20,8 @@ public class DefaultGenerator implements Generator { public void generate(Swagger swagger) { try { + // models Map definitions = swagger.getDefinitions(); - for(String name: definitions.keySet()) { Model model = definitions.get(name); Map modelMap = new HashMap(); @@ -39,12 +39,77 @@ public class DefaultGenerator implements Generator { writeToFile(filename, tmpl.execute(models)); } } + // apis + Map> paths = groupPaths(swagger.getPaths()); + for(String tag: paths.keySet()) { + List ops = paths.get(tag); + + Object tagObject = processOperations(config, tag, ops); + Json.prettyPrint(tagObject); + + for(String templateName: config.apiTemplateFiles().keySet()) { + String suffix = config.apiTemplateFiles().get(templateName); + String filename = config.apiFileFolder() + File.separator + config.toApiFilename(tag) + suffix; + + String template = readTemplate(config.templateDir() + File.separator + templateName); + Template tmpl = Mustache.compiler() + .defaultValue("") + .compile(template); + + writeToFile(filename, tmpl.execute(tagObject)); + } + + } } catch (Exception e) { e.printStackTrace(); } } + public void processOperation(String tag, String resourcePath, String httpMethod, Operation operation, Map> operations) { + if(tag == null) + tag = "default"; + + List opList = operations.get(tag); + if(opList == null) { + opList = new ArrayList(); + operations.put(tag, opList); + } + CodegenOperation co = config.fromOperation(resourcePath, httpMethod, operation); + opList.add(co); + } + + public Map> groupPaths(Map paths) { + // group by tag, create a Default grouping if none + Map> ops = new HashMap>(); + List tags = null; + + 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 ops = ops + Operation put = path.getPut(); + Operation post = path.getPost(); + Operation delete = path.getDelete(); + Operation patch = path.getPatch(); + Operation options = path.getOptions(); + + } + Json.prettyPrint(ops); + return ops; + } + public File writeToFile(String filename, String contents) throws IOException { System.out.println("writing file " + filename); File output = new File(filename); @@ -77,11 +142,21 @@ public class DefaultGenerator implements Generator { throw new RuntimeException("can't load template " + name); } + public Map processOperations(CodegenConfig config, String tag, List ops) { + Map operations = new HashMap(); + Map objs = new HashMap(); + objs.put("classname", config.toApiName(tag)); + objs.put("operation", ops); + operations.put("operations", objs); + return operations; + } + public Map processModels(CodegenConfig config, Map definitions) { Map objs = new HashMap(); objs.put("package", config.modelPackage()); List models = new ArrayList(); List model = new ArrayList(); + Set allImports = new HashSet(); for(String key: definitions.keySet()) { Model mm = definitions.get(key); if(mm instanceof ModelImpl) { @@ -89,9 +164,24 @@ public class DefaultGenerator implements Generator { Map mo = new HashMap(); mo.put("model", cm); models.add(mo); + allImports.addAll(cm.imports); } } objs.put("models", models); + + List> imports = new ArrayList>(); + for(String i: allImports) { + Map im = new HashMap(); + String m = config.importMapping().get(i); + if(m == null) + m = config.toModelImport(i); + if(m != null) { + im.put("import", m); + imports.add(im); + } + } + + objs.put("imports", imports); return objs; } } \ No newline at end of file diff --git a/src/main/java/com/wordnik/swagger/codegen/JavaCodegen.java b/src/main/java/com/wordnik/swagger/codegen/JavaCodegen.java deleted file mode 100644 index c8765558174d..000000000000 --- a/src/main/java/com/wordnik/swagger/codegen/JavaCodegen.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.wordnik.swagger.codegen; - -public class JavaCodegen extends DefaultCodegen implements CodegenConfig { - public JavaCodegen() { - super(); - outputFolder = "generated-code/java"; - modelTemplateFiles.put("model.mustache", ".java"); - apiTemplateFiles.put("api.mustache", ".java"); - templateDir = "Java"; - modelPackage = "com.wordnik.model"; - } - - -} \ No newline at end of file diff --git a/src/main/java/com/wordnik/swagger/codegen/Person.java b/src/main/java/com/wordnik/swagger/codegen/Person.java deleted file mode 100644 index c59492237ff0..000000000000 --- a/src/main/java/com/wordnik/swagger/codegen/Person.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.wordnik.swagger.codegen; - -public class Person { - public final String name; - public Person (String name, int age) { - this.name = name; - _age = age; - } - public int getAge () { - return _age; - } - protected int _age; -} \ No newline at end of file diff --git a/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java b/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java new file mode 100644 index 000000000000..e2e78d4fd383 --- /dev/null +++ b/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java @@ -0,0 +1,61 @@ +package com.wordnik.swagger.codegen.languages; + +import com.wordnik.swagger.codegen.*; +import com.wordnik.swagger.models.properties.*; + +import java.util.*; + +public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig { + public JavaClientCodegen() { + super(); + outputFolder = "generated-code/java"; + modelTemplateFiles.put("model.mustache", ".java"); + apiTemplateFiles.put("api.mustache", ".java"); + templateDir = "Java"; + apiPackage = "com.wordnik.api"; + modelPackage = "com.wordnik.model"; + + languageSpecificPrimitives = new HashSet( + Arrays.asList( + "String", + "boolean", + "Boolean", + "Double", + "Integer", + "Long", + "Float") + ); + } + + @Override + public String toModelImport(String name) { + return null; + } + + @Override + public String getTypeDeclaration(Property p) { + if(p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + Property inner = ap.getItems(); + return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">"; + } + else if (p instanceof MapProperty) { + throw new RuntimeException("not supported yet"); + } + return super.getTypeDeclaration(p); + } + + @Override + public String getSwaggerType(Property p) { + String swaggerType = super.getSwaggerType(p); + String type = null; + if(typeMapping.containsKey(swaggerType)) { + type = typeMapping.get(swaggerType); + if(languageSpecificPrimitives.contains(type)) + return toModelName(type); + } + else + type = swaggerType; + return toModelName(type); + } +} \ No newline at end of file diff --git a/src/main/java/com/wordnik/swagger/codegen/languages/ObjcClientCodegen.java b/src/main/java/com/wordnik/swagger/codegen/languages/ObjcClientCodegen.java new file mode 100644 index 000000000000..a50afe77d69f --- /dev/null +++ b/src/main/java/com/wordnik/swagger/codegen/languages/ObjcClientCodegen.java @@ -0,0 +1,136 @@ +package com.wordnik.swagger.codegen.languages; + +import com.wordnik.swagger.util.Json; +import com.wordnik.swagger.codegen.*; +import com.wordnik.swagger.models.properties.*; + +import java.util.*; +import java.io.File; + +public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { + protected Set foundationClasses = new HashSet(); + + public ObjcClientCodegen() { + super(); + outputFolder = "generated-code/objc"; + modelTemplateFiles.put("model-header.mustache", ".h"); + modelTemplateFiles.put("model-body.mustache", ".m"); + apiTemplateFiles.put("api-header.mustache", ".h"); + apiTemplateFiles.put("api-body.mustache", ".m"); + templateDir = "objc"; + modelPackage = "com.wordnik.model"; + + defaultIncludes = new HashSet( + Arrays.asList("bool", + "int", + "NSString", + "NSObject", + "NSArray", + "NSNumber") + ); + languageSpecificPrimitives = new HashSet( + Arrays.asList( + "NSNumber", + "NSString", + "NSObject", + "bool") + ); + + reservedWords = new HashSet( + Arrays.asList( + "void", "char", "short", "int", "void", "char", "short", "int", + "long", "float", "double", "signed", "unsigned", "id", "const", + "volatile", "in", "out", "inout", "bycopy", "byref", "oneway", + "self", "super" + )); + + typeMapping = new HashMap(); + typeMapping.put("enum", "NSString"); + typeMapping.put("date", "SWGDate"); + typeMapping.put("dateTime", "SWGDate"); + // typeMapping.put("Date", "SWGDate"); + typeMapping.put("boolean", "NSNumber"); + typeMapping.put("string", "NSString"); + typeMapping.put("integer", "NSNumber"); + typeMapping.put("int", "NSNumber"); + typeMapping.put("float", "NSNumber"); + typeMapping.put("long", "NSNumber"); + typeMapping.put("double", "NSNumber"); + typeMapping.put("Array", "NSArray"); + // typeMapping.put("array", "NSArray"); + typeMapping.put("List", "NSArray"); + typeMapping.put("object", "NSObject"); + + importMapping = new HashMap (); + importMapping.put("Date", "SWGDate"); + + foundationClasses = new HashSet ( + Arrays.asList( + "NSNumber", + "NSObject", + "NSString") + ); + } + + @Override + public String getSwaggerType(Property p) { + String swaggerType = super.getSwaggerType(p); + String type = null; + System.out.println("checking type mapping for " + swaggerType); + if(typeMapping.containsKey(swaggerType)) { + type = typeMapping.get(swaggerType); + if(languageSpecificPrimitives.contains(type) && !foundationClasses.contains(type)) + return toModelName(type); + } + else + type = swaggerType; + return toModelName(type); + } + + @Override + public String getTypeDeclaration(Property p) { + String swaggerType = getSwaggerType(p); + if(languageSpecificPrimitives.contains(swaggerType) && !foundationClasses.contains(swaggerType)) + return toModelName(swaggerType); + else + return swaggerType + "*"; + } + + @Override + public String toModelName(String type) { + if(typeMapping.keySet().contains(type) || + foundationClasses.contains(type) || + importMapping.values().contains(type) || + defaultIncludes.contains(type) || + languageSpecificPrimitives.contains(type)) { + return Character.toUpperCase(type.charAt(0)) + type.substring(1); + } + else { + return "SWG" + Character.toUpperCase(type.charAt(0)) + type.substring(1); + } + } + + @Override + public String modelFileFolder() { + return outputFolder + File.separator + "models"; + } + + @Override + public String toModelFilename(String name) { + return "SWG" + name; + } + + @Override + public String toVarName(String name) { + String paramName = name.replaceAll("[^a-zA-Z0-9_]",""); + if(paramName.startsWith("new") || reservedWords.contains(paramName)) { + return escapeReservedWord(paramName); + } + else + return paramName; + } + + public String escapeReservedWord(String name) { + return "_" + name; + } +} \ No newline at end of file diff --git a/src/main/resources/Java/api.mustache b/src/main/resources/Java/api.mustache index 91472d131e11..87c764417d55 100644 --- a/src/main/resources/Java/api.mustache +++ b/src/main/resources/Java/api.mustache @@ -35,7 +35,7 @@ public class {{classname}} { {{/responseModel}}{{^responseModel}} {{/responseModel}} {{/errorList}} - public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}} {{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException { + public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}} ({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException { Object postBody = {{#bodyParam}}{{bodyParam}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}}; {{#requiredParamCount}} // verify required params are set diff --git a/src/main/resources/Java/model.mustache b/src/main/resources/Java/model.mustache index f6a493e3e3a3..938daf4d5f67 100644 --- a/src/main/resources/Java/model.mustache +++ b/src/main/resources/Java/model.mustache @@ -4,24 +4,23 @@ package {{package}}; {{/imports}} {{#models}} -{{#model}} -public class {{classname}} { - {{#vars}} - - {{#description}}/* {{{description}}} */ - {{/description}} - private {{{datatype}}} {{name}} = {{{defaultValue}}}; - {{#allowableValues}}{{#min}} // range from {{min}} to {{max}} - {{/min}} +{{#model}}{{#description}} +/** + * {{description}} + **/{{/description}} +public class {{classname}} { {{#vars}} + /**{{#description}} + * {{{description}}}{{/description}} + * required: {{required}}{{#minimum}} + * minimum: {{minimum}}{{/minimum}}{{#maximum}} + * maximum: {{maximum}}{{/maximum}} + **/ + private {{{datatype}}} {{name}} = {{{defaultValue}}};{{#allowableValues}} + //{{^min}}public enum {{name}}Enum { {{#values}} {{.}}, {{/values}} }; - {{/min}} - {{/allowableValues}} + {{/min}}{{/allowableValues}}{{/vars}} - {{/vars}} - - {{#vars}} - - public {{{datatype}}} {{getter}}() { + {{#vars}}public {{{datatype}}} {{getter}}() { return {{name}}; } public void {{setter}}({{{datatype}}} {{name}}) { @@ -34,10 +33,8 @@ public class {{classname}} { public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class {{classname}} {\n"); - {{#vars}} - sb.append(" {{name}}: ").append({{name}}).append("\n"); - {{/vars}} - sb.append("}\n"); + {{#vars}}sb.append(" {{name}}: ").append({{name}}).append("\n"); + {{/vars}}sb.append("}\n"); return sb.toString(); } } diff --git a/src/main/resources/objc/model-body.mustache b/src/main/resources/objc/model-body.mustache index f927adedb00b..190d9bfc308d 100644 --- a/src/main/resources/objc/model-body.mustache +++ b/src/main/resources/objc/model-body.mustache @@ -5,10 +5,10 @@ @implementation {{classname}} --(id){{#vars}}{{name}}: ({{datatype}}) {{name}}{{#hasMore}}{{newline}} {{/hasMore}}{{/vars}}{{newline}}{ - {{#vars}}_{{name}} = {{name}}; - {{/vars}} - +-(id){{#vars}}{{name}}: ({{datatype}}) {{name}}{{^hasMore}} { {{/hasMore}} + {{/vars}} + {{#vars}}_{{name}} = {{name}}; + {{/vars}} return self; } @@ -16,16 +16,9 @@ { self = [super init]; if(self) { - {{#vars}} - - {{#isPrimitiveType}} - _{{name}} = dict[@"{{baseName}}"]; - {{/isPrimitiveType}} - {{#complexType}} - id {{name}}_dict = dict[@"{{baseName}}"]; - {{#isContainer}} + {{#vars}}{{#isPrimitiveType}}_{{name}} = dict[@"{{baseName}}"];{{/isPrimitiveType}}{{#complexType}} + id {{name}}_dict = dict[@"{{baseName}}"];{{#isContainer}} if([{{name}}_dict isKindOfClass:[NSArray class]]) { - NSMutableArray * objs = [[NSMutableArray alloc] initWithCapacity:[(NSArray*){{name}}_dict count]]; if([(NSArray*){{name}}_dict count] > 0) { @@ -44,21 +37,16 @@ _{{name}} = [[NSArray alloc] init]; } {{/isContainer}} - {{#isNotContainer}} - if({{name}}_dict != nil) + {{#isNotContainer}}if({{name}}_dict != nil) _{{name}} = [[{{#instantiationType}}NSClassFromString(@"{{{instantiationType}}}") {{/instantiationType}}{{^instantiationType}}{{{complexType}}} {{/instantiationType}} alloc]initWithValues:{{name}}_dict]; - {{/isNotContainer}} - {{/complexType}} - {{/vars}}{{newline}} + {{/isNotContainer}}{{/complexType}}{{/vars}} } return self; } -(NSDictionary*) asDictionary { NSMutableDictionary* dict = [[NSMutableDictionary alloc] init]; - {{#vars}} - {{#complexType}} - if(_{{name}} != nil){ + {{#vars}}{{#complexType}}if(_{{name}} != nil){ if([_{{name}} isKindOfClass:[NSArray class]]){ NSMutableArray * array = [[NSMutableArray alloc] init]; for( {{complexType}} *{{name}} in (NSArray*)_{{name}}) { @@ -73,14 +61,12 @@ } } else { - {{/complexType}} - if(_{{name}} != nil) dict[@"{{baseName}}"] = {{#complexType}}[(SWGObject*){{/complexType}}_{{name}} {{#complexType}}asDictionary]{{/complexType}}; - {{#complexType}} + if(_{{name}} != nil) dict[@"{{baseName}}"] = [(SWGObject*)_{{name}} asDictionary]; } } - {{/complexType}} - {{/vars}} - + {{/complexType}}{{#isPrimitiveType}}if(_{{name}} != nil) + dict[@"{{baseName}}"] = [(SWGObject*)_{{name}} asDictionary]; + {{/isPrimitiveType}}{{/vars}} NSDictionary* output = [dict copy]; return output; } diff --git a/swagger.json b/swagger.json index a9a0e2cb3420..4e8fe2310e6d 100644 --- a/swagger.json +++ b/swagger.json @@ -275,7 +275,10 @@ "200": { "description": "successful operation", "schema": { - "$ref": "#/definitions/Pet" + "type": "array", + "items": { + "$ref": "#/definitions/Pet" + } } }, "400": { @@ -417,7 +420,10 @@ "200": { "description": "successful operation", "schema": { - "$ref": "#/definitions/Pet" + "type": "array", + "items": { + "$ref": "#/definitions/Pet" + } } }, "400": { @@ -600,15 +606,22 @@ }, "Pet": { "enum": [ + "id", "photoUrls", "name" ], "properties": { - "tags": { - "type": "array", - "items": { - "$ref": "Tag" - } + "id": { + "type": "integer", + "format": "int64" + }, + "category": { + "$ref": "Category" + }, + "name": { + "type": "string", + "example": "doggie", + "position": 0 }, "photoUrls": { "type": "array", @@ -616,17 +629,11 @@ "type": "string" } }, - "category": { - "$ref": "Category" - }, - "id": { - "type": "integer", - "format": "int64" - }, - "name": { - "type": "string", - "example": "doggie", - "position": 0 + "tags": { + "type": "array", + "items": { + "$ref": "Tag" + } }, "status": { "type": "string", @@ -646,31 +653,35 @@ } }, "Order": { + "description": "All you ever needed to know about orders", + "enum": [ "id" ], "properties": { - "complete": { - "type": "boolean" + "id": { + "description": "the unique ID for the order", + "type": "integer", + "format": "int64" + }, + "petId": { + "description": "the ID of the pet being purchased", + "type": "integer", + "format": "int64" + }, + "quantity": { + "description": "number of pets in the order", + "type": "integer", + "format": "int32", + "minimum": 1, + "maximum": 100 + }, + "status": { + "type": "string", + "enum": [ "dead", "alive" ] }, "shipDate": { "type": "string", "format": "date-time" - }, - "quantity": { - "type": "integer", - "format": "int32" - }, - "petId": { - "type": "integer", - "format": "int64" - }, - "id": { - "type": "integer", - "format": "int64" - }, - "status": { - "type": "string", - "position": 0 } } } } -} \ No newline at end of file +}