org.openapitools.codegen.languages.JavaCXFExtServerCodegen Maven / Gradle / Ivy
/*
* Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright 2019 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.languages;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenParameter;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.SupportingFile;
import org.openapitools.codegen.languages.features.CXFExtServerFeatures;
import org.openapitools.codegen.utils.JsonCache;
import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.JsonCache.CacheException;
import org.openapitools.codegen.utils.JsonCache.Root.MergePolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.mifmif.common.regex.Generex;
import io.swagger.v3.oas.models.media.Schema;
/**
* An Apache CXF-based JAX-RS server with extended capabilities.
*
* @author Adrian Price, TIBCO Software Inc.
*/
public class JavaCXFExtServerCodegen extends JavaCXFServerCodegen implements CXFExtServerFeatures {
class CodegenVariable {
CodegenVariable parent;
String name;
String dataFormat;
String dataType;
String enumName;
Map allowableValues;
boolean isArray;
boolean isContainer;
boolean isListContainer;
boolean isMapContainer;
boolean isPrimitiveType;
CodegenVariable items;
Integer minItems;
int itemCount = 1;
String minimum;
String maximum;
boolean exclusiveMinimum;
boolean exclusiveMaximum;
Integer minLength;
Integer maxLength;
String pattern;
String setter;
String testDataPath;
int index;
Map varVendorExtensions;
private CodegenVariable() {
varVendorExtensions = new HashMap<>();
}
private CodegenVariable(CodegenVariable parent, CodegenOperation op, String testDataPath,
Map models) {
name = "response";
dataFormat = null;// op.dataFormat;
dataType = op.returnType;
enumName = null;// op.enumName;
allowableValues = null;// op.allowableValues;
isContainer = op.isListContainer || op.isMapContainer;
isListContainer = op.isListContainer;
isMapContainer = op.isMapContainer;
isPrimitiveType = op.returnTypeIsPrimitive;
minItems = null;// op.minItems;
minimum = null;// op.minimum;
maximum = null;// op.maximum;
exclusiveMinimum = false;// op.exclusiveMinimum;
exclusiveMaximum = false;// op.exclusiveMaximum;
minLength = null;// op.minLength;
maxLength = null;// op.maxLength;
pattern = null;// op.pattern;
setter = null;// op.getSetter();
varVendorExtensions = op.vendorExtensions;
init(parent, testDataPath, models);
if (op.isListContainer || op.isMapContainer) {
items = new CodegenVariable();
items.dataType = op.returnBaseType;
items.isPrimitiveType = op.returnTypeIsPrimitive;
items.name = "item";
// TODO: populate other fields?
items.init(this, testDataPath, models);
}
}
private CodegenVariable(CodegenVariable parent, CodegenParameter param, String testDataPath,
Map models) {
name = param.paramName;
dataFormat = param.dataFormat;
dataType = param.dataType;
enumName = param.enumName;
allowableValues = param.allowableValues;
isContainer = param.isContainer;
isListContainer = param.isListContainer;
isMapContainer = param.isMapContainer;
isPrimitiveType = param.isPrimitiveType;
minItems = param.minItems;
minimum = param.minimum;
maximum = param.maximum;
exclusiveMinimum = param.exclusiveMinimum;
exclusiveMaximum = param.exclusiveMaximum;
minLength = param.minLength;
maxLength = param.maxLength;
pattern = param.pattern;
setter = null;
varVendorExtensions = param.vendorExtensions;
init(parent, testDataPath, models);
items = param.items == null ? null : new CodegenVariable(this, param.items, null, models);
}
private CodegenVariable(CodegenVariable parent, CodegenProperty prop, String testDataPath,
Map models) {
name = prop.name;
dataFormat = prop.dataFormat;
dataType = prop.dataType;
enumName = prop.enumName;
allowableValues = prop.allowableValues;
isContainer = prop.isContainer;
isListContainer = prop.isListContainer;
isMapContainer = prop.isMapContainer;
isPrimitiveType = prop.isPrimitiveType;
minItems = prop.minItems;
minimum = prop.minimum;
maximum = prop.maximum;
exclusiveMinimum = prop.exclusiveMinimum;
exclusiveMaximum = prop.exclusiveMaximum;
minLength = prop.minLength;
maxLength = prop.maxLength;
pattern = prop.pattern;
setter = prop.getSetter();
varVendorExtensions = prop.vendorExtensions;
init(parent, testDataPath, models);
items = prop.items == null ? null : new CodegenVariable(this, prop.items, null, models);
}
void addTestData(Object value) {
JsonPointer ptr = getPointer(null, true, true);
if (!testDataCache.exists(ptr)) {
try {
testDataCache.set(ptr, value);
} catch (CacheException e) {
LOGGER.error("Unable to update test data cache for " + ptr, e);
}
}
}
private void appendPath(StringBuilder path, boolean includeIndexes) {
if (parent == null)
path.append(testDataPath);
else
parent.appendPath(path, includeIndexes);
if (!isListItem())
path.append('/').append(name);
if (includeIndexes && isIndexed())
path.append('/').append(index);
}
String getComponentType() {
return isArray ? dataType.substring(0, dataType.length() - 2) : (isContainer ? items : this).dataType;
}
private JsonPointer getPointer(String suffix, boolean includeIndexes, boolean includeLastIndex) {
StringBuilder path = new StringBuilder();
appendPath(path, includeIndexes);
if (includeIndexes && !includeLastIndex && isIndexed())
path.setLength(path.lastIndexOf("/"));
if (suffix != null)
path.append('/').append(suffix);
return JsonPointer.compile(path.toString());
}
private void init(CodegenVariable parent, String testDataPath, Map models) {
this.parent = parent;
this.isArray = dataType.endsWith("[]");
this.testDataPath = testDataPath;
CodegenModel cm = models.get(dataType);
if (cm != null && (cm.isArrayModel || cm.isMapModel)) {
this.isContainer = true;
this.isListContainer = cm.isArrayModel;
this.isMapContainer = cm.isMapModel;
this.items = new CodegenVariable();
this.items.name = "item";
this.items.dataType = cm.additionalPropertiesType;
this.items.init(this, testDataPath, models);
}
try {
if ((isArray || isContainer) && testDataControlCache != null)
this.itemCount = testDataControlCache.getInt(getPointer("testItemCount", false, false), 1);
} catch (CacheException e) {
LOGGER.error("Error accessing test data control cache", e);
}
}
private boolean isIndexed() {
return isListContainer || isArray && !dataType.equals("byte[]");
}
private boolean isListItem() {
return parent != null && parent.isListContainer;
}
int size() {
return loadTestDataFromFile ? testDataCache.size(getPointer(null, true, false)) : 0;
}
@Override
public String toString() {
return "CodegenVariable [name=" + name + ", dataType=" + dataType + ", dataFormat=" + dataFormat
+ ", isArray=" + isArray + ", isContainer=" + isContainer + ", isListContainer=" + isListContainer
+ ", isMapContainer=" + isMapContainer + ", isPrimitiveType=" + isPrimitiveType + ", testDataPath="
+ testDataPath + ", enumName=" + enumName + ", allowableValues=" + allowableValues + ", minItems="
+ minItems + ", itemCount=" + itemCount + ", minimum=" + minimum + ", maximum=" + maximum
+ ", exclusiveMinimum=" + exclusiveMinimum + ", exclusiveMaximum=" + exclusiveMaximum
+ ", minLength=" + minLength + ", maxLength=" + maxLength + ", pattern=" + pattern + ", setter="
+ setter + ", vendorExtensions=" + varVendorExtensions + "]";
}
}
private static final Logger LOGGER = LoggerFactory.getLogger(JavaCXFExtServerCodegen.class);
private static final String INDENT = " ";
// SimpleDateFormat is not thread-safe, and may not be stored in a static field unless stored by ThreadLocal.
// It's not enough to add a ThreadLocal at the usage site.
@SuppressWarnings("squid:S5164")
private static final ThreadLocal ISO8601_DATE_FORMAT = ThreadLocal.withInitial(() ->
{
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
f.setTimeZone(TimeZone.getTimeZone("UTC"));
return f;
});
// SimpleDateFormat is not thread-safe, and may not be stored in a static field unless stored by ThreadLocal.
// It's not enough to add a ThreadLocal at the usage site.
@SuppressWarnings("squid:S5164")
private static final ThreadLocal ISO8601_DATETIME_FORMAT = ThreadLocal.withInitial(() ->
{
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.getDefault());
f.setTimeZone(TimeZone.getTimeZone("UTC"));
return f;
});
private static final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
private static final long MIN_DATE;
private static final long MAX_DATE;
private static final String NL = System.lineSeparator();
private static final Collection DATE_TYPES = Arrays.asList("Date", "DateTime", "OffsetDateTime",
"LocalDateTime", "LocalDate");
static {
long minDate = 0;
long maxDate = 0;
try {
minDate = ISO8601_DATETIME_FORMAT.get().parse("1970-01-01T00:00:00Z").getTime();
maxDate = ISO8601_DATETIME_FORMAT.get().parse("2099-12-31T23:59:59Z").getTime();
} catch (ParseException e) {
// Won't happen with the values provided.
}
MIN_DATE = minDate;
MAX_DATE = maxDate;
}
private Map REGEX_GENERATORS = new HashMap<>();
protected boolean generateOperationBody = false;
protected boolean loadTestDataFromFile = false;
protected boolean supportMultipleSpringServices = false;
protected JsonCache testDataCache = null;
protected JsonCache testDataControlCache = null;
protected File testDataFile = null;
protected File testDataControlFile = null;
protected String localVariablePrefix = "";
public JavaCXFExtServerCodegen() {
super();
embeddedTemplateDir = templateDir = JAXRS_TEMPLATE_DIRECTORY_NAME + File.separator + "cxf-ext";
cliOptions.add(CliOption.newBoolean(SUPPORT_MULTIPLE_SPRING_SERVICES,
"Support generation of Spring services from multiple specifications"));
cliOptions.add(CliOption.newBoolean(GENERATE_OPERATION_BODY, "Generate fully functional operation bodies"));
cliOptions.add(CliOption.newBoolean(LOAD_TEST_DATA_FROM_FILE, "Load test data from a generated JSON file"));
cliOptions.add(CliOption.newString(TEST_DATA_FILE, "JSON file to contain generated test data"));
cliOptions.add(CliOption.newString(TEST_DATA_CONTROL_FILE, "JSON file to control test data generation"));
}
private void appendArrayValue(StringBuilder buffer, String indent, CodegenOperation op, CodegenVariable var,
String localVar, Collection localVars, Map models) {
if (var.dataType.equals("byte[]")) {
// Byte arrays are represented as Base64-encoded strings.
appendByteArrayValue(buffer, indent, op, var, localVar, localVars, models);
} else {
boolean isPrimitiveType = var.isPrimitiveType && !"Object".equals(var.items.dataType);
int itemCount = Math.max(var.itemCount, var.minItems == null ? 1 : Math.max(1, var.minItems));
if (!loadTestDataFromFile) {
buffer.append("new ").append(var.getComponentType());
if (isPrimitiveType)
buffer.append("[] {");
else
buffer.append('[').append(itemCount).append("];");
}
var.index = var.size();
for (int i = var.index; i < itemCount; i++) {
if (isPrimitiveType) {
// We don't need a local variable for a primitive value
appendValue(buffer, indent, op, var.items, localVar, localVars, models);
if (i < itemCount - 1 && !loadTestDataFromFile)
buffer.append(", ");
} else {
String itemVar = appendLocalVariable(buffer, indent, op, var.items, localVars, models);
if (!loadTestDataFromFile) {
buffer.append(NL).append(indent).append(localVar).append('[').append(i).append("] = ")
.append(itemVar).append(';');
}
}
var.index++;
}
var.index = 0;
if (isPrimitiveType && !loadTestDataFromFile)
buffer.append("};");
}
}
private void appendByteArrayValue(StringBuilder buffer, String indent, CodegenOperation op, CodegenVariable var,
String localVar, Collection localVars, Map models) {
if (!loadTestDataFromFile)
buffer.append('"');
short min = var == null || var.minimum == null ? Byte.MIN_VALUE : Byte.parseByte(var.minimum);
short max = var == null || var.maximum == null ? Byte.MAX_VALUE : Byte.parseByte(var.maximum);
short exclusiveMin = (short) (var != null && var.exclusiveMinimum ? 1 : 0);
short inclusiveMax = (short) (var == null || !var.exclusiveMaximum ? 1 : 0);
int itemCount = 0;
if (var != null) {
itemCount = Math.max(var.itemCount, var.minItems == null ? 1 : Math.max(1, var.minItems));
}
byte[] randomBytes = new byte[itemCount];
for (int i = 0; i < itemCount; i++)
randomBytes[i] = (byte) (min + exclusiveMin + ((max + inclusiveMax - min - exclusiveMin) * Math.random()));
String randomBytesBase64 = Base64.getEncoder().encodeToString(randomBytes);
if (loadTestDataFromFile && var != null)
var.addTestData(randomBytesBase64);
else
buffer.append('"');
}
private void appendListValue(StringBuilder buffer, String indent, CodegenOperation op, CodegenVariable var,
String localVar, Collection localVars, Map models) {
op.imports.add("List");
if (!loadTestDataFromFile) {
op.imports.add("ArrayList");
buffer.append("new ArrayList<");
if (supportJava6)
buffer.append(var.dataType);
buffer.append(">();");
}
var.index = var.size();
int itemCount = Math.max(var.itemCount, var.minItems == null ? 1 : Math.max(1, var.minItems));
for (int i = var.index; i < itemCount; i++) {
if (var.isPrimitiveType && !"Object".equals(var.items.dataType)) {
// We don't need a local variable for a primitive value
if (!loadTestDataFromFile)
buffer.append(NL).append(indent).append(localVar).append(".add(");
appendValue(buffer, indent, op, var.items, localVar, localVars, models);
} else {
String itemVar = appendLocalVariable(buffer, indent, op, var.items, localVars, models);
if (!loadTestDataFromFile)
buffer.append(NL).append(indent).append(localVar).append(".add(").append(itemVar);
}
if (!loadTestDataFromFile)
buffer.append(");");
var.index++;
}
var.index = 0;
}
/**
* Declares and initialises a local variable of the specified type.
*
* @param buffer
* @param indent
* @param op
* @param var
* @param localVars
* @param models
*
* @return localVar
with a numeric suffix if necessary to ensure uniqueness.
*/
private String appendLocalVariable(StringBuilder buffer, String indent, CodegenOperation op, CodegenVariable var,
Collection localVars, Map models) {
// Ensure that we're using a unique local variable name (to avoid typing and overwriting conflicts).
String localVar = localVariablePrefix + var.name;
for (int i = 2; localVars.contains(localVar); i++)
localVar = localVariablePrefix + var.name + i;
localVars.add(localVar);
if (!loadTestDataFromFile)
buffer.append(NL).append(indent).append(var.dataType).append(' ').append(localVar).append(" = ");
appendValue(buffer, indent, op, var, localVar, localVars, models);
if (!loadTestDataFromFile)
appendSemicolon(buffer);
return localVar;
}
private void appendMapValue(StringBuilder buffer, String indent, CodegenOperation op, CodegenVariable var,
String localVar, Collection localVars, Map models) {
op.imports.add("Map");
if (!loadTestDataFromFile) {
op.imports.add("HashMap");
buffer.append("new HashMap<");
if (supportJava6)
buffer.append("String, ").append(var.dataType);
buffer.append(">();");
}
var.index = var.size();
int itemCount = Math.max(var.itemCount, var.minItems == null ? 1 : Math.max(1, var.minItems));
for (int i = var.index; i < itemCount; i++) {
// Map entries need a random key (the default value for var.items.name is "items").
var.items.name = generateRandomString(null);
if (var.isPrimitiveType) {
// We don't need a local variable for a primitive value
if (!loadTestDataFromFile) {
buffer.append(NL).append(indent).append(localVar).append(".put(").append(var.items.name)
.append(", ");
}
appendValue(buffer, indent, op, var.items, localVar, localVars, models);
} else {
String itemVar = appendLocalVariable(buffer, indent, op, var.items, localVars, models);
if (!loadTestDataFromFile)
buffer.append(localVar).append(".put(\"").append(var.items.name).append("\", ").append(itemVar);
}
if (!loadTestDataFromFile)
buffer.append(");");
var.index++;
}
}
private void appendObjectValue(StringBuilder buffer, String indent, CodegenOperation op, CodegenVariable var,
String localVar, Collection localVars, Map models) {
if ("Object".equals(var.dataType)) {
// Jackson can't serialize java.lang.Object, so we'll provide an empty JSON ObjectNode instead.
if (loadTestDataFromFile)
var.addTestData(JsonNodeFactory.instance.objectNode());
else
buffer.append("JsonNodeFactory.instance.objectNode();");
} else {
if (needToImport(var.dataType))
op.imports.add(var.dataType);
if (!loadTestDataFromFile)
buffer.append("new ").append(var.dataType).append("();");
appendPropertyAssignments(buffer, indent, op, var, localVar, localVars, models);
}
}
private void appendPropertyAssignments(StringBuilder buffer, String indent, CodegenOperation op,
CodegenVariable parent, String localVar, Collection localVars, Map models) {
CodegenModel cm = models.get(parent.dataType);
if (cm != null) { // TODO: handle isArrayModel and isMapModel
for (CodegenProperty cp : cm.allVars) {
CodegenVariable var = new CodegenVariable(parent, cp, null, models);
if (var.isContainer || !var.isPrimitiveType) {
String containerVar = appendLocalVariable(buffer, indent, op, var, localVars, models);
if (!loadTestDataFromFile) {
buffer.append(NL).append(indent).append(localVar).append('.').append(var.setter).append('(')
.append(containerVar);
}
} else {
// No need to use a local variable for types which can be initialised with a single expression.
if (!loadTestDataFromFile)
buffer.append(NL).append(indent).append(localVar).append('.').append(var.setter).append('(');
appendValue(buffer, indent, op, var, localVar, localVars, models);
}
if (!loadTestDataFromFile)
buffer.append(");");
}
}
}
private void appendRandomBoolean(StringBuilder buffer, CodegenOperation op, CodegenVariable var) {
boolean randomBoolean = Math.random() > 0.5;
if (loadTestDataFromFile)
var.addTestData(randomBoolean);
else
buffer.append(randomBoolean);
}
private void appendRandomByte(StringBuilder buffer, CodegenOperation op, CodegenVariable var) {
if (!appendRandomEnum(buffer, op, var)) {
// NOTE: use short to hold byte values, to avoid numeric overflow.
short min = var == null || var.minimum == null ? Byte.MIN_VALUE : Byte.parseByte(var.minimum);
short max = var == null || var.maximum == null ? Byte.MAX_VALUE : Byte.parseByte(var.maximum);
short exclusiveMin = (short) (var != null && var.exclusiveMinimum ? 1 : 0);
short inclusiveMax = (short) (var == null || !var.exclusiveMaximum ? 1 : 0);
byte randomByte = (byte) (min + exclusiveMin + ((max + inclusiveMax - min - exclusiveMin) * Math.random()));
if (loadTestDataFromFile)
var.addTestData(randomByte);
else
buffer.append(String.format(Locale.getDefault(), "(byte)%0#2x", randomByte));
}
}
private void appendRandomChar(StringBuilder buffer, CodegenOperation op, CodegenVariable var) {
if (!appendRandomEnum(buffer, op, var)) {
// TODO: consider whether to broaden the default range.
// NOTE: char is unsigned, so there's no overflow issue in computing (max - min).
char min = var == null || var.minimum == null ? 'a' : var.minimum.charAt(0);
char max = var == null || var.maximum == null ? 'z' : var.maximum.charAt(0);
char exclusiveMin = (char) (var != null && var.exclusiveMinimum ? 1 : 0);
char inclusiveMax = (char) (var == null || !var.exclusiveMaximum ? 1 : 0);
char randomChar = (char) (min + exclusiveMin + ((max + inclusiveMax - min - exclusiveMin) * Math.random()));
if (loadTestDataFromFile)
var.addTestData(randomChar);
else
buffer.append(String.format(Locale.getDefault(), "'%c'", randomChar));
}
}
private void appendRandomDate(StringBuilder buffer, CodegenOperation op, CodegenVariable var) {
if (!appendRandomEnum(buffer, op, var)) {
long minDate = MIN_DATE;
long maxDate = MAX_DATE;
if (var != null) {
DateFormat df = var.dataFormat.equals("date-time") ? ISO8601_DATETIME_FORMAT.get() : ISO8601_DATE_FORMAT.get();
String isoFormat = var.dataFormat.equals("date-time") ? "date-time" : "full-date";
if (var.minimum != null) {
try {
minDate = df.parse(var.minimum).getTime();
} catch (ParseException e) {
// Ignore, use MIN_DATE.
LOGGER.warn("Could not parse minimum {} value for '{}/{}' as an ISO-8601 {}: {}",
var.dataFormat, op.operationId, var.name, isoFormat, var.minimum);
}
}
if (var.maximum != null) {
try {
maxDate = df.parse(var.maximum).getTime();
} catch (ParseException e) {
// Ignore, use MAX_DATE.
LOGGER.warn("Could not parse maximum {} value for '{}/{}' as an ISO-8601 {}: {}",
var.dataFormat, op.operationId, var.name, isoFormat, var.minimum);
}
}
}
// NOTE: use BigDecimal to hold long values, to avoid numeric overflow.
BigDecimal minLong = new BigDecimal(minDate);
BigDecimal maxLong = new BigDecimal(maxDate);
BigDecimal exclusiveMinLong = new BigDecimal(var != null && var.exclusiveMinimum ? 1 : 0);
BigDecimal inclusiveMaxLong = new BigDecimal(var == null || !var.exclusiveMaximum ? 1 : 0);
long randomDateLong = minLong.add(exclusiveMinLong).add(maxLong.add(inclusiveMaxLong).subtract(minLong)
.subtract(exclusiveMinLong).multiply(new BigDecimal(Math.random()))).longValue();
// If it's just a date without a time, round downwards to the nearest day.
if ("date".equals(var.dataFormat))
randomDateLong = (randomDateLong % MILLIS_PER_DAY) * MILLIS_PER_DAY;
// NOTE: By default Jackson serializes Date as long milliseconds since epoch date, but that conflicts with
// the OpenAPI 2.0/3.0 specs, which mandates the ISO-8601 full-date or date-time formats. Accordingly, date
// and date-time fields are annotated with @JsonFormat to specify the appropriate ISO format.
if (loadTestDataFromFile) {
Date randomDate = new Date(randomDateLong);
switch (var.dataFormat) {
case "date":
var.addTestData(ISO8601_DATE_FORMAT.get().format(randomDate));
break;
case "date-time":
var.addTestData(ISO8601_DATETIME_FORMAT.get().format(randomDate));
break;
}
} else {
buffer.append("new Date(").append(randomDateLong).append(')');
}
}
}
private void appendRandomDouble(StringBuilder buffer, CodegenOperation op, CodegenVariable var) {
if (!appendRandomEnum(buffer, op, var)) {
// NOTE: use BigDecimal to hold double values, to avoid numeric overflow.
BigDecimal min = new BigDecimal(
var == null || var.minimum == null ? Long.MIN_VALUE : Double.parseDouble(var.minimum));
BigDecimal max = new BigDecimal(
var == null || var.maximum == null ? Long.MAX_VALUE : Double.parseDouble(var.maximum));
BigDecimal exclusiveMin = new BigDecimal(var != null && var.exclusiveMinimum ? 1 : 0);
BigDecimal inclusiveMax = new BigDecimal(var == null || !var.exclusiveMaximum ? 1 : 0);
BigDecimal randomBigDecimal = min.add(exclusiveMin).add(max.add(inclusiveMax).subtract(min)
.subtract(exclusiveMin).multiply(new BigDecimal(String.valueOf(Math.random()))));
if (loadTestDataFromFile)
var.addTestData(randomBigDecimal);
else
buffer.append(randomBigDecimal.toString()).append('D');
}
}
private boolean appendRandomEnum(StringBuilder buffer, CodegenOperation op, CodegenVariable var) {
if (var != null && var.allowableValues != null) {
List> values = (List>) var.allowableValues.get("values");
int i = (int) (values.size() * Math.random());
Object randomEnum = values.get(i);
boolean usingEnumLiteral = false;
String definingClass = (String) var.varVendorExtensions.get("x-defining-class");
if (definingClass != null) {
@SuppressWarnings("unchecked")
List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy