From 530ebe1f7dd5564c664c1824d1a4c20587dbc8c3 Mon Sep 17 00:00:00 2001 From: Tony Tam Date: Sat, 27 Sep 2014 09:13:26 -0700 Subject: [PATCH] added map, list model types with tests --- .../swagger/codegen/CodegenConfig.java | 1 + .../swagger/codegen/DefaultCodegen.java | 101 +++++++++++------- .../swagger/codegen/DefaultGenerator.java | 8 +- .../codegen/languages/JavaClientCodegen.java | 2 + .../codegen/languages/ObjcClientCodegen.java | 23 +++- src/main/resources/Java/model.mustache | 21 ++-- src/main/resources/Java/pom.mustache | 19 ++-- src/main/resources/objc/model-header.mustache | 2 +- src/test/resources/petstore.json | 6 -- src/test/scala/Java/JavaModelTest.scala | 33 ++++++ src/test/scala/Objc/ObjcModelTest.scala | 34 +++++- 11 files changed, 184 insertions(+), 66 deletions(-) diff --git a/src/main/java/com/wordnik/swagger/codegen/CodegenConfig.java b/src/main/java/com/wordnik/swagger/codegen/CodegenConfig.java index 5bb8e2e9e3f..d97d2b49c13 100644 --- a/src/main/java/com/wordnik/swagger/codegen/CodegenConfig.java +++ b/src/main/java/com/wordnik/swagger/codegen/CodegenConfig.java @@ -33,6 +33,7 @@ public interface CodegenConfig { CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation); Set defaultIncludes(); Map typeMapping(); + Map instantiationTypes(); Map importMapping(); Map apiTemplateFiles(); Map modelTemplateFiles(); diff --git a/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java b/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java index 53ec1b311e9..c715cfe6b41 100644 --- a/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java +++ b/src/main/java/com/wordnik/swagger/codegen/DefaultCodegen.java @@ -45,6 +45,9 @@ public class DefaultCodegen { public Map typeMapping() { return typeMapping; } + public Map instantiationTypes() { + return instantiationTypes; + } public Set reservedWords() { return reservedWords; } @@ -171,7 +174,6 @@ public class DefaultCodegen { typeMapping.put("integer", "Integer"); instantiationTypes = new HashMap(); - instantiationTypes.put("array", "ArrayList"); reservedWords = new HashSet ( Arrays.asList( @@ -206,12 +208,12 @@ public class DefaultCodegen { if (p instanceof MapProperty) { MapProperty ap = (MapProperty) p; String inner = getSwaggerType(ap.getAdditionalProperties()); - return "HashMap"; + return instantiationTypes.get("map") + ""; } else if (p instanceof ArrayProperty) { ArrayProperty ap = (ArrayProperty) p; String inner = getSwaggerType(ap.getItems()); - return "ArrayList<" + inner + ">"; + return instantiationTypes.get("array") + "<" + inner + ">"; } else return null; @@ -319,11 +321,12 @@ public class DefaultCodegen { ArrayModel am = (ArrayModel) model; ArrayProperty arrayProperty = new ArrayProperty(am.getItems()); CodegenProperty cp = fromProperty(name, arrayProperty); - // m.vars.add(cp); if(cp.complexType != null && !defaultIncludes.contains(cp.complexType)) m.imports.add(cp.complexType); - m.parent = cp.baseType; + m.parent = toInstantiationType(arrayProperty); String containerType = cp.containerType; + if(instantiationTypes.containsKey(containerType)) + m.imports.add(instantiationTypes.get(containerType)); if(typeMapping.containsKey(containerType)) { containerType = typeMapping.get(containerType); cp.containerType = containerType; @@ -335,46 +338,62 @@ public class DefaultCodegen { } else { ModelImpl impl = (ModelImpl) model; - // Json.prettyPrint(impl); - for(String key: impl.getProperties().keySet()) { - Property prop = impl.getProperties().get(key); - - if(prop == null) { - System.out.println("null property for " + key); + if(impl.getAdditionalProperties() != null) { + MapProperty mapProperty = new MapProperty(impl.getAdditionalProperties()); + CodegenProperty cp = fromProperty(name, mapProperty); + if(cp.complexType != null && !defaultIncludes.contains(cp.complexType)) + m.imports.add(cp.complexType); + m.parent = toInstantiationType(mapProperty); + String containerType = cp.containerType; + if(instantiationTypes.containsKey(containerType)) + m.imports.add(instantiationTypes.get(containerType)); + if(typeMapping.containsKey(containerType)) { + containerType = typeMapping.get(containerType); + cp.containerType = containerType; + m.imports.add(containerType); } - else { - CodegenProperty cp = fromProperty(key, prop); - cp.required = false; - if(impl.getRequired() != null) { - for(String req : impl.getRequired()) { - if(key.equals(req)) - cp.required = true; + } + if(impl.getProperties() != null) { + for(String key: impl.getProperties().keySet()) { + Property prop = impl.getProperties().get(key); + + if(prop == null) { + System.out.println("null property for " + key); + } + else { + CodegenProperty cp = fromProperty(key, prop); + cp.required = false; + if(impl.getRequired() != null) { + for(String req : impl.getRequired()) { + if(key.equals(req)) + cp.required = true; + } + } + 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); + if(cp.isContainer != null) { + String arrayImport = typeMapping.get("array"); + if(arrayImport != null && + !languageSpecificPrimitives.contains(arrayImport) && + !defaultIncludes.contains(arrayImport)) + m.imports.add(arrayImport); } - } - 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); - if(cp.isContainer != null) { - String arrayImport = typeMapping.get("array"); - if(arrayImport != null && - !languageSpecificPrimitives.contains(arrayImport) && - !defaultIncludes.contains(arrayImport)) - m.imports.add(arrayImport); - } - if(cp.complexType != null && - !languageSpecificPrimitives.contains(cp.complexType) && - !defaultIncludes.contains(cp.complexType)) - m.imports.add(cp.complexType); + if(cp.complexType != null && + !languageSpecificPrimitives.contains(cp.complexType) && + !defaultIncludes.contains(cp.complexType)) + m.imports.add(cp.complexType); - if(cp.baseType != null && - !languageSpecificPrimitives.contains(cp.baseType) && - !defaultIncludes.contains(cp.baseType)) - m.imports.add(cp.baseType); + if(cp.baseType != null && + !languageSpecificPrimitives.contains(cp.baseType) && + !defaultIncludes.contains(cp.baseType)) + m.imports.add(cp.baseType); + } } } } diff --git a/src/main/java/com/wordnik/swagger/codegen/DefaultGenerator.java b/src/main/java/com/wordnik/swagger/codegen/DefaultGenerator.java index 321e9b83ddf..27251a1cedc 100644 --- a/src/main/java/com/wordnik/swagger/codegen/DefaultGenerator.java +++ b/src/main/java/com/wordnik/swagger/codegen/DefaultGenerator.java @@ -262,10 +262,16 @@ public class DefaultGenerator implements Generator { String m = config.importMapping().get(i); if(m == null) m = config.toModelImport(i); - if(m != null) { + if(m != null && !config.defaultIncludes().contains(m)) { im.put("import", m); imports.add(im); } + // add instantiation types + m = config.instantiationTypes().get(i); + if(m != null && !config.defaultIncludes().contains(m)) { + im.put("import", m); + imports.add(im); + } } objs.put("imports", imports); diff --git a/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java b/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java index 1bf0d5e92f8..654186d65e7 100644 --- a/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java +++ b/src/main/java/com/wordnik/swagger/codegen/languages/JavaClientCodegen.java @@ -45,6 +45,8 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig { "Long", "Float") ); + instantiationTypes.put("array", "ArrayList"); + instantiationTypes.put("map", "HashMap"); } @Override diff --git a/src/main/java/com/wordnik/swagger/codegen/languages/ObjcClientCodegen.java b/src/main/java/com/wordnik/swagger/codegen/languages/ObjcClientCodegen.java index fd515cc94ff..19bc95fe32d 100644 --- a/src/main/java/com/wordnik/swagger/codegen/languages/ObjcClientCodegen.java +++ b/src/main/java/com/wordnik/swagger/codegen/languages/ObjcClientCodegen.java @@ -30,7 +30,9 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { "NSObject", "NSArray", "NSNumber", - "NSDictionary") + "NSDictionary", + "NSMutableArray", + "NSMutableDictionary") ); languageSpecificPrimitives = new HashSet( Arrays.asList( @@ -77,6 +79,9 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { "NSDictionary") ); + instantiationTypes.put("array", "NSMutableArray"); + instantiationTypes.put("map", "NSMutableDictionary"); + supportingFiles.add(new SupportingFile("SWGObject.h", sourceFolder, "SWGObject.h")); supportingFiles.add(new SupportingFile("SWGObject.m", sourceFolder, "SWGObject.m")); supportingFiles.add(new SupportingFile("SWGApiClient.h", sourceFolder, "SWGApiClient.h")); @@ -88,6 +93,22 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("Podfile.mustache", "", "Podfile")); } + @Override + public String toInstantiationType(Property p) { + if (p instanceof MapProperty) { + MapProperty ap = (MapProperty) p; + String inner = getSwaggerType(ap.getAdditionalProperties()); + return instantiationTypes.get("map"); + } + else if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + String inner = getSwaggerType(ap.getItems()); + return instantiationTypes.get("array"); + } + else + return null; + } + @Override public String getTypeDeclaration(String name) { if(languageSpecificPrimitives.contains(name) && !foundationClasses.contains(name)) diff --git a/src/main/resources/Java/model.mustache b/src/main/resources/Java/model.mustache index 938daf4d5f6..0d60aedd068 100644 --- a/src/main/resources/Java/model.mustache +++ b/src/main/resources/Java/model.mustache @@ -2,25 +2,29 @@ package {{package}}; {{#imports}}import {{import}}; {{/imports}} + +import com.wordnik.swagger.annotations.*; {{#models}} {{#model}}{{#description}} /** * {{description}} **/{{/description}} -public class {{classname}} { {{#vars}} - /**{{#description}} - * {{{description}}}{{/description}} - * required: {{required}}{{#minimum}} - * minimum: {{minimum}}{{/minimum}}{{#maximum}} - * maximum: {{maximum}}{{/maximum}} - **/ +@ApiModel(description = "{{{description}}}") +public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} { {{#vars}} private {{{datatype}}} {{name}} = {{{defaultValue}}};{{#allowableValues}} //{{^min}}public enum {{name}}Enum { {{#values}} {{.}}, {{/values}} }; {{/min}}{{/allowableValues}}{{/vars}} - {{#vars}}public {{{datatype}}} {{getter}}() { + {{#vars}} + /**{{#description}} + * {{{description}}}{{/description}}{{#minimum}} + * minimum: {{minimum}}{{/minimum}}{{#maximum}} + * maximum: {{maximum}}{{/maximum}} + **/ + @ApiModelProperty(required = {{required}}, value = "{{{description}}}") + public {{{datatype}}} {{getter}}() { return {{name}}; } public void {{setter}}({{{datatype}}} {{name}}) { @@ -33,6 +37,7 @@ public class {{classname}} { {{#vars}} public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class {{classname}} {\n"); + {{#parent}}sb.append(" " + super.toString()).append("\n");{{/parent}} {{#vars}}sb.append(" {{name}}: ").append({{name}}).append("\n"); {{/vars}}sb.append("}\n"); return sb.toString(); diff --git a/src/main/resources/Java/pom.mustache b/src/main/resources/Java/pom.mustache index 1e2dd35d069..5e71517d8a5 100644 --- a/src/main/resources/Java/pom.mustache +++ b/src/main/resources/Java/pom.mustache @@ -107,35 +107,35 @@ + + com.wordnik + swagger-annotations + ${swagger-annotations-version} + com.sun.jersey jersey-client ${jersey-version} - compile com.sun.jersey.contribs jersey-multipart ${jersey-version} - compile com.fasterxml.jackson.core jackson-core ${jackson-version} - compile com.fasterxml.jackson.core jackson-annotations ${jackson-version} - compile com.fasterxml.jackson.core jackson-databind ${jackson-version} - compile com.fasterxml.jackson.datatype @@ -146,7 +146,6 @@ joda-time joda-time ${jodatime-version} - compile @@ -157,8 +156,14 @@ test - + + + sonatype-snapshots + https://oss.sonatype.org/content/repositories/snapshots + + + 1.5.0-SNAPSHOT 1.7 2.1.4 2.3 diff --git a/src/main/resources/objc/model-header.mustache b/src/main/resources/objc/model-header.mustache index 9dc5f15f4e8..de4b085e000 100644 --- a/src/main/resources/objc/model-header.mustache +++ b/src/main/resources/objc/model-header.mustache @@ -6,7 +6,7 @@ {{#models}} {{#model}} -@interface {{classname}} : SWGObject +@interface {{classname}} : {{^parent}}SWGObject{{/parent}}{{#parent}}{{parent}}{{/parent}} {{#vars}} @property(nonatomic) {{datatype}} {{name}}; {{#description}}/* {{{description}}} {{#isNotRequired}}[optional]{{/isNotRequired}} */{{/description}}{{newline}} diff --git a/src/test/resources/petstore.json b/src/test/resources/petstore.json index ae078d34351..9f8fb0e47af 100644 --- a/src/test/resources/petstore.json +++ b/src/test/resources/petstore.json @@ -709,12 +709,6 @@ }, "complete": { "type": "boolean" - }, - "keyValuePairs": { - "type": "object", - "additionalProperties": { - "type": "string" - } } } } diff --git a/src/test/scala/Java/JavaModelTest.scala b/src/test/scala/Java/JavaModelTest.scala index c2004b0f969..7e1cd709340 100644 --- a/src/test/scala/Java/JavaModelTest.scala +++ b/src/test/scala/Java/JavaModelTest.scala @@ -206,4 +206,37 @@ class JavaModelTest extends FlatSpec with Matchers { vars.get(0).isContainer should equal (true) vars.get(0).isNotContainer should be (null) } + + it should "convert an array model" in { + val model = new ArrayModel() + .description("an array model") + .items(new RefProperty("#/definitions/Children")) + val codegen = new JavaClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be ("sample") + cm.classname should be ("Sample") + cm.description should be ("an array model") + cm.vars.size should be (0) + cm.parent should be ("ArrayList") + cm.imports.size should be (3) + (cm.imports.asScala.toSet & Set("List", "ArrayList", "Children")).size should be (3) + } + + it should "convert an map model" in { + val model = new ModelImpl() + .description("an map model") + .additionalProperties(new RefProperty("#/definitions/Children")) + + val codegen = new JavaClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be ("sample") + cm.classname should be ("Sample") + cm.description should be ("an map model") + cm.vars.size should be (0) + cm.parent should be ("HashMap") + cm.imports.size should be (3) + (cm.imports.asScala.toSet & Set("Map", "HashMap", "Children")).size should be (3) + } } \ No newline at end of file diff --git a/src/test/scala/Objc/ObjcModelTest.scala b/src/test/scala/Objc/ObjcModelTest.scala index 70364e9375a..198fc019e84 100644 --- a/src/test/scala/Objc/ObjcModelTest.scala +++ b/src/test/scala/Objc/ObjcModelTest.scala @@ -63,7 +63,6 @@ class ObjcModelTest extends FlatSpec with Matchers { vars.get(2).required should equal (false) vars.get(2).isNotContainer should equal (true) - (cm.imports.asScala.toSet & Set("SWGDate")).size should be (1) } @@ -206,4 +205,37 @@ class ObjcModelTest extends FlatSpec with Matchers { vars.get(0).isContainer should equal (true) vars.get(0).isNotContainer should be (null) } + + it should "convert an array model" in { + val model = new ArrayModel() + .description("an array model") + .items(new RefProperty("#/definitions/Children")) + val codegen = new ObjcClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be ("sample") + cm.classname should be ("SWGSample") + cm.description should be ("an array model") + cm.vars.size should be (0) + cm.parent should be ("NSMutableArray") + cm.imports.size should be (3) + (cm.imports.asScala.toSet & Set("SWGChildren", "NSArray", "NSMutableArray")).size should be (3) + } + + it should "convert an map model" in { + val model = new ModelImpl() + .description("an map model") + .additionalProperties(new RefProperty("#/definitions/Children")) + + val codegen = new ObjcClientCodegen() + val cm = codegen.fromModel("sample", model) + + cm.name should be ("sample") + cm.classname should be ("SWGSample") + cm.description should be ("an map model") + cm.vars.size should be (0) + cm.parent should be ("NSMutableDictionary") + cm.imports.size should be (3) + (cm.imports.asScala.toSet & Set("SWGChildren", "NSDictionary", "NSMutableDictionary")).size should be (3) + } } \ No newline at end of file