added map, list model types with tests

This commit is contained in:
Tony Tam 2014-09-27 09:13:26 -07:00
parent ba45641801
commit 530ebe1f7d
11 changed files with 184 additions and 66 deletions

View File

@ -33,6 +33,7 @@ public interface CodegenConfig {
CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation); CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation);
Set<String> defaultIncludes(); Set<String> defaultIncludes();
Map<String, String> typeMapping(); Map<String, String> typeMapping();
Map<String, String> instantiationTypes();
Map<String, String> importMapping(); Map<String, String> importMapping();
Map<String, String> apiTemplateFiles(); Map<String, String> apiTemplateFiles();
Map<String, String> modelTemplateFiles(); Map<String, String> modelTemplateFiles();

View File

@ -45,6 +45,9 @@ public class DefaultCodegen {
public Map<String, String> typeMapping() { public Map<String, String> typeMapping() {
return typeMapping; return typeMapping;
} }
public Map<String, String> instantiationTypes() {
return instantiationTypes;
}
public Set<String> reservedWords() { public Set<String> reservedWords() {
return reservedWords; return reservedWords;
} }
@ -171,7 +174,6 @@ public class DefaultCodegen {
typeMapping.put("integer", "Integer"); typeMapping.put("integer", "Integer");
instantiationTypes = new HashMap<String, String>(); instantiationTypes = new HashMap<String, String>();
instantiationTypes.put("array", "ArrayList");
reservedWords = new HashSet<String> ( reservedWords = new HashSet<String> (
Arrays.asList( Arrays.asList(
@ -206,12 +208,12 @@ public class DefaultCodegen {
if (p instanceof MapProperty) { if (p instanceof MapProperty) {
MapProperty ap = (MapProperty) p; MapProperty ap = (MapProperty) p;
String inner = getSwaggerType(ap.getAdditionalProperties()); String inner = getSwaggerType(ap.getAdditionalProperties());
return "HashMap<String, " + inner + ">"; return instantiationTypes.get("map") + "<String, " + inner + ">";
} }
else if (p instanceof ArrayProperty) { else if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p; ArrayProperty ap = (ArrayProperty) p;
String inner = getSwaggerType(ap.getItems()); String inner = getSwaggerType(ap.getItems());
return "ArrayList<" + inner + ">"; return instantiationTypes.get("array") + "<" + inner + ">";
} }
else else
return null; return null;
@ -319,11 +321,12 @@ public class DefaultCodegen {
ArrayModel am = (ArrayModel) model; ArrayModel am = (ArrayModel) model;
ArrayProperty arrayProperty = new ArrayProperty(am.getItems()); ArrayProperty arrayProperty = new ArrayProperty(am.getItems());
CodegenProperty cp = fromProperty(name, arrayProperty); CodegenProperty cp = fromProperty(name, arrayProperty);
// m.vars.add(cp);
if(cp.complexType != null && !defaultIncludes.contains(cp.complexType)) if(cp.complexType != null && !defaultIncludes.contains(cp.complexType))
m.imports.add(cp.complexType); m.imports.add(cp.complexType);
m.parent = cp.baseType; m.parent = toInstantiationType(arrayProperty);
String containerType = cp.containerType; String containerType = cp.containerType;
if(instantiationTypes.containsKey(containerType))
m.imports.add(instantiationTypes.get(containerType));
if(typeMapping.containsKey(containerType)) { if(typeMapping.containsKey(containerType)) {
containerType = typeMapping.get(containerType); containerType = typeMapping.get(containerType);
cp.containerType = containerType; cp.containerType = containerType;
@ -335,46 +338,62 @@ public class DefaultCodegen {
} }
else { else {
ModelImpl impl = (ModelImpl) model; ModelImpl impl = (ModelImpl) model;
// Json.prettyPrint(impl); if(impl.getAdditionalProperties() != null) {
for(String key: impl.getProperties().keySet()) { MapProperty mapProperty = new MapProperty(impl.getAdditionalProperties());
Property prop = impl.getProperties().get(key); CodegenProperty cp = fromProperty(name, mapProperty);
if(cp.complexType != null && !defaultIncludes.contains(cp.complexType))
if(prop == null) { m.imports.add(cp.complexType);
System.out.println("null property for " + key); 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); if(impl.getProperties() != null) {
cp.required = false; for(String key: impl.getProperties().keySet()) {
if(impl.getRequired() != null) { Property prop = impl.getProperties().get(key);
for(String req : impl.getRequired()) {
if(key.equals(req)) if(prop == null) {
cp.required = true; 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 && if(cp.complexType != null &&
!languageSpecificPrimitives.contains(cp.complexType) && !languageSpecificPrimitives.contains(cp.complexType) &&
!defaultIncludes.contains(cp.complexType)) !defaultIncludes.contains(cp.complexType))
m.imports.add(cp.complexType); m.imports.add(cp.complexType);
if(cp.baseType != null && if(cp.baseType != null &&
!languageSpecificPrimitives.contains(cp.baseType) && !languageSpecificPrimitives.contains(cp.baseType) &&
!defaultIncludes.contains(cp.baseType)) !defaultIncludes.contains(cp.baseType))
m.imports.add(cp.baseType); m.imports.add(cp.baseType);
}
} }
} }
} }

View File

@ -262,10 +262,16 @@ public class DefaultGenerator implements Generator {
String m = config.importMapping().get(i); String m = config.importMapping().get(i);
if(m == null) if(m == null)
m = config.toModelImport(i); m = config.toModelImport(i);
if(m != null) { if(m != null && !config.defaultIncludes().contains(m)) {
im.put("import", m); im.put("import", m);
imports.add(im); 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); objs.put("imports", imports);

View File

@ -45,6 +45,8 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
"Long", "Long",
"Float") "Float")
); );
instantiationTypes.put("array", "ArrayList");
instantiationTypes.put("map", "HashMap");
} }
@Override @Override

View File

@ -30,7 +30,9 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
"NSObject", "NSObject",
"NSArray", "NSArray",
"NSNumber", "NSNumber",
"NSDictionary") "NSDictionary",
"NSMutableArray",
"NSMutableDictionary")
); );
languageSpecificPrimitives = new HashSet<String>( languageSpecificPrimitives = new HashSet<String>(
Arrays.asList( Arrays.asList(
@ -77,6 +79,9 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
"NSDictionary") "NSDictionary")
); );
instantiationTypes.put("array", "NSMutableArray");
instantiationTypes.put("map", "NSMutableDictionary");
supportingFiles.add(new SupportingFile("SWGObject.h", sourceFolder, "SWGObject.h")); supportingFiles.add(new SupportingFile("SWGObject.h", sourceFolder, "SWGObject.h"));
supportingFiles.add(new SupportingFile("SWGObject.m", sourceFolder, "SWGObject.m")); supportingFiles.add(new SupportingFile("SWGObject.m", sourceFolder, "SWGObject.m"));
supportingFiles.add(new SupportingFile("SWGApiClient.h", sourceFolder, "SWGApiClient.h")); 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")); 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 @Override
public String getTypeDeclaration(String name) { public String getTypeDeclaration(String name) {
if(languageSpecificPrimitives.contains(name) && !foundationClasses.contains(name)) if(languageSpecificPrimitives.contains(name) && !foundationClasses.contains(name))

View File

@ -2,25 +2,29 @@ package {{package}};
{{#imports}}import {{import}}; {{#imports}}import {{import}};
{{/imports}} {{/imports}}
import com.wordnik.swagger.annotations.*;
{{#models}} {{#models}}
{{#model}}{{#description}} {{#model}}{{#description}}
/** /**
* {{description}} * {{description}}
**/{{/description}} **/{{/description}}
public class {{classname}} { {{#vars}} @ApiModel(description = "{{{description}}}")
/**{{#description}} public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} { {{#vars}}
* {{{description}}}{{/description}}
* required: {{required}}{{#minimum}}
* minimum: {{minimum}}{{/minimum}}{{#maximum}}
* maximum: {{maximum}}{{/maximum}}
**/
private {{{datatype}}} {{name}} = {{{defaultValue}}};{{#allowableValues}} private {{{datatype}}} {{name}} = {{{defaultValue}}};{{#allowableValues}}
//{{^min}}public enum {{name}}Enum { {{#values}} {{.}}, {{/values}} }; //{{^min}}public enum {{name}}Enum { {{#values}} {{.}}, {{/values}} };
{{/min}}{{/allowableValues}}{{/vars}} {{/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}}; return {{name}};
} }
public void {{setter}}({{{datatype}}} {{name}}) { public void {{setter}}({{{datatype}}} {{name}}) {
@ -33,6 +37,7 @@ public class {{classname}} { {{#vars}}
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("class {{classname}} {\n"); sb.append("class {{classname}} {\n");
{{#parent}}sb.append(" " + super.toString()).append("\n");{{/parent}}
{{#vars}}sb.append(" {{name}}: ").append({{name}}).append("\n"); {{#vars}}sb.append(" {{name}}: ").append({{name}}).append("\n");
{{/vars}}sb.append("}\n"); {{/vars}}sb.append("}\n");
return sb.toString(); return sb.toString();

View File

@ -107,35 +107,35 @@
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations-version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.sun.jersey</groupId> <groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId> <artifactId>jersey-client</artifactId>
<version>${jersey-version}</version> <version>${jersey-version}</version>
<scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.sun.jersey.contribs</groupId> <groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId> <artifactId>jersey-multipart</artifactId>
<version>${jersey-version}</version> <version>${jersey-version}</version>
<scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId> <artifactId>jackson-core</artifactId>
<version>${jackson-version}</version> <version>${jackson-version}</version>
<scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId> <artifactId>jackson-annotations</artifactId>
<version>${jackson-version}</version> <version>${jackson-version}</version>
<scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version> <version>${jackson-version}</version>
<scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.datatype</groupId> <groupId>com.fasterxml.jackson.datatype</groupId>
@ -146,7 +146,6 @@
<groupId>joda-time</groupId> <groupId>joda-time</groupId>
<artifactId>joda-time</artifactId> <artifactId>joda-time</artifactId>
<version>${jodatime-version}</version> <version>${jodatime-version}</version>
<scope>compile</scope>
</dependency> </dependency>
<!-- test dependencies --> <!-- test dependencies -->
@ -157,8 +156,14 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<repositories>
<repository>
<id>sonatype-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repositories>
<properties> <properties>
<swagger-annotations-version>1.5.0-SNAPSHOT</swagger-annotations-version>
<jersey-version>1.7</jersey-version> <jersey-version>1.7</jersey-version>
<jackson-version>2.1.4</jackson-version> <jackson-version>2.1.4</jackson-version>
<jodatime-version>2.3</jodatime-version> <jodatime-version>2.3</jodatime-version>

View File

@ -6,7 +6,7 @@
{{#models}} {{#models}}
{{#model}} {{#model}}
@interface {{classname}} : SWGObject @interface {{classname}} : {{^parent}}SWGObject{{/parent}}{{#parent}}{{parent}}{{/parent}}
{{#vars}} {{#vars}}
@property(nonatomic) {{datatype}} {{name}}; {{#description}}/* {{{description}}} {{#isNotRequired}}[optional]{{/isNotRequired}} */{{/description}}{{newline}} @property(nonatomic) {{datatype}} {{name}}; {{#description}}/* {{{description}}} {{#isNotRequired}}[optional]{{/isNotRequired}} */{{/description}}{{newline}}

View File

@ -709,12 +709,6 @@
}, },
"complete": { "complete": {
"type": "boolean" "type": "boolean"
},
"keyValuePairs": {
"type": "object",
"additionalProperties": {
"type": "string"
}
} }
} }
} }

View File

@ -206,4 +206,37 @@ class JavaModelTest extends FlatSpec with Matchers {
vars.get(0).isContainer should equal (true) vars.get(0).isContainer should equal (true)
vars.get(0).isNotContainer should be (null) 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<Children>")
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<String, Children>")
cm.imports.size should be (3)
(cm.imports.asScala.toSet & Set("Map", "HashMap", "Children")).size should be (3)
}
} }

View File

@ -63,7 +63,6 @@ class ObjcModelTest extends FlatSpec with Matchers {
vars.get(2).required should equal (false) vars.get(2).required should equal (false)
vars.get(2).isNotContainer should equal (true) vars.get(2).isNotContainer should equal (true)
(cm.imports.asScala.toSet & (cm.imports.asScala.toSet &
Set("SWGDate")).size should be (1) 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).isContainer should equal (true)
vars.get(0).isNotContainer should be (null) 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)
}
} }