added support for array and model inline types

This commit is contained in:
Tony Tam 2015-10-18 20:51:55 -07:00
parent ad1626ad2d
commit 3cf1f1a56a
2 changed files with 266 additions and 31 deletions

View File

@ -3,9 +3,9 @@ package io.swagger.codegen;
import io.swagger.models.*; import io.swagger.models.*;
import io.swagger.models.parameters.BodyParameter; import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.Parameter; import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.ObjectProperty; import io.swagger.models.parameters.RefParameter;
import io.swagger.models.properties.Property; import io.swagger.models.properties.*;
import io.swagger.models.properties.RefProperty; import io.swagger.util.Json;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -14,12 +14,18 @@ import java.util.Map;
public class InlineModelResolver { public class InlineModelResolver {
private Swagger swagger = null; private Swagger swagger = null;
private boolean skipMatches = false;
Map<String, Model> addedModels = new HashMap<String, Model>(); Map<String, Model> addedModels = new HashMap<String, Model>();
Map<String, String> generatedSignature = new HashMap<String, String>();
public void flatten(Swagger swagger) { public void flatten(Swagger swagger) {
this.swagger = swagger; this.swagger = swagger;
if(swagger.getDefinitions() == null) {
swagger.setDefinitions(new HashMap<String, Model>());
}
// operations // operations
Map<String, Path> paths = swagger.getPaths(); Map<String, Path> paths = swagger.getPaths();
Map<String, Model> models = swagger.getDefinitions(); Map<String, Model> models = swagger.getDefinitions();
@ -35,24 +41,20 @@ public class InlineModelResolver {
for(Parameter parameter : parameters) { for(Parameter parameter : parameters) {
if(parameter instanceof BodyParameter) { if(parameter instanceof BodyParameter) {
BodyParameter bp = (BodyParameter) parameter; BodyParameter bp = (BodyParameter) parameter;
if(bp.getSchema() != null) { if(bp.getSchema() != null) {
Model model = bp.getSchema(); Model model = bp.getSchema();
if(model instanceof ModelImpl) { if(model instanceof ModelImpl) {
String name = bp.getName(); String existing = matchGenerated(model);
if(existing != null) {
if(models == null) { bp.setSchema(new RefModel(existing));
models = new HashMap<String, Model>();
swagger.setDefinitions(models);
} }
else { else {
if (swagger.getDefinitions().containsKey(bp.getName())) { String name = uniqueName(bp.getName());
name += "_" + "inline"; bp.setSchema(new RefModel(name));
} addGenerated(name, model);
swagger.addDefinition(name, model);
} }
swagger.addDefinition(name, model);
bp.setSchema(new RefModel(name));
} }
} }
} }
@ -68,8 +70,44 @@ public class InlineModelResolver {
String modelName = uniqueName("inline_response_" + key); String modelName = uniqueName("inline_response_" + key);
ObjectProperty op = (ObjectProperty) property; ObjectProperty op = (ObjectProperty) property;
Model model = modelFromProperty(op, modelName); Model model = modelFromProperty(op, modelName);
response.setSchema(new RefProperty(modelName)); String existing = matchGenerated(model);
swagger.addDefinition(modelName, model); if(existing != null) {
response.setSchema(new RefProperty(existing));
}
else {
response.setSchema(new RefProperty(modelName));
addGenerated(modelName, model);
swagger.addDefinition(modelName, model);
}
}
else if(property instanceof ArrayProperty) {
String modelName = uniqueName("inline_response_" + key);
ArrayProperty ap = (ArrayProperty) property;
Model model = modelFromProperty(ap, modelName);
if(model != null) {
String existing = matchGenerated(model);
if (existing != null) {
response.setSchema(new RefProperty(existing));
} else {
response.setSchema(new RefProperty(modelName));
addGenerated(modelName, model);
swagger.addDefinition(modelName, model);
}
}
}
else if(property instanceof MapProperty) {
MapProperty op = (MapProperty) property;
String modelName = uniqueName("inline_response_" + key);
Model model = modelFromProperty(op, modelName);
String existing = matchGenerated(model);
if(existing != null) {
response.setSchema(new RefProperty(existing));
}
else {
response.setSchema(new RefProperty(modelName));
addGenerated(modelName, model);
swagger.addDefinition(modelName, model);
}
} }
} }
} }
@ -88,15 +126,24 @@ public class InlineModelResolver {
Map<String, Property> properties = m.getProperties(); Map<String, Property> properties = m.getProperties();
flattenProperties(properties, modelName); flattenProperties(properties, modelName);
} }
else if (model instanceof ArrayModel) { else if (model instanceof ArrayModel) {
ArrayModel m = (ArrayModel) model; ArrayModel m = (ArrayModel) model;
Property inner = m.getItems(); Property inner = m.getItems();
if(inner instanceof ObjectProperty) { if(inner instanceof ObjectProperty) {
String innerModelName = uniqueName(modelName + "_" + inner); String innerModelName = uniqueName(modelName + "_inner");
Model innerModel = modelFromProperty((ObjectProperty)inner, modelName); Model innerModel = modelFromProperty((ObjectProperty) inner, modelName);
swagger.addDefinition(innerModelName, innerModel);
m.setItems(new RefProperty(innerModelName)); String existing = matchGenerated(innerModel);
if(existing == null) {
swagger.addDefinition(innerModelName, innerModel);
addGenerated(innerModelName, innerModel);
m.setItems(new RefProperty(innerModelName));
}
else {
m.setItems(new RefProperty(existing));
}
} }
} }
else if (model instanceof ComposedModel) { else if (model instanceof ComposedModel) {
@ -106,6 +153,21 @@ public class InlineModelResolver {
} }
} }
public String matchGenerated(Model model) {
if(this.skipMatches) {
return null;
}
String json = Json.pretty(model);
if(generatedSignature.containsKey(json)) {
return generatedSignature.get(json);
}
return null;
}
public void addGenerated(String name, Model model) {
generatedSignature.put(Json.pretty(model), name);
}
public String uniqueName(String key) { public String uniqueName(String key) {
int count = 0; int count = 0;
boolean done = false; boolean done = false;
@ -135,11 +197,22 @@ public class InlineModelResolver {
Property property = properties.get(key); Property property = properties.get(key);
if(property instanceof ObjectProperty) { if(property instanceof ObjectProperty) {
String modelName = uniqueName(path + "_" + key); String modelName = uniqueName(path + "_" + key);
ObjectProperty op = (ObjectProperty) property; ObjectProperty op = (ObjectProperty) property;
Model model = modelFromProperty(op, modelName); Model model = modelFromProperty(op, modelName);
modelsToAdd.put(modelName, model); String existing = matchGenerated(model);
propsToUpdate.put(key, new RefProperty(modelName));
if(existing != null) {
propsToUpdate.put(key, new RefProperty(existing));
}
else {
propsToUpdate.put(key, new RefProperty(modelName));
modelsToAdd.put(modelName, model);
addGenerated(modelName, model);
swagger.addDefinition(modelName, model);
}
} }
} }
if(propsToUpdate.size() > 0) { if(propsToUpdate.size() > 0) {
@ -153,6 +226,41 @@ public class InlineModelResolver {
} }
} }
public Model modelFromProperty(ArrayProperty object, String path) {
String access = object.getAccess();
String description = object.getDescription();
String example = object.getExample();
String name = object.getName();
Integer position = object.getPosition();
Boolean readOnly = object.getReadOnly();
Boolean required = object.getRequired();
String title = object.getTitle();
Map<String, Object> extensions = object.getVendorExtensions();
Xml xml = object.getXml();
// object.getItems()
// Map<String, Property> properties = object.getProperties();
Property inner = object.getItems();
if(inner instanceof ObjectProperty) {
ArrayModel model = new ArrayModel();
model.setDescription(description);
model.setExample(example);
// model.setName(name);
// model.setXml(xml);
model.setItems(object.getItems());
return model;
}
// if(properties != null) {
// flattenProperties(properties, path);
// model.setProperties(properties);
// }
return null;
}
public Model modelFromProperty(ObjectProperty object, String path) { public Model modelFromProperty(ObjectProperty object, String path) {
String access = object.getAccess(); String access = object.getAccess();
String description = object.getDescription(); String description = object.getDescription();
@ -180,4 +288,32 @@ public class InlineModelResolver {
return model; return model;
} }
public Model modelFromProperty(MapProperty object, String path) {
String access = object.getAccess();
String description = object.getDescription();
String example = object.getExample();
String name = object.getName();
Integer position = object.getPosition();
Boolean readOnly = object.getReadOnly();
Boolean required = object.getRequired();
String title = object.getTitle();
Map<String, Object> extensions = object.getVendorExtensions();
Xml xml = object.getXml();
ArrayModel model = new ArrayModel();
model.setDescription(description);
model.setExample(example);
model.setItems(object.getAdditionalProperties());
return model;
}
public boolean isSkipMatches() {
return skipMatches;
}
public void setSkipMatches(boolean skipMatches) {
this.skipMatches = skipMatches;
}
} }

View File

@ -4,11 +4,17 @@ package io.swagger.codegen;
import io.swagger.models.*; import io.swagger.models.*;
import io.swagger.models.parameters.BodyParameter; import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.Parameter; import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.ObjectProperty; import io.swagger.models.properties.*;
import io.swagger.models.properties.StringProperty;
import io.swagger.util.Json; import io.swagger.util.Json;
import org.junit.Test; import org.junit.Test;
import java.lang.reflect.Array;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class InlineModelResolverTest { public class InlineModelResolverTest {
@Test @Test
public void resolveInlineModelTest() throws Exception { public void resolveInlineModelTest() throws Exception {
@ -31,7 +37,15 @@ public class InlineModelResolverTest {
new InlineModelResolver().flatten(swagger); new InlineModelResolver().flatten(swagger);
Json.prettyPrint(swagger); ModelImpl user = (ModelImpl)swagger.getDefinitions().get("User");
assertNotNull(user);
assertTrue(user.getProperties().get("address") instanceof RefProperty);
ModelImpl address = (ModelImpl)swagger.getDefinitions().get("User_address");
assertNotNull(address);
assertNotNull(address.getProperties().get("city"));
assertNotNull(address.getProperties().get("street"));
} }
@Test @Test
@ -50,12 +64,18 @@ public class InlineModelResolverTest {
.vendorExtension("x-foo", "bar") .vendorExtension("x-foo", "bar")
.description("it works!") .description("it works!")
.schema(new ObjectProperty() .schema(new ObjectProperty()
.vendorExtension("x-baz", "boo") .property("name", new StringProperty())))));
.property("name", new StringProperty()
.vendorExtension("x-bars", "bleh"))))));
new InlineModelResolver().flatten(swagger); new InlineModelResolver().flatten(swagger);
Json.prettyPrint(swagger); Map<String, Response> responses = swagger.getPaths().get("/foo/bar").getGet().getResponses();
Response response = responses.get("200");
assertNotNull(response);
assertTrue(response.getSchema() instanceof RefProperty);
ModelImpl model = (ModelImpl)swagger.getDefinitions().get("inline_response_200");
assertTrue(model.getProperties().size() == 1);
assertNotNull(model.getProperties().get("name"));
} }
@Test @Test
@ -76,7 +96,12 @@ public class InlineModelResolverTest {
new InlineModelResolver().flatten(swagger); new InlineModelResolver().flatten(swagger);
Json.prettyPrint(swagger); Model model = swagger.getDefinitions().get("User");
assertTrue(model instanceof ArrayModel);
Model user = swagger.getDefinitions().get("User_inner");
assertNotNull(user);
assertEquals("description", user.getDescription());
} }
@Test @Test
@ -92,6 +117,80 @@ public class InlineModelResolverTest {
new InlineModelResolver().flatten(swagger); new InlineModelResolver().flatten(swagger);
Json.prettyPrint(swagger); Operation operation = swagger.getPaths().get("/hello").getGet();
BodyParameter bp = (BodyParameter)operation.getParameters().get(0);
assertTrue(bp.getSchema() instanceof RefModel);
Model body = swagger.getDefinitions().get("body");
assertTrue(body instanceof ModelImpl);
ModelImpl impl = (ModelImpl) body;
assertNotNull(impl.getProperties().get("name"));
}
@Test
public void resolveInlineArrayResponse() throws Exception {
Swagger swagger = new Swagger();
swagger.path("/foo/baz", new Path()
.get(new Operation()
.response(200, new Response()
.vendorExtension("x-foo", "bar")
.description("it works!")
.schema(new ArrayProperty()
.items(
new ObjectProperty()
.property("name", new StringProperty()))))));
new InlineModelResolver().flatten(swagger);
Response response = swagger.getPaths().get("/foo/baz").getGet().getResponses().get("200");
assertNotNull(response);
assertNotNull(response.getSchema());
Property responseProperty = response.getSchema();
assertTrue(responseProperty instanceof RefProperty);
Model inline = swagger.getDefinitions().get("inline_response_200");
assertNotNull(inline);
assertTrue(inline instanceof ArrayModel);
ArrayModel am = (ArrayModel) inline;
assertTrue(am.getItems() instanceof RefProperty);
Model inlineInner = swagger.getDefinitions().get("inline_response_200_inner");
assertNotNull(inlineInner);
assertTrue(inlineInner instanceof ModelImpl);
ModelImpl innerModel = (ModelImpl) inlineInner;
assertTrue(innerModel.getProperties().size() == 1);
assertNotNull(innerModel.getProperties().get("name"));
}
@Test
public void testInlineMapResponse() throws Exception {
Swagger swagger = new Swagger();
MapProperty schema = new MapProperty();
schema.setAdditionalProperties(new StringProperty());
swagger.path("/foo/baz", new Path()
.get(new Operation()
.response(200, new Response()
.vendorExtension("x-foo", "bar")
.description("it works!")
.schema(schema))));
new InlineModelResolver().flatten(swagger);
Response response = swagger.getPaths().get("/foo/baz").getGet().getResponses().get("200");
Property property = response.getSchema();
assertTrue(property instanceof RefProperty);
Model inline = swagger.getDefinitions().get("inline_response_200");
assertTrue(inline instanceof ArrayModel);
ArrayModel am = (ArrayModel) inline;
Property innerProperty = am.getItems();
assertTrue(innerProperty instanceof StringProperty);
} }
} }