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 0c0791e..b439ce0 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 @@ -100,7 +100,6 @@ public class JsonQuery { public StringBuffer createQuery() throws SchemaException, InvalidQueryException, ResourceRegistryException { entryPoint = getJsonQueryERElement(jsonQuery); entryPoint.setEntryPoint(true); - entryPoint.setNoTraversal(true); return entryPoint.analize(new StringBuffer()); } diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/JsonQueryERElement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/JsonQueryERElement.java index e6a19a9..ed37194 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/JsonQueryERElement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/JsonQueryERElement.java @@ -20,10 +20,12 @@ import org.gcube.informationsystem.resourceregistry.queries.operators.Conditiona import org.gcube.informationsystem.resourceregistry.queries.operators.LogicalOperator; import org.gcube.informationsystem.resourceregistry.types.TypesCache; import org.gcube.informationsystem.utils.TypeUtility; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class JsonQueryERElement { - // private Logger logger = LoggerFactory.getLogger(this.getClass()); + protected Logger logger = LoggerFactory.getLogger(this.getClass()); public static void validateType(String type, AccessType requiredAccessType) throws SchemaException, ResourceRegistryException { AccessType accessType = TypesCache.getInstance().getCachedType(type).getAccessType(); @@ -42,15 +44,23 @@ public abstract class JsonQueryERElement { protected Direction direction; protected boolean entryPoint; - protected boolean noTraversal; + /** + * it indicates the number of properties in this.jsonNode + * This number is manipulated while analyzing the jsonNode + * to properly create the query. + */ + protected int size; + + protected boolean traverseBack; public JsonQueryERElement(JsonNode jsonQuery, AccessType accessType) throws SchemaException, ResourceRegistryException { this.objectMapper = new ObjectMapper(); this.type = TypeUtility.getTypeName(jsonQuery); this.jsonNode = jsonQuery; + this.size = jsonNode.size(); this.accessType = accessType; this.entryPoint = false; - this.noTraversal = false; + this.traverseBack = true; this.fieldNamesToRemove = new HashSet<>(); this.fieldNamesToRemove.add(Element.TYPE_PROPERTY); @@ -78,14 +88,15 @@ public abstract class JsonQueryERElement { public void setEntryPoint(boolean entryPoint) { this.entryPoint = entryPoint; + this.traverseBack = !entryPoint; } - public boolean isNoTraversal() { - return noTraversal; + public boolean isTraverseBack() { + return traverseBack; } - public void setNoTraversal(boolean noTraversal) { - this.noTraversal = noTraversal; + public void setTraverseBack(boolean traverseBack) { + this.traverseBack = traverseBack; } public abstract StringBuffer analize(StringBuffer stringBuffer) throws SchemaNotFoundException, InvalidQueryException, SchemaException, ResourceRegistryException; diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/entities/JsonQueryFacet.java b/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/entities/JsonQueryFacet.java index 5683e70..5d021d5 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/entities/JsonQueryFacet.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/entities/JsonQueryFacet.java @@ -27,17 +27,17 @@ public class JsonQueryFacet extends JsonQueryEntity { int size = jsonNode.size(); - boolean noTraversalLocal = noTraversal; + boolean traverseBackLocal = traverseBack; if(jsonNode.has(_SOURCE)) { if(!entryPoint) { throw new InvalidQueryException(_SOURCE + " property cannot be used in a facet if it is not the entry object"); } JsonNode consistsOfNode = jsonNode.get(_SOURCE); JsonQueryConsistsOf jsonQueryConsistsOf = new JsonQueryConsistsOf(consistsOfNode); - jsonQueryConsistsOf.setNoTraversal(noTraversal); + jsonQueryConsistsOf.setTraverseBack(traverseBackLocal); jsonQueryConsistsOf.setDirection(Direction.OUT); stringBuffer = jsonQueryConsistsOf.analize(stringBuffer); - noTraversalLocal = false; + traverseBackLocal = true; /* Need to substract 1 from size otherwise * it add WHERE at the end because _in @@ -48,14 +48,14 @@ public class JsonQueryFacet extends JsonQueryEntity { newBuffer.append("SELECT FROM "); - if(!noTraversalLocal) { + if(traverseBackLocal) { newBuffer.append("( "); newBuffer.append("TRAVERSE inV(\""); } newBuffer.append(type); - if(!noTraversalLocal) { + if(traverseBackLocal) { newBuffer.append("\") FROM ( "); newBuffer.append(stringBuffer); newBuffer.append(")"); diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/entities/JsonQueryResource.java b/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/entities/JsonQueryResource.java index a090d3a..004591e 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/entities/JsonQueryResource.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/entities/JsonQueryResource.java @@ -18,42 +18,74 @@ public class JsonQueryResource extends JsonQueryEntity { public JsonQueryResource(JsonNode jsonQuery) throws SchemaException, ResourceRegistryException { super(jsonQuery, AccessType.RESOURCE); - fieldNamesToRemove.add(Resource.CONSISTS_OF_PROPERTY); - fieldNamesToRemove.add(Resource.IS_RELATED_TO_PROPERTY); + this.fieldNamesToRemove.add(Resource.CONSISTS_OF_PROPERTY); + this.fieldNamesToRemove.add(Resource.IS_RELATED_TO_PROPERTY); + } + + public StringBuffer createSelect(StringBuffer stringBuffer, boolean wrapInnerQuery) throws SchemaException, ResourceRegistryException { + StringBuffer buffer = new StringBuffer(); + buffer.append("SELECT FROM "); + + if(wrapInnerQuery) { + buffer.append("( "); + buffer.append(stringBuffer); + buffer.append(")"); + }else { + buffer.append(type); + } + + if(entryPoint || size>1) { + buffer.append(" WHERE "); + } + + if(size > 1) { + buffer.append(addConstraints(jsonNode, null, null)); + if(entryPoint) { + buffer.append(" AND "); + } + } + + if(entryPoint) { + buffer.append(OrientDBUtility.ORIENTDB_CLASS_PROPERTY); + buffer.append(" INSTANCEOF \""); + buffer.append(type); + buffer.append("\""); + } + + return buffer; } @Override public StringBuffer analize(StringBuffer stringBuffer) throws SchemaException, ResourceRegistryException { - boolean initFound = false; - int size = jsonNode.size(); + boolean wrapInnerQuery = false; - if(!noTraversal) { - StringBuffer newBuffer = new StringBuffer(); - newBuffer.append("TRAVERSE "); - newBuffer.append(direction.name().toLowerCase()); - newBuffer.append("V(\""); - newBuffer.append(type); - newBuffer.append("\") FROM ( "); - newBuffer.append(stringBuffer); - newBuffer.append(")"); - stringBuffer = newBuffer; + if(traverseBack) { + StringBuffer buffer = new StringBuffer(); + buffer.append("TRAVERSE "); + buffer.append(direction.name().toLowerCase()); + buffer.append("V(\""); + buffer.append(type); + buffer.append("\") FROM ( "); + buffer.append(stringBuffer); + buffer.append(")"); + stringBuffer = buffer; - initFound = true; + wrapInnerQuery = true; } ArrayNode isRelatedToArray = (ArrayNode) jsonNode.get(Resource.IS_RELATED_TO_PROPERTY); if(isRelatedToArray!=null && isRelatedToArray.size()>0) { --size; - initFound = true; for(int i=0; i1) || !initFound)) { - newBuffer.append("SELECT FROM "); + // The Resource has no other referenced ER inside + if(!wrapInnerQuery) { + return createSelect(stringBuffer, wrapInnerQuery); } - if(initFound) { - if(size > 1 || entryPoint){ - newBuffer.append("( "); - } - newBuffer.append(stringBuffer); - - if(size > 1 || entryPoint){ - newBuffer.append(")"); - } - }else { - newBuffer.append(type); + if(entryPoint || size>1) { + return createSelect(stringBuffer, wrapInnerQuery); } - if(size > 1 || entryPoint ) { - newBuffer.append(" WHERE "); - } - - if(size > 1) { - newBuffer.append(addConstraints(jsonNode, null, null)); - if(entryPoint) { - newBuffer.append(" AND "); - } - } - - if(entryPoint) { - newBuffer.append(OrientDBUtility.ORIENTDB_CLASS_PROPERTY); - newBuffer.append(" INSTANCEOF \""); - newBuffer.append(type); - newBuffer.append("\""); - } - - stringBuffer = newBuffer; - return stringBuffer; } diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/relations/JsonQueryConsistsOf.java b/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/relations/JsonQueryConsistsOf.java index 1528e2e..caf3f51 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/relations/JsonQueryConsistsOf.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/relations/JsonQueryConsistsOf.java @@ -8,6 +8,7 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegis import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaException; import org.gcube.informationsystem.resourceregistry.queries.json.base.entities.JsonQueryFacet; import org.gcube.informationsystem.resourceregistry.queries.json.base.entities.JsonQueryResource; +import org.gcube.informationsystem.resourceregistry.utils.OrientDBUtility; /** * @author Luca Frosini (ISTI - CNR) @@ -29,30 +30,58 @@ public class JsonQueryConsistsOf extends JsonQueryRelation { this.requestedResourceType = requestedResourceType; } + protected StringBuffer traverseBackToCallerResource(StringBuffer stringBuffer) { + StringBuffer buffer = new StringBuffer(); + buffer.append("TRAVERSE "); + buffer.append(direction.opposite().name().toLowerCase()); + buffer.append("V(\""); + buffer.append(requestedResourceType); + buffer.append("\") FROM ( "); // Open ( + buffer.append(stringBuffer); + buffer.append(")"); // Close ) + return buffer; + } + + + public StringBuffer createSelect(StringBuffer stringBuffer, boolean wrapInnerQuery) throws SchemaException, ResourceRegistryException { + StringBuffer buffer = new StringBuffer(); + buffer.append("SELECT FROM "); + + if(wrapInnerQuery) { + buffer.append("( "); + buffer.append(stringBuffer); + buffer.append(")"); + }else { + buffer.append(type); + } + + if(entryPoint || size>1) { + buffer.append(" WHERE "); + } + + if(size > 1) { + buffer.append(addConstraints(jsonNode, null, null)); + if(entryPoint) { + buffer.append(" AND "); + } + } + + if(entryPoint) { + buffer.append(OrientDBUtility.ORIENTDB_CLASS_PROPERTY); + buffer.append(" INSTANCEOF \""); + buffer.append(type); + buffer.append("\""); + } + + return buffer; + } + @Override public StringBuffer analize(StringBuffer stringBuffer) throws SchemaException, ResourceRegistryException { - StringBuffer consistsOfBuffer = new StringBuffer(); - if(!jsonNode.has(ConsistsOf.SOURCE_PROPERTY)) { - consistsOfBuffer.append("TRAVERSE "); - consistsOfBuffer.append(direction.opposite().name().toLowerCase()); - consistsOfBuffer.append("V(\""); - consistsOfBuffer.append(requestedResourceType); - consistsOfBuffer.append("\") FROM ( "); // Open ( 1 - } + boolean wrapInnerQuery = false; - int size = jsonNode.size(); - if(size > 2) { - consistsOfBuffer.append("SELECT FROM ( "); // Open ( SELECT - } - - consistsOfBuffer.append("TRAVERSE "); - consistsOfBuffer.append(direction.name().toLowerCase()); - consistsOfBuffer.append("E(\""); - consistsOfBuffer.append(type); - consistsOfBuffer.append("\") FROM ( "); // Open ( 2 - - if(!noTraversal) { + if(traverseBack) { StringBuffer buffer = new StringBuffer(); buffer.append("TRAVERSE "); buffer.append(direction.opposite().name().toLowerCase()); @@ -62,34 +91,49 @@ public class JsonQueryConsistsOf extends JsonQueryRelation { buffer.append(stringBuffer); buffer.append(")"); stringBuffer = buffer; + wrapInnerQuery = true; } if(jsonNode.has(ConsistsOf.TARGET_PROPERTY)) { + --size; JsonNode facetJsonNode = jsonNode.get(ConsistsOf.TARGET_PROPERTY); JsonQueryFacet jsonQueryFacet = new JsonQueryFacet(facetJsonNode); - jsonQueryFacet.setNoTraversal(noTraversal); + jsonQueryFacet.setTraverseBack(!((!traverseBack) && !wrapInnerQuery)); stringBuffer = jsonQueryFacet.analize(stringBuffer); - } else if(jsonNode.has(ConsistsOf.SOURCE_PROPERTY)) { + wrapInnerQuery = true; + } + + if(jsonNode.has(ConsistsOf.SOURCE_PROPERTY)) { + --size; JsonNode resourceJsonNode = jsonNode.get(ConsistsOf.SOURCE_PROPERTY); JsonQueryResource jsonQueryResource = new JsonQueryResource(resourceJsonNode); - jsonQueryResource.setNoTraversal(noTraversal); + jsonQueryResource.setTraverseBack(!((!traverseBack) && !wrapInnerQuery)); stringBuffer = jsonQueryResource.analize(stringBuffer); + wrapInnerQuery = true; } - consistsOfBuffer.append(stringBuffer); - consistsOfBuffer.append(")"); // Close ) 2 - - // Size 2 means that only 'type' and 'target' properties are present - if(size > 2) { - consistsOfBuffer.append(") WHERE "); // Close ) SELECT - consistsOfBuffer.append(addConstraints(jsonNode, null, null)); + if(wrapInnerQuery) { + StringBuffer buffer = new StringBuffer(); + buffer.append("TRAVERSE "); + buffer.append(direction.name().toLowerCase()); + buffer.append("E(\""); + buffer.append(type); + buffer.append("\") FROM ( "); + buffer.append(stringBuffer); + buffer.append(")"); + stringBuffer = buffer; } - if(!jsonNode.has(ConsistsOf.SOURCE_PROPERTY)) { - consistsOfBuffer.append(")"); // Close ) 1 + if(entryPoint || size>1) { + stringBuffer = createSelect(stringBuffer, wrapInnerQuery); } - return consistsOfBuffer; + if(!entryPoint && requestedResourceType!=null) { + stringBuffer = traverseBackToCallerResource(stringBuffer); + } + + + return stringBuffer; } } diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/relations/JsonQueryIsRelatedTo.java b/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/relations/JsonQueryIsRelatedTo.java index 103ca24..b23783d 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/relations/JsonQueryIsRelatedTo.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/relations/JsonQueryIsRelatedTo.java @@ -1,5 +1,7 @@ package org.gcube.informationsystem.resourceregistry.queries.json.base.relations; +import javax.ws.rs.InternalServerErrorException; + import org.gcube.com.fasterxml.jackson.databind.JsonNode; import org.gcube.informationsystem.base.reference.AccessType; import org.gcube.informationsystem.base.reference.Direction; @@ -8,6 +10,7 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegis import org.gcube.informationsystem.resourceregistry.api.exceptions.queries.InvalidQueryException; import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaException; import org.gcube.informationsystem.resourceregistry.queries.json.base.entities.JsonQueryResource; +import org.gcube.informationsystem.resourceregistry.utils.OrientDBUtility; /** * @author Luca Frosini (ISTI - CNR) @@ -18,6 +21,7 @@ public class JsonQueryIsRelatedTo extends JsonQueryRelation { public JsonQueryIsRelatedTo(JsonNode jsonQuery) throws SchemaException, ResourceRegistryException { super(jsonQuery, AccessType.IS_RELATED_TO); + direction = null; } public String getRequestedResourceType() { @@ -27,39 +31,98 @@ public class JsonQueryIsRelatedTo extends JsonQueryRelation { public void setRequestedResourceType(String requestedResourceType) { this.requestedResourceType = requestedResourceType; } - - private StringBuffer traverseThisEdge(StringBuffer stringBuffer) throws InvalidQueryException { + + protected StringBuffer traverseBackToCallerResource(StringBuffer stringBuffer) { StringBuffer buffer = new StringBuffer(); + buffer.append("TRAVERSE "); + buffer.append(direction.opposite().name().toLowerCase()); + buffer.append("V(\""); + buffer.append(requestedResourceType); + buffer.append("\") FROM ( "); // Open ( + buffer.append(stringBuffer); + buffer.append(")"); // Close ) + return buffer; + } + + public StringBuffer createSelect(StringBuffer stringBuffer, boolean wrapInnerQuery) throws SchemaException, ResourceRegistryException { + StringBuffer buffer = new StringBuffer(); + buffer.append("SELECT FROM "); - int size = jsonNode.size(); + if(wrapInnerQuery) { + buffer.append("( "); + buffer.append(stringBuffer); + buffer.append(")"); + }else { + buffer.append(type); + } - // Remove type from size - --size; + if(entryPoint || size>1) { + buffer.append(" WHERE "); + } + + if(size > 1) { + buffer.append(addConstraints(jsonNode, null, null)); + if(entryPoint) { + buffer.append(" AND "); + } + } + + if(entryPoint) { + buffer.append(OrientDBUtility.ORIENTDB_CLASS_PROPERTY); + buffer.append(" INSTANCEOF \""); + buffer.append(type); + buffer.append("\""); + } + + return buffer; + } + + public void setDirectionByJson() throws InvalidQueryException { + if(entryPoint) { + String error = "The function JsonQueryIsRelatedTo#setDirectionByJson() cannot be called for an entry point"; + logger.error(error); + throw new InternalServerErrorException(error); + } + + boolean found = false; if(jsonNode.has(IsRelatedTo.SOURCE_PROPERTY)) { - --size; + logger.trace("{} for type {} has {} property", IsRelatedTo.NAME, type, IsRelatedTo.SOURCE_PROPERTY); + direction = Direction.OUT; + found = true; } - + if(jsonNode.has(IsRelatedTo.TARGET_PROPERTY)) { - --size; + if(found) { + StringBuffer buffer = new StringBuffer(); + buffer.append(IsRelatedTo.NAME); + buffer.append(" for type "); + buffer.append(type); + buffer.append(" has both "); + buffer.append(IsRelatedTo.SOURCE_PROPERTY); + buffer.append(" and "); + buffer.append(IsRelatedTo.TARGET_PROPERTY); + buffer.append(" property. Only entry points can have both because one is implicit from the resource containg the "); + buffer.append(IsRelatedTo.NAME); + buffer.append(" relation."); + logger.error("This part of the json query is not valid {}\n{}", jsonNode.toString(), buffer.toString()); + throw new InvalidQueryException(buffer.toString()); + } + direction = Direction.IN; + } + } + + @Override + public StringBuffer analize(StringBuffer stringBuffer) throws SchemaException, ResourceRegistryException { + + if(!entryPoint && direction==null) { + throw new InternalServerErrorException("Caller Resource must invoke setDirectionByJson() first. This is a server bug. Please contact the administator. "); } - if(size > 0) { - buffer.append("SELECT FROM "); - if(noTraversal) { - buffer.append(type); - }else { - buffer.append(" ( "); // Open ( SELECT - } - - }else { - if(noTraversal) { - buffer.append("SELECT FROM "); - buffer.append(type); - } - } + boolean wrapInnerQuery = false; - if(!noTraversal) { + if(traverseBack) { + StringBuffer buffer = new StringBuffer(); buffer.append("TRAVERSE "); buffer.append(direction.opposite().name().toLowerCase()); buffer.append("E(\""); @@ -67,80 +130,64 @@ public class JsonQueryIsRelatedTo extends JsonQueryRelation { buffer.append("\") FROM ( "); buffer.append(stringBuffer); buffer.append(")"); + stringBuffer = buffer; + wrapInnerQuery = true; } + Direction wrapDirection = direction; - stringBuffer = buffer; - - // Size 0 means that only 'type' and 'target'/'source' properties are present - if(size > 0) { - if(!noTraversal) { - stringBuffer.append(" )"); // Close ) SELECT - } - stringBuffer.append(" WHERE "); - stringBuffer.append(addConstraints(jsonNode, null, null)); - } - - return stringBuffer; - } - - @Override - public StringBuffer analize(StringBuffer stringBuffer) throws SchemaException, ResourceRegistryException { - - JsonNode sourceJsonNode = jsonNode.get(IsRelatedTo.SOURCE_PROPERTY); - JsonNode targetJsonNode = jsonNode.get(IsRelatedTo.TARGET_PROPERTY); - - JsonNode resourceJsonNode = null; - - if(sourceJsonNode!=null) { - resourceJsonNode = sourceJsonNode; - direction = Direction.OUT; - } else if(targetJsonNode!=null) { - resourceJsonNode = targetJsonNode; - direction = Direction.IN; - } - - stringBuffer = traverseThisEdge(stringBuffer); - - JsonQueryResource jsonQueryResource = new JsonQueryResource(resourceJsonNode); - jsonQueryResource.setDirection(direction); - jsonQueryResource.setNoTraversal(false); - stringBuffer = jsonQueryResource.analize(stringBuffer); - - StringBuffer buffer = new StringBuffer(); - if(requestedResourceType!=null) { - buffer.append("TRAVERSE "); - buffer.append(direction.opposite().name().toLowerCase()); - buffer.append("V(\""); - buffer.append(requestedResourceType); - buffer.append("\") FROM ( "); - } - buffer.append("TRAVERSE "); - buffer.append(direction.name().toLowerCase()); - buffer.append("E(\""); - buffer.append(type); - buffer.append("\") FROM ( "); - buffer.append(stringBuffer); - buffer.append(")"); - if(requestedResourceType!=null) { - buffer.append(")"); - } - stringBuffer = buffer; - - if(sourceJsonNode!=null && targetJsonNode!=null) { - // Target has still to be analised - - jsonQueryResource = new JsonQueryResource(targetJsonNode); - jsonQueryResource.setDirection(Direction.IN); - jsonQueryResource.setNoTraversal(false); + if(jsonNode.has(IsRelatedTo.SOURCE_PROPERTY)) { + --size; + JsonNode sourceJsonNode = jsonNode.get(IsRelatedTo.SOURCE_PROPERTY); + JsonQueryResource jsonQueryResource = new JsonQueryResource(sourceJsonNode); + wrapDirection = Direction.OUT; + jsonQueryResource.setDirection(Direction.OUT); + jsonQueryResource.setTraverseBack(!((!traverseBack) && !wrapInnerQuery)); stringBuffer = jsonQueryResource.analize(stringBuffer); + wrapInnerQuery = true; + } + + if(jsonNode.has(IsRelatedTo.TARGET_PROPERTY)) { + if(jsonNode.has(IsRelatedTo.SOURCE_PROPERTY)) { + StringBuffer buffer = new StringBuffer(); + buffer.append("TRAVERSE "); + buffer.append(wrapDirection.name().toLowerCase()); + buffer.append("E(\""); + buffer.append(type); + buffer.append("\") FROM ( "); + buffer.append(stringBuffer); + buffer.append(")"); + stringBuffer = buffer; + } - boolean noTraversalOldValue = noTraversal; - // It is no more and entry point for the function traverseThisEdge - noTraversal = false; - stringBuffer = traverseThisEdge(stringBuffer); - // Restoring entryPoint indication - noTraversal = noTraversalOldValue; + --size; + JsonNode targetJsonNode = jsonNode.get(IsRelatedTo.TARGET_PROPERTY); + JsonQueryResource jsonQueryResource = new JsonQueryResource(targetJsonNode); + wrapDirection = Direction.IN; + jsonQueryResource.setDirection(Direction.IN); + jsonQueryResource.setTraverseBack(!((!traverseBack) && !wrapInnerQuery)); + stringBuffer = jsonQueryResource.analize(stringBuffer); + wrapInnerQuery = true; + } + + if(wrapInnerQuery) { + StringBuffer buffer = new StringBuffer(); + buffer.append("TRAVERSE "); + buffer.append(wrapDirection.name().toLowerCase()); + buffer.append("E(\""); + buffer.append(type); + buffer.append("\") FROM ( "); + buffer.append(stringBuffer); + buffer.append(")"); + stringBuffer = buffer; + } + + if(entryPoint || size>1) { + stringBuffer = createSelect(stringBuffer, wrapInnerQuery); + } + + if(!entryPoint) { + stringBuffer = traverseBackToCallerResource(stringBuffer); } return stringBuffer; diff --git a/src/test/java/org/gcube/informationsystem/resourceregistry/queries/JsonQueryTest.java b/src/test/java/org/gcube/informationsystem/resourceregistry/queries/JsonQueryTest.java index 00fdae5..08e7578 100644 --- a/src/test/java/org/gcube/informationsystem/resourceregistry/queries/JsonQueryTest.java +++ b/src/test/java/org/gcube/informationsystem/resourceregistry/queries/JsonQueryTest.java @@ -81,7 +81,7 @@ public class JsonQueryTest extends ContextTest { @Test public void testSingleCreateQuery() throws Exception { File queriesDirectory = getQueriesDirectory(); - File jsonQueryFile = new File(queriesDirectory, "query3.json"); + File jsonQueryFile = new File(queriesDirectory, "query9.json"); ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.readTree(jsonQueryFile); logger.info("Going to test the following JSON query {}", jsonNode.toString()); diff --git a/src/test/resources/queries/query1-indented.query b/src/test/resources/queries/query1-indented.query new file mode 100644 index 0000000..7de6f95 --- /dev/null +++ b/src/test/resources/queries/query1-indented.query @@ -0,0 +1,19 @@ +SELECT FROM ( + TRAVERSE outV("EService") FROM ( + TRAVERSE inE("IsIdentifiedBy") FROM ( + SELECT FROM ( + TRAVERSE inV("SoftwareFacet") FROM ( + TRAVERSE outE("IsIdentifiedBy") FROM ( + TRAVERSE outV("EService") FROM ( + SELECT FROM ( + TRAVERSE inE("ConsistsOf") FROM ( + SELECT FROM StateFacet WHERE value = "down" + ) + ) WHERE propagationConstraint.add = "propagate" + ) + ) + ) + ) WHERE name = "data-transfer-service" AND group = "DataTransfer" + ) + ) +) WHERE @class INSTANCEOF "EService" \ No newline at end of file diff --git a/src/test/resources/queries/query2-indented.query b/src/test/resources/queries/query2-indented.query new file mode 100644 index 0000000..3dc5112 --- /dev/null +++ b/src/test/resources/queries/query2-indented.query @@ -0,0 +1,41 @@ +SELECT FROM ( + TRAVERSE outV("EService") FROM ( + TRAVERSE inE("ConsistsOf") FROM ( + SELECT FROM ( + TRAVERSE inV("AccessPointFacet") FROM ( + TRAVERSE outE("ConsistsOf") FROM ( + TRAVERSE outV("EService") FROM ( + TRAVERSE inE("IsIdentifiedBy") FROM ( + SELECT FROM ( + TRAVERSE inV("SoftwareFacet") FROM ( + TRAVERSE outE("IsIdentifiedBy") FROM ( + TRAVERSE outV("EService") FROM ( + SELECT FROM ( + TRAVERSE inE("ConsistsOf") FROM ( + SELECT FROM ( + TRAVERSE inV("StateFacet") FROM ( + TRAVERSE outE("ConsistsOf") FROM ( + TRAVERSE inV("EService") FROM ( + SELECT FROM ( + TRAVERSE outE("Activates") FROM ( + SELECT FROM HostingNode WHERE id = "5fbc1a56-d450-4f0f-85c1-9b1684581717" + ) + ) WHERE id = "d3f58e52-5346-47bc-b736-9d77a0b554ce" + ) + ) + ) + ) WHERE value = "down" + ) + ) WHERE propagationConstraint.add = "propagate" + ) + ) + ) + ) WHERE name = "data-transfer-service" AND group = "DataTransfer" + ) + ) + ) + ) + ) WHERE endpoint = "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service" + ) + ) +) WHERE @class INSTANCEOF "EService" \ No newline at end of file diff --git a/src/test/resources/queries/query2.query b/src/test/resources/queries/query2.query index 84082d6..a8ecc3f 100644 --- a/src/test/resources/queries/query2.query +++ b/src/test/resources/queries/query2.query @@ -1 +1 @@ -SELECT FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("AccessPointFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM ( TRAVERSE inV("SoftwareFacet") FROM ( TRAVERSE outE("IsIdentifiedBy") FROM ( TRAVERSE outV("EService") FROM ( SELECT FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("StateFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE inV("EService") FROM ( TRAVERSE outE("Activates") FROM ( SELECT FROM ( TRAVERSE outV("HostingNode") FROM ( SELECT FROM Activates WHERE id = "d3f58e52-5346-47bc-b736-9d77a0b554ce")) WHERE id = "5fbc1a56-d450-4f0f-85c1-9b1684581717"))))) WHERE value = "down")) WHERE propagationConstraint.add = "propagate")))) WHERE name = "data-transfer-service" AND group = "DataTransfer"))))) WHERE endpoint = "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service"))) WHERE @class INSTANCEOF "EService" \ No newline at end of file +SELECT FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("AccessPointFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM ( TRAVERSE inV("SoftwareFacet") FROM ( TRAVERSE outE("IsIdentifiedBy") FROM ( TRAVERSE outV("EService") FROM ( SELECT FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("StateFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE inV("EService") FROM ( SELECT FROM ( TRAVERSE outE("Activates") FROM ( SELECT FROM HostingNode WHERE id = "5fbc1a56-d450-4f0f-85c1-9b1684581717")) WHERE id = "d3f58e52-5346-47bc-b736-9d77a0b554ce")))) WHERE value = "down")) WHERE propagationConstraint.add = "propagate")))) WHERE name = "data-transfer-service" AND group = "DataTransfer"))))) WHERE endpoint = "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service"))) WHERE @class INSTANCEOF "EService" \ No newline at end of file diff --git a/src/test/resources/queries/query3-indented.query b/src/test/resources/queries/query3-indented.query new file mode 100644 index 0000000..0772748 --- /dev/null +++ b/src/test/resources/queries/query3-indented.query @@ -0,0 +1,43 @@ +SELECT FROM ( + TRAVERSE outV("EService") FROM ( + TRAVERSE inE("ConsistsOf") FROM ( + SELECT FROM ( + TRAVERSE inV("AccessPointFacet") FROM ( + TRAVERSE outE("ConsistsOf") FROM ( + TRAVERSE outV("EService") FROM ( + TRAVERSE inE("IsIdentifiedBy") FROM ( + SELECT FROM ( + TRAVERSE inV("SoftwareFacet") FROM ( + TRAVERSE outE("IsIdentifiedBy") FROM ( + TRAVERSE outV("EService") FROM ( + SELECT FROM ( + TRAVERSE inE("ConsistsOf") FROM ( + SELECT FROM ( + TRAVERSE inV("StateFacet") FROM ( + TRAVERSE outE("ConsistsOf") FROM ( + TRAVERSE inV("EService") FROM ( + TRAVERSE outE("Activates") FROM ( + TRAVERSE outV("HostingNode") FROM ( + TRAVERSE inE("ConsistsOf") FROM ( + SELECT FROM CPUFacet WHERE vendor = "GenuineIntel" + ) + ) + ) + ) + ) + ) + ) WHERE value = "down" + ) + ) WHERE propagationConstraint.add = "propagate" + ) + ) + ) + ) WHERE name = "data-transfer-service" AND group = "DataTransfer" + ) + ) + ) + ) + ) WHERE endpoint = "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service" + ) + ) +) WHERE @class INSTANCEOF "EService" \ No newline at end of file diff --git a/src/test/resources/queries/query3.query b/src/test/resources/queries/query3.query index 7a2abac..62c7059 100644 --- a/src/test/resources/queries/query3.query +++ b/src/test/resources/queries/query3.query @@ -1 +1 @@ -SELECT FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("AccessPointFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM ( TRAVERSE inV("SoftwareFacet") FROM ( TRAVERSE outE("IsIdentifiedBy") FROM ( TRAVERSE outV("EService") FROM ( SELECT FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("StateFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE inV("EService") FROM ( TRAVERSE outE("Activates") FROM ( TRAVERSE outV("HostingNode") FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("CPUFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE outV("HostingNode") FROM ( SELECT FROM Activates)))) WHERE vendor = "GenuineIntel"))))))) WHERE value = "down")) WHERE propagationConstraint.add = "propagate")))) WHERE name = "data-transfer-service" AND group = "DataTransfer"))))) WHERE endpoint = "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service"))) WHERE @class INSTANCEOF "EService" \ No newline at end of file +SELECT FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("AccessPointFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM ( TRAVERSE inV("SoftwareFacet") FROM ( TRAVERSE outE("IsIdentifiedBy") FROM ( TRAVERSE outV("EService") FROM ( SELECT FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("StateFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE inV("EService") FROM ( TRAVERSE outE("Activates") FROM ( TRAVERSE outV("HostingNode") FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM CPUFacet WHERE vendor = "GenuineIntel"))))))) WHERE value = "down")) WHERE propagationConstraint.add = "propagate")))) WHERE name = "data-transfer-service" AND group = "DataTransfer"))))) WHERE endpoint = "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service"))) WHERE @class INSTANCEOF "EService" \ No newline at end of file diff --git a/src/test/resources/queries/query6-indented.query b/src/test/resources/queries/query6-indented.query new file mode 100644 index 0000000..80ad1ec --- /dev/null +++ b/src/test/resources/queries/query6-indented.query @@ -0,0 +1,47 @@ +SELECT FROM ( + TRAVERSE outV("EService") FROM ( + TRAVERSE inE("ConsistsOf") FROM ( + SELECT FROM ( + TRAVERSE inV("AccessPointFacet") FROM ( + TRAVERSE outE("ConsistsOf") FROM ( + TRAVERSE outV("EService") FROM ( + TRAVERSE inE("IsIdentifiedBy") FROM ( + SELECT FROM ( + TRAVERSE inV("SoftwareFacet") FROM ( + TRAVERSE outE("IsIdentifiedBy") FROM ( + TRAVERSE outV("EService") FROM ( + SELECT FROM ( + TRAVERSE inE("ConsistsOf") FROM ( + SELECT FROM ( + TRAVERSE inV("StateFacet") FROM ( + TRAVERSE outE("ConsistsOf") FROM ( + TRAVERSE inV("EService") FROM ( + SELECT FROM ( + TRAVERSE outE("Activates") FROM ( + SELECT FROM ( + TRAVERSE outV("HostingNode") FROM ( + TRAVERSE inE("ConsistsOf") FROM ( + SELECT FROM CPUFacet WHERE vendor = "GenuineIntel" + ) + ) + ) WHERE id = "5fbc1a56-d450-4f0f-85c1-9b1684581717" + ) + ) WHERE id = "d3f58e52-5346-47bc-b736-9d77a0b554ce" + ) + ) + ) + ) WHERE value = "down" + ) + ) WHERE propagationConstraint.add = "propagate" + ) + ) + ) + ) WHERE name = "data-transfer-service" AND group = "DataTransfer" + ) + ) + ) + ) + ) WHERE endpoint = "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service" + ) + ) +) WHERE id = "0255b7ec-e3da-4071-b456-9a2907ece1db" AND @class INSTANCEOF "EService" \ No newline at end of file diff --git a/src/test/resources/queries/query6.query b/src/test/resources/queries/query6.query index 7892004..345499d 100644 --- a/src/test/resources/queries/query6.query +++ b/src/test/resources/queries/query6.query @@ -1 +1 @@ -SELECT FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("AccessPointFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM ( TRAVERSE inV("SoftwareFacet") FROM ( TRAVERSE outE("IsIdentifiedBy") FROM ( TRAVERSE outV("EService") FROM ( SELECT FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("StateFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE inV("EService") FROM ( TRAVERSE outE("Activates") FROM ( SELECT FROM ( TRAVERSE outV("HostingNode") FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("CPUFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE outV("HostingNode") FROM ( SELECT FROM Activates WHERE id = "d3f58e52-5346-47bc-b736-9d77a0b554ce")))) WHERE vendor = "GenuineIntel"))) WHERE id = "5fbc1a56-d450-4f0f-85c1-9b1684581717"))))) WHERE value = "down")) WHERE propagationConstraint.add = "propagate")))) WHERE name = "data-transfer-service" AND group = "DataTransfer"))))) WHERE endpoint = "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service"))) WHERE id = "0255b7ec-e3da-4071-b456-9a2907ece1db" AND @class INSTANCEOF "EService" \ No newline at end of file +SELECT FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("AccessPointFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM ( TRAVERSE inV("SoftwareFacet") FROM ( TRAVERSE outE("IsIdentifiedBy") FROM ( TRAVERSE outV("EService") FROM ( SELECT FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("StateFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE inV("EService") FROM ( SELECT FROM ( TRAVERSE outE("Activates") FROM ( SELECT FROM ( TRAVERSE outV("HostingNode") FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM CPUFacet WHERE vendor = "GenuineIntel"))) WHERE id = "5fbc1a56-d450-4f0f-85c1-9b1684581717")) WHERE id = "d3f58e52-5346-47bc-b736-9d77a0b554ce")))) WHERE value = "down")) WHERE propagationConstraint.add = "propagate")))) WHERE name = "data-transfer-service" AND group = "DataTransfer"))))) WHERE endpoint = "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service"))) WHERE id = "0255b7ec-e3da-4071-b456-9a2907ece1db" AND @class INSTANCEOF "EService" \ No newline at end of file diff --git a/src/test/resources/queries/query7-indented.query b/src/test/resources/queries/query7-indented.query new file mode 100644 index 0000000..080d01a --- /dev/null +++ b/src/test/resources/queries/query7-indented.query @@ -0,0 +1,11 @@ +SELECT FROM ( + TRAVERSE inV("StateFacet") FROM ( + TRAVERSE outE("ConsistsOf") FROM ( + SELECT FROM EService + WHERE ( + (id = "aec0ef31-c735-4a4c-b2f4-57dfbd2fe925" AND metadata.createdBy <> "luca.frosini") OR + (id = "0255b7ec-e3da-4071-b456-9a2907ece1db" AND metadata.createdBy = "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080") + ) + ) + ) +) WHERE @class INSTANCEOF "StateFacet" \ No newline at end of file diff --git a/src/test/resources/queries/query8-indented.query b/src/test/resources/queries/query8-indented.query new file mode 100644 index 0000000..473af75 --- /dev/null +++ b/src/test/resources/queries/query8-indented.query @@ -0,0 +1,23 @@ +SELECT FROM ( + TRAVERSE inE("CallsFor") FROM ( + TRAVERSE outV("VirtualService") FROM ( + TRAVERSE inE("IsIdentifiedBy") FROM ( + SELECT FROM ( + TRAVERSE inV("SoftwareFacet") FROM ( + TRAVERSE outE("IsIdentifiedBy") FROM ( + TRAVERSE inV("VirtualService") FROM ( + TRAVERSE outE("CallsFor") FROM ( + TRAVERSE outV("EService") FROM ( + TRAVERSE inE("IsIdentifiedBy") FROM ( + SELECT FROM SoftwareFacet WHERE group = "org.gcube.data-catalogue" AND name = "gcat" + ) + ) + ) + ) + ) + ) + ) WHERE group = "org.gcube.data-catalogue" AND name = "catalogue-virtual-service" + ) + ) + ) +) WHERE @class INSTANCEOF "CallsFor" \ No newline at end of file diff --git a/src/test/resources/queries/query8.query b/src/test/resources/queries/query8.query index 6720b28..6d37960 100644 --- a/src/test/resources/queries/query8.query +++ b/src/test/resources/queries/query8.query @@ -1 +1 @@ -TRAVERSE inE("CallsFor") FROM ( TRAVERSE outV("VirtualService") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM ( TRAVERSE inV("SoftwareFacet") FROM ( TRAVERSE outE("IsIdentifiedBy") FROM ( TRAVERSE inV("VirtualService") FROM ( TRAVERSE outE("CallsFor") FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM ( TRAVERSE inV("SoftwareFacet") FROM ( TRAVERSE outE("IsIdentifiedBy") FROM ( TRAVERSE outV("EService") FROM ( SELECT FROM CallsFor)))) WHERE group = "org.gcube.data-catalogue" AND name = "gcat"))))))) WHERE group = "org.gcube.data-catalogue" AND name = "catalogue-virtual-service"))) \ No newline at end of file +SELECT FROM ( TRAVERSE inE("CallsFor") FROM ( TRAVERSE outV("VirtualService") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM ( TRAVERSE inV("SoftwareFacet") FROM ( TRAVERSE outE("IsIdentifiedBy") FROM ( TRAVERSE inV("VirtualService") FROM ( TRAVERSE outE("CallsFor") FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM SoftwareFacet WHERE group = "org.gcube.data-catalogue" AND name = "gcat"))))))) WHERE group = "org.gcube.data-catalogue" AND name = "catalogue-virtual-service")))) WHERE @class INSTANCEOF "CallsFor" \ No newline at end of file diff --git a/src/test/resources/queries/query9-indented.query b/src/test/resources/queries/query9-indented.query new file mode 100644 index 0000000..cfc4309 --- /dev/null +++ b/src/test/resources/queries/query9-indented.query @@ -0,0 +1,25 @@ +SELECT FROM ( + TRAVERSE inV("SimpleFacet") FROM ( + TRAVERSE outE("ConsistsOf") FROM ( + TRAVERSE outV("Configuration") FROM ( + TRAVERSE inE("IsIdentifiedBy") FROM ( + SELECT FROM ( + TRAVERSE inV("IdentifierFacet") FROM ( + TRAVERSE outE("IsIdentifiedBy") FROM ( + TRAVERSE inV("Configuration") FROM ( + TRAVERSE outE("IsCustomizedBy") FROM ( + TRAVERSE outV("VirtualService") FROM ( + TRAVERSE inE("IsIdentifiedBy") FROM ( + SELECT FROM SoftwareFacet WHERE group = "org.gcube.data-catalogue" AND name = "catalogue-virtual-service" + ) + ) + ) + ) + ) + ) + ) WHERE value = "gcat-configuration" + ) + ) + ) + ) +) WHERE @class INSTANCEOF "SimpleFacet" \ No newline at end of file diff --git a/src/test/resources/queries/query9.query b/src/test/resources/queries/query9.query index 258bbba..f335a3f 100644 --- a/src/test/resources/queries/query9.query +++ b/src/test/resources/queries/query9.query @@ -1 +1 @@ -SELECT FROM ( TRAVERSE inV("SimpleFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE outV("Configuration") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM ( TRAVERSE inV("IdentifierFacet") FROM ( TRAVERSE outE("IsIdentifiedBy") FROM ( TRAVERSE inV("Configuration") FROM ( TRAVERSE outE("IsCustomizedBy") FROM ( TRAVERSE outV("VirtualService") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM ( TRAVERSE inV("SoftwareFacet") FROM ( TRAVERSE outE("IsIdentifiedBy") FROM ( TRAVERSE outV("VirtualService") FROM ( SELECT FROM IsCustomizedBy)))) WHERE group = "org.gcube.data-catalogue" AND name = "catalogue-virtual-service"))))))) WHERE value = "gcat-configuration"))))) WHERE @class INSTANCEOF "SimpleFacet" \ No newline at end of file +SELECT FROM ( TRAVERSE inV("SimpleFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE outV("Configuration") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM ( TRAVERSE inV("IdentifierFacet") FROM ( TRAVERSE outE("IsIdentifiedBy") FROM ( TRAVERSE inV("Configuration") FROM ( TRAVERSE outE("IsCustomizedBy") FROM ( TRAVERSE outV("VirtualService") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM SoftwareFacet WHERE group = "org.gcube.data-catalogue" AND name = "catalogue-virtual-service"))))))) WHERE value = "gcat-configuration"))))) WHERE @class INSTANCEOF "SimpleFacet" \ No newline at end of file