Skip to content

Commit

Permalink
Updated return types to JsonNode in ExampleJsonGenerator.java
Browse files Browse the repository at this point in the history
  • Loading branch information
dipeshsingh253 committed Oct 9, 2023
1 parent 6e0c6bf commit 1de7f6f
Showing 1 changed file with 53 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.*;
import com.fasterxml.jackson.databind.util.RawValue;
import io.swagger.v3.core.util.Json;
import io.swagger.v3.oas.models.media.Schema;
Expand All @@ -14,12 +14,7 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.*;

import static io.github.stavshamir.springwolf.configuration.properties.SpringwolfConfigConstants.SPRINGWOLF_SCHEMA_EXAMPLE_GENERATOR;

Expand All @@ -29,25 +24,25 @@
public class ExampleJsonGenerator implements ExampleGenerator {

private static final ObjectMapper objectMapper = Json.mapper();
private static final String DEFAULT_NUMBER_EXAMPLE = "1.1";
private static final String DEFAULT_INTEGER_EXAMPLE = "0";
private static final Double DEFAULT_NUMBER_EXAMPLE = 1.1;
private static final Integer DEFAULT_INTEGER_EXAMPLE = 0;
private static final String DEFAULT_BOOLEAN_EXAMPLE = "true";
private static final String DEFAULT_DATE_EXAMPLE = "\"2015-07-20\"";
private static final String DEFAULT_DATE_TIME_EXAMPLE = "\"2015-07-20T15:49:04-07:00\"";
private static final String DEFAULT_PASSWORD_EXAMPLE = "\"string-password\"";
private static final String DEFAULT_BYTE_EXAMPLE = "\"YmFzZTY0LWV4YW1wbGU=\"";
private static final String DEFAULT_DATE_EXAMPLE = "2015-07-20";
private static final String DEFAULT_DATE_TIME_EXAMPLE = "2015-07-20T15:49:04-07:00";
private static final String DEFAULT_PASSWORD_EXAMPLE = "string-password";
private static final String DEFAULT_BYTE_EXAMPLE = "YmFzZTY0LWV4YW1wbGU=";
private static final String DEFAULT_BINARY_EXAMPLE =
"\"0111010001100101011100110111010000101101011000100110100101101110011000010110010001111001\"";
private static final String DEFAULT_STRING_EXAMPLE = "\"string\"";
private static final String DEFAULT_EMAIL_EXAMPLE = "\"[email protected]\"";
private static final String DEFAULT_UUID_EXAMPLE = "\"3fa85f64-5717-4562-b3fc-2c963f66afa6\"";
"0111010001100101011100110111010000101101011000100110100101101110011000010110010001111001";
private static final String DEFAULT_STRING_EXAMPLE = "string";
private static final String DEFAULT_EMAIL_EXAMPLE = "[email protected]";
private static final String DEFAULT_UUID_EXAMPLE = "3fa85f64-5717-4562-b3fc-2c963f66afa6";

private static String DEFAULT_UNKNOWN_SCHEMA_EXAMPLE(String type) {
return "\"unknown schema type: " + type + "\"";
return "unknown schema type: " + type;
}

private static String DEFAULT_UNKNOWN_SCHEMA_STRING_EXAMPLE(String format) {
return "\"unknown string schema format: " + format + "\"";
return "unknown string schema format: " + format;
}

@Override
Expand All @@ -65,13 +60,13 @@ static String buildSchema(Schema schema, Map<String, Schema> definitions) {
return buildSchemaInternal(schema, definitions, new HashSet<>()).toString();
}

private static ObjectNode buildSchemaInternal(Schema schema, Map<String, Schema> definitions, Set<Schema> visited) {
ObjectNode exampleValue = ExampleJsonGenerator.getExampleValueFromSchemaAnnotation(schema);
private static JsonNode buildSchemaInternal(Schema schema, Map<String, Schema> definitions, Set<Schema> visited) {
JsonNode exampleValue = ExampleJsonGenerator.getExampleValueFromSchemaAnnotation(schema);
if (exampleValue != null) {
return exampleValue;
}

ObjectNode schemaNode = objectMapper.createObjectNode();
JsonNode schemaNode = objectMapper.createObjectNode();

String ref = schema.get$ref();
if (ref != null) {
Expand All @@ -84,53 +79,40 @@ private static ObjectNode buildSchemaInternal(Schema schema, Map<String, Schema>
}

String type = schema.getType();
switch (type) {
case "array":
// Handle array schema
ObjectNode itemsNode = ExampleJsonGenerator.handleArraySchema(schema, definitions, visited);
schemaNode.set("items", itemsNode); // Set the "items" property
break;
case "boolean":
schemaNode.textNode(DEFAULT_BOOLEAN_EXAMPLE);
break;
case "integer":
schemaNode.textNode(DEFAULT_INTEGER_EXAMPLE);
break;
case "number":
schemaNode.textNode(DEFAULT_NUMBER_EXAMPLE);
break;
case "object":
// Handle object schema
ObjectNode objectNode = ExampleJsonGenerator.handleObject(schema, definitions, visited);
schemaNode.set("object", objectNode); // Set the "properties" property
break;
case "string":
// Handle string schema
schemaNode.textNode(ExampleJsonGenerator.handleStringSchema(schema));
break;
default:
schemaNode.put("example", DEFAULT_UNKNOWN_SCHEMA_EXAMPLE(type));
}
schemaNode = switch (type) {
case "array" -> ExampleJsonGenerator.handleArraySchema(schema, definitions, visited); // Handle array schema
case "boolean" -> BooleanNode.valueOf(Boolean.parseBoolean(DEFAULT_BOOLEAN_EXAMPLE));
case "integer" -> new IntNode(DEFAULT_INTEGER_EXAMPLE);
case "number" -> new DoubleNode(DEFAULT_NUMBER_EXAMPLE);
case "object" -> ExampleJsonGenerator.handleObject(schema, definitions, visited); // Handle object schema
case "string" -> JsonNodeFactory.instance.textNode(handleStringSchema(schema)); // Handle string schema
default -> JsonNodeFactory.instance.textNode(DEFAULT_UNKNOWN_SCHEMA_EXAMPLE(type));};

return schemaNode;
}

private static ObjectNode getExampleValueFromSchemaAnnotation(Schema schema) {
private static JsonNode getExampleValueFromSchemaAnnotation(Schema schema) {
Object exampleValue = schema.getExample();

// schema is a map of properties from a nested object, whose example cannot be inferred
if (exampleValue == null) {
return null;
}

// Create an ObjectNode to hold the example JSON
ObjectNode exampleNode = objectMapper.createObjectNode();
JsonNode exampleNode = objectMapper.createObjectNode();

// Handle special types (i.e. map) with custom @Schema annotation and specified example value
Object additionalProperties = schema.getAdditionalProperties();
if (additionalProperties instanceof StringSchema) {
StringSchema additionalPropertiesSchema = (StringSchema) additionalProperties;
Object exampleValueString = additionalPropertiesSchema.getExample();
if (exampleValueString != null) {
exampleNode.set((String) exampleValueString, objectMapper.convertValue(exampleValue, JsonNode.class));
try {
exampleNode = objectMapper.readTree(exampleValueString.toString());
} catch (JsonProcessingException ex) {
log.debug("Unable to convert example to JSON: %s".formatted(exampleValue.toString()), ex);
}
return exampleNode;
}
}
Expand All @@ -141,42 +123,43 @@ private static ObjectNode getExampleValueFromSchemaAnnotation(Schema schema) {
}

// exampleValue is represented in their native type
if (exampleValue instanceof Boolean || exampleValue instanceof Number) {
exampleNode.set("example", objectMapper.convertValue(exampleValue, JsonNode.class));
/*
JsonNode node = objectMapper.createObjectNode();
node = objectMapper.valueToTree("false");
return (ObjectNode) node;
*/

return exampleNode;
if (exampleValue instanceof Boolean) {
return (Boolean) exampleValue ? BooleanNode.TRUE : BooleanNode.FALSE;
} else if (exampleValue instanceof Number) {
double doubleValue = ((Number) exampleValue).doubleValue();

// Check if it's an integer (whole number)
if (doubleValue == (int) doubleValue) {
return new IntNode((int) doubleValue);
}

return new DoubleNode(doubleValue);
}

try {
// exampleValue (i.e. OffsetDateTime) is represented as string
exampleNode.set("example", objectMapper.convertValue(exampleValue.toString(), JsonNode.class));
exampleNode = JsonNodeFactory.instance.textNode(exampleValue.toString());
} catch (IllegalArgumentException ex) {
log.debug("Unable to convert example to JSON: %s".formatted(exampleValue.toString()), ex);
}

return exampleNode;
}

private static ObjectNode handleArraySchema(Schema schema, Map<String, Schema> definitions, Set<Schema> visited) {

ObjectNode objectNode = objectMapper.createObjectNode();
private static ArrayNode handleArraySchema(Schema schema, Map<String, Schema> definitions, Set<Schema> visited) {
ArrayNode arrayNode = JsonNodeFactory.instance.arrayNode();

List<ObjectNode> list = Arrays.asList(buildSchemaInternal(schema.getItems(), definitions, visited));
List<JsonNode> list = Arrays.asList(buildSchemaInternal(schema.getItems(), definitions, visited));

objectNode.set("array", objectMapper.valueToTree(list));
for (JsonNode node : list) arrayNode.add(node);

return objectNode;
return arrayNode;
}

private static String handleStringSchema(Schema schema) {
String firstEnumValue = getFirstEnumValue(schema);
if (firstEnumValue != null) {
return "\"" + firstEnumValue + "\"";
return firstEnumValue;
}

String format = schema.getFormat();
Expand Down Expand Up @@ -208,7 +191,7 @@ private static String getFirstEnumValue(Schema schema) {
return null;
}

private static ObjectNode handleObject(Schema schema, Map<String, Schema> definitions, Set<Schema> visited) {
private static JsonNode handleObject(Schema schema, Map<String, Schema> definitions, Set<Schema> visited) {

Map<String, Schema> properties = schema.getProperties();
if (properties != null) {
Expand Down

0 comments on commit 1de7f6f

Please sign in to comment.