in schema-converter/json-schema-converter/src/main/java/org/apache/rocketmq/schema/json/JsonSchemaData.java [648:816]
private Schema toConnectSchema(org.everit.json.schema.Schema jsonSchema, Integer version, boolean forceOptional) {
if (jsonSchema == null) {
return null;
}
final SchemaBuilder builder;
if (jsonSchema instanceof BooleanSchema) {
builder = SchemaBuilder.bool();
} else if (jsonSchema instanceof NumberSchema) {
NumberSchema numberSchema = (NumberSchema) jsonSchema;
String type = (String) numberSchema.getUnprocessedProperties().get(CONNECT_TYPE_PROP);
if (type == null) {
builder = numberSchema.requiresInteger() ? SchemaBuilder.int64() : SchemaBuilder.float64();
} else {
switch (type) {
case CONNECT_TYPE_INT8:
builder = SchemaBuilder.int8();
break;
case CONNECT_TYPE_INT16:
builder = SchemaBuilder.int16();
break;
case CONNECT_TYPE_INT32:
builder = SchemaBuilder.int32();
break;
case CONNECT_TYPE_INT64:
builder = SchemaBuilder.int64();
break;
case CONNECT_TYPE_FLOAT32:
builder = SchemaBuilder.float32();
break;
case CONNECT_TYPE_FLOAT64:
builder = SchemaBuilder.float64();
break;
case CONNECT_TYPE_BYTES:
builder = SchemaBuilder.bytes();
break;
default:
throw new IllegalArgumentException("Unsupported type " + type);
}
}
} else if (jsonSchema instanceof StringSchema) {
String type = (String) jsonSchema.getUnprocessedProperties().get(CONNECT_TYPE_PROP);
builder = CONNECT_TYPE_BYTES.equals(type) ? SchemaBuilder.bytes() : SchemaBuilder.string();
} else if (jsonSchema instanceof EnumSchema) {
EnumSchema enumSchema = (EnumSchema) jsonSchema;
builder = SchemaBuilder.string();
builder.parameter(JSON_TYPE_ENUM, ""); // JSON enums have no name, use empty string as placeholder
for (Object enumObj : enumSchema.getPossibleValuesAsList()) {
String enumSymbol = enumObj.toString();
builder.parameter(JSON_TYPE_ENUM_PREFIX + enumSymbol, enumSymbol);
}
} else if (jsonSchema instanceof CombinedSchema) {
CombinedSchema combinedSchema = (CombinedSchema) jsonSchema;
CombinedSchema.ValidationCriterion criterion = combinedSchema.getCriterion();
String name = null;
if (criterion == CombinedSchema.ONE_CRITERION || criterion == CombinedSchema.ANY_CRITERION) {
name = JSON_TYPE_ONE_OF;
} else if (criterion == CombinedSchema.ALL_CRITERION) {
return allOfToConnectSchema(combinedSchema, version, forceOptional);
} else {
throw new IllegalArgumentException("Unsupported criterion: " + criterion);
}
if (combinedSchema.getSubschemas().size() == 2) {
boolean foundNullSchema = false;
org.everit.json.schema.Schema nonNullSchema = null;
for (org.everit.json.schema.Schema subSchema : combinedSchema.getSubschemas()) {
if (subSchema instanceof NullSchema) {
foundNullSchema = true;
} else {
nonNullSchema = subSchema;
}
}
if (foundNullSchema) {
return toConnectSchema(nonNullSchema, version, true);
}
}
int index = 0;
builder = SchemaBuilder.struct().name(name);
for (org.everit.json.schema.Schema subSchema : combinedSchema.getSubschemas()) {
if (subSchema instanceof NullSchema) {
builder.optional();
} else {
String subFieldName = name + ".field." + index++;
builder.field(subFieldName, toConnectSchema(subSchema, null, true));
}
}
} else if (jsonSchema instanceof ArraySchema) {
ArraySchema arraySchema = (ArraySchema) jsonSchema;
org.everit.json.schema.Schema itemsSchema = arraySchema.getAllItemSchema();
if (itemsSchema == null) {
throw new ConnectException("Array schema did not specify the items type");
}
String type = (String) arraySchema.getUnprocessedProperties().get(CONNECT_TYPE_PROP);
if (CONNECT_TYPE_MAP.equals(type) && itemsSchema instanceof ObjectSchema) {
ObjectSchema objectSchema = (ObjectSchema) itemsSchema;
builder = SchemaBuilder.map(toConnectSchema(objectSchema.getPropertySchemas().get(KEY_FIELD)),
toConnectSchema(objectSchema.getPropertySchemas().get(VALUE_FIELD))
);
} else {
builder = SchemaBuilder.array(toConnectSchema(itemsSchema));
}
} else if (jsonSchema instanceof ObjectSchema) {
ObjectSchema objectSchema = (ObjectSchema) jsonSchema;
String type = (String) objectSchema.getUnprocessedProperties().get(CONNECT_TYPE_PROP);
if (CONNECT_TYPE_MAP.equals(type)) {
builder = SchemaBuilder.map(
SchemaBuilder.string().build(),
toConnectSchema(objectSchema.getSchemaOfAdditionalProperties())
);
} else {
builder = SchemaBuilder.struct();
Map<String, org.everit.json.schema.Schema> properties = objectSchema.getPropertySchemas();
SortedMap<Integer, Map.Entry<String, org.everit.json.schema.Schema>> sortedMap = new TreeMap<>();
for (Map.Entry<String, org.everit.json.schema.Schema> property : properties.entrySet()) {
org.everit.json.schema.Schema subSchema = property.getValue();
Integer index = (Integer) subSchema.getUnprocessedProperties().get(CONNECT_INDEX_PROP);
if (index == null) {
index = sortedMap.size();
}
sortedMap.put(index, property);
}
for (Map.Entry<String, org.everit.json.schema.Schema> property : sortedMap.values()) {
String subFieldName = property.getKey();
org.everit.json.schema.Schema subSchema = property.getValue();
boolean isFieldOptional = config.useOptionalForNonRequiredProperties()
&& !objectSchema.getRequiredProperties().contains(subFieldName);
builder.field(subFieldName, toConnectSchema(subSchema, null, isFieldOptional));
}
}
} else if (jsonSchema instanceof ReferenceSchema) {
ReferenceSchema refSchema = (ReferenceSchema) jsonSchema;
return toConnectSchema(refSchema.getReferredSchema(), version, forceOptional);
} else {
throw new ConnectException("Unsupported schema type " + jsonSchema.getClass().getName());
}
String title = jsonSchema.getTitle();
if (title != null) {
builder.name(title);
}
Integer connectVersion = (Integer) jsonSchema.getUnprocessedProperties()
.get(CONNECT_VERSION_PROP);
if (connectVersion != null) {
builder.version(connectVersion);
} else if (version != null) {
builder.version(version);
}
String description = jsonSchema.getDescription();
if (description != null) {
builder.doc(description);
}
Map<String, String> parameters = (Map<String, String>) jsonSchema.getUnprocessedProperties()
.get(CONNECT_PARAMETERS_PROP);
if (parameters != null) {
builder.parameters(parameters);
}
if (jsonSchema.hasDefaultValue()) {
JsonNode jsonNode = OBJECT_MAPPER.convertValue(jsonSchema.getDefaultValue(), JsonNode.class);
builder.defaultValue(toConnectData(builder.build(), jsonNode));
}
if (!forceOptional) {
builder.required();
}
Schema result = builder.build();
return result;
}