I have this JSON schema:
{
"name":{
"first":{
"attributeValue":"firstName",
"attributeType":1,
"dataType":1
},
"last":{
"attributeValue":"lastName",
"attributeType":1,
"dataType":1
}
},
"age":{
"attributeValue":"age",
"attributeType":1,
"dataType":2
},
"address":{
"number":{
"attributeValue":"number",
"attributeType":1,
"dataType":1
},
"street":{
"attributeValue":"street",
"attributeType":1,
"dataType":1
},
"city":{
"attributeValue":"city",
"attributeType":1,
"dataType":1
},
"country":{
"attributeValue":"country",
"attributeType":1,
"dataType":1
}
},
"fullName":{
"attributeValue":"#firstName.concat(' ').concat(#lastName)",
"attributeType":2,
"dataType":1
}
}
In here, each node that has attributeValue
, dataType
and attributeType
nodes are called Field
. Every other parent node is a handler. "name" is a handler which has "first" and "last" fields. But for age, since there is no parent key, there should be a handler created named "age" and a field "age" should be added to that. Handlers can have handlers. Handlers have fields in them.
Here is the Handler
object representation:
public interface Handler<T> {
void addField(Field field);
void addHandler(Handler handler);
String getName();
List<Field> getFields();
T handle(T target);
}
Here is the field representation:
public interface Field<T> {
void setValue(String value);
T getField();
String getFieldName();
}
Now I need to parse the json schema and return a list of handlers:
private List<Handler> parseJsonSchema(Handler handler, String jsonSchema) throws JSONMapperException {
List<Handler> handlerList = new ArrayList<>();
boolean isParentLeaf = false;
Field<ObjectNode> objectNodeField = null;
try {
JsonNode rootNode = objectMapper.readTree(jsonSchema);
Iterator<Map.Entry<String, JsonNode>> childrenIterator = rootNode.fields();
while (childrenIterator.hasNext()) {
Map.Entry<String, JsonNode> field = childrenIterator.next();
System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
if (field.getValue().has("attributeValue") && field.getValue().has("attributeType")
&& field.getValue().has("dataType")) {
if (handler == null) {
handler = jsonNodeHandlerFactory.create(field.getKey());
isParentLeaf = true;
}
JsonNode valueNode = field.getValue();
//String fieldName = valueNode.get("attributeValue").toString();
String fieldName = field.getKey();
String dataType = valueNode.get("dataType").toString();
switch (dataType) {
case "1":
objectNodeField = dataFieldFactory.createStringField(fieldName);
break;
case "2":
objectNodeField = dataFieldFactory.createIntField(fieldName);
break;
case "3":
objectNodeField = dataFieldFactory.createBooleanField(fieldName);
break;
default:
break;
}
handler.addField(objectNodeField);
if(isParentLeaf) {
handlerList.add(handler);
handler =null;
}
} else {
handler = jsonNodeHandlerFactory.create(field.getKey());
List<Handler> handlers = parseJsonSchema(handler, field.getValue().toString());
for (Handler handler1 : handlers) {
if(handler != null) { //means we already have a handler and we've come into another handler
handler.addHandler(handler1);
handlerList.add(handler);
} else {
handlerList.add(handler1);
}
}
handler = null;
}
if ((handler != null && handler.getFields().size() == rootNode.size())) {
handlerList.add(handler);
}
}
} catch (IOException e) {
logger.error(JSON_SCHEMA_PARSE_EXCEPTION, e);
throw new JSONMapperException(JSON_SCHEMA_PARSE_EXCEPTION);
}
return handlerList;
}
But it overrides handlers, when there are handlers within handlers. Also, it looks pretty clumsy with too many null
assignments and if
checks. Is there a better way to do what this method is already doing? That is, return the schema as a list of handlers.