added bigDecimalAsString option to allow serializing with strings

This commit is contained in:
Tony Tam 2015-12-30 12:32:37 -08:00
parent ac7856d009
commit 1cd54ee685
7 changed files with 68 additions and 32 deletions

View File

@ -109,6 +109,10 @@ public interface CodegenConfig {
Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs);
void postProcessModelProperty(CodegenModel model, CodegenProperty property);
void postProcessParameter(CodegenParameter parameter);
String apiFilename(String templateName, String tag);
boolean shouldOverwrite(String filename);

View File

@ -34,6 +34,9 @@ public class CodegenConstants {
public static final String SERIALIZABLE_MODEL = "serializableModel";
public static final String SERIALIZABLE_MODEL_DESC = "boolean - toggle \"implements Serializable\" for generated models";
public static final String SERIALIZE_BIG_DECIMAL_AS_STRING = "bigDecimalAsString";
public static final String SERIALIZE_BIG_DECIMAL_AS_STRING_DESC = "boolean - treat BigDecimal values as Strings to avoid precision loss. Default: false";
public static final String LIBRARY = "library";
public static final String LIBRARY_DESC = "library template (sub-template)";

View File

@ -120,6 +120,12 @@ public class DefaultCodegen {
return objs;
}
// override to post-process any model properties
public void postProcessModelProperty(CodegenModel model, CodegenProperty property){}
// override to post-process any parameters
public void postProcessParameter(CodegenParameter parameter){}
//override with any special handling of the entire swagger spec
public void preprocessSwagger(Swagger swagger) {
}
@ -620,7 +626,9 @@ public class DefaultCodegen {
**/
public String getSwaggerType(Property p) {
String datatype = null;
if (p instanceof StringProperty) {
if (p instanceof StringProperty && "number".equals(p.getFormat())) {
datatype = "BigDecimal";
} else if (p instanceof StringProperty) {
datatype = "string";
} else if (p instanceof ByteArrayProperty) {
datatype = "ByteArray";
@ -843,6 +851,12 @@ public class DefaultCodegen {
}
addVars(m, impl.getProperties(), impl.getRequired());
}
if(m.vars != null) {
for(CodegenProperty prop : m.vars) {
postProcessModelProperty(m, prop);
}
}
return m;
}
@ -1595,6 +1609,8 @@ public class DefaultCodegen {
}
p.paramName = toParamName(bp.getName());
}
postProcessParameter(p);
return p;
}

View File

@ -1,45 +1,21 @@
package io.swagger.codegen.languages;
import com.google.common.base.Strings;
import io.swagger.codegen.CliOption;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.CodegenModel;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.CodegenProperty;
import io.swagger.codegen.CodegenType;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.SupportingFile;
import io.swagger.codegen.*;
import io.swagger.models.Model;
import io.swagger.models.Operation;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.FormParameter;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.BooleanProperty;
import io.swagger.models.properties.DoubleProperty;
import io.swagger.models.properties.FloatProperty;
import io.swagger.models.properties.IntegerProperty;
import io.swagger.models.properties.LongProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.StringProperty;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import io.swagger.models.properties.*;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(JavaClientCodegen.class);
public static final String FULL_JAVA_UTIL = "fullJavaUtil";
@ -55,6 +31,7 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
protected boolean fullJavaUtil = false;
protected String javaUtilPrefix = "";
protected Boolean serializableModel = false;
protected boolean serializeBigDecimalAsString = false;
public JavaClientCodegen() {
super();
@ -101,6 +78,8 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
cliOptions.add(new CliOption(CodegenConstants.LOCAL_VARIABLE_PREFIX, CodegenConstants.LOCAL_VARIABLE_PREFIX_DESC));
cliOptions.add(new CliOption(CodegenConstants.SERIALIZABLE_MODEL, CodegenConstants.SERIALIZABLE_MODEL_DESC,
BooleanProperty.TYPE));
cliOptions.add(new CliOption(CodegenConstants.SERIALIZE_BIG_DECIMAL_AS_STRING, CodegenConstants.SERIALIZE_BIG_DECIMAL_AS_STRING_DESC,
BooleanProperty.TYPE));
cliOptions.add(new CliOption(FULL_JAVA_UTIL, "whether to use fully qualified name for classes under java.util",
BooleanProperty.TYPE).defaultValue(Boolean.FALSE.toString()));
@ -181,6 +160,10 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
this.setLibrary((String) additionalProperties.get(CodegenConstants.LIBRARY));
}
if(additionalProperties.containsKey(CodegenConstants.SERIALIZE_BIG_DECIMAL_AS_STRING)) {
this.setSerializeBigDecimalAsString(Boolean.valueOf(additionalProperties.get(CodegenConstants.SERIALIZE_BIG_DECIMAL_AS_STRING).toString()));
}
// need to put back serializableModel (boolean) into additionalProperties as value in additionalProperties is string
additionalProperties.put(CodegenConstants.SERIALIZABLE_MODEL, serializableModel);
@ -212,6 +195,11 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
this.sanitizeConfig();
// optional jackson mappings for BigDecimal support
importMapping.put("ToStringSerializer", "com.fasterxml.jackson.databind.ser.std.ToStringSerializer");
importMapping.put("JsonSerialize", "com.fasterxml.jackson.databind.annotation.JsonSerialize");
final String invokerFolder = (sourceFolder + '/' + invokerPackage).replace(".", "/");
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
@ -471,6 +459,26 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
return codegenModel;
}
@Override
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
if(serializeBigDecimalAsString) {
if (property.baseType.equals("BigDecimal")) {
// we serialize BigDecimal as `string` to avoid precision loss
property.vendorExtensions.put("extraAnnotation", "@JsonSerialize(using = ToStringSerializer.class)");
// this requires some more imports to be added for this model...
model.imports.add("ToStringSerializer");
model.imports.add("JsonSerialize");
}
}
return;
}
@Override
public void postProcessParameter(CodegenParameter parameter) {
return;
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
List<Object> models = (List<Object>) objs.get("models");
@ -702,6 +710,9 @@ public class JavaClientCodegen extends DefaultCodegen implements CodegenConfig {
this.localVariablePrefix = localVariablePrefix;
}
public void setSerializeBigDecimalAsString(boolean s) {
this.serializeBigDecimalAsString = s;
}
public Boolean getSerializableModel() {
return serializableModel;

View File

@ -14,6 +14,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#seriali
* minimum: {{minimum}}{{/minimum}}{{#maximum}}
* maximum: {{maximum}}{{/maximum}}
**/
{{#vendorExtensions.extraAnnotation}}{{vendorExtensions.extraAnnotation}}{{/vendorExtensions.extraAnnotation}}
@ApiModelProperty({{#required}}required = {{required}}, {{/required}}value = "{{{description}}}")
@JsonProperty("{{baseName}}")
public {{{datatypeWithEnum}}} {{getter}}() {

View File

@ -4,8 +4,6 @@ import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.java.JavaClientOptionsTest;
import io.swagger.codegen.languages.JavaInflectorServerCodegen;
import io.swagger.codegen.options.JavaInflectorServerOptionsProvider;
import io.swagger.codegen.options.JavaOptionsProvider;
import mockit.Expectations;
import mockit.Tested;
@ -50,6 +48,8 @@ public class JavaInflectorServerOptionsTest extends JavaClientOptionsTest {
times = 1;
clientCodegen.setFullJavaUtil(Boolean.valueOf(JavaInflectorServerOptionsProvider.FULL_JAVA_UTIL_VALUE));
times = 1;
clientCodegen.setSerializeBigDecimalAsString(true);
times = 1;
}};
}
}

View File

@ -38,6 +38,7 @@ public class JavaOptionsProvider implements OptionsProvider {
.put(CodegenConstants.SERIALIZABLE_MODEL, SERIALIZABLE_MODEL_VALUE)
.put(JavaClientCodegen.FULL_JAVA_UTIL, FULL_JAVA_UTIL_VALUE)
.put(CodegenConstants.LIBRARY, LIBRARY_VALUE)
.put(CodegenConstants.SERIALIZE_BIG_DECIMAL_AS_STRING, "true")
.build();
}