Для моего проекта у меня есть несколько JSON схем, и мне нужно преобразовать их в JSON во время выполнения.
Для анализа схемы у меня есть 2 класса:
public class SchemaToTemplate {
public static JsonObject convert(JsonObject schema) {
if(isEmpty(schema)) return new JsonObject();
if(!isNode(schema)) throw new RuntimeException("The given schema is malformed. Its root should be a valid JsonObject");
if(!hasChildren(schema)) return new JsonObject();
return parseParent(schema);
}
private static JsonObject parseParent(JsonObject schemaNode) {
if(hasChildren(schemaNode)) {
return parseParent(schemaNode, new JsonObject(), getChildrenNames(schemaNode));
}
return new JsonObject();
}
private static JsonObject parseChild(JsonObject schemaParent, JsonObject instanceParent, String key) {
final JsonObject schemaChildNode = getChild(schemaParent, key);
if(isEmpty(schemaChildNode)) return instanceParent;
if(isNode(schemaChildNode)) {
add(instanceParent, key, parseParent(schemaChildNode));
}else{
add(instanceParent, key, getValue(schemaChildNode));
}
return instanceParent;
}
private static JsonObject parseParent(JsonObject schemaParent, JsonObject instanceParent, List<String> childrenNames) {
if(childrenNames.isEmpty()) {
return instanceParent;
}
final String childName = childrenNames.remove(0);
if(isSelector(childName)) {
return parseSelector(schemaParent, instanceParent, childName);
}
final JsonObject newInstanceParent = parseChild(schemaParent, instanceParent, childName);
return parseParent(schemaParent, newInstanceParent, childrenNames);
}
private static JsonObject parseSelector(JsonObject schemaParent, JsonObject instanceParent, String key) {
final JsonArray array = schemaParent.getAsJsonArray(key);
final JsonObject selector = new JsonObject();
instanceParent.add("selector_" + key, selector);
return parseArray(array, selector);
}
private static JsonObject parseArray(JsonArray schemaArray, JsonObject instanceNode) {
if(schemaArray.size() == 0) {
return instanceNode;
}
final JsonObject item = schemaArray.remove(0).getAsJsonObject();
final JsonObject newInstanceNode = parseChild(item, instanceNode, getName(item));
return parseArray(schemaArray, newInstanceNode);
}
//Util
private static final String PROPERTIES = "properties";
private static final String VALUE = "default";
private static final String NAME = "title";
private static final String TYPE = "type";
private static final String TYPE_OBJECT = "object";
private static final JsonObject EMPTY = new JsonObject();
private static boolean isEmpty(JsonObject element) {
return element.equals(EMPTY);
}
public static String getName(JsonObject element) {
return SchemaUtil.getValue(element, NAME);
}
public static String getValue(JsonObject element) {
return SchemaUtil.getValue(element, VALUE);
}
public static boolean isNode(JsonObject element) {
return SchemaUtil.getValue(element, TYPE).equals(TYPE_OBJECT);
}
private static boolean hasChildren(JsonObject element) {
return !isEmpty(getChildrenContainer(element));
}
public static List<String> getChildrenNames(JsonObject element) {
return Lists.newArrayList(getChildrenContainer(element).keySet());
}
public static JsonObject getChild(JsonObject element, String key) {
return getChildrenContainer(element).get(key).getAsJsonObject();
}
private static JsonObject getChildrenContainer(JsonObject element) {
return getChildObject(element, PROPERTIES);
}
private static void add(JsonObject element, String key, JsonObject value){
element.add(key, value);
}
private static void add(JsonObject element, String key, String value){
element.addProperty(key, value);
}
}
И класс утилит:
public class SchemaUtil {
public static JsonObject getChildObject(JsonObject json, String key) {
return json.get(key).getAsJsonObject();
}
public static String getValue(JsonObject json, String key) {
return json.get(key).getAsJsonPrimitive().getAsString();
}
public static JsonObject replaceProperty(JsonObject json, String key, String value) {
json.remove(key);
json.addProperty(key, value);
return json;
}
public static List<String> getKeys(JsonObject json) {
return Lists.newArrayList(json.keySet());
}
public static boolean isSelector(String key) {
return key.equals("oneOf") ||
key.equals("anyOf") ||
key.equals("allOf");
}
}
Работает для всех схем, кроме тех, что , которые содержат "oneOf"
Fe
{
"type": "object",
"title": "Simple case",
"properties": {
"soaRS": {
"$id": "/properties/simpleCase",
"title": "Case Data",
"type": "object",
"oneOf": [
{
"title": "Simple Case 1",
"type": "object",
"properties": {
"zah": {
"$id": "/properties/data/properties/simpleCase/properties/parameter",
"type": "string",
"title": "Parameter 1",
"default": "PA",
"examples": [
"PA"
]
}
}
},
{
"title": "Simple case 2",
"type": "object",
"properties": {
"zah": {
"$id": "/properties/data/properties/simpleCase/properties/parameter3",
"type": "string",
"title": "Parameter 3",
"default": "BBB",
"examples": [
"AI"
]
}
}
}
]
}
}
}
Не могли бы вы указать мне направление, в котором я иду / делаю неправильно. Пытался бороться с разбором уже один день и до сих пор не знаю, как разобрать такой случай
Заранее спасибо!