/** * */ package org.gcube.informationsystem.model.impl.relations; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import org.gcube.com.fasterxml.jackson.annotation.JsonIgnore; import org.gcube.com.fasterxml.jackson.annotation.JsonSetter; import org.gcube.com.fasterxml.jackson.annotation.JsonTypeName; import org.gcube.informationsystem.base.impl.relations.RelationElementImpl; import org.gcube.informationsystem.base.reference.Element; import org.gcube.informationsystem.model.reference.ERElement; import org.gcube.informationsystem.model.reference.entities.Entity; import org.gcube.informationsystem.model.reference.entities.Resource; import org.gcube.informationsystem.model.reference.properties.PropagationConstraint; import org.gcube.informationsystem.model.reference.properties.Property; import org.gcube.informationsystem.model.reference.relations.Relation; import org.gcube.informationsystem.serialization.ElementMapper; /** * @author Luca Frosini (ISTI - CNR) */ @JsonTypeName(value = Relation.NAME) public abstract class RelationImpl extends RelationElementImpl implements Relation { /** * */ private static final long serialVersionUID = -6249979476879235053L; protected List supertypes; protected String expectedtype; protected Map contexts; protected PropagationConstraint propagationConstraint; @JsonIgnore protected Map additionalProperties; /** * Used to allow to have an additional property starting with '_' or '@' */ protected final Set allowedAdditionalKeys; protected RelationImpl() { super(); this.additionalProperties = new HashMap<>(); this.allowedAdditionalKeys = new HashSet<>(); this.allowedAdditionalKeys.add(SUPERTYPES_PROPERTY); } protected RelationImpl(S source, T target, PropagationConstraint propagationConstraint) { this(); this.source = source; this.target = target; this.propagationConstraint = propagationConstraint; } @Override public List getSupertypes() { return this.supertypes; } @Override public String getExpectedtype() { return this.expectedtype; } public Map getContexts(){ return this.contexts; } @JsonSetter(value = ERElement.CONTEXTS_PROPERTY) protected void setContexts(Map contexts) { this.contexts = contexts; } @Override public PropagationConstraint getPropagationConstraint() { return this.propagationConstraint; } @Override public Map getAdditionalProperties() { return additionalProperties; } @Override public void setAdditionalProperties(Map additionalProperties) { this.additionalProperties = additionalProperties; } @Override public Object getAdditionalProperty(String key) { return additionalProperties.get(key); } @Override public void setAdditionalProperty(String key, Object value) { if (!allowedAdditionalKeys.contains(key)) { if (key.startsWith("_")) { return; } if (key.startsWith("@")) { return; } if (key.compareTo(PROPAGATION_CONSTRAINT_PROPERTY) == 0) { return; } if (key.compareTo(TARGET_PROPERTY) == 0) { return; } if (key.compareTo(SOURCE_PROPERTY) == 0) { return; } } /* Additional properties are not deserialized to the proper Property type. The first attempt was to try to write a specific deserializer but it fails. This fix the issue. */ try { if(value instanceof Map) { @SuppressWarnings("unchecked") Map map = (Map) value; if(map.containsKey(Element.TYPE_PROPERTY)) { String reserialized = ElementMapper.getObjectMapper().writeValueAsString(map); Property property = ElementMapper.unmarshal(Property.class, reserialized); value = property; } } }catch (Throwable e) { e.getMessage(); // Any type of error/exception must be catched } /* END of fix to properly deserialize Property types*/ this.additionalProperties.put(key, value); } }