diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java index 2910c89..b264f2d 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java @@ -46,6 +46,12 @@ import org.gcube.informationsystem.resourceregistry.types.TypesCache; import org.gcube.informationsystem.resourceregistry.utils.HeaderOrient; import org.gcube.informationsystem.resourceregistry.utils.HeaderUtility; import org.gcube.informationsystem.resourceregistry.utils.Utility; +import org.gcube.informationsystem.types.PropertyTypeName; +import org.gcube.informationsystem.types.PropertyTypeName.BaseType; +import org.gcube.informationsystem.types.impl.properties.PropertyDefinitionImpl; +import org.gcube.informationsystem.types.reference.Type; +import org.gcube.informationsystem.types.reference.entities.FacetType; +import org.gcube.informationsystem.types.reference.properties.PropertyDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -453,8 +459,6 @@ public abstract class ElementManagement { public abstract String reallyGetAll(boolean polymorphic) throws ResourceRegistryException; - public abstract void sanityCheck() throws SchemaViolationException, ResourceRegistryException; - public String all(boolean polymorphic) throws ResourceRegistryException { ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal(); try { @@ -1042,4 +1046,101 @@ public abstract class ElementManagement { } } + protected String getNotNullErrorMessage(String fieldName) { + StringBuffer stringBuffer = new StringBuffer(); + stringBuffer.append("The type "); + stringBuffer.append(typeName); + stringBuffer.append(" defines the fields "); + stringBuffer.append(fieldName); + stringBuffer.append(" as not nullable. Null or no value has been provided instead."); + return stringBuffer.toString(); + } + + protected String getMandatoryErrorMessage(String fieldName) { + StringBuffer stringBuffer = new StringBuffer(); + stringBuffer.append("The type "); + stringBuffer.append(typeName); + stringBuffer.append(" defines the fields "); + stringBuffer.append(fieldName); + stringBuffer.append(" as mandatory but no value has been provided."); + return stringBuffer.toString(); + } + + /* + * Get not only the properties defined in the type but also the properties + * defined in the super types + */ + protected Set getAllProperties() throws SchemaException, ResourceRegistryException{ + TypesCache typesCache = TypesCache.getInstance(); + CachedType cachedType = typesCache.getCachedType(typeName); + Type type = (FacetType) cachedType.getType(); + + Set definedProperties = type.getProperties(); + + Set cachedSuperTypes = new HashSet<>(); + List superTypes = cachedType.getSuperTypes(); + for(String superTypeName : superTypes) { + CachedType cachedSuperType = typesCache.getCachedType(superTypeName); + cachedSuperTypes.add(cachedSuperType); + + Type superType = cachedSuperType.getType(); + definedProperties.addAll(superType.getProperties()); + } + + return definedProperties; + } + + public void sanityCheck() throws SchemaViolationException, ResourceRegistryException { + // OrientDB distributed mode does not support + // mandatory and notnull constraints due to technical problem + // https://www.orientdb.com/docs/last/java/Graph-Schema-Property.html#using-constraints + // Going to validate them here + + JsonNode instances = createCompleteJsonNode(); + + Set definedProperties = getAllProperties(); + + + for(PropertyDefinition propertyDefinition : definedProperties) { + String fieldName = propertyDefinition.getName(); + + if(propertyDefinition.isMandatory() && !instances.has(fieldName)) { + if(propertyDefinition.isNotnull()) { + // If the field is mandatory but null value is accepted I add the + // field as null value + element.setProperty(fieldName, null); + } else { + throw new SchemaViolationException(getMandatoryErrorMessage(fieldName)); + } + } + + JsonNode jsonNode = instances.get(fieldName); + + if(!propertyDefinition.isNotnull() && jsonNode==null) { + throw new SchemaViolationException(getNotNullErrorMessage(fieldName)); + } + + PropertyTypeName propertyTypeName = ((PropertyDefinitionImpl) propertyDefinition).getPropertyTypeName(); + BaseType baseType = propertyTypeName.getBaseType(); + switch (baseType) { + case PROPERTY: + + break; + + case LIST: case SET: case MAP: + + propertyTypeName.getGenericBaseType(); + + break; + + default: + break; + } + + // leaving the rest of validation to OrientDB + + } + + } + } diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/relations/RelationElementManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/relations/RelationElementManagement.java index f2c77d6..d1e9336 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/relations/RelationElementManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/relations/RelationElementManagement.java @@ -162,6 +162,9 @@ public abstract class RelationElementManagement {}", typeName, source.toString(), target.toString()); element = oDatabaseDocument.newEdge(source, target, typeName); diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/FacetManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/FacetManagement.java index b3881de..30e1bf6 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/FacetManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/FacetManagement.java @@ -1,7 +1,5 @@ package org.gcube.informationsystem.resourceregistry.instances.model.entities; -import java.util.Set; - import org.gcube.com.fasterxml.jackson.databind.JsonNode; import org.gcube.informationsystem.base.reference.AccessType; import org.gcube.informationsystem.model.reference.entities.Facet; @@ -10,11 +8,6 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegis import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet.FacetAlreadyPresentException; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet.FacetAvailableInAnotherContextException; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.facet.FacetNotFoundException; -import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaViolationException; -import org.gcube.informationsystem.resourceregistry.types.CachedType; -import org.gcube.informationsystem.resourceregistry.types.TypesCache; -import org.gcube.informationsystem.types.reference.entities.FacetType; -import org.gcube.informationsystem.types.reference.properties.PropertyDefinition; import com.orientechnologies.orient.core.record.OVertex; @@ -66,62 +59,4 @@ public class FacetManagement extends EntityManagement { return true; } - private String getNotNullErrorMessage(String fieldName) { - StringBuffer stringBuffer = new StringBuffer(); - stringBuffer.append("The type "); - stringBuffer.append(typeName); - stringBuffer.append(" defines the fields "); - stringBuffer.append(fieldName); - stringBuffer.append(" as not nullable. Null or no value has been provided instead."); - return stringBuffer.toString(); - } - - private String getMandatoryErrorMessage(String fieldName) { - StringBuffer stringBuffer = new StringBuffer(); - stringBuffer.append("The type "); - stringBuffer.append(typeName); - stringBuffer.append(" defines the fields "); - stringBuffer.append(fieldName); - stringBuffer.append(" as mandatory but no value has been provided."); - return stringBuffer.toString(); - } - - @Override - public void sanityCheck() throws SchemaViolationException, ResourceRegistryException { - // OrientDB distributed mode does not support - // mandatory and notnull constraints due to technical problem - // https://www.orientdb.com/docs/last/java/Graph-Schema-Property.html#using-constraints - // Going to validate them here - - JsonNode facetInstance = createCompleteJsonNode(); - - TypesCache typesCache = TypesCache.getInstance(); - CachedType cachedType = typesCache.getCachedType(typeName); - FacetType facetType = (FacetType) cachedType.getType(); - Set definedProperties = facetType.getProperties(); - for(PropertyDefinition propertyDefinition : definedProperties) { - String fieldName = propertyDefinition.getName(); - - if(propertyDefinition.isMandatory() && !facetInstance.has(fieldName)) { - if(propertyDefinition.isNotnull()) { - // If the field is mandatory but null value is accepted I add the - // field as null value - element.setProperty(fieldName, null); - } else { - throw new SchemaViolationException(getMandatoryErrorMessage(fieldName)); - } - } - - JsonNode jsonNode = facetInstance.get(fieldName); - - if(!propertyDefinition.isNotnull() && jsonNode==null) { - throw new SchemaViolationException(getNotNullErrorMessage(fieldName)); - } - - // leaving the rest of validation to OrientDB - - } - - } - } diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/ResourceManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/ResourceManagement.java index 85e6bd2..c3601cd 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/ResourceManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/ResourceManagement.java @@ -399,6 +399,11 @@ public class ResourceManagement extends EntityManagement { return true; } + /** + * The default sanity check is not valid for resources which do not have properties + * and instead must be validated in terms of facets. + * The Resource Header is managed with dedicated code for all instaces. + */ @Override public void sanityCheck() throws SchemaViolationException, ResourceRegistryException { JsonNode resourceInstance = createCompleteJsonNode(); diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/types/CachedType.java b/src/main/java/org/gcube/informationsystem/resourceregistry/types/CachedType.java index 4603d11..4a5af4c 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/types/CachedType.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/types/CachedType.java @@ -197,7 +197,7 @@ public class CachedType { return accessType; } - private List internaGetSuperTypes() throws SchemaException, ResourceRegistryException { + private List internalGetSuperTypes() throws SchemaException, ResourceRegistryException { if(superTypes==null) { superTypes = getAllSuperclasses(superClassesToBeExcluded); } @@ -225,7 +225,7 @@ public class CachedType { } public synchronized List getSuperTypes() throws SchemaException, ResourceRegistryException { - return internaGetSuperTypes(); + return internalGetSuperTypes(); } public synchronized List getSubTypes() throws SchemaException, ResourceRegistryException {