144 lines
4.7 KiB
Java
144 lines
4.7 KiB
Java
/**
|
|
*
|
|
*/
|
|
package org.gcube.informationsystem.serialization;
|
|
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import org.gcube.com.fasterxml.jackson.core.JsonFactory;
|
|
import org.gcube.com.fasterxml.jackson.core.JsonParser;
|
|
import org.gcube.com.fasterxml.jackson.core.JsonProcessingException;
|
|
import org.gcube.com.fasterxml.jackson.core.TreeNode;
|
|
import org.gcube.com.fasterxml.jackson.databind.DeserializationContext;
|
|
import org.gcube.com.fasterxml.jackson.databind.JavaType;
|
|
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
|
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
|
|
import org.gcube.com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
|
import org.gcube.com.fasterxml.jackson.databind.exc.InvalidTypeIdException;
|
|
import org.gcube.com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
|
|
import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode;
|
|
import org.gcube.com.fasterxml.jackson.databind.node.JsonNodeType;
|
|
import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode;
|
|
import org.gcube.com.fasterxml.jackson.databind.node.TextNode;
|
|
import org.gcube.informationsystem.base.reference.AccessType;
|
|
import org.gcube.informationsystem.base.reference.Element;
|
|
import org.gcube.informationsystem.types.TypeMapper;
|
|
|
|
/**
|
|
* @author Luca Frosini (ISTI - CNR)
|
|
*/
|
|
public class ElementDeserializer<ISM extends Element> extends StdDeserializer<ISM> {
|
|
|
|
private static final long serialVersionUID = -2551569658316955137L;
|
|
|
|
protected final ObjectMapper mapper;
|
|
|
|
public ElementDeserializer(Class<ISM> clz, ObjectMapper mapper) {
|
|
super(clz);
|
|
this.mapper = mapper;
|
|
}
|
|
|
|
@Override
|
|
public Object deserializeWithType(JsonParser jp,
|
|
DeserializationContext ctxt, TypeDeserializer typeDeserializer)
|
|
throws IOException {
|
|
|
|
TreeNode treeNode = jp.readValueAsTree();
|
|
JsonFactory jsonFactory = mapper.getFactory();
|
|
JsonParser clonedJP = jsonFactory.createParser(treeNode.toString());
|
|
clonedJP.nextToken();
|
|
try {
|
|
return typeDeserializer.deserializeTypedFromAny(clonedJP, ctxt);
|
|
} catch (InvalidTypeIdException e) {
|
|
|
|
Class<?> candidatedSuperClass = _valueClass;
|
|
List<TextNode> toBeKeepSuperClasses = new ArrayList<>();
|
|
|
|
ObjectNode objectNode = (ObjectNode) treeNode;
|
|
|
|
try {
|
|
JsonNode superClassesTreeNode = objectNode
|
|
.get(Element.SUPERCLASSES_PROPERTY);
|
|
if (superClassesTreeNode != null
|
|
&& superClassesTreeNode.isArray()) {
|
|
ArrayNode arrayNode = (ArrayNode) superClassesTreeNode;
|
|
for (int i = 0; i < arrayNode.size(); i++) {
|
|
try {
|
|
JsonNode jsonNode = arrayNode.get(i);
|
|
JsonNodeType jsonNodeType = jsonNode.getNodeType();
|
|
switch (jsonNodeType) {
|
|
case STRING:
|
|
String superClass = jsonNode.asText();
|
|
try {
|
|
Enum.valueOf(AccessType.class,
|
|
superClass.toUpperCase());
|
|
// It is one of the BaseType. Looking for
|
|
// another type because the base one
|
|
continue;
|
|
} catch (Exception ex) {
|
|
// can continue discovery
|
|
}
|
|
|
|
JavaType javaType = typeDeserializer
|
|
.getTypeIdResolver().typeFromId(ctxt,
|
|
superClass);
|
|
if (javaType == null) {
|
|
TextNode textNode = new TextNode(superClass);
|
|
toBeKeepSuperClasses.add(textNode);
|
|
continue;
|
|
}
|
|
Class<?> clz = javaType.getRawClass();
|
|
if (candidatedSuperClass.isAssignableFrom(clz)) {
|
|
// clz is a subClass so that is a candidate
|
|
candidatedSuperClass = clz;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
} catch (Exception ex) {
|
|
// Trying the next one
|
|
}
|
|
|
|
}
|
|
arrayNode.removeAll();
|
|
arrayNode.addAll(toBeKeepSuperClasses);
|
|
}
|
|
|
|
} catch (Exception ex) {
|
|
// Using already known candidatedSuperClass
|
|
}
|
|
|
|
|
|
if(candidatedSuperClass == _valueClass){
|
|
// No suitable class found Using Dummy Implementation
|
|
candidatedSuperClass = AccessType.getAccessType(_valueClass).getDummyImplementationClass();
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
String typeName = TypeMapper.getType((Class<? extends Element>) candidatedSuperClass);
|
|
objectNode.set(Element.CLASS_PROPERTY, new TextNode(typeName));
|
|
JsonParser jsonParser = jsonFactory.createParser(objectNode
|
|
.toString());
|
|
jsonParser.nextToken();
|
|
return typeDeserializer.deserializeTypedFromAny(jsonParser, ctxt);
|
|
|
|
}catch (Exception e) {
|
|
throw e;
|
|
}
|
|
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
@Override
|
|
public ISM deserialize(JsonParser jp, DeserializationContext ctxt)
|
|
throws IOException, JsonProcessingException {
|
|
TypeDeserializer typeDeserializer = ctxt.getFactory().findTypeDeserializer(ctxt.getConfig(), ctxt.constructType(Element.class));
|
|
return (ISM) deserializeWithType(jp, ctxt, typeDeserializer);
|
|
}
|
|
|
|
}
|