mirror of
https://github.com/jlengrand/openapi-generator.git
synced 2026-05-16 00:21:19 +00:00
added example generator, updated signatures to match
This commit is contained in:
@@ -26,6 +26,7 @@ public interface CodegenConfig {
|
||||
String getTypeDeclaration(Property p);
|
||||
String getTypeDeclaration(String name);
|
||||
void processOpts();
|
||||
String generateExamplePath(String path, Operation operation);
|
||||
|
||||
Set<String> reservedWords();
|
||||
|
||||
@@ -35,7 +36,7 @@ public interface CodegenConfig {
|
||||
String getOutputDir();
|
||||
|
||||
CodegenModel fromModel(String name, Model model);
|
||||
CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation);
|
||||
CodegenOperation fromOperation(String resourcePath, String httpMethod, Operation operation, Map<String, Model> definitions);
|
||||
List<CodegenSecurity> fromSecurity(Map<String, SecuritySchemeDefinition> schemes);
|
||||
|
||||
Set<String> defaultIncludes();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.wordnik.swagger.codegen;
|
||||
|
||||
import com.wordnik.swagger.codegen.examples.ExampleGenerator;
|
||||
import com.wordnik.swagger.models.*;
|
||||
import com.wordnik.swagger.models.auth.ApiKeyAuthDefinition;
|
||||
import com.wordnik.swagger.models.auth.BasicAuthDefinition;
|
||||
@@ -235,6 +236,55 @@ public class DefaultCodegen {
|
||||
importMapping.put("LocalTime", "org.joda.time.*");
|
||||
}
|
||||
|
||||
|
||||
public String generateExamplePath(String path, Operation operation) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(path);
|
||||
|
||||
if(operation.getParameters() != null) {
|
||||
int count = 0;
|
||||
|
||||
for(Parameter param : operation.getParameters()) {
|
||||
if(param instanceof QueryParameter) {
|
||||
StringBuilder paramPart = new StringBuilder();
|
||||
QueryParameter qp = (QueryParameter) param;
|
||||
|
||||
if(count == 0)
|
||||
paramPart.append("?");
|
||||
else
|
||||
paramPart.append(",");
|
||||
count += 1;
|
||||
if(!param.getRequired())
|
||||
paramPart.append("[");
|
||||
paramPart.append(param.getName()).append("=");
|
||||
paramPart.append("{");
|
||||
if(qp.getCollectionFormat() != null) {
|
||||
paramPart.append(param.getName() + "1");
|
||||
if("csv".equals(qp.getCollectionFormat()))
|
||||
paramPart.append(",");
|
||||
else if("pipes".equals(qp.getCollectionFormat()))
|
||||
paramPart.append("|");
|
||||
else if("tsv".equals(qp.getCollectionFormat()))
|
||||
paramPart.append("\t");
|
||||
else if("multi".equals(qp.getCollectionFormat())) {
|
||||
paramPart.append("&").append(param.getName()).append("=");
|
||||
paramPart.append(param.getName() + "2");
|
||||
}
|
||||
}
|
||||
else {
|
||||
paramPart.append(param.getName());
|
||||
}
|
||||
paramPart.append("}");
|
||||
if(!param.getRequired())
|
||||
paramPart.append("]");
|
||||
sb.append(paramPart.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String toInstantiationType(Property p) {
|
||||
if (p instanceof MapProperty) {
|
||||
MapProperty ap = (MapProperty) p;
|
||||
@@ -584,7 +634,7 @@ public class DefaultCodegen {
|
||||
return responses.get(code);
|
||||
}
|
||||
|
||||
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation){
|
||||
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map<String, Model> definitions) {
|
||||
CodegenOperation op = CodegenModelFactory.newInstance(CodegenModelType.OPERATION);
|
||||
Set<String> imports = new HashSet<String>();
|
||||
|
||||
@@ -671,24 +721,40 @@ public class DefaultCodegen {
|
||||
}
|
||||
op.responses.get(op.responses.size() - 1).hasMore = false;
|
||||
|
||||
if (methodResponse != null) {
|
||||
op.returnType = methodCodegenResponse.dataType;
|
||||
op.returnBaseType = methodCodegenResponse.baseType;
|
||||
op.returnSimpleType = methodCodegenResponse.simpleType;
|
||||
op.returnTypeIsPrimitive = methodCodegenResponse.primitiveType;
|
||||
op.returnContainer = methodCodegenResponse.containerType;
|
||||
op.isListContainer = methodCodegenResponse.isListContainer;
|
||||
op.isMapContainer = methodCodegenResponse.isMapContainer;
|
||||
if (methodResponse.getSchema() != null) {
|
||||
Property responseProperty = methodResponse.getSchema();
|
||||
responseProperty.setRequired(true);
|
||||
CodegenProperty cm = fromProperty("response", responseProperty);
|
||||
op.examples = toExamples(methodResponse.getExamples());
|
||||
op.defaultResponse = toDefaultValue(responseProperty);
|
||||
addHeaders(methodResponse, op.responseHeaders);
|
||||
}
|
||||
if(methodResponse != null) {
|
||||
if (methodResponse.getSchema() != null) {
|
||||
CodegenProperty cm = fromProperty("response", methodResponse.getSchema());
|
||||
|
||||
Property responseProperty = methodResponse.getSchema();
|
||||
|
||||
if(responseProperty instanceof ArrayProperty) {
|
||||
ArrayProperty ap = (ArrayProperty) responseProperty;
|
||||
CodegenProperty innerProperty = fromProperty("response", ap.getItems());
|
||||
op.returnBaseType = innerProperty.baseType;
|
||||
}
|
||||
else {
|
||||
if(cm.complexType != null)
|
||||
op.returnBaseType = cm.complexType;
|
||||
else
|
||||
op.returnBaseType = cm.baseType;
|
||||
}
|
||||
op.examples = new ExampleGenerator(definitions).generate(methodResponse.getExamples(), operation.getProduces(), responseProperty);
|
||||
op.defaultResponse = toDefaultValue(responseProperty);
|
||||
op.returnType = cm.datatype;
|
||||
if(cm.isContainer != null) {
|
||||
op.returnContainer = cm.containerType;
|
||||
if("map".equals(cm.containerType))
|
||||
op.isMapContainer = Boolean.TRUE;
|
||||
else if ("list".equalsIgnoreCase(cm.containerType))
|
||||
op.isListContainer = Boolean.TRUE;
|
||||
}
|
||||
else
|
||||
op.returnSimpleType = true;
|
||||
if (languageSpecificPrimitives().contains(op.returnBaseType) || op.returnBaseType == null)
|
||||
op.returnTypeIsPrimitive = true;
|
||||
}
|
||||
addHeaders(methodResponse, op.responseHeaders);
|
||||
}
|
||||
}
|
||||
|
||||
List<Parameter> parameters = operation.getParameters();
|
||||
|
||||
@@ -271,7 +271,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
}
|
||||
|
||||
for (String tag : tags) {
|
||||
CodegenOperation co = config.fromOperation(resourcePath, httpMethod, operation);
|
||||
CodegenOperation co = config.fromOperation(resourcePath, httpMethod, operation, swagger.getDefinitions());
|
||||
co.tags = new ArrayList<String>();
|
||||
co.tags.add(sanitizeTag(tag));
|
||||
config.addOperationToGroup(sanitizeTag(tag), resourcePath, operation, co, operations);
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
package com.wordnik.swagger.codegen.examples;
|
||||
|
||||
import com.wordnik.swagger.models.*;
|
||||
import com.wordnik.swagger.models.properties.*;
|
||||
import com.wordnik.swagger.util.Json;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Marshaller;
|
||||
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
|
||||
public class ExampleGenerator {
|
||||
protected Map<String, Model> examples;
|
||||
|
||||
public ExampleGenerator(Map<String, Model> examples) {
|
||||
this.examples = examples;
|
||||
}
|
||||
|
||||
public List<Map<String, String>> generate(Map<String, String> examples, List<String> mediaTypes, Property property) {
|
||||
List<Map<String, String>> output = new ArrayList<Map<String, String>>();
|
||||
if(examples == null ) {
|
||||
if(mediaTypes == null) {
|
||||
// assume application/json for this
|
||||
mediaTypes = Arrays.asList("application/json");
|
||||
}
|
||||
for(String mediaType : mediaTypes) {
|
||||
Map<String, String> kv = new HashMap<String, String>();
|
||||
kv.put("contentType", mediaType);
|
||||
if(property != null && mediaType.startsWith("application/json")) {
|
||||
String example = Json.pretty(resolvePropertyToExample(mediaType, property));
|
||||
|
||||
if(example != null) {
|
||||
example = example.replaceAll("\n", "\\\\n");
|
||||
kv.put("example", example);
|
||||
output.add(kv);
|
||||
}
|
||||
}
|
||||
else if(property != null && mediaType.startsWith("application/xml")) {
|
||||
String example = new XmlExampleGenerator(this.examples).toXml(property);
|
||||
if(example != null) {
|
||||
example = example.replaceAll("\n", "\\\\n");
|
||||
kv.put("example", example);
|
||||
output.add(kv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(String key: examples.keySet()) {
|
||||
String value = examples.get(key);
|
||||
|
||||
Map<String, String> kv = new HashMap<String, String>();
|
||||
kv.put("contentType", key);
|
||||
kv.put("example", value);
|
||||
output.add(kv);
|
||||
}
|
||||
}
|
||||
if(output.size() == 0) {
|
||||
Map<String, String> kv = new HashMap<String, String>();
|
||||
kv.put("output", "none");
|
||||
output.add(kv);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
protected Object resolvePropertyToExample(String mediaType, Property property) {
|
||||
if(property.getExample() != null) {
|
||||
return property.getExample();
|
||||
}
|
||||
else if(property instanceof StringProperty) {
|
||||
return "aeiou";
|
||||
}
|
||||
else if(property instanceof BooleanProperty) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
else if(property instanceof ArrayProperty) {
|
||||
Property innerType = ((ArrayProperty)property).getItems();
|
||||
if(innerType != null) {
|
||||
Object[] output = new Object[]{
|
||||
resolvePropertyToExample(mediaType, innerType)
|
||||
};
|
||||
return output;
|
||||
}
|
||||
}
|
||||
else if(property instanceof DateProperty) {
|
||||
return new java.util.Date(System.currentTimeMillis());
|
||||
}
|
||||
else if(property instanceof DateTimeProperty) {
|
||||
return new java.util.Date(System.currentTimeMillis());
|
||||
}
|
||||
else if(property instanceof DecimalProperty) {
|
||||
return new BigDecimal(1.3579);
|
||||
}
|
||||
else if(property instanceof DoubleProperty) {
|
||||
return new Double(3.149);
|
||||
}
|
||||
else if(property instanceof FileProperty) {
|
||||
return ""; // TODO
|
||||
}
|
||||
else if(property instanceof FloatProperty) {
|
||||
return new Float(1.23);
|
||||
}
|
||||
else if(property instanceof IntegerProperty) {
|
||||
return new Integer(123);
|
||||
}
|
||||
else if(property instanceof LongProperty) {
|
||||
return new Long(123456789);
|
||||
}
|
||||
else if(property instanceof MapProperty) {
|
||||
Map<String, Object> mp = new HashMap<String, Object>();
|
||||
if(property.getName() != null) {
|
||||
mp.put(property.getName(),
|
||||
resolvePropertyToExample(mediaType, ((MapProperty)property).getAdditionalProperties()));
|
||||
}
|
||||
else {
|
||||
mp.put("key",
|
||||
resolvePropertyToExample(mediaType, ((MapProperty)property).getAdditionalProperties()));
|
||||
}
|
||||
return mp;
|
||||
}
|
||||
else if(property instanceof ObjectProperty) {
|
||||
return "{}";
|
||||
}
|
||||
else if(property instanceof RefProperty) {
|
||||
Model model = examples.get(((RefProperty)property).getSimpleRef());
|
||||
if(model != null)
|
||||
return resolveModelToExample(mediaType, model);
|
||||
}
|
||||
else if(property instanceof UUIDProperty) {
|
||||
return "046b6c7f-0b8a-43b9-b35d-6489e6daee91";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public Object resolveModelToExample(String mediaType, Model model) {
|
||||
if(model instanceof ModelImpl) {
|
||||
ModelImpl impl = (ModelImpl) model;
|
||||
Map<String, Object> values = new HashMap<String, Object>();
|
||||
|
||||
for(String name : impl.getProperties().keySet()) {
|
||||
Property property = impl.getProperties().get(name);
|
||||
values.put(name, resolvePropertyToExample(mediaType, property));
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
package com.wordnik.swagger.codegen.examples;
|
||||
|
||||
|
||||
import com.wordnik.swagger.util.Json;
|
||||
import com.wordnik.swagger.models.*;
|
||||
import com.wordnik.swagger.models.properties.*;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
public class XmlExampleGenerator {
|
||||
public static String NEWLINE = "\n";
|
||||
public static String TAG_START = "<";
|
||||
public static String CLOSE_TAG = ">";
|
||||
public static String TAG_END = "</";
|
||||
protected Map<String, Model> examples;
|
||||
protected SimpleDateFormat dtFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
|
||||
protected SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
|
||||
|
||||
public XmlExampleGenerator(Map<String, Model> examples) {
|
||||
this.examples = examples;
|
||||
if(examples == null)
|
||||
examples = new HashMap<String, Model>();
|
||||
}
|
||||
|
||||
public String toXml(Property property) {
|
||||
return toXml(null, property, 0);
|
||||
}
|
||||
|
||||
protected String toXml(Model model, int indent) {
|
||||
if(model instanceof RefModel) {
|
||||
RefModel ref = (RefModel) model;
|
||||
Model actualModel = examples.get(ref.getSimpleRef());
|
||||
if(actualModel instanceof ModelImpl)
|
||||
return modelImplToXml((ModelImpl)actualModel, indent);
|
||||
}
|
||||
else if(model instanceof ModelImpl) {
|
||||
return modelImplToXml((ModelImpl)model, indent);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String modelImplToXml(ModelImpl model, int indent) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// attributes
|
||||
Map<String, Property> attributes = new LinkedHashMap<String, Property>();
|
||||
Map<String, Property> elements = new LinkedHashMap<String, Property>();
|
||||
|
||||
String name = model.getName();
|
||||
String namespace;
|
||||
String prefix;
|
||||
Boolean wrapped;
|
||||
|
||||
Xml xml = model.getXml();
|
||||
if(xml != null) {
|
||||
if(xml.getName() != null)
|
||||
name = xml.getName();
|
||||
}
|
||||
for(String pName : model.getProperties().keySet()) {
|
||||
Property p = model.getProperties().get(pName);
|
||||
if(p != null && p.getXml() != null && p.getXml().getAttribute() != null && p.getXml().getAttribute())
|
||||
attributes.put(pName, p);
|
||||
else
|
||||
elements.put(pName, p);
|
||||
}
|
||||
sb.append(indent(indent)).append(TAG_START);
|
||||
sb.append(name);
|
||||
for(String pName : attributes.keySet()) {
|
||||
Property p = attributes.get(pName);
|
||||
sb.append(" ").append(pName).append("=").append(quote(toXml(null, p, 0)));
|
||||
}
|
||||
sb.append(CLOSE_TAG);
|
||||
sb.append(NEWLINE);
|
||||
for(String pName : elements.keySet()) {
|
||||
Property p = elements.get(pName);
|
||||
sb.append(toXml(pName, p, indent + 1));
|
||||
sb.append(NEWLINE);
|
||||
}
|
||||
sb.append(indent(indent)).append(TAG_END).append(name).append(CLOSE_TAG);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
protected String quote(String string) {
|
||||
return "\"" + string + "\"";
|
||||
}
|
||||
|
||||
protected String toXml(String name, Property property, int indent) {
|
||||
if(property == null) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if(property instanceof ArrayProperty) {
|
||||
ArrayProperty p = (ArrayProperty) property;
|
||||
Property inner = p.getItems();
|
||||
boolean wrapped = false;
|
||||
if(property.getXml() != null && property.getXml().getWrapped())
|
||||
wrapped = true;
|
||||
if(wrapped) {
|
||||
if(name != null) {
|
||||
sb.append(indent(indent));
|
||||
sb.append(openTag(name));
|
||||
sb.append(NEWLINE);
|
||||
}
|
||||
sb.append(toXml(name, inner, indent + 1));
|
||||
if(name != null) {
|
||||
sb.append(NEWLINE);
|
||||
sb.append(indent(indent));
|
||||
sb.append(closeTag(name));
|
||||
}
|
||||
}
|
||||
else
|
||||
sb.append(toXml(name, inner, indent));
|
||||
}
|
||||
else if(property instanceof RefProperty) {
|
||||
RefProperty ref = (RefProperty) property;
|
||||
Model actualModel = examples.get(ref.getSimpleRef());
|
||||
sb.append(toXml(actualModel, indent));
|
||||
}
|
||||
else {
|
||||
if(name != null) {
|
||||
sb.append(indent(indent));
|
||||
sb.append(openTag(name));
|
||||
}
|
||||
sb.append(getExample(property));
|
||||
if(name != null)
|
||||
sb.append(closeTag(name));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
protected String getExample(Property property) {
|
||||
if(property instanceof DateTimeProperty) {
|
||||
if(property.getExample() != null)
|
||||
return property.getExample();
|
||||
else
|
||||
return dtFormat.format(new Date());
|
||||
}
|
||||
else if(property instanceof StringProperty) {
|
||||
if(property.getExample() != null)
|
||||
return property.getExample();
|
||||
else
|
||||
return "string";
|
||||
}
|
||||
else if(property instanceof DateProperty) {
|
||||
if(property.getExample() != null)
|
||||
return property.getExample();
|
||||
else
|
||||
return dateFormat.format(new Date());
|
||||
}
|
||||
else if(property instanceof IntegerProperty) {
|
||||
if(property.getExample() != null)
|
||||
return property.getExample();
|
||||
else
|
||||
return "0";
|
||||
}
|
||||
else if(property instanceof BooleanProperty) {
|
||||
if(property.getExample() != null)
|
||||
return property.getExample();
|
||||
else
|
||||
return "true";
|
||||
}
|
||||
else if(property instanceof LongProperty) {
|
||||
if(property.getExample() != null)
|
||||
return property.getExample();
|
||||
else
|
||||
return "123456";
|
||||
}
|
||||
return "not implemented " + property;
|
||||
}
|
||||
|
||||
protected String openTag(String name) {
|
||||
return "<" + name + ">";
|
||||
}
|
||||
|
||||
protected String closeTag(String name) {
|
||||
return "</" + name + ">";
|
||||
}
|
||||
|
||||
protected String indent(int indent) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for(int i = 0; i < indent; i++) {
|
||||
sb.append(" ");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -115,6 +115,11 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
|
||||
"",
|
||||
"package.json")
|
||||
);
|
||||
if(System.getProperty("service") != null) {
|
||||
apiTemplateFiles.put(
|
||||
"service.mustache", // the template to use
|
||||
"Service.js"); // the extension for each file to write
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -164,6 +169,22 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
|
||||
resp.code = "default";
|
||||
}
|
||||
}
|
||||
if(operation.examples != null && operation.examples.size() > 0) {
|
||||
List<Map<String, String>> examples = operation.examples;
|
||||
for(int i = examples.size() - 1; i >= 0; i--) {
|
||||
Map<String, String> example = examples.get(i);
|
||||
String contentType = example.get("contentType");
|
||||
if(contentType != null && contentType.indexOf("application/json") == 0) {
|
||||
String jsonExample = example.get("example");
|
||||
if(jsonExample != null) {
|
||||
jsonExample = jsonExample.replaceAll("\\\\n", "\n");
|
||||
example.put("example", jsonExample);
|
||||
}
|
||||
}
|
||||
else
|
||||
examples.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user