diff --git a/src/main/java/org/gcube/informationsystem/base/impl/ElementImpl.java b/src/main/java/org/gcube/informationsystem/base/impl/ElementImpl.java index 46b730e..8b7e4f1 100644 --- a/src/main/java/org/gcube/informationsystem/base/impl/ElementImpl.java +++ b/src/main/java/org/gcube/informationsystem/base/impl/ElementImpl.java @@ -22,8 +22,9 @@ public class ElementImpl implements Element { */ private static final long serialVersionUID = 7338083489551084860L; - private List supertypes; - + protected List supertypes; + protected String expectedtype; + @Override public String getTypeName() { return TypeUtility.getTypeName(this.getClass()); @@ -34,6 +35,11 @@ public class ElementImpl implements Element { return this.supertypes; } + @Override + public String getExpectedtype() { + return this.expectedtype; + } + @Override public String toString(){ StringWriter stringWriter = new StringWriter(); diff --git a/src/main/java/org/gcube/informationsystem/base/reference/Element.java b/src/main/java/org/gcube/informationsystem/base/reference/Element.java index acb65fb..7bd7e8b 100644 --- a/src/main/java/org/gcube/informationsystem/base/reference/Element.java +++ b/src/main/java/org/gcube/informationsystem/base/reference/Element.java @@ -21,7 +21,7 @@ import org.gcube.informationsystem.utils.Version; * @author Luca Frosini (ISTI - CNR) */ @Abstract -@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY }) +@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY, Element.EXPECTED_TYPE_PROPERTY }) @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = Element.TYPE_PROPERTY) // @JsonTypeIdResolver(ElementTypeIdResolver.class) @TypeMetadata(name = Element.NAME, description = "This is the base type for Element", version = Version.MINIMAL_VERSION_STRING) @@ -34,6 +34,13 @@ public interface Element extends Serializable { public static final String SUPERTYPES_PROPERTY = "supertypes"; + /* + * This is the key used by the deserializer to indicate the expected type + * which instead has been deserialized using the best available + * supertype + */ + public static final String EXPECTED_TYPE_PROPERTY = "expectedtype"; + /** * DateTime Pattern to be used to serialize Dates in every element */ @@ -46,4 +53,8 @@ public interface Element extends Serializable { @JsonGetter(value = SUPERTYPES_PROPERTY) public List getSupertypes(); + @JsonInclude(Include.NON_EMPTY) + @JsonGetter(value = EXPECTED_TYPE_PROPERTY) + public String getExpectedtype(); + } diff --git a/src/main/java/org/gcube/informationsystem/base/reference/IdentifiableElement.java b/src/main/java/org/gcube/informationsystem/base/reference/IdentifiableElement.java index a06b618..a2c65ff 100644 --- a/src/main/java/org/gcube/informationsystem/base/reference/IdentifiableElement.java +++ b/src/main/java/org/gcube/informationsystem/base/reference/IdentifiableElement.java @@ -12,7 +12,7 @@ import org.gcube.informationsystem.model.reference.properties.Metadata; * * @author Luca Frosini (ISTI - CNR) */ -@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY, IdentifiableElement.ID_PROPERTY, IdentifiableElement.METADATA_PROPERTY }) +@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY, Element.EXPECTED_TYPE_PROPERTY, IdentifiableElement.ID_PROPERTY, IdentifiableElement.METADATA_PROPERTY }) public interface IdentifiableElement extends Element { public static final String ID_PROPERTY = "id"; diff --git a/src/main/java/org/gcube/informationsystem/base/reference/entities/EntityElement.java b/src/main/java/org/gcube/informationsystem/base/reference/entities/EntityElement.java index 0e61ff9..27755c6 100644 --- a/src/main/java/org/gcube/informationsystem/base/reference/entities/EntityElement.java +++ b/src/main/java/org/gcube/informationsystem/base/reference/entities/EntityElement.java @@ -18,7 +18,7 @@ import org.gcube.informationsystem.utils.Version; */ @Abstract @JsonIgnoreProperties(ignoreUnknown=true) -@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY, IdentifiableElement.ID_PROPERTY, IdentifiableElement.METADATA_PROPERTY }) +@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY, Element.EXPECTED_TYPE_PROPERTY, IdentifiableElement.ID_PROPERTY, IdentifiableElement.METADATA_PROPERTY }) //@JsonDeserialize(as=EntityElementImpl.class) Do not uncomment to manage subclasses @TypeMetadata(name = EntityElement.NAME, description = "This is the base type for any EntityElement", version = Version.MINIMAL_VERSION_STRING) @Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION) diff --git a/src/main/java/org/gcube/informationsystem/model/reference/ERElement.java b/src/main/java/org/gcube/informationsystem/model/reference/ERElement.java index 8defc21..09a0e50 100644 --- a/src/main/java/org/gcube/informationsystem/model/reference/ERElement.java +++ b/src/main/java/org/gcube/informationsystem/model/reference/ERElement.java @@ -16,7 +16,7 @@ import org.gcube.informationsystem.base.reference.IdentifiableElement; * * @author Luca Frosini (ISTI - CNR) */ -@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY, IdentifiableElement.ID_PROPERTY, IdentifiableElement.METADATA_PROPERTY, ERElement.CONTEXTS_PROPERTY }) +@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY, Element.EXPECTED_TYPE_PROPERTY, IdentifiableElement.ID_PROPERTY, IdentifiableElement.METADATA_PROPERTY, ERElement.CONTEXTS_PROPERTY }) public interface ERElement extends IdentifiableElement { /** diff --git a/src/main/java/org/gcube/informationsystem/model/reference/entities/Entity.java b/src/main/java/org/gcube/informationsystem/model/reference/entities/Entity.java index 9763c92..66c7189 100644 --- a/src/main/java/org/gcube/informationsystem/model/reference/entities/Entity.java +++ b/src/main/java/org/gcube/informationsystem/model/reference/entities/Entity.java @@ -19,7 +19,7 @@ import org.gcube.informationsystem.utils.Version; * @author Luca Frosini (ISTI - CNR) */ @Abstract -@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY, IdentifiableElement.ID_PROPERTY, IdentifiableElement.METADATA_PROPERTY, ERElement.CONTEXTS_PROPERTY }) +@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY, Element.EXPECTED_TYPE_PROPERTY, IdentifiableElement.ID_PROPERTY, IdentifiableElement.METADATA_PROPERTY, ERElement.CONTEXTS_PROPERTY }) //@JsonDeserialize(as=EntityImpl.class) Do not uncomment to manage subclasses @TypeMetadata(name = Entity.NAME, description = "This is the base type for any Entity", version = Version.MINIMAL_VERSION_STRING) @Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION) diff --git a/src/main/java/org/gcube/informationsystem/model/reference/entities/Resource.java b/src/main/java/org/gcube/informationsystem/model/reference/entities/Resource.java index fb5876e..7742dd8 100644 --- a/src/main/java/org/gcube/informationsystem/model/reference/entities/Resource.java +++ b/src/main/java/org/gcube/informationsystem/model/reference/entities/Resource.java @@ -29,7 +29,7 @@ import org.gcube.informationsystem.utils.Version; */ @Abstract @JsonIgnoreProperties(ignoreUnknown=true) -@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY, IdentifiableElement.ID_PROPERTY, IdentifiableElement.METADATA_PROPERTY, ERElement.CONTEXTS_PROPERTY, Resource.CONSISTS_OF_PROPERTY, Resource.IS_RELATED_TO_PROPERTY }) +@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY, Element.EXPECTED_TYPE_PROPERTY, IdentifiableElement.ID_PROPERTY, IdentifiableElement.METADATA_PROPERTY, ERElement.CONTEXTS_PROPERTY, Resource.CONSISTS_OF_PROPERTY, Resource.IS_RELATED_TO_PROPERTY }) // @JsonDeserialize(as=ResourceImpl.class) Do not uncomment to manage subclasses @ResourceSchema( facets={ diff --git a/src/main/java/org/gcube/informationsystem/model/reference/properties/Property.java b/src/main/java/org/gcube/informationsystem/model/reference/properties/Property.java index df56b62..fbcd89c 100644 --- a/src/main/java/org/gcube/informationsystem/model/reference/properties/Property.java +++ b/src/main/java/org/gcube/informationsystem/model/reference/properties/Property.java @@ -26,7 +26,7 @@ import org.gcube.informationsystem.utils.Version; * @author Luca Frosini (ISTI - CNR) */ // @JsonIgnoreProperties(ignoreUnknown=true) -@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY }) +@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY, Element.EXPECTED_TYPE_PROPERTY }) @JsonDeserialize(as=PropertyImpl.class) @TypeMetadata(name = Property.NAME, description = "This is the base type for any Property", version = Version.MINIMAL_VERSION_STRING) @Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION) diff --git a/src/main/java/org/gcube/informationsystem/model/reference/relations/Relation.java b/src/main/java/org/gcube/informationsystem/model/reference/relations/Relation.java index b196108..8d6d494 100644 --- a/src/main/java/org/gcube/informationsystem/model/reference/relations/Relation.java +++ b/src/main/java/org/gcube/informationsystem/model/reference/relations/Relation.java @@ -35,7 +35,7 @@ import org.gcube.informationsystem.utils.Version; * https://wiki.gcube-system.org/gcube/Facet_Based_Resource_Model#Relation */ @Abstract -@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY, IdentifiableElement.ID_PROPERTY, IdentifiableElement.METADATA_PROPERTY, ERElement.CONTEXTS_PROPERTY, Relation.PROPAGATION_CONSTRAINT_PROPERTY }) +@JsonPropertyOrder({ Element.TYPE_PROPERTY, Element.SUPERTYPES_PROPERTY, Element.EXPECTED_TYPE_PROPERTY, IdentifiableElement.ID_PROPERTY, IdentifiableElement.METADATA_PROPERTY, ERElement.CONTEXTS_PROPERTY, Relation.PROPAGATION_CONSTRAINT_PROPERTY }) // @JsonDeserialize(as=RelationImpl.class) Do not uncomment to manage subclasses @TypeMetadata(name = Relation.NAME, description = "This is the base type for any Relation", version = Version.MINIMAL_VERSION_STRING) @Change(version = Version.MINIMAL_VERSION_STRING, description = Version.MINIMAL_VERSION_DESCRIPTION) diff --git a/src/main/java/org/gcube/informationsystem/serialization/ElementDeserializer.java b/src/main/java/org/gcube/informationsystem/serialization/ElementDeserializer.java index 308a993..2ff0edb 100644 --- a/src/main/java/org/gcube/informationsystem/serialization/ElementDeserializer.java +++ b/src/main/java/org/gcube/informationsystem/serialization/ElementDeserializer.java @@ -57,6 +57,9 @@ public class ElementDeserializer extends StdDeserializer toBeKeepSuperClasses = new ArrayList<>(); ObjectNode objectNode = (ObjectNode) treeNode; + if(!objectNode.has(Element.EXPECTED_TYPE_PROPERTY)) { + objectNode.set(Element.EXPECTED_TYPE_PROPERTY, objectNode.get(Element.TYPE_PROPERTY)); + } try { JsonNode superClassesTreeNode = objectNode diff --git a/src/main/java/org/gcube/informationsystem/serialization/ElementMapper.java b/src/main/java/org/gcube/informationsystem/serialization/ElementMapper.java index 0ebf0cd..c5bf200 100644 --- a/src/main/java/org/gcube/informationsystem/serialization/ElementMapper.java +++ b/src/main/java/org/gcube/informationsystem/serialization/ElementMapper.java @@ -204,22 +204,20 @@ public abstract class ElementMapper { String unknownType = jsonNode.get(Element.TYPE_PROPERTY).asText(); ArrayNode arrayNode = (ArrayNode) jsonNode.get(Element.SUPERTYPES_PROPERTY); - // TODO save original class and superclasses - - String candidatedSuperClass = null; + String candidatedSupertype = null; for(int i = 0; i < arrayNode.size(); i++) { - String superClass = arrayNode.get(i).asText(); - if(knownTypes.containsKey(superClass)) { - candidatedSuperClass = superClass; + String superType = arrayNode.get(i).asText(); + if(knownTypes.containsKey(superType)) { + candidatedSupertype = superType; try { // Checking if it is one of the base type. In some cases we need to use dummy // implementation - AccessType accessType = Enum.valueOf(AccessType.class, superClass.toUpperCase()); + AccessType accessType = AccessType.getAccessType(superType); // It is one of the BaseType. // Looking if we need to set the dummy implementation class if(accessType.getDummyImplementationClass()!=null) { // This should not happen because the type has been assigned already to the dummy class. - candidatedSuperClass = accessType.getDummyImplementationClass().getSimpleName(); + candidatedSupertype = accessType.getDummyImplementationClass().getSimpleName(); } } catch(Exception ex) { // can continue discovery @@ -228,8 +226,12 @@ public abstract class ElementMapper { } } - if(candidatedSuperClass!=null) { - ((ObjectNode) jsonNode).set(Element.TYPE_PROPERTY, new TextNode(candidatedSuperClass)); + if(candidatedSupertype!=null) { + if(!jsonNode.has(Element.EXPECTED_TYPE_PROPERTY)) { + ((ObjectNode) jsonNode).set(Element.EXPECTED_TYPE_PROPERTY, jsonNode.get(Element.TYPE_PROPERTY)); + } + ((ObjectNode) jsonNode).set(Element.TYPE_PROPERTY, new TextNode(candidatedSupertype)); + ((ObjectNode) jsonNode).remove(Element.SUPERTYPES_PROPERTY); return jsonNode; } @@ -314,7 +316,7 @@ public abstract class ElementMapper { JsonNode jsonNode = mapper.readTree(string); jsonNode = analizeFullJson(jsonNode); return ElementMapper.unmarshal(clz, mapper.writeValueAsString(jsonNode)); - } + } } public static List unmarshalList(Class clz, String string) diff --git a/src/main/java/org/gcube/informationsystem/types/impl/TypeImpl.java b/src/main/java/org/gcube/informationsystem/types/impl/TypeImpl.java index a9d10bb..561af15 100644 --- a/src/main/java/org/gcube/informationsystem/types/impl/TypeImpl.java +++ b/src/main/java/org/gcube/informationsystem/types/impl/TypeImpl.java @@ -62,7 +62,8 @@ public class TypeImpl implements Type { protected UUID uuid; protected Metadata metadata; - private List supertypes; + protected List supertypes; + protected String expectedtype; protected String name; protected String description; @@ -301,4 +302,10 @@ public class TypeImpl implements Type { public List getSupertypes() { return this.supertypes; } + + @Override + public String getExpectedtype() { + return this.expectedtype; + } + } diff --git a/src/main/java/org/gcube/informationsystem/types/impl/properties/PropertyDefinitionImpl.java b/src/main/java/org/gcube/informationsystem/types/impl/properties/PropertyDefinitionImpl.java index cbd51c4..fd25bbe 100644 --- a/src/main/java/org/gcube/informationsystem/types/impl/properties/PropertyDefinitionImpl.java +++ b/src/main/java/org/gcube/informationsystem/types/impl/properties/PropertyDefinitionImpl.java @@ -36,7 +36,8 @@ public final class PropertyDefinitionImpl implements PropertyDefinition { public final static String URI_REGEX = null; public final static String URL_REGEX = null; - private List supertypes; + protected List supertypes; + protected String expectedtype; private String name= ""; private String description= ""; @@ -294,4 +295,10 @@ public final class PropertyDefinitionImpl implements PropertyDefinition { public List getSupertypes() { return this.supertypes; } + + @Override + public String getExpectedtype() { + return this.expectedtype; + } + }