fix NPE with requestbody

This commit is contained in:
wing328 2018-03-22 21:57:56 +08:00
parent f2489b256a
commit a8c64f458f
7 changed files with 976 additions and 220 deletions

View File

@ -11,12 +11,12 @@ import static java.util.ServiceLoader.load;
/**
* User: lanwen Date: 24.03.15 Time: 20:25
*/
@Command(name = "langs", description = "Shows available langs")
@Command(name = "langs", description = "Shows available languages (generators)")
public class Langs implements Runnable {
@Override
public void run() {
LambdaIterable<String> langs =
with(load(CodegenConfig.class)).extract(on(CodegenConfig.class).getName());
System.out.printf("Available languages: %s%n", langs);
System.out.printf("Available languages (generators): %s%n", langs);
}
}

View File

@ -32,6 +32,7 @@ public class CodegenOperation {
public List<CodegenParameter> queryParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> headerParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> formParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> cookieParams = new ArrayList<CodegenParameter>();
public List<CodegenParameter> requiredParams = new ArrayList<CodegenParameter>();
public List<CodegenSecurity> authMethods;
public List<Tag> tags;
@ -101,6 +102,15 @@ public class CodegenOperation {
return nonempty(formParams);
}
/**
* Check if there's at least one form parameter
*
* @return true if any cookie parameter exists, false otherwise
*/
public boolean getHasCookieParams() {
return nonempty(cookieParams);
}
/**
* Check if there's at least one example parameter
*
@ -281,6 +291,8 @@ public class CodegenOperation {
return false;
if (formParams != null ? !formParams.equals(that.formParams) : that.formParams != null)
return false;
if (cookieParams != null ? !cookieParams.equals(that.cookieParams) : that.cookieParams != null)
return false;
if (authMethods != null ? !authMethods.equals(that.authMethods) : that.authMethods != null)
return false;
if (tags != null ? !tags.equals(that.tags) : that.tags != null)
@ -347,6 +359,7 @@ public class CodegenOperation {
result = 31 * result + (queryParams != null ? queryParams.hashCode() : 0);
result = 31 * result + (headerParams != null ? headerParams.hashCode() : 0);
result = 31 * result + (formParams != null ? formParams.hashCode() : 0);
result = 31 * result + (cookieParams != null ? cookieParams.hashCode() : 0);
result = 31 * result + (authMethods != null ? authMethods.hashCode() : 0);
result = 31 * result + (tags != null ? tags.hashCode() : 0);
result = 31 * result + (responses != null ? responses.hashCode() : 0);
@ -361,4 +374,6 @@ public class CodegenOperation {
result = 31 * result + (operationIdCamelCase != null ? operationIdCamelCase.hashCode() : 0);
return result;
}
}

View File

@ -343,128 +343,6 @@ public class CodegenParameter {
result = 31 * result + (multipleOf != null ? multipleOf.hashCode() : 0);
return result;
}
public boolean getSecondaryParam() {
return secondaryParam;
}
public String getBaseName() {
return baseName;
}
public String getParamName() {
return paramName;
}
public String getDataType() {
return dataType;
}
public String getDatatypeWithEnum() {
return datatypeWithEnum;
}
public String getDataFormat() {
return dataFormat;
}
public String getCollectionFormat() {
return collectionFormat;
}
public String getDescription() {
return description;
}
public String getUnescapedDescription() {
return unescapedDescription;
}
public String getBaseType() {
return baseType;
}
public String getDefaultValue() {
return defaultValue;
}
public String getEnumName() {
return enumName;
}
public String getExample() {
return example;
}
public String getJsonSchema() {
return jsonSchema;
}
public boolean getIsNotFile() {
return notFile;
}
public List<String> get_enum() {
return _enum;
}
public Map<String, Object> getAllowableValues() {
return allowableValues;
}
public CodegenProperty getItems() {
return items;
}
public Map<String, Object> getVendorExtensions() {
return vendorExtensions;
}
public boolean getRequired() {
return required;
}
public String getMaximum() {
return maximum;
}
public boolean getExclusiveMaximum() {
return exclusiveMaximum;
}
public String getMinimum() {
return minimum;
}
public boolean getExclusiveMinimum() {
return exclusiveMinimum;
}
public Integer getMaxLength() {
return maxLength;
}
public Integer getMinLength() {
return minLength;
}
public String getPattern() {
return pattern;
}
public Integer getMaxItems() {
return maxItems;
}
public Integer getMinItems() {
return minItems;
}
public boolean getUniqueItems() {
return uniqueItems;
}
public Number getMultipleOf() {
return multipleOf;
}
}

View File

@ -3,6 +3,7 @@ package org.openapitools.codegen;
import javax.annotation.Nullable;
import java.io.File;
import java.util.*;
import java.util.ArrayList;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -52,7 +53,7 @@ import org.openapitools.codegen.examples.ExampleGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DefaultCodegen {
public class DefaultCodegen implements CodegenConfig {
protected static final Logger LOGGER = LoggerFactory.getLogger(DefaultCodegen.class);
protected String inputSpec;
@ -164,15 +165,15 @@ public class DefaultCodegen {
}
// Fix up all parent and interface CodegenModel references.
for (CodegenModel cm : allModels.values()) {
if (cm.parent != null) {
cm.parentModel = allModels.get(cm.parent);
if (cm.getParent() != null) {
cm.setParentModel(allModels.get(cm.getParent()));
}
if (cm.interfaces != null && !cm.interfaces.isEmpty()) {
cm.interfaceModels = new ArrayList<CodegenModel>(cm.interfaces.size());
for (String intf : cm.interfaces) {
if (cm.getInterfaces() != null && !cm.getInterfaces().isEmpty()) {
cm.setInterfaceModels(new ArrayList<CodegenModel>(cm.getInterfaces().size()));
for (String intf : cm.getInterfaces()) {
CodegenModel intfModel = allModels.get(intf);
if (intfModel != null) {
cm.interfaceModels.add(intfModel);
cm.getInterfaceModels().add(intfModel);
}
}
}
@ -180,15 +181,15 @@ public class DefaultCodegen {
// Let parent know about all its children
for (String name : allModels.keySet()) {
CodegenModel cm = allModels.get(name);
CodegenModel parent = allModels.get(cm.parent);
// if a discriminator exists on the parent, don't add this child to the inheritance hierarchy
CodegenModel parent = allModels.get(cm.getParent());
// if a discriminator exists on the parent, don't add this child to the inheritance heirarchy
// TODO Determine what to do if the parent discriminator name == the grandparent discriminator name
while (parent != null) {
if (parent.children == null) {
parent.children = new ArrayList<CodegenModel>();
if (parent.getChildren() == null) {
parent.setChildren(new ArrayList<CodegenModel>());
}
parent.children.add(cm);
if (parent.discriminator == null) {
parent.getChildren().add(cm);
if (parent.getDiscriminator() == null) {
parent = allModels.get(parent.parent);
} else {
parent = null;
@ -936,25 +937,30 @@ public class DefaultCodegen {
}
paramPart.append(param.getName()).append("=");
paramPart.append("{");
// TODO the following needs to be commented out?
/*
if (qp.getCollectionFormat() != null) {
// TODO support for multi, tsv?
if (qp.getStyle() != null) {
paramPart.append(param.getName()).append("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()).append("2");
if (Parameter.StyleEnum.FORM.equals(qp.getStyle())) {
if (qp.getExplode() != null && qp.getExplode()) {
paramPart.append(",");
} else {
paramPart.append("&").append(param.getName()).append("=");
paramPart.append(param.getName()).append("2");
}
}
else if (Parameter.StyleEnum.PIPEDELIMITED.equals(qp.getStyle())) {
paramPart.append("|");
}
else if (Parameter.StyleEnum.SPACEDELIMITED.equals(qp.getStyle())) {
paramPart.append("%20");
} else {
LOGGER.warn("query parameter '" + param.getName() + "style not support: " + qp.getStyle());
}
} else {
paramPart.append(param.getName());
} */
paramPart.append(param.getName());
// TODO --END
paramPart.append(param.getName());
}
paramPart.append("}");
if (!param.getRequired()) {
paramPart.append("]");
@ -1087,12 +1093,15 @@ public class DefaultCodegen {
datatype = datatype.substring("#/components/schemas/".length());
}
} catch (Exception e) {
LOGGER.warn("Error obtaining the datatype from ref:" + schema + ". Datatype default to Object");
LOGGER.warn("Error obtaining the datatype (" + datatype + ") from ref:" + schema + ". Datatype default to Object");
datatype = "Object";
}
return datatype;
}
if (schema instanceof ByteArraySchema) {
if (schema instanceof StringSchema && "number".equals(schema.getFormat())) {
datatype = "BigDecimal";
} else if (schema instanceof ByteArraySchema || (schema instanceof StringSchema && "byte".equals(schema.getFormat()))) {
datatype = "ByteArray";
} else if (schema instanceof BinarySchema) {
datatype = SchemaTypeUtil.BINARY_FORMAT;
@ -1123,15 +1132,14 @@ public class DefaultCodegen {
} else if ( schema instanceof UUIDSchema) {
datatype = "UUID";
} else if (schema instanceof StringSchema) {
datatype = "string";
if ("number".equals(schema.getFormat())) {
datatype = "BigDecimal";
} else {
datatype = "string";
}
datatype = "string";
} else {
if (schema != null) {
datatype = schema.getType();
if (SchemaTypeUtil.OBJECT_TYPE.equals(schema.getType()) && schema.getAdditionalProperties() != null) {
datatype = "map";
} else {
datatype = schema.getType();
}
}
}
@ -1348,6 +1356,7 @@ public class DefaultCodegen {
if (interfaces != null) {
if (m.interfaces == null)
m.interfaces = new ArrayList<String>();
for (Schema interfaceSchema : interfaces) {
if (StringUtils.isBlank(interfaceSchema.get$ref())) {
continue;
@ -1373,7 +1382,7 @@ public class DefaultCodegen {
if (parent != null) {
m.parentSchema = parentName;
m.parent = StringUtils.capitalize(modelNamePrefix + "_" + parentName + "_" + modelNameSuffix);
m.parent = toModelName(parentName);
addImport(m, m.parent);
if (allDefinitions != null) {
if (supportsInheritance) {
@ -1403,14 +1412,14 @@ public class DefaultCodegen {
//} else if (schema instanceof RefModel) {
} else {
m.dataType = getSchemaType(schema);
if(schema.getEnum() != null && !schema.getEnum().isEmpty()) {
if (schema.getEnum() != null && !schema.getEnum().isEmpty()) {
m.isEnum = true;
// comment out below as allowableValues is not set in post processing model enum
m.allowableValues = new HashMap<String, Object>();
m.allowableValues.put("values", schema.getEnum());
}
if (schema.getAdditionalProperties() != null) {
addAdditionPropertiesToCodeGenModel(m, schema);
addParentContainer(m, m.name, schema);
}
addVars(m, schema.getProperties(), schema.getRequired());
}
@ -1454,11 +1463,6 @@ public class DefaultCodegen {
return false;
}
// TODO deco this function?
protected void addAdditionPropertiesToCodeGenModel(CodegenModel model, Schema schema) {
addParentContainer(model, model.name, schema);
}
protected void addProperties(Map<String, Schema> properties, List<String> required, Schema schema, Map<String, Schema> allSchemas) {
if (schema instanceof ComposedSchema) {
ComposedSchema composedSchema = (ComposedSchema) schema;
@ -1507,7 +1511,7 @@ public class DefaultCodegen {
*/
public CodegenProperty fromProperty(String name, Schema p) {
if (p == null) {
LOGGER.error("unexpected missing property for name " + name);
LOGGER.error("Unexpected missing property for name " + name);
return null;
}
@ -1521,7 +1525,7 @@ public class DefaultCodegen {
property.getter = toGetter(name);
property.setter = toSetter(name);
String example = toExampleValue(p);
if(!"null".equals(example)) {
if (!"null".equals(example)) {
property.example = example;
}
property.defaultValue = toDefaultValue(p);
@ -1543,6 +1547,7 @@ public class DefaultCodegen {
}
String type = getSchemaType(p);
//LOGGER.info("from property = " + p);
if (p instanceof IntegerSchema) {
property.isNumeric = Boolean.TRUE;
if (SchemaTypeUtil.INTEGER64_FORMAT.equals(p.getFormat())) {
@ -1643,11 +1648,11 @@ public class DefaultCodegen {
} else { // type is number and without format
property.isNumber = Boolean.TRUE;
}
/* TODO fix Could not process model 'Enum_Test'.Please make sure that your schema is correct!
if (p.getEnum() != null) {
List<Double> _enum = p.getEnum();
if (p.getEnum() != null && !p.getEnum().isEmpty()) {
List<Number> _enum = p.getEnum();
property._enum = new ArrayList<String>();
for (Double i : _enum) { <<<<< line throwing exception
for (Number i : _enum) {
property._enum.add(i.toString());
}
property.isEnum = true;
@ -1656,7 +1661,7 @@ public class DefaultCodegen {
Map<String, Object> allowableValues = new HashMap<String, Object>();
allowableValues.put("values", _enum);
property.allowableValues = allowableValues;
} */
}
}
if (p instanceof DateSchema) {
@ -1729,7 +1734,7 @@ public class DefaultCodegen {
}
CodegenProperty cp = fromProperty(itemName, ((ArraySchema) p).getItems());
updatePropertyForArray(property, cp);
} else if (p instanceof MapSchema) {
} else if (p instanceof MapSchema || p.getAdditionalProperties() != null) {
property.isContainer = true;
property.isMapContainer = true;
property.containerType = "map";
@ -1740,15 +1745,17 @@ public class DefaultCodegen {
// handle inner property
CodegenProperty cp = fromProperty("inner", (Schema) p.getAdditionalProperties());
updatePropertyForMap(property, cp);
} else {
} else { // model
// TODO revise the logic below
if (StringUtils.isNotBlank(p.get$ref())) {
property.baseType = getSimpleRef(p.get$ref());
}
//if (StringUtils.isNotBlank(p.get$ref())) {
// property.baseType = getSimpleRef(p.get$ref());
//}
// --END of revision
setNonArrayMapProperty(property, type);
}
//LOGGER.info("from property end = " + property);
return property;
}
@ -1950,6 +1957,7 @@ public class DefaultCodegen {
Operation operation,
Map<String, Schema> schemas,
OpenAPI openAPI) {
//LOGGER.info("fromOperation => operation: " + operation);
CodegenOperation op = CodegenModelFactory.newInstance(CodegenModelType.OPERATION);
Set<String> imports = new HashSet<String>();
if (operation.getExtensions() != null && !operation.getExtensions().isEmpty()) {
@ -1995,7 +2003,7 @@ public class DefaultCodegen {
!defaultIncludes.contains(r.baseType) &&
!languageSpecificPrimitives.contains(r.baseType)) {
imports.add(r.baseType);
}
}
r.isDefault = response == methodResponse;
op.responses.add(r);
if (Boolean.TRUE.equals(r.isBinary) && Boolean.TRUE.equals(r.isDefault)){
@ -2063,7 +2071,6 @@ public class DefaultCodegen {
}
List<Parameter> parameters = operation.getParameters();
CodegenParameter bodyParam = null;
List<CodegenParameter> allParams = new ArrayList<CodegenParameter>();
List<CodegenParameter> bodyParams = new ArrayList<CodegenParameter>();
List<CodegenParameter> pathParams = new ArrayList<CodegenParameter>();
@ -2073,18 +2080,38 @@ public class DefaultCodegen {
List<CodegenParameter> formParams = new ArrayList<CodegenParameter>();
List<CodegenParameter> requiredParams = new ArrayList<CodegenParameter>();
if (operation.getRequestBody() != null) {
bodyParam = fromRequestBody(operation.getRequestBody(), schemas, imports);
bodyParams.add(bodyParam);
allParams.add(bodyParam);
CodegenParameter bodyParam = null;
RequestBody requestBody = operation.getRequestBody();
if (requestBody != null) {
if ("application/x-www-form-urlencoded".equalsIgnoreCase(getContentType(requestBody)) ||
"multipart/form-data".equalsIgnoreCase(getContentType(requestBody))) {
// process form parameters
formParams = fromRequestBodyToFormParameters(requestBody, schemas, imports);
for (CodegenParameter cp: formParams) {
LOGGER.info("Adding " + cp.baseName + " to allParams list");
allParams.add(cp.copy());
}
} else {
// process body parameter
if (StringUtils.isNotBlank(requestBody.get$ref())) {
LOGGER.info("request body name: " + getSimpleRef(requestBody.get$ref()));
requestBody = openAPI.getComponents().getRequestBodies().get(getSimpleRef(requestBody.get$ref()));
}
bodyParam = fromRequestBody(requestBody, schemas, imports);
bodyParams.add(bodyParam);
allParams.add(bodyParam);
}
}
if (parameters != null) {
for (Parameter param : parameters) {
if (StringUtils.isNotBlank(param.get$ref())) {
param = getParameterFromRef(param.get$ref(), openAPI);
}
CodegenParameter p = fromParameter(param, imports);
// rename parameters to make sure all of them have unique names
if (ensureUniqueParams) {
while (true) {
boolean exists = false;
for (CodegenParameter cp : allParams) {
if (p.paramName.equals(cp.paramName)) {
@ -2097,21 +2124,25 @@ public class DefaultCodegen {
} else {
break;
}
}
}
allParams.add(p);
// Issue #2561 (neilotoole) : Moved setting of is<Type>Param flags
// from here to fromParameter().
if (param instanceof QueryParameter) {
if (param instanceof QueryParameter || "query".equalsIgnoreCase(param.getIn())) {
queryParams.add(p.copy());
} else if (param instanceof PathParameter) {
} else if (param instanceof PathParameter || "path".equalsIgnoreCase(param.getIn())) {
LOGGER.info("Adding path parameter: "+ p.paramName);
pathParams.add(p.copy());
} else if (param instanceof HeaderParameter) {
} else if (param instanceof HeaderParameter || "header".equalsIgnoreCase(param.getIn())) {
headerParams.add(p.copy());
} else if (param instanceof CookieParameter) {
} else if (param instanceof CookieParameter || "cookie".equalsIgnoreCase(param.getIn())) {
cookieParams.add(p.copy());
}
//} else if (Boolean.TRUE.equals(p.isFormParam)) {
// do nothing as form parameter has been handled above
} else {
LOGGER.warn("Unknown parameter type " + p.baseType + " for " + p.baseName);
}
/* TODO need to handle body and form parameter below
else if (param instanceof RequestBody) {
bodyParam = p;
@ -2131,6 +2162,7 @@ public class DefaultCodegen {
}
}
for (String i : imports) {
if (needToImport(i)) {
op.imports.add(i);
@ -2157,7 +2189,7 @@ public class DefaultCodegen {
op.pathParams = addHasMore(pathParams);
op.queryParams = addHasMore(queryParams);
op.headerParams = addHasMore(headerParams);
// op.cookieParams = cookieParams;
op.cookieParams = addHasMore(cookieParams);
op.formParams = addHasMore(formParams);
op.requiredParams = addHasMore(requiredParams);
op.externalDocs = operation.getExternalDocs();
@ -2198,6 +2230,7 @@ public class DefaultCodegen {
r.schema = responseSchema;
r.message = escapeText(response.getDescription());
// TODO need to revise and test examples in responses
// ApiResponse does not support examples at the moment
//r.examples = toExamples(response.getExamples());
r.jsonSchema = Json.pretty(response);
if (response.getExtensions() != null && !response.getExtensions().isEmpty()) {
@ -2299,6 +2332,7 @@ public class DefaultCodegen {
if (System.getProperty("debugParser") != null) {
LOGGER.info("working on Parameter " + parameter.getName());
LOGGER.info("JSON schema: " + codegenParameter.jsonSchema);
}
// TODO need to revise the logic below
@ -2328,16 +2362,17 @@ public class DefaultCodegen {
if (parameter.getSchema() != null) {
Schema parameterSchema = parameter.getSchema();
// TDOO revise collectionFormat
String collectionFormat = "csv";
String collectionFormat = "UNKNOWN_COLLECTION_FORMAT";
if (parameterSchema instanceof ArraySchema) { // for array parameter
final ArraySchema arraySchema = (ArraySchema) parameterSchema;
Schema inner = arraySchema.getItems();
if (inner == null) {
LOGGER.warn("warning! No inner type supplied for array parameter \"" + parameter.getName() + "\", using String");
inner = new StringSchema().description("//TODO automatically added by openapi-generator");
LOGGER.warn("warning! No inner type supplied for array parameter \"" + parameter.getName() + "\", using String");
inner = new StringSchema().description("//TODO automatically added by openapi-generator due to missing iner type definition in the spec");
arraySchema.setItems(inner);
}
collectionFormat = getCollectionFormat(parameter);
CodegenProperty codegenProperty = fromProperty("inner", inner);
codegenParameter.items = codegenProperty;
codegenParameter.baseType = codegenProperty.datatype;
@ -2356,22 +2391,29 @@ public class DefaultCodegen {
codegenParameter.baseType = codegenProperty.datatype;
codegenParameter.isContainer = true;
codegenParameter.isMapContainer = true;
collectionFormat = getCollectionFormat(parameter);
// recursively add import
while (codegenProperty != null) {
imports.add(codegenProperty.baseType);
codegenProperty = codegenProperty.items;
}
}
/*
} else {
Map<PropertyId, Object> args = new HashMap<PropertyId, Object>();
String format = qp.getFormat();
args.put(PropertyId.ENUM, qp.getEnum());
property = PropertyBuilder.build(type, format, args);
}
*/
if (parameterSchema == null) {
LOGGER.warn("warning! Schema not found for parameter \"" + parameter.getName() + "\", using String");
parameterSchema = new StringSchema().description("//TODO automatically added by openapi-generator.");
parameterSchema = new StringSchema().description("//TODO automatically added by openapi-generator due to missing type definition.");
}
// TODO need to setRequired?
//property.setRequired(param.getRequired());
//codegenParameter.setRequired(param.getRequired());
CodegenProperty codegenProperty = fromProperty(parameter.getName(), parameterSchema);
// set boolean flag (e.g. isString)
@ -2528,15 +2570,17 @@ public class DefaultCodegen {
// This code has been moved to here from #fromOperation
// because these values should be set before calling #postProcessParameter.
// See: https://github.com/swagger-api/swagger-codegen/issues/2561
if (parameter instanceof QueryParameter) {
if (parameter instanceof QueryParameter || "query".equalsIgnoreCase(parameter.getIn())) {
codegenParameter.isQueryParam = true;
} else if (parameter instanceof PathParameter) {
} else if (parameter instanceof PathParameter || "path".equalsIgnoreCase(parameter.getIn())) {
codegenParameter.required = true;
codegenParameter.isPathParam = true;
} else if (parameter instanceof HeaderParameter) {
} else if (parameter instanceof HeaderParameter || "header".equalsIgnoreCase(parameter.getIn())) {
codegenParameter.isHeaderParam = true;
} else if (parameter instanceof CookieParameter) {
} else if (parameter instanceof CookieParameter || "cookie".equalsIgnoreCase(parameter.getIn())) {
codegenParameter.isCookieParam = true;
} else {
LOGGER.warn("Unknown parameter type: " + parameter.getName());
}
/* TODO: need to fix body parameter and form parameter
else if (parameter instanceof BodyParameter) {
@ -2825,7 +2869,7 @@ public class DefaultCodegen {
String uniqueName = co.operationId;
int counter = 0;
for(CodegenOperation op : opList) {
for (CodegenOperation op : opList) {
if(uniqueName.equals(op.operationId)) {
uniqueName = co.operationId + "_" + counter;
counter ++;
@ -2936,7 +2980,6 @@ public class DefaultCodegen {
m.hasVars = true;
m.hasEnums = false;
Set<String> mandatory = required == null ? Collections.<String> emptySet()
: new TreeSet<String>(required);
addVars(m, m.vars, properties, mandatory);
@ -3624,6 +3667,19 @@ public class DefaultCodegen {
}
protected Schema getSchemaFromBody(RequestBody requestBody) {
/*
if (requestBody == null) {
LOGGER.warn("requestBody is null in getSchemaFromBody");
return null;
}
if (requestBody.getContent() == null) {
LOGGER.warn("requestBody.getContent() is null in getSchemaFromBody");
return null;
}
if ( requestBody.getContent().keySet() == null) {
LOGGER.warn("requestBody.getContent().keySet() is null in getSchemaFromBody");
return null;
} */
String contentType = new ArrayList<>(requestBody.getContent().keySet()).get(0);
MediaType mediaType = requestBody.getContent().get(contentType);
return mediaType.getSchema();
@ -3695,6 +3751,13 @@ public class DefaultCodegen {
codegenOperation.hasConsumes = true;
}
public static Set<String> getConsumesInfo(Operation operation) {
if(operation.getRequestBody() == null || operation.getRequestBody().getContent() == null || operation.getRequestBody().getContent().isEmpty()) {
return null;
}
return operation.getRequestBody().getContent().keySet();
}
private void addProducesInfo(ApiResponse response, CodegenOperation codegenOperation) {
if (response == null || response.getContent() == null || response.getContent().isEmpty()) {
return;
@ -3760,7 +3823,7 @@ public class DefaultCodegen {
}
protected String getSimpleRef(String ref) {
if (ref.startsWith("#/components/schemas/")) {
if (ref.startsWith("#/components/")) {
ref = ref.substring(ref.lastIndexOf("/") + 1);
}
return ref;
@ -3802,7 +3865,49 @@ public class DefaultCodegen {
return null;
}
public List<CodegenParameter> fromRequestBodyToFormParameters(RequestBody body, Map<String, Schema> schemas, Set<String> imports) {
List<CodegenParameter> parameters = new ArrayList<CodegenParameter>();
LOGGER.info("Request body = " + body);
Schema schema = getSchemaFromBody(body);
if (schema.getProperties() != null && !schema.getProperties().isEmpty()) {
Map<String, Schema> properties = schema.getProperties();
for (Map.Entry<String, Schema> entry : properties.entrySet()) {
CodegenParameter codegenParameter = CodegenModelFactory.newInstance(CodegenModelType.PARAMETER);
String name = entry.getKey();
Schema propertySchema = entry.getValue();
CodegenProperty codegenProperty = fromProperty(name, propertySchema);
codegenParameter.isFormParam = Boolean.TRUE;
codegenParameter.baseName = codegenProperty.baseName;
codegenParameter.paramName = toParamName((codegenParameter.baseName));
codegenParameter.baseType = codegenProperty.baseType;
codegenParameter.dataType = codegenProperty.datatype;
codegenParameter.description = codegenProperty.description;
setParameterBooleanFlagWithCodegenProperty(codegenParameter, codegenProperty);
setParameterExampleValue(codegenParameter);
if (codegenProperty.getVendorExtensions() != null && !codegenProperty.getVendorExtensions().isEmpty()) {
codegenParameter.vendorExtensions = codegenProperty.getVendorExtensions();
}
if (schema.getRequired() != null && !schema.getRequired().isEmpty() && schema.getRequired().contains(codegenProperty.baseName)) {
codegenParameter.required = Boolean.TRUE;
}
//TODO collectionFormat for form parameter not yet supported
//codegenParameter.collectionFormat = getCollectionFormat(propertySchema);
parameters.add(codegenParameter);
}
}
for (int i = 0; i < parameters.size(); i++) {
System.out.println("parmaeter name:" + parameters.get(i).baseName);
}
return parameters;
}
public CodegenParameter fromRequestBody(RequestBody body, Map<String, Schema> schemas, Set<String> imports) {
if (body == null) {
LOGGER.error("body in fromRequestBody cannot be null!");
}
CodegenParameter codegenParameter = CodegenModelFactory.newInstance(CodegenModelType.PARAMETER);
codegenParameter.baseName = "UNKNOWN_BASE_NAME";
codegenParameter.paramName = "UNKNOWN_PARAM_NAME";
@ -3810,31 +3915,32 @@ public class DefaultCodegen {
codegenParameter.isBodyParam = Boolean.TRUE;
String name = null;
LOGGER.debug("Request body = " + body);
Schema schema = getSchemaFromBody(body);
if (StringUtils.isNotBlank(schema.get$ref())) {
name = getSimpleRef(schema.get$ref());
schema = schemas.get(name);
}
if ((SchemaTypeUtil.OBJECT_TYPE.equals(schema.getType())
|| (schema.getType() == null && schema.getProperties() != null && !schema.getProperties().isEmpty()))
&& !(schema instanceof MapSchema)) {
if (isObjectSchema(schema)) {
CodegenModel codegenModel = null;
if (StringUtils.isNotBlank(name)) {
schema.setName(name);
codegenModel = fromModel(name, schema, schemas);
}
if (codegenModel != null && !codegenModel.emptyVars) {
codegenParameter.paramName = codegenModel.classname.toLowerCase();
codegenParameter.paramName = toParamName(codegenModel.name);
codegenParameter.baseType = codegenModel.classname;
codegenParameter.dataType = getTypeDeclaration(codegenModel.classname);
codegenParameter.description = codegenModel.description;
imports.add(codegenParameter.dataType);
} else {
CodegenProperty codegenProperty = fromProperty("property", schema);
if (codegenProperty != null) {
codegenParameter.baseType = codegenProperty.baseType;
codegenParameter.dataType = codegenProperty.datatype;
codegenParameter.isPrimitiveType = codegenProperty.isPrimitiveType;
codegenParameter.isBinary = codegenProperty.isBinary;
codegenParameter.isFile = codegenProperty.isFile;
codegenParameter.description = codegenProperty.description;
LOGGER.info("Seting description to body parameter: " + codegenProperty.description);
if (codegenProperty.complexType != null) {
imports.add(codegenProperty.complexType);
@ -3842,8 +3948,7 @@ public class DefaultCodegen {
}
setParameterBooleanFlagWithCodegenProperty(codegenParameter, codegenProperty);
}
}
else if (schema instanceof ArraySchema) {
} else if (schema instanceof ArraySchema) {
final ArraySchema arraySchema = (ArraySchema) schema;
Schema inner = arraySchema.getItems();
if (inner == null) {
@ -3865,9 +3970,9 @@ public class DefaultCodegen {
codegenParameter.items = codegenProperty;
codegenParameter.dataType = codegenProperty.datatype;
codegenParameter.baseType = codegenProperty.complexType;
codegenParameter.isPrimitiveType = codegenProperty.isPrimitiveType;
codegenParameter.isContainer = codegenProperty.isContainer;
codegenParameter.isListContainer = codegenProperty.isListContainer;
codegenParameter.description = codegenProperty.description;
setParameterBooleanFlagWithCodegenProperty(codegenParameter, codegenProperty);
@ -3875,8 +3980,27 @@ public class DefaultCodegen {
imports.add(codegenProperty.baseType);
codegenProperty = codegenProperty.items;
}
} else {
LOGGER.warn("Scheme type " + schema.getType() + "not handled in reqeust body");
}
// set the parameter's example value
// should be overridden by lang codegen
setParameterExampleValue(codegenParameter);
return codegenParameter;
}
private boolean isObjectSchema (Schema schema) {
if (schema instanceof ObjectSchema) {
return true;
}
if (SchemaTypeUtil.OBJECT_TYPE.equals(schema.getType()) && !(schema instanceof MapSchema)) {
return true;
}
if (schema.getType() == null && schema.getProperties() != null && !schema.getProperties().isEmpty()) {
return true;
}
return false;
}
}

View File

@ -151,9 +151,16 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
if (!generateApiTests && !generateModelTests) {
config.additionalProperties().put(CodegenConstants.EXCLUDE_TESTS, true);
}
// for backward compatibility
if (System.getProperty("debugSwagger") != null) {
LOGGER.info("Please use 'debugOpenAPI' instead of 'debugSwagger` moving forward.");
Json.prettyPrint(openAPI);
}
if (System.getProperty("debugOpenAPI") != null) {
Json.prettyPrint(openAPI);
}
config.processOpts();
config.preprocessOpenAPI(openAPI);
config.additionalProperties().put("generatorVersion", ImplementationVersion.read());

View File

@ -0,0 +1,731 @@
package org.openapitools.codegen.languages;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenParameter;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.DefaultCodegen;
import org.openapitools.codegen.SupportingFile;
import java.io.File;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.HashSet;
import java.util.regex.Matcher;
import org.apache.commons.lang3.StringUtils;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PhpClientCodegen extends DefaultCodegen implements CodegenConfig {
@SuppressWarnings("hiding")
static Logger LOGGER = LoggerFactory.getLogger(PhpClientCodegen.class);
public static final String VARIABLE_NAMING_CONVENTION = "variableNamingConvention";
public static final String PACKAGE_PATH = "packagePath";
public static final String SRC_BASE_PATH = "srcBasePath";
public static final String COMPOSER_VENDOR_NAME = "composerVendorName";
public static final String COMPOSER_PROJECT_NAME = "composerProjectName";
protected String invokerPackage = "Swagger\\Client";
protected String composerVendorName = null;
protected String composerProjectName = null;
protected String packagePath = "SwaggerClient-php";
protected String artifactVersion = null;
protected String srcBasePath = "lib";
protected String testBasePath = "test";
protected String docsBasePath = "docs";
protected String apiDirName = "Api";
protected String modelDirName = "Model";
protected String variableNamingConvention= "snake_case";
protected String apiDocPath = docsBasePath + "/" + apiDirName;
protected String modelDocPath = docsBasePath + "/" + modelDirName;
public PhpClientCodegen() {
super();
// clear import mapping (from default generator) as php does not use it
// at the moment
importMapping.clear();
supportsInheritance = true;
outputFolder = "generated-code" + File.separator + "php";
modelTemplateFiles.put("model.mustache", ".php");
apiTemplateFiles.put("api.mustache", ".php");
modelTestTemplateFiles.put("model_test.mustache", ".php");
apiTestTemplateFiles.put("api_test.mustache", ".php");
embeddedTemplateDir = templateDir = "php";
apiPackage = invokerPackage + "\\" + apiDirName;
modelPackage = invokerPackage + "\\" + modelDirName;
modelDocTemplateFiles.put("model_doc.mustache", ".md");
apiDocTemplateFiles.put("api_doc.mustache", ".md");
setReservedWordsLowerCase(
Arrays.asList(
// local variables used in api methods (endpoints)
"resourcePath", "httpBody", "queryParams", "headerParams",
"formParams", "_header_accept", "_tempBody",
// PHP reserved words
"__halt_compiler", "abstract", "and", "array", "as", "break", "callable", "case", "catch", "class", "clone", "const", "continue", "declare", "default", "die", "do", "echo", "else", "elseif", "empty", "enddeclare", "endfor", "endforeach", "endif", "endswitch", "endwhile", "eval", "exit", "extends", "final", "for", "foreach", "function", "global", "goto", "if", "implements", "include", "include_once", "instanceof", "insteadof", "interface", "isset", "list", "namespace", "new", "or", "print", "private", "protected", "public", "require", "require_once", "return", "static", "switch", "throw", "trait", "try", "unset", "use", "var", "while", "xor")
);
// ref: http://php.net/manual/en/language.types.intro.php
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"bool",
"boolean",
"int",
"integer",
"double",
"float",
"string",
"object",
"DateTime",
"mixed",
"number",
"void",
"byte")
);
instantiationTypes.put("array", "array");
instantiationTypes.put("map", "map");
// provide primitives to mustache template
List sortedLanguageSpecificPrimitives= new ArrayList(languageSpecificPrimitives);
Collections.sort(sortedLanguageSpecificPrimitives);
String primitives = "'" + StringUtils.join(sortedLanguageSpecificPrimitives, "', '") + "'";
additionalProperties.put("primitives", primitives);
// ref: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types
typeMapping = new HashMap<String, String>();
typeMapping.put("integer", "int");
typeMapping.put("long", "int");
typeMapping.put("number", "float");
typeMapping.put("float", "float");
typeMapping.put("double", "double");
typeMapping.put("string", "string");
typeMapping.put("byte", "int");
typeMapping.put("boolean", "bool");
typeMapping.put("date", "\\DateTime");
typeMapping.put("Date", "\\DateTime");
typeMapping.put("DateTime", "\\DateTime");
typeMapping.put("file", "\\SplFileObject");
typeMapping.put("map", "map");
typeMapping.put("array", "array");
typeMapping.put("list", "array");
typeMapping.put("object", "object");
typeMapping.put("binary", "string");
typeMapping.put("ByteArray", "string");
typeMapping.put("UUID", "string");
cliOptions.add(new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
cliOptions.add(new CliOption(VARIABLE_NAMING_CONVENTION, "naming convention of variable name, e.g. camelCase.")
.defaultValue("snake_case"));
cliOptions.add(new CliOption(CodegenConstants.INVOKER_PACKAGE, "The main namespace to use for all classes. e.g. Yay\\Pets"));
cliOptions.add(new CliOption(PACKAGE_PATH, "The main package name for classes. e.g. GeneratedPetstore"));
cliOptions.add(new CliOption(SRC_BASE_PATH, "The directory under packagePath to serve as source root."));
cliOptions.add(new CliOption(COMPOSER_VENDOR_NAME, "The vendor name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. yaypets. IMPORTANT NOTE (2016/03): composerVendorName will be deprecated and replaced by gitUserId in the next swagger-codegen release"));
cliOptions.add(new CliOption(CodegenConstants.GIT_USER_ID, CodegenConstants.GIT_USER_ID_DESC));
cliOptions.add(new CliOption(COMPOSER_PROJECT_NAME, "The project name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. petstore-client. IMPORTANT NOTE (2016/03): composerProjectName will be deprecated and replaced by gitRepoId in the next swagger-codegen release"));
cliOptions.add(new CliOption(CodegenConstants.GIT_REPO_ID, CodegenConstants.GIT_REPO_ID_DESC));
cliOptions.add(new CliOption(CodegenConstants.ARTIFACT_VERSION, "The version to use in the composer package version field. e.g. 1.2.3"));
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "hides the timestamp when files were generated")
.defaultValue(Boolean.TRUE.toString()));
}
public String getPackagePath() {
return packagePath;
}
public String toPackagePath(String packageName, String basePath) {
return (getPackagePath() + File.separatorChar + toSrcPath(packageName, basePath));
}
public String toSrcPath(String packageName, String basePath) {
packageName = packageName.replace(invokerPackage, ""); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
if (basePath != null && basePath.length() > 0) {
basePath = basePath.replaceAll("[\\\\/]?$", "") + File.separatorChar; // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
}
String regFirstPathSeparator;
if ("/".equals(File.separator)) { // for mac, linux
regFirstPathSeparator = "^/";
} else { // for windows
regFirstPathSeparator = "^\\\\";
}
String regLastPathSeparator;
if ("/".equals(File.separator)) { // for mac, linux
regLastPathSeparator = "/$";
} else { // for windows
regLastPathSeparator = "\\\\$";
}
return (basePath
// Replace period, backslash, forward slash with file separator in package name
+ packageName.replaceAll("[\\.\\\\/]", Matcher.quoteReplacement(File.separator))
// Trim prefix file separators from package path
.replaceAll(regFirstPathSeparator, ""))
// Trim trailing file separators from the overall path
.replaceAll(regLastPathSeparator+ "$", "");
}
@Override
public String escapeText(String input) {
if (input != null) {
// Trim the string to avoid leading and trailing spaces.
return super.escapeText(input).trim();
}
return input;
}
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public String getName() {
return "php";
}
@Override
public String getHelp() {
return "Generates a PHP client library.";
}
@Override
public void processOpts() {
super.processOpts();
// default HIDE_GENERATION_TIMESTAMP to true
if (!additionalProperties.containsKey(CodegenConstants.HIDE_GENERATION_TIMESTAMP)) {
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, Boolean.TRUE.toString());
} else {
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP,
Boolean.valueOf(additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP).toString()));
}
if (additionalProperties.containsKey(PACKAGE_PATH)) {
this.setPackagePath((String) additionalProperties.get(PACKAGE_PATH));
} else {
additionalProperties.put(PACKAGE_PATH, packagePath);
}
if (additionalProperties.containsKey(SRC_BASE_PATH)) {
this.setSrcBasePath((String) additionalProperties.get(SRC_BASE_PATH));
} else {
additionalProperties.put(SRC_BASE_PATH, srcBasePath);
}
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
// Update the invokerPackage for the default apiPackage and modelPackage
apiPackage = invokerPackage + "\\" + apiDirName;
modelPackage = invokerPackage + "\\" + modelDirName;
} else {
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
}
if (additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
// Update model package to contain the specified model package name and the invoker package
modelPackage = invokerPackage + "\\" + (String) additionalProperties.get(CodegenConstants.MODEL_PACKAGE);
}
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
if (additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
// Update model package to contain the specified model package name and the invoker package
apiPackage = invokerPackage + "\\" + (String) additionalProperties.get(CodegenConstants.API_PACKAGE);
}
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
if (additionalProperties.containsKey(COMPOSER_PROJECT_NAME)) {
this.setComposerProjectName((String) additionalProperties.get(COMPOSER_PROJECT_NAME));
} else {
additionalProperties.put(COMPOSER_PROJECT_NAME, composerProjectName);
}
if (additionalProperties.containsKey(CodegenConstants.GIT_USER_ID)) {
this.setGitUserId((String) additionalProperties.get(CodegenConstants.GIT_USER_ID));
} else {
additionalProperties.put(CodegenConstants.GIT_USER_ID, gitUserId);
}
if (additionalProperties.containsKey(COMPOSER_VENDOR_NAME)) {
this.setComposerVendorName((String) additionalProperties.get(COMPOSER_VENDOR_NAME));
} else {
additionalProperties.put(COMPOSER_VENDOR_NAME, composerVendorName);
}
if (additionalProperties.containsKey(CodegenConstants.GIT_REPO_ID)) {
this.setGitRepoId((String) additionalProperties.get(CodegenConstants.GIT_REPO_ID));
} else {
additionalProperties.put(CodegenConstants.GIT_REPO_ID, gitRepoId);
}
if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_VERSION)) {
this.setArtifactVersion((String) additionalProperties.get(CodegenConstants.ARTIFACT_VERSION));
} else {
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
}
if (additionalProperties.containsKey(VARIABLE_NAMING_CONVENTION)) {
this.setParameterNamingConvention((String) additionalProperties.get(VARIABLE_NAMING_CONVENTION));
}
additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\"));
// make api and model src path available in mustache template
additionalProperties.put("apiSrcPath", "./" + toSrcPath(apiPackage, srcBasePath));
additionalProperties.put("modelSrcPath", "./" + toSrcPath(modelPackage, srcBasePath));
additionalProperties.put("apiTestPath", "./" + testBasePath + "/" + apiDirName);
additionalProperties.put("modelTestPath", "./" + testBasePath + "/" + modelDirName);
// make api and model doc path available in mustache template
additionalProperties.put("apiDocPath", apiDocPath);
additionalProperties.put("modelDocPath", modelDocPath);
// make test path available in mustache template
additionalProperties.put("testBasePath", testBasePath);
supportingFiles.add(new SupportingFile("ApiException.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiException.php"));
supportingFiles.add(new SupportingFile("Configuration.mustache", toPackagePath(invokerPackage, srcBasePath), "Configuration.php"));
supportingFiles.add(new SupportingFile("ObjectSerializer.mustache", toPackagePath(invokerPackage, srcBasePath), "ObjectSerializer.php"));
supportingFiles.add(new SupportingFile("ModelInterface.mustache", toPackagePath(modelPackage, srcBasePath), "ModelInterface.php"));
supportingFiles.add(new SupportingFile("HeaderSelector.mustache", toPackagePath(invokerPackage, srcBasePath), "HeaderSelector.php"));
supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json"));
supportingFiles.add(new SupportingFile("README.mustache", getPackagePath(), "README.md"));
supportingFiles.add(new SupportingFile("phpunit.xml.mustache", getPackagePath(), "phpunit.xml.dist"));
supportingFiles.add(new SupportingFile(".travis.yml", getPackagePath(), ".travis.yml"));
supportingFiles.add(new SupportingFile(".php_cs", getPackagePath(), ".php_cs"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", getPackagePath(), "git_push.sh"));
}
@Override
public String escapeReservedWord(String name) {
if(this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "_" + name;
}
@Override
public String apiFileFolder() {
return (outputFolder + "/" + toPackagePath(apiPackage, srcBasePath));
}
@Override
public String modelFileFolder() {
return (outputFolder + "/" + toPackagePath(modelPackage, srcBasePath));
}
@Override
public String apiTestFileFolder() {
return (outputFolder + "/" + getPackagePath() + "/" + testBasePath + "/" + apiDirName);
}
@Override
public String modelTestFileFolder() {
return (outputFolder + "/" + getPackagePath() + "/" + testBasePath + "/" + modelDirName);
}
@Override
public String apiDocFileFolder() {
return (outputFolder + "/" + getPackagePath() + "/" + apiDocPath);
}
@Override
public String modelDocFileFolder() {
return (outputFolder + "/" + getPackagePath() + "/" + modelDocPath);
}
@Override
public String toModelDocFilename(String name) {
return toModelName(name);
}
@Override
public String toApiDocFilename(String name) {
return toApiName(name);
}
@Override
public String getTypeDeclaration(Schema p) {
if (p instanceof ArraySchema) {
ArraySchema ap = (ArraySchema) p;
Schema inner = ap.getItems();
return getTypeDeclaration(inner) + "[]";
} else if (p instanceof MapSchema) {
Schema inner = (Schema) p.getAdditionalProperties();
return getSchemaType(p) + "[string," + getTypeDeclaration(inner) + "]";
} else if (StringUtils.isNotBlank(p.get$ref())) {
String type = super.getTypeDeclaration(p);
return (!languageSpecificPrimitives.contains(type))
? "\\" + modelPackage + "\\" + type : type;
}
return super.getTypeDeclaration(p);
}
@Override
public String getTypeDeclaration(String name) {
if (!languageSpecificPrimitives.contains(name)) {
return "\\" + modelPackage + "\\" + name;
}
return super.getTypeDeclaration(name);
}
@Override
public String getSchemaType(Schema p) {
String schemaType = super.getSchemaType(p);
String type = null;
if (typeMapping.containsKey(schemaType)) {
type = typeMapping.get(schemaType);
if (languageSpecificPrimitives.contains(type)) {
return type;
} else if (instantiationTypes.containsKey(type)) {
return type;
}
} else {
type = schemaType;
}
if (type == null) {
return null;
}
return toModelName(type);
}
public void setInvokerPackage(String invokerPackage) {
this.invokerPackage = invokerPackage;
}
public void setArtifactVersion(String artifactVersion) {
this.artifactVersion = artifactVersion;
}
public void setPackagePath(String packagePath) {
this.packagePath = packagePath;
}
public void setSrcBasePath(String srcBasePath) {
this.srcBasePath = srcBasePath;
}
public void setParameterNamingConvention(String variableNamingConvention) {
this.variableNamingConvention = variableNamingConvention;
}
public void setComposerVendorName(String composerVendorName) {
this.composerVendorName = composerVendorName;
}
public void setComposerProjectName(String composerProjectName) {
this.composerProjectName = composerProjectName;
}
@Override
public String toVarName(String name) {
// sanitize name
name = sanitizeName(name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
if ("camelCase".equals(variableNamingConvention)) {
// return the name in camelCase style
// phone_number => phoneNumber
name = camelize(name, true);
} else { // default to snake case
// return the name in underscore style
// PhoneNumber => phone_number
name = underscore(name);
}
// parameter name starting with number won't compile
// need to escape it by appending _ at the beginning
if (name.matches("^\\d.*")) {
name = "_" + name;
}
return name;
}
@Override
public String toParamName(String name) {
// should be the same as variable name
return toVarName(name);
}
@Override
public String toModelName(String name) {
// remove [
name = name.replaceAll("\\]", "");
// Note: backslash ("\\") is allowed for e.g. "\\DateTime"
name = name.replaceAll("[^\\w\\\\]+", "_"); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'.
// remove dollar sign
name = name.replaceAll("$", "");
// model name cannot use reserved keyword
if (isReservedWord(name)) {
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + camelize("model_" + name));
name = "model_" + name; // e.g. return => ModelReturn (after camelize)
}
// model name starts with number
if (name.matches("^\\d.*")) {
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + camelize("model_" + name));
name = "model_" + name; // e.g. 200Response => Model200Response (after camelize)
}
// add prefix and/or suffic only if name does not start wth \ (e.g. \DateTime)
if (!name.matches("^\\\\.*")) {
if (!StringUtils.isEmpty(modelNamePrefix)) {
name = modelNamePrefix + "_" + name;
}
if (!StringUtils.isEmpty(modelNameSuffix)) {
name = name + "_" + modelNameSuffix;
}
}
// camelize the model name
// phone_number => PhoneNumber
return camelize(name);
}
@Override
public String toModelFilename(String name) {
// should be the same as the model name
return toModelName(name);
}
@Override
public String toModelTestFilename(String name) {
// should be the same as the model name
return toModelName(name) + "Test";
}
@Override
public String toOperationId(String operationId) {
// throw exception if method name is empty
if (StringUtils.isEmpty(operationId)) {
throw new RuntimeException("Empty method name (operationId) not allowed");
}
// method name cannot use reserved keyword, e.g. return
if (isReservedWord(operationId)) {
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + camelize(sanitizeName("call_" + operationId), true));
operationId = "call_" + operationId;
}
return camelize(sanitizeName(operationId), true);
}
/**
* Return the default value of the property
*
* @param p property schema
* @return string presentation of the default value of the property
*/
@Override
public String toDefaultValue(Schema p) {
if (p instanceof StringSchema) {
StringSchema dp = (StringSchema) p;
if (dp.getDefault() != null) {
return "'" + dp.getDefault() + "'";
}
} else if (p instanceof BooleanSchema) {
BooleanSchema dp = (BooleanSchema) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof DateSchema) {
// TODO
} else if (p instanceof DateTimeSchema) {
// TODO
} else if (p instanceof NumberSchema) {
NumberSchema dp = (NumberSchema) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
} else if (p instanceof IntegerSchema) {
IntegerSchema dp = (IntegerSchema) p;
if (dp.getDefault() != null) {
return dp.getDefault().toString();
}
}
return null;
}
@Override
public void setParameterExampleValue(CodegenParameter p) {
String example;
if (p.defaultValue == null) {
example = p.example;
} else {
example = p.defaultValue;
}
String type = p.baseType;
if (type == null) {
type = p.dataType;
}
if ("String".equalsIgnoreCase(type)) {
if (example == null) {
example = p.paramName + "_example";
}
example = "\"" + escapeText(example) + "\"";
} else if ("Integer".equals(type) || "int".equals(type)) {
if (example == null) {
example = "56";
}
} else if ("Float".equalsIgnoreCase(type) || "Double".equalsIgnoreCase(type)) {
if (example == null) {
example = "3.4";
}
} else if ("BOOLEAN".equalsIgnoreCase(type) || "bool".equalsIgnoreCase(type)) {
if (example == null) {
example = "True";
}
} else if ("\\SplFileObject".equalsIgnoreCase(type)) {
if (example == null) {
example = "/path/to/file";
}
example = "\"" + escapeText(example) + "\"";
} else if ("\\Date".equalsIgnoreCase(type)) {
if (example == null) {
example = "2013-10-20";
}
example = "new \\DateTime(\"" + escapeText(example) + "\")";
} else if ("\\DateTime".equalsIgnoreCase(type)) {
if (example == null) {
example = "2013-10-20T19:20:30+01:00";
}
example = "new \\DateTime(\"" + escapeText(example) + "\")";
} else if ("object".equals(type)) {
example = "new \\stdClass";
} else if (!languageSpecificPrimitives.contains(type)) {
// type is a model class, e.g. User
example = "new " + getTypeDeclaration(type) + "()";
} else {
LOGGER.warn("Type " + type + " not handled properly in setParameterExampleValue");
}
if (example == null) {
example = "NULL";
} else if (Boolean.TRUE.equals(p.isListContainer)) {
example = "array(" + example + ")";
} else if (Boolean.TRUE.equals(p.isMapContainer)) {
example = "array('key' => " + example + ")";
}
p.example = example;
}
@Override
public String toEnumValue(String value, String datatype) {
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
return value;
} else {
return "\'" + escapeText(value) + "\'";
}
}
@Override
public String toEnumDefaultValue(String value, String datatype) {
return datatype + "_" + value;
}
@Override
public String toEnumVarName(String name, String datatype) {
if (name.length() == 0) {
return "EMPTY";
}
// number
if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) {
String varName = name;
varName = varName.replaceAll("-", "MINUS_");
varName = varName.replaceAll("\\+", "PLUS_");
varName = varName.replaceAll("\\.", "_DOT_");
return varName;
}
// for symbol, e.g. $, #
if (getSymbolName(name) != null) {
return getSymbolName(name).toUpperCase();
}
// string
String enumName = sanitizeName(underscore(name).toUpperCase());
enumName = enumName.replaceFirst("^_", "");
enumName = enumName.replaceFirst("_$", "");
if (isReservedWord(enumName) || enumName.matches("\\d.*")) { // reserved word or starts with number
return escapeReservedWord(enumName);
} else {
return enumName;
}
}
@Override
public String toEnumName(CodegenProperty property) {
String enumName = underscore(toModelName(property.name)).toUpperCase();
// remove [] for array or map of enum
enumName = enumName.replace("[]", "");
if (enumName.matches("\\d.*")) { // starts with number
return "_" + enumName;
} else {
return enumName;
}
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
// process enum in models
return postProcessModelsEnum(objs);
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation op : operationList) {
// for API test method name
// e.g. public function test{{vendorExtensions.x-testOperationId}}()
op.vendorExtensions.put("x-testOperationId", camelize(op.operationId));
}
return objs;
}
@Override
public String escapeQuotationMark(String input) {
// remove ' to avoid code injection
return input.replace("'", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
}

View File

@ -1 +1,2 @@
org.openapitools.codegen.languages.PhpClientCodegen
org.openapitools.codegen.languages.RubyClientCodegen