From b025d080998b9b604d644308d4f3723e70916c23 Mon Sep 17 00:00:00 2001 From: Luca Frosini Date: Tue, 26 Oct 2021 20:49:58 +0200 Subject: [PATCH] Changed the management of instance property to properly support Map, List and Set --- .../instances/base/ElementManagement.java | 151 +++++++++++------- .../properties/PropertyElementManagement.java | 4 + .../queries/json/JsonQuery.java | 3 +- .../templates/QueryTemplateManagement.java | 99 ++++++++++-- .../QueryTemplateManagementTest.java | 85 +++++++--- .../queryTemplates/queryTemplate1-bis.json | 23 +++ 6 files changed, 277 insertions(+), 88 deletions(-) create mode 100644 src/test/resources/queryTemplates/queryTemplate1-bis.json 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 52bf1dc..8e41fd5 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 @@ -876,7 +876,7 @@ public abstract class ElementManagement { return null; } - public static Object getObjectFromElement(JsonNode value) + public static Object getObjectFromJsonNode(JsonNode value) throws UnsupportedDataTypeException, ResourceRegistryException { JsonNodeType jsonNodeType = value.getNodeType(); @@ -885,23 +885,8 @@ public abstract class ElementManagement { return PropertyElementManagement.getPropertyDocument(value); case ARRAY: - List list = new ArrayList(); - Iterator arrayElement = value.elements(); - while(arrayElement.hasNext()) { - JsonNode arrayNode = arrayElement.next(); - Object objectNode = getObjectFromElement(arrayNode); - if(objectNode != null) { - list.add(objectNode); - } - } - return list; + break; - /* - * List/Set support is currently disabled due to OrientDB bug see https://github.com/orientechnologies/orientdb/issues/7354 - * - throw new UnsupportedDataTypeException( - "List/Set support is currently disabled due to OrientDB bug see https://github.com/orientechnologies/orientdb/issues/7354"); - */ case BINARY: break; @@ -940,10 +925,10 @@ public abstract class ElementManagement { return null; } - public Map getPropertyMap(JsonNode jsonNode, Set ignoreKeys, + public Map getPropertyMap(JsonNode jsonNode, Set ignoreKeys, Set ignoreStartWith) throws JsonProcessingException, IOException { - Map map = new HashMap<>(); + Map map = new HashMap<>(); if(ignoreKeys == null) { ignoreKeys = new HashSet<>(); @@ -971,15 +956,7 @@ public abstract class ElementManagement { } JsonNode value = entry.getValue(); - Object object = null; - try { - object = getObjectFromElement(value); - if(object != null) { - map.put(key, object); - } - } catch(ResourceRegistryException e) { - logger.warn("An invalidy property has been provided. It will be ignored."); - } + map.put(key, value); } @@ -991,7 +968,7 @@ public abstract class ElementManagement { Set oldKeys = element.getPropertyNames(); - Map properties; + Map properties; try { properties = getPropertyMap(jsonNode, ignoreKeys, ignoreStartWithKeys); } catch(IOException e) { @@ -1000,33 +977,88 @@ public abstract class ElementManagement { oldKeys.removeAll(properties.keySet()); + getOClass(); + for(String key : properties.keySet()) { try { - Object object = properties.get(key); + JsonNode value = properties.get(key); - boolean set = false; + OProperty oProperty = oClass.getProperty(key); - if(object instanceof ODocument) { - ODocument oDocument = (ODocument) object; - element.setProperty(key, oDocument, OType.EMBEDDED); - set = true; - } - - /* - * List/Set support is currently disabled due to OrientDB bug see https://github.com/orientechnologies/orientdb/issues/7354 - */ - if(object instanceof Set) { - element.setProperty(key, object, OType.EMBEDDEDSET); - set = true; - } - if(object instanceof List) { - element.setProperty(key, object, OType.EMBEDDEDLIST); - set = true; - } - - if(!set) { - element.setProperty(key, object); + if(oProperty==null) { + Object object = getObjectFromJsonNode(value); + if(object != null) { + if(object instanceof ODocument) { + element.setProperty(key, object, OType.EMBEDDED); + }else { + element.setProperty(key, object); + } + } + }else { + switch (oProperty.getType()) { + case EMBEDDED: + ODocument oDocument = PropertyElementManagement.getPropertyDocument(value); + element.setProperty(key, oDocument, OType.EMBEDDED); + break; + + case EMBEDDEDLIST: + List list = new ArrayList(); + Iterator arrayElement = value.elements(); + while(arrayElement.hasNext()) { + JsonNode elementOfArray = arrayElement.next(); + Object object = null; + + if(oProperty.getLinkedType()!=null) { + object = getObjectFromJsonNode(elementOfArray); + }else { + object = PropertyElementManagement.getPropertyDocument(elementOfArray); + } + list.add(object); + } + element.setProperty(key, list, OType.EMBEDDEDLIST); + break; + + case EMBEDDEDSET: + Set set = new HashSet(); + Iterator setElement = value.elements(); + while(setElement.hasNext()) { + JsonNode elementOfSet = setElement.next(); + Object object = null; + + if(oProperty.getLinkedType()!=null) { + object = getObjectFromJsonNode(elementOfSet); + }else { + object = PropertyElementManagement.getPropertyDocument(elementOfSet); + } + set.add(object); + } + element.setProperty(key, set, OType.EMBEDDEDSET); + break; + + case EMBEDDEDMAP: + Map map = new HashMap<>(); + Iterator fieldNames = value.fieldNames(); + while(fieldNames.hasNext()) { + String fieldKey = fieldNames.next(); + Object object = null; + if(oProperty.getLinkedType()!=null) { + object = getObjectFromJsonNode(value.get(fieldKey)); + }else { + object = PropertyElementManagement.getPropertyDocument(value.get(fieldKey)); + } + map.put(fieldKey, object); + } + element.setProperty(key, map, OType.EMBEDDEDMAP); + break; + + default: + Object object = getObjectFromJsonNode(value); + if(object != null) { + element.setProperty(key, object); + } + break; + } } } catch(Exception e) { @@ -1035,6 +1067,7 @@ public abstract class ElementManagement { logger.error(error); throw new ResourceRegistryException(error, e); } + } OUTER_FOR: for(String key : oldKeys) { @@ -1118,16 +1151,26 @@ public abstract class ElementManagement { ArrayNode arrayNode = objectMapper.createArrayNode(); for(Object o : collection) { - Object obj = getPropertyForJson("PLACEHOLDER", o); - + JsonNode obj = getPropertyForJson("PLACEHOLDER", o); if(obj!=null) { - arrayNode.add((JsonNode) obj); + arrayNode.add(obj); } } return arrayNode; } + if(object instanceof Map) { + @SuppressWarnings("unchecked") + Map map = (Map) object; + ObjectNode objectNode = objectMapper.createObjectNode(); + for(String k : map.keySet()) { + JsonNode obj = getPropertyForJson("PLACEHOLDER", map.get(k)); + objectNode.set(k, obj); + } + return objectNode; + } + return new TextNode(object.toString()); } catch(Exception e) { diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/properties/PropertyElementManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/properties/PropertyElementManagement.java index f6b09e2..8847950 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/properties/PropertyElementManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/properties/PropertyElementManagement.java @@ -51,6 +51,10 @@ public class PropertyElementManagement { public static ODocument getPropertyDocument(JsonNode jsonNode) throws ResourceRegistryException { ODocument oDocument = null; + if(jsonNode.isNull()) { + return null; + } + if(jsonNode.has(Element.CLASS_PROPERTY)) { // Complex type String type = ElementManagement.getClassProperty(jsonNode); diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/JsonQuery.java b/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/JsonQuery.java index 4e95593..e953862 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/JsonQuery.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/JsonQuery.java @@ -46,6 +46,7 @@ public class JsonQuery { protected ObjectMapper objectMapper; protected JsonNode jsonQuery; protected JsonQueryERElement entryPoint; + protected ODatabaseDocument oDatabaseDocument; public JsonQuery() { this.objectMapper = new ObjectMapper(); @@ -105,7 +106,7 @@ public class JsonQuery { public String query() throws InvalidQueryException, ResourceRegistryException { ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal(); - ODatabaseDocument oDatabaseDocument = null; + oDatabaseDocument = null; try { Integer limit = AccessPath.UNBOUNDED; diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/queries/templates/QueryTemplateManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/queries/templates/QueryTemplateManagement.java index 81cf349..1ee3999 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/queries/templates/QueryTemplateManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/queries/templates/QueryTemplateManagement.java @@ -7,7 +7,6 @@ import org.gcube.com.fasterxml.jackson.databind.JsonNode; import org.gcube.com.fasterxml.jackson.databind.ObjectMapper; import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode; import org.gcube.informationsystem.base.reference.AccessType; -import org.gcube.informationsystem.contexts.reference.entities.Context; import org.gcube.informationsystem.queries.templates.reference.entities.QueryTemplate; import org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresentException; import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException; @@ -16,21 +15,25 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.queries.Inval import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaViolationException; import org.gcube.informationsystem.resourceregistry.contexts.security.QueryTemplatesSecurityContext; import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext; +import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagementUtility; import org.gcube.informationsystem.resourceregistry.instances.base.entities.EntityElementManagement; +import org.gcube.informationsystem.resourceregistry.queries.json.JsonQuery; import org.gcube.informationsystem.resourceregistry.utils.Utility; import org.gcube.informationsystem.types.reference.entities.EntityType; +import org.gcube.informationsystem.utils.ElementMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.orientechnologies.orient.core.db.document.ODatabaseDocument; import com.orientechnologies.orient.core.record.OVertex; import com.orientechnologies.orient.core.record.impl.ODocument; +import com.orientechnologies.orient.core.sql.executor.OResult; import com.orientechnologies.orient.core.sql.executor.OResultSet; /** * @author Luca Frosini (ISTI - CNR) */ -public class QueryTemplateManagement extends EntityElementManagement { +public class QueryTemplateManagement extends EntityElementManagement { private static Logger logger = LoggerFactory.getLogger(QueryTemplateManagement.class); @@ -52,18 +55,36 @@ public class QueryTemplateManagement extends EntityElementManagement()); + + if(resultSet == null || !resultSet.hasNext()) { + throw new NotFoundException("Error retrieving " + QueryTemplate.NAME + " with name " + getName()); + } + + OResult oResult = resultSet.next(); + OVertex queryTemplate = ElementManagementUtility.getElementFromOptional(oResult.getVertex()); + + logger.trace("{} representing vertex is {}", QueryTemplate.NAME, Utility.toJsonString(queryTemplate, true)); + + if(resultSet.hasNext()) { + throw new NotFoundException("Found more than one " + QueryTemplate.NAME + " with name " + name + ". This should not occur, please contact the administrator"); + } + + return queryTemplate; + } catch(NotFoundException e) { + throw getSpecificNotFoundException(e); + } catch(ResourceRegistryException e) { + throw e; + } catch(Exception e) { + throw new ResourceRegistryException(e); + } } @Override @@ -198,17 +263,27 @@ public class QueryTemplateManagement extends EntityElementManagement