Unknown subtypes deserializiation decoupled from jackson version
This commit is contained in:
parent
4b06b1b6bc
commit
409bf29cd4
|
@ -27,8 +27,11 @@ import org.gcube.informationsystem.base.reference.Element;
|
||||||
import org.gcube.informationsystem.types.TypeMapper;
|
import org.gcube.informationsystem.types.TypeMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This is not used anymore.
|
||||||
|
* Keeping the class in case something is not solved
|
||||||
* @author Luca Frosini (ISTI - CNR)
|
* @author Luca Frosini (ISTI - CNR)
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class ElementDeserializer<ISM extends Element> extends StdDeserializer<ISM> {
|
public class ElementDeserializer<ISM extends Element> extends StdDeserializer<ISM> {
|
||||||
|
|
||||||
private static final long serialVersionUID = -2551569658316955137L;
|
private static final long serialVersionUID = -2551569658316955137L;
|
||||||
|
|
|
@ -23,9 +23,7 @@ import org.gcube.com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
||||||
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
|
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.gcube.com.fasterxml.jackson.databind.SerializationFeature;
|
import org.gcube.com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
import org.gcube.com.fasterxml.jackson.databind.module.SimpleModule;
|
|
||||||
import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode;
|
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.ObjectNode;
|
||||||
import org.gcube.com.fasterxml.jackson.databind.node.TextNode;
|
import org.gcube.com.fasterxml.jackson.databind.node.TextNode;
|
||||||
import org.gcube.informationsystem.base.reference.AccessType;
|
import org.gcube.informationsystem.base.reference.AccessType;
|
||||||
|
@ -82,7 +80,8 @@ public abstract class ElementMapper {
|
||||||
if(!Type.class.isAssignableFrom(clz)) {
|
if(!Type.class.isAssignableFrom(clz)) {
|
||||||
Class<Element> dummyClz = accessType.getDummyImplementationClass();
|
Class<Element> dummyClz = accessType.getDummyImplementationClass();
|
||||||
if(dummyClz != null) {
|
if(dummyClz != null) {
|
||||||
ElementMapper.registerSubtypes(clz, dummyClz);
|
// ElementMapper.registerSubtypes(clz, dummyClz);
|
||||||
|
ElementMapper.registerSubtype(dummyClz);
|
||||||
}else {
|
}else {
|
||||||
ElementMapper.registerSubtype(clz);
|
ElementMapper.registerSubtype(clz);
|
||||||
}
|
}
|
||||||
|
@ -115,14 +114,15 @@ public abstract class ElementMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <El extends Element> void registerSubtypes(Class<El> clz, Class<El> implementationClass) {
|
// This add the ElementDeserializer which has been deprecated thank to the fix in
|
||||||
String typeName = TypeMapper.getType(clz);
|
// public static <El extends Element> void registerSubtypes(Class<El> clz, Class<El> implementationClass) {
|
||||||
SimpleModule isModule = new SimpleModule(typeName);
|
// String typeName = TypeMapper.getType(clz);
|
||||||
isModule.addDeserializer(clz, new ElementDeserializer<>(clz, mapper));
|
// SimpleModule isModule = new SimpleModule(typeName);
|
||||||
mapper.registerModule(isModule);
|
// isModule.addDeserializer(clz, new ElementDeserializer<>(clz, mapper));
|
||||||
registerSubtype(implementationClass);
|
// mapper.registerModule(isModule);
|
||||||
}
|
// registerSubtype(implementationClass);
|
||||||
|
// }
|
||||||
|
|
||||||
public static <El extends Element> void registerSubtype(Class<El> clz) {
|
public static <El extends Element> void registerSubtype(Class<El> clz) {
|
||||||
String typeName = TypeMapper.getType(clz);
|
String typeName = TypeMapper.getType(clz);
|
||||||
|
@ -200,9 +200,9 @@ public abstract class ElementMapper {
|
||||||
return stringBuffer;
|
return stringBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static JsonNode setAvailableSuperclass(JsonNode jsonNode) {
|
protected static ObjectNode setTypeToBestAvailable(ObjectNode objectNode) {
|
||||||
String unknownType = jsonNode.get(Element.TYPE_PROPERTY).asText();
|
String unknownType = objectNode.get(Element.TYPE_PROPERTY).asText();
|
||||||
ArrayNode arrayNode = (ArrayNode) jsonNode.get(Element.SUPERTYPES_PROPERTY);
|
ArrayNode arrayNode = (ArrayNode) objectNode.get(Element.SUPERTYPES_PROPERTY);
|
||||||
|
|
||||||
String candidatedSupertype = null;
|
String candidatedSupertype = null;
|
||||||
for(int i = 0; i < arrayNode.size(); i++) {
|
for(int i = 0; i < arrayNode.size(); i++) {
|
||||||
|
@ -227,34 +227,67 @@ public abstract class ElementMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(candidatedSupertype!=null) {
|
if(candidatedSupertype!=null) {
|
||||||
if(!jsonNode.has(Element.EXPECTED_TYPE_PROPERTY)) {
|
if(!objectNode.has(Element.EXPECTED_TYPE_PROPERTY)) {
|
||||||
((ObjectNode) jsonNode).set(Element.EXPECTED_TYPE_PROPERTY, jsonNode.get(Element.TYPE_PROPERTY));
|
objectNode.set(Element.EXPECTED_TYPE_PROPERTY, objectNode.get(Element.TYPE_PROPERTY));
|
||||||
}
|
}
|
||||||
((ObjectNode) jsonNode).set(Element.TYPE_PROPERTY, new TextNode(candidatedSupertype));
|
objectNode.set(Element.TYPE_PROPERTY, new TextNode(candidatedSupertype));
|
||||||
((ObjectNode) jsonNode).remove(Element.SUPERTYPES_PROPERTY);
|
objectNode.remove(Element.SUPERTYPES_PROPERTY);
|
||||||
return jsonNode;
|
return objectNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuffer stringBuffer = getError(unknownType);
|
StringBuffer stringBuffer = getError(unknownType);
|
||||||
logger.trace("Unable to unmarshall {}. {}", jsonNode.toString(), stringBuffer.toString());
|
logger.trace("Unable to unmarshall {}. {}", objectNode.toString(), stringBuffer.toString());
|
||||||
throw new RuntimeException(stringBuffer.toString());
|
throw new RuntimeException(stringBuffer.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static JsonNode analizeFullJson(JsonNode jsonNode) {
|
protected static JsonNode analizeTypes(ObjectNode objectNode) {
|
||||||
String cls = jsonNode.get(Element.TYPE_PROPERTY).asText();
|
String cls = objectNode.get(Element.TYPE_PROPERTY).asText();
|
||||||
if(!knownTypes.containsKey(cls)) {
|
if(!knownTypes.containsKey(cls)) {
|
||||||
jsonNode = setAvailableSuperclass(jsonNode);
|
objectNode = setTypeToBestAvailable(objectNode);
|
||||||
}
|
}
|
||||||
Iterator<String> iterator = jsonNode.fieldNames();
|
Iterator<String> iterator = objectNode.fieldNames();
|
||||||
while(iterator.hasNext()) {
|
while(iterator.hasNext()) {
|
||||||
String fieldName = iterator.next();
|
String fieldName = iterator.next();
|
||||||
JsonNode jn = jsonNode.get(fieldName);
|
JsonNode jn = objectNode.get(fieldName);
|
||||||
if(jn.getNodeType() == JsonNodeType.OBJECT) {
|
switch (jn.getNodeType()) {
|
||||||
jn = analizeFullJson(jn);
|
case OBJECT:
|
||||||
((ObjectNode) jsonNode).set(fieldName, jn);
|
jn = analizeTypes((ObjectNode)jn);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARRAY:
|
||||||
|
jn = analizeTypes((ArrayNode) jn);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
objectNode.replace(fieldName, jn);
|
||||||
}
|
}
|
||||||
return jsonNode;
|
return objectNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static ArrayNode analizeTypes(ArrayNode arrayNode) {
|
||||||
|
ArrayNode ret = mapper.createArrayNode();
|
||||||
|
|
||||||
|
for(JsonNode jsonNode : arrayNode) {
|
||||||
|
|
||||||
|
switch (jsonNode.getNodeType()) {
|
||||||
|
case OBJECT:
|
||||||
|
jsonNode = analizeTypes((ObjectNode) jsonNode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARRAY:
|
||||||
|
jsonNode = analizeTypes((ArrayNode) jsonNode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.add(jsonNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -273,7 +306,7 @@ public abstract class ElementMapper {
|
||||||
return mapper.readValue(reader, clz);
|
return mapper.readValue(reader, clz);
|
||||||
} catch (JsonMappingException e) {
|
} catch (JsonMappingException e) {
|
||||||
JsonNode jsonNode = mapper.readTree(reader);
|
JsonNode jsonNode = mapper.readTree(reader);
|
||||||
jsonNode = analizeFullJson(jsonNode);
|
jsonNode = analizeTypes((ObjectNode) jsonNode);
|
||||||
return ElementMapper.unmarshal(clz, mapper.writeValueAsString(jsonNode));
|
return ElementMapper.unmarshal(clz, mapper.writeValueAsString(jsonNode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -294,7 +327,7 @@ public abstract class ElementMapper {
|
||||||
return mapper.readValue(stream, clz);
|
return mapper.readValue(stream, clz);
|
||||||
} catch (JsonMappingException e) {
|
} catch (JsonMappingException e) {
|
||||||
JsonNode jsonNode = mapper.readTree(stream);
|
JsonNode jsonNode = mapper.readTree(stream);
|
||||||
jsonNode = analizeFullJson(jsonNode);
|
jsonNode = analizeTypes((ObjectNode) jsonNode);
|
||||||
return ElementMapper.unmarshal(clz, mapper.writeValueAsString(jsonNode));
|
return ElementMapper.unmarshal(clz, mapper.writeValueAsString(jsonNode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,7 +347,7 @@ public abstract class ElementMapper {
|
||||||
return mapper.readValue(string, clz);
|
return mapper.readValue(string, clz);
|
||||||
} catch (JsonMappingException e) {
|
} catch (JsonMappingException e) {
|
||||||
JsonNode jsonNode = mapper.readTree(string);
|
JsonNode jsonNode = mapper.readTree(string);
|
||||||
jsonNode = analizeFullJson(jsonNode);
|
jsonNode = analizeTypes((ObjectNode) jsonNode);
|
||||||
return ElementMapper.unmarshal(clz, mapper.writeValueAsString(jsonNode));
|
return ElementMapper.unmarshal(clz, mapper.writeValueAsString(jsonNode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,7 +361,7 @@ public abstract class ElementMapper {
|
||||||
List<El> ret = new ArrayList<>();
|
List<El> ret = new ArrayList<>();
|
||||||
ArrayNode arrayNode = (ArrayNode) mapper.readTree(string);
|
ArrayNode arrayNode = (ArrayNode) mapper.readTree(string);
|
||||||
for(JsonNode jsonNode : arrayNode) {
|
for(JsonNode jsonNode : arrayNode) {
|
||||||
jsonNode = analizeFullJson(jsonNode);
|
jsonNode = analizeTypes((ObjectNode) jsonNode);
|
||||||
ret.add(ElementMapper.unmarshal(clz, mapper.writeValueAsString(jsonNode)));
|
ret.add(ElementMapper.unmarshal(clz, mapper.writeValueAsString(jsonNode)));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -344,7 +377,7 @@ public abstract class ElementMapper {
|
||||||
List<El> ret = new ArrayList<>();
|
List<El> ret = new ArrayList<>();
|
||||||
ArrayNode arrayNode = (ArrayNode) mapper.readTree(string);
|
ArrayNode arrayNode = (ArrayNode) mapper.readTree(string);
|
||||||
for(JsonNode jsonNode : arrayNode) {
|
for(JsonNode jsonNode : arrayNode) {
|
||||||
jsonNode = analizeFullJson(jsonNode);
|
jsonNode = analizeTypes((ObjectNode) jsonNode);
|
||||||
ret.add((El) ElementMapper.unmarshal(Element.class, mapper.writeValueAsString(jsonNode)));
|
ret.add((El) ElementMapper.unmarshal(Element.class, mapper.writeValueAsString(jsonNode)));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue