Refactoring JsonQuery
This commit is contained in:
parent
6099c2636e
commit
5a2035d21f
|
@ -1,5 +1,8 @@
|
|||
package org.gcube.informationsystem.resourceregistry.instances.model;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR)
|
||||
*/
|
||||
public enum Operation {
|
||||
|
||||
CREATE,
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
package org.gcube.informationsystem.resourceregistry.query;
|
||||
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.query.InvalidQueryException;
|
||||
|
||||
public interface JsonQuery {
|
||||
|
||||
public String query(String jsonQuery) throws InvalidQueryException, ResourceRegistryException;
|
||||
|
||||
}
|
|
@ -1,297 +0,0 @@
|
|||
package org.gcube.informationsystem.resourceregistry.query;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
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.base.reference.Element;
|
||||
import org.gcube.informationsystem.model.reference.entities.Resource;
|
||||
import org.gcube.informationsystem.model.reference.relations.ConsistsOf;
|
||||
import org.gcube.informationsystem.model.reference.relations.Relation;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.query.InvalidQueryException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.rest.AccessPath;
|
||||
import org.gcube.informationsystem.resourceregistry.contexts.ContextUtility;
|
||||
import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext;
|
||||
import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext.PermissionMode;
|
||||
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagement;
|
||||
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagementUtility;
|
||||
import org.gcube.informationsystem.resourceregistry.instances.model.entities.ResourceManagement;
|
||||
import org.gcube.informationsystem.resourceregistry.utils.Utility;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
|
||||
import com.orientechnologies.orient.core.record.OElement;
|
||||
import com.orientechnologies.orient.core.sql.executor.OResult;
|
||||
import com.orientechnologies.orient.core.sql.executor.OResultSet;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR)
|
||||
*/
|
||||
public class JsonQueryImpl implements JsonQuery {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(JsonQueryImpl.class);
|
||||
|
||||
@Override
|
||||
public String query(String jsonQuery) throws InvalidQueryException, ResourceRegistryException {
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
JsonNode jsonNode = objectMapper.readTree(jsonQuery);
|
||||
return query(jsonNode, objectMapper);
|
||||
} catch(ResourceRegistryException e) {
|
||||
throw e;
|
||||
} catch(Exception e) {
|
||||
throw new InvalidQueryException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
protected StringBuffer createQuery(JsonNode jsonQuery) throws SchemaNotFoundException, InvalidQueryException {
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
|
||||
String requestedResourceType = jsonQuery.get(Element.CLASS_PROPERTY).asText();
|
||||
validateType(requestedResourceType, AccessType.RESOURCE);
|
||||
|
||||
ArrayNode consistsOfArray = (ArrayNode) jsonQuery.get(Resource.CONSISTS_OF_PROPERTY);
|
||||
|
||||
if(consistsOfArray.size()>0) {
|
||||
stringBuffer.append("SELECT FROM (");
|
||||
stringBuffer.append("TRAVERSE outV(\"");
|
||||
stringBuffer.append(requestedResourceType);
|
||||
stringBuffer.append("\") FROM (");
|
||||
|
||||
StringBuffer consistsOfBuffer = new StringBuffer();
|
||||
for(int i=0; i<consistsOfArray.size(); i++) {
|
||||
JsonNode consistsOfJsonNode = consistsOfArray.get(i);
|
||||
consistsOfBuffer = analizeConsistsOf(consistsOfJsonNode, requestedResourceType, consistsOfBuffer, i);
|
||||
}
|
||||
|
||||
stringBuffer.append(consistsOfBuffer);
|
||||
|
||||
|
||||
stringBuffer.append(")");
|
||||
stringBuffer.append(")");
|
||||
}else {
|
||||
stringBuffer.append("SELECT FROM ");
|
||||
stringBuffer.append(requestedResourceType);
|
||||
}
|
||||
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
public String query(JsonNode jsonQuery, ObjectMapper objectMapper) throws InvalidQueryException, ResourceRegistryException {
|
||||
ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
|
||||
ODatabaseDocument oDatabaseDocument = null;
|
||||
try {
|
||||
Integer limit = AccessPath.UNBOUNDED;
|
||||
|
||||
SecurityContext securityContext = ContextUtility.getCurrentSecurityContext();
|
||||
|
||||
oDatabaseDocument = securityContext.getDatabaseDocument(PermissionMode.READER);
|
||||
oDatabaseDocument.begin();
|
||||
|
||||
StringBuffer stringBuffer = createQuery(jsonQuery);
|
||||
stringBuffer.append(" limit :limit");
|
||||
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("limit", limit);
|
||||
|
||||
OResultSet resultSet = oDatabaseDocument.query(stringBuffer.toString(), map);
|
||||
|
||||
|
||||
ArrayNode arrayNode = objectMapper.createArrayNode();
|
||||
|
||||
while(resultSet.hasNext()) {
|
||||
OResult oResult = resultSet.next();
|
||||
OElement element = ElementManagementUtility.getElementFromOptional(oResult.getElement());
|
||||
|
||||
try {
|
||||
JsonNode jsonNodeResult = null;
|
||||
ElementManagement<?,?> erManagement = ElementManagementUtility.getERManagement(securityContext, oDatabaseDocument,
|
||||
element);
|
||||
if(erManagement instanceof ResourceManagement) {
|
||||
jsonNodeResult = erManagement.serializeAsJsonNode();
|
||||
arrayNode.add(jsonNodeResult);
|
||||
}else {
|
||||
// Got relations and facets because the query does not include @class="TypeName" to support polymorphism
|
||||
}
|
||||
|
||||
} catch(ResourceRegistryException e) {
|
||||
logger.error("Unable to correctly serialize {}. It will be excluded from results. {}",
|
||||
element.toString(), Utility.SHOULD_NOT_OCCUR_ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
return objectMapper.writeValueAsString(arrayNode);
|
||||
|
||||
} catch(Exception e) {
|
||||
throw new InvalidQueryException(e.getMessage());
|
||||
} finally {
|
||||
if(oDatabaseDocument != null) {
|
||||
oDatabaseDocument.close();
|
||||
}
|
||||
if(current!=null) {
|
||||
current.activateOnCurrentThread();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private StringBuffer addNameToCompare(StringBuffer stringBuffer, String fieldName, String fieldNamePrefix) {
|
||||
if(fieldNamePrefix!=null) {
|
||||
stringBuffer.append(fieldNamePrefix);
|
||||
stringBuffer.append(".");
|
||||
}
|
||||
stringBuffer.append(fieldName);
|
||||
stringBuffer.append("=");
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
private StringBuffer addValueToMatch(StringBuffer stringBuffer, JsonNode gotJoJsonNode, String value) {
|
||||
if(gotJoJsonNode.isNumber()) {
|
||||
stringBuffer.append(value);
|
||||
} else {
|
||||
stringBuffer.append("\"");
|
||||
stringBuffer.append(value);
|
||||
stringBuffer.append("\"");
|
||||
}
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
private StringBuffer getNameValueToMatch(JsonNode jsonNode, String fieldName, String fieldNamePrefix) throws InvalidQueryException {
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
JsonNode gotJoJsonNode = jsonNode.get(fieldName);
|
||||
|
||||
if(gotJoJsonNode.isContainerNode()) {
|
||||
if(gotJoJsonNode.isArray()) {
|
||||
throw new InvalidQueryException("Array not supported for " + fieldName);
|
||||
}
|
||||
|
||||
if(gotJoJsonNode.isObject()) {
|
||||
StringBuffer newPrefix = new StringBuffer();
|
||||
if(fieldNamePrefix!=null) {
|
||||
newPrefix.append(fieldNamePrefix);
|
||||
newPrefix.append(".");
|
||||
}
|
||||
newPrefix.append(fieldName);
|
||||
return addWhereConstraint(gotJoJsonNode, stringBuffer, newPrefix.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
addNameToCompare(stringBuffer, fieldName, fieldNamePrefix);
|
||||
String value = jsonNode.get(fieldName).asText();
|
||||
addValueToMatch(stringBuffer, gotJoJsonNode, value);
|
||||
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
|
||||
private StringBuffer addWhereConstraint(JsonNode jsonNode, StringBuffer stringBuffer, String fieldNamePrefix) throws InvalidQueryException {
|
||||
Iterator<String> iterator = jsonNode.fieldNames();
|
||||
boolean first = true;
|
||||
while(iterator.hasNext()) {
|
||||
String fieldName = iterator.next();
|
||||
|
||||
if(fieldName.compareTo(Element.CLASS_PROPERTY)==0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(fieldName.compareTo(Relation.TARGET_PROPERTY)==0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(first) {
|
||||
first = false;
|
||||
}else {
|
||||
stringBuffer.append(" AND ");
|
||||
}
|
||||
|
||||
|
||||
stringBuffer.append(getNameValueToMatch(jsonNode, fieldName, fieldNamePrefix));
|
||||
|
||||
|
||||
}
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
private StringBuffer analizeFacet(JsonNode facetJsonNode, StringBuffer stringBuffer, int i) throws InvalidQueryException {
|
||||
StringBuffer newBuffer = new StringBuffer();
|
||||
int size = facetJsonNode.size();
|
||||
newBuffer.append("SELECT FROM ");
|
||||
|
||||
String facetType = facetJsonNode.get(Element.CLASS_PROPERTY).asText();
|
||||
if(i!=0) {
|
||||
newBuffer.append(" (");
|
||||
newBuffer.append("TRAVERSE inV(\"");
|
||||
}
|
||||
|
||||
newBuffer.append(facetType);
|
||||
|
||||
if(i!=0) {
|
||||
newBuffer.append("\") FROM (");
|
||||
newBuffer.append(stringBuffer);
|
||||
newBuffer.append(")");
|
||||
newBuffer.append(")");
|
||||
}
|
||||
|
||||
// Size 1 means that only '@class' property is present
|
||||
if(size > 1) {
|
||||
newBuffer.append(" WHERE ");
|
||||
addWhereConstraint(facetJsonNode, newBuffer, null);
|
||||
}
|
||||
|
||||
return newBuffer;
|
||||
}
|
||||
|
||||
private StringBuffer analizeConsistsOf(JsonNode consistsOfJsonNode, String resourceType, StringBuffer stringBuffer, int i) throws InvalidQueryException {
|
||||
StringBuffer newBuffer = new StringBuffer();
|
||||
|
||||
int size = consistsOfJsonNode.size();
|
||||
if(size > 2) {
|
||||
newBuffer.append("SELECT FROM ( ");
|
||||
}
|
||||
|
||||
newBuffer.append("TRAVERSE inE(\"");
|
||||
String consistsOfType = consistsOfJsonNode.get(Element.CLASS_PROPERTY).asText();
|
||||
newBuffer.append(consistsOfType);
|
||||
newBuffer.append("\") FROM ("); // Open (
|
||||
|
||||
JsonNode facetJsonNode = consistsOfJsonNode.get(ConsistsOf.TARGET_PROPERTY);
|
||||
if(i>0) {
|
||||
StringBuffer anotherBuffer = new StringBuffer();
|
||||
anotherBuffer.append(" TRAVERSE outV(\"");
|
||||
anotherBuffer.append(resourceType);
|
||||
anotherBuffer.append("\").outE(\"");
|
||||
anotherBuffer.append(consistsOfType);
|
||||
anotherBuffer.append("\") FROM (");
|
||||
anotherBuffer.append(stringBuffer);
|
||||
anotherBuffer.append(")");
|
||||
|
||||
stringBuffer = anotherBuffer;
|
||||
}
|
||||
|
||||
newBuffer.append(analizeFacet(facetJsonNode, stringBuffer, i));
|
||||
|
||||
newBuffer.append(")"); // Close )
|
||||
|
||||
// Size 2 means that only '@class' and 'target' properties present
|
||||
if(size > 2) {
|
||||
newBuffer.append(") WHERE ");
|
||||
addWhereConstraint(consistsOfJsonNode, newBuffer, null);
|
||||
}
|
||||
|
||||
return newBuffer;
|
||||
|
||||
}
|
||||
|
||||
private void validateType(String requestedResourceType, AccessType resource) throws SchemaNotFoundException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -8,7 +8,5 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.query.Invalid
|
|||
public interface Query {
|
||||
|
||||
public String query(String query, Integer limit, String fetchPlan, boolean raw) throws InvalidQueryException;
|
||||
|
||||
public String gremlinQuery(String query) throws InvalidQueryException;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -102,39 +102,4 @@ public class QueryImpl implements Query {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String gremlinQuery(String query) throws InvalidQueryException {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
/*
|
||||
OGremlinHelper.global().create();
|
||||
|
||||
ODatabaseDocumentTx oDatabaseDocumentTx = null;
|
||||
try {
|
||||
oDatabaseDocumentTx = ContextUtility.getActualSecurityContextDatabaseTx(PermissionMode.READER);
|
||||
|
||||
String finalQuery = String.format("select gremlin('%s')", query);
|
||||
OCommandSQL OCommandSQL = new OCommandSQL(finalQuery);
|
||||
OCommandRequest oCommandRequest = oDatabaseDocumentTx.command(OCommandSQL);
|
||||
OBasicResultSet res = oCommandRequest.execute();
|
||||
|
||||
Iterator iterator = res.iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
ODocument oDocument = (ODocument) iterator.next();
|
||||
logger.debug("{}", oDocument);
|
||||
}
|
||||
|
||||
return res.toString();
|
||||
|
||||
} catch(Exception e) {
|
||||
throw new InvalidQueryException(e.getMessage());
|
||||
} finally {
|
||||
if(oDatabaseDocumentTx != null) {
|
||||
oDatabaseDocumentTx.close();
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
package org.gcube.informationsystem.resourceregistry.query.json;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
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.Direction;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.query.InvalidQueryException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.rest.AccessPath;
|
||||
import org.gcube.informationsystem.resourceregistry.contexts.ContextUtility;
|
||||
import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext;
|
||||
import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext.PermissionMode;
|
||||
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagement;
|
||||
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagementUtility;
|
||||
import org.gcube.informationsystem.resourceregistry.instances.model.entities.ResourceManagement;
|
||||
import org.gcube.informationsystem.resourceregistry.utils.Utility;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
|
||||
import com.orientechnologies.orient.core.record.OElement;
|
||||
import com.orientechnologies.orient.core.sql.executor.OResult;
|
||||
import com.orientechnologies.orient.core.sql.executor.OResultSet;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR)
|
||||
*/
|
||||
public class JsonQuery {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(JsonQuery.class);
|
||||
|
||||
public StringBuffer createQuery(JsonNode jsonQuery) throws SchemaNotFoundException, InvalidQueryException {
|
||||
JsonQueryResource jsonQueryResource = new JsonQueryResource(jsonQuery);
|
||||
jsonQueryResource.setEntryPoint(true);
|
||||
jsonQueryResource.setDirection(Direction.OUT);
|
||||
|
||||
return jsonQueryResource.analize(new StringBuffer());
|
||||
}
|
||||
|
||||
public String query(String jsonQuery) throws InvalidQueryException, ResourceRegistryException {
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
JsonNode jsonNode = objectMapper.readTree(jsonQuery);
|
||||
return query(jsonNode, objectMapper);
|
||||
} catch(ResourceRegistryException e) {
|
||||
throw e;
|
||||
} catch(Exception e) {
|
||||
throw new InvalidQueryException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public String query(JsonNode jsonQuery, ObjectMapper objectMapper) throws InvalidQueryException, ResourceRegistryException {
|
||||
ODatabaseDocument current = ContextUtility.getCurrentODatabaseDocumentFromThreadLocal();
|
||||
ODatabaseDocument oDatabaseDocument = null;
|
||||
try {
|
||||
Integer limit = AccessPath.UNBOUNDED;
|
||||
|
||||
SecurityContext securityContext = ContextUtility.getCurrentSecurityContext();
|
||||
|
||||
oDatabaseDocument = securityContext.getDatabaseDocument(PermissionMode.READER);
|
||||
oDatabaseDocument.begin();
|
||||
|
||||
StringBuffer stringBuffer = createQuery(jsonQuery);
|
||||
stringBuffer.append(" limit :limit");
|
||||
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("limit", limit);
|
||||
|
||||
OResultSet resultSet = oDatabaseDocument.query(stringBuffer.toString(), map);
|
||||
|
||||
ArrayNode arrayNode = objectMapper.createArrayNode();
|
||||
|
||||
while(resultSet.hasNext()) {
|
||||
OResult oResult = resultSet.next();
|
||||
OElement element = ElementManagementUtility.getElementFromOptional(oResult.getElement());
|
||||
|
||||
try {
|
||||
JsonNode jsonNodeResult = null;
|
||||
ElementManagement<?,?> erManagement = ElementManagementUtility.getERManagement(securityContext, oDatabaseDocument,
|
||||
element);
|
||||
if(erManagement instanceof ResourceManagement) {
|
||||
jsonNodeResult = erManagement.serializeAsJsonNode();
|
||||
arrayNode.add(jsonNodeResult);
|
||||
}else {
|
||||
// Got relations and facets because the query does not include @class="TypeName" to support polymorphism
|
||||
}
|
||||
|
||||
} catch(ResourceRegistryException e) {
|
||||
logger.error("Unable to correctly serialize {}. It will be excluded from results. {}",
|
||||
element.toString(), Utility.SHOULD_NOT_OCCUR_ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
return objectMapper.writeValueAsString(arrayNode);
|
||||
|
||||
} catch(Exception e) {
|
||||
throw new InvalidQueryException(e.getMessage());
|
||||
} finally {
|
||||
if(oDatabaseDocument != null) {
|
||||
oDatabaseDocument.close();
|
||||
}
|
||||
if(current!=null) {
|
||||
current.activateOnCurrentThread();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package org.gcube.informationsystem.resourceregistry.query.json;
|
||||
|
||||
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.gcube.informationsystem.base.reference.AccessType;
|
||||
import org.gcube.informationsystem.model.reference.relations.ConsistsOf;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.query.InvalidQueryException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR)
|
||||
*/
|
||||
public class JsonQueryConsistsOf extends JsonQueryERElement{
|
||||
|
||||
protected String requestedResourceType;
|
||||
|
||||
public JsonQueryConsistsOf(JsonNode jsonQuery) throws SchemaNotFoundException {
|
||||
super(jsonQuery, AccessType.CONSISTS_OF);
|
||||
}
|
||||
|
||||
public String getRequestedResourceType() {
|
||||
return requestedResourceType;
|
||||
}
|
||||
|
||||
public void setRequestedResourceType(String requestedResourceType) {
|
||||
this.requestedResourceType = requestedResourceType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StringBuffer analize(StringBuffer stringBuffer) throws SchemaNotFoundException, InvalidQueryException {
|
||||
StringBuffer newBuffer = new StringBuffer();
|
||||
|
||||
int size = jsonNode.size();
|
||||
if(size > 2) {
|
||||
newBuffer.append("SELECT FROM ( ");
|
||||
}
|
||||
|
||||
newBuffer.append("TRAVERSE inE(\"");
|
||||
newBuffer.append(type);
|
||||
newBuffer.append("\") FROM ("); // Open (
|
||||
|
||||
if(!entryPoint) {
|
||||
StringBuffer anotherBuffer = new StringBuffer();
|
||||
anotherBuffer.append(" TRAVERSE outV(\"");
|
||||
anotherBuffer.append(requestedResourceType);
|
||||
anotherBuffer.append("\").outE(\"");
|
||||
anotherBuffer.append(type);
|
||||
anotherBuffer.append("\") FROM (");
|
||||
anotherBuffer.append(stringBuffer);
|
||||
anotherBuffer.append(")");
|
||||
|
||||
stringBuffer = anotherBuffer;
|
||||
}
|
||||
|
||||
|
||||
JsonNode facetJsonNode = jsonNode.get(ConsistsOf.TARGET_PROPERTY);
|
||||
JsonQueryFacet jsonQueryFacet = new JsonQueryFacet(facetJsonNode);
|
||||
jsonQueryFacet.setEntryPoint(entryPoint);
|
||||
|
||||
newBuffer.append(jsonQueryFacet.analize(stringBuffer));
|
||||
|
||||
newBuffer.append(")"); // Close )
|
||||
|
||||
// Size 2 means that only '@class' and 'target' properties present
|
||||
if(size > 2) {
|
||||
newBuffer.append(") WHERE ");
|
||||
addWhereConstraint(jsonNode, newBuffer, null);
|
||||
}
|
||||
|
||||
return newBuffer;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
package org.gcube.informationsystem.resourceregistry.query.json;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.gcube.informationsystem.base.reference.AccessType;
|
||||
import org.gcube.informationsystem.base.reference.Direction;
|
||||
import org.gcube.informationsystem.base.reference.Element;
|
||||
import org.gcube.informationsystem.model.reference.relations.Relation;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.query.InvalidQueryException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException;
|
||||
|
||||
public abstract class JsonQueryERElement {
|
||||
|
||||
// private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
public static void validateType(String type, AccessType resource) throws SchemaNotFoundException {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
protected final String type;
|
||||
protected final JsonNode jsonNode;
|
||||
protected final AccessType accessType;
|
||||
|
||||
protected Direction direction;
|
||||
protected boolean entryPoint;
|
||||
|
||||
public JsonQueryERElement(JsonNode jsonQuery, AccessType accessType) throws SchemaNotFoundException {
|
||||
this.type = jsonQuery.get(Element.CLASS_PROPERTY).asText();
|
||||
this.jsonNode = jsonQuery;
|
||||
this.accessType = accessType;
|
||||
this.entryPoint = false;
|
||||
validateType(this.type, this.accessType);
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
public Direction getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public void setDirection(Direction direction) {
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public boolean isEntryPoint() {
|
||||
return entryPoint;
|
||||
}
|
||||
|
||||
public void setEntryPoint(boolean entryPoint) {
|
||||
this.entryPoint = entryPoint;
|
||||
}
|
||||
|
||||
protected abstract StringBuffer analize(StringBuffer stringBuffer) throws SchemaNotFoundException, InvalidQueryException;
|
||||
|
||||
protected StringBuffer addWhereConstraint(JsonNode jsonNode, StringBuffer stringBuffer, String fieldNamePrefix) throws InvalidQueryException {
|
||||
Iterator<String> iterator = jsonNode.fieldNames();
|
||||
|
||||
boolean first = true;
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
String fieldName = iterator.next();
|
||||
|
||||
if(fieldName.compareTo(Element.CLASS_PROPERTY)==0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(fieldName.compareTo(Relation.TARGET_PROPERTY)==0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(first) {
|
||||
first = false;
|
||||
}else {
|
||||
stringBuffer.append(" AND ");
|
||||
}
|
||||
|
||||
stringBuffer.append(getNameValueToMatch(jsonNode, fieldName, fieldNamePrefix));
|
||||
}
|
||||
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
private StringBuffer getNameValueToMatch(JsonNode jsonNode, String fieldName, String fieldNamePrefix) throws InvalidQueryException {
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
JsonNode gotJoJsonNode = jsonNode.get(fieldName);
|
||||
|
||||
if(gotJoJsonNode.isContainerNode()) {
|
||||
if(gotJoJsonNode.isArray()) {
|
||||
throw new InvalidQueryException("Array not supported for " + fieldName);
|
||||
}
|
||||
|
||||
if(gotJoJsonNode.isObject()) {
|
||||
StringBuffer newPrefix = new StringBuffer();
|
||||
if(fieldNamePrefix!=null) {
|
||||
newPrefix.append(fieldNamePrefix);
|
||||
newPrefix.append(".");
|
||||
}
|
||||
newPrefix.append(fieldName);
|
||||
return addWhereConstraint(gotJoJsonNode, stringBuffer, newPrefix.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
addNameToCompare(stringBuffer, fieldName, fieldNamePrefix);
|
||||
String value = jsonNode.get(fieldName).asText();
|
||||
addValueToMatch(stringBuffer, gotJoJsonNode, value);
|
||||
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
protected StringBuffer addNameToCompare(StringBuffer stringBuffer, String fieldName, String fieldNamePrefix) {
|
||||
if(fieldNamePrefix!=null) {
|
||||
stringBuffer.append(fieldNamePrefix);
|
||||
stringBuffer.append(".");
|
||||
}
|
||||
stringBuffer.append(fieldName);
|
||||
stringBuffer.append("=");
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
protected StringBuffer addValueToMatch(StringBuffer stringBuffer, JsonNode gotJoJsonNode, String value) {
|
||||
if(gotJoJsonNode.isNumber()) {
|
||||
stringBuffer.append(value);
|
||||
} else {
|
||||
stringBuffer.append("\"");
|
||||
stringBuffer.append(value);
|
||||
stringBuffer.append("\"");
|
||||
}
|
||||
return stringBuffer;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package org.gcube.informationsystem.resourceregistry.query.json;
|
||||
|
||||
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.gcube.informationsystem.base.reference.AccessType;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.query.InvalidQueryException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR)
|
||||
*/
|
||||
public class JsonQueryFacet extends JsonQueryERElement{
|
||||
|
||||
public JsonQueryFacet(JsonNode jsonQuery) throws SchemaNotFoundException {
|
||||
super(jsonQuery, AccessType.FACET);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StringBuffer analize(StringBuffer stringBuffer) throws SchemaNotFoundException, InvalidQueryException {
|
||||
StringBuffer newBuffer = new StringBuffer();
|
||||
|
||||
int size = jsonNode.size();
|
||||
newBuffer.append("SELECT FROM ");
|
||||
|
||||
if(!entryPoint) {
|
||||
newBuffer.append(" (");
|
||||
newBuffer.append("TRAVERSE inV(\"");
|
||||
}
|
||||
|
||||
newBuffer.append(type);
|
||||
|
||||
if(!entryPoint) {
|
||||
newBuffer.append("\") FROM (");
|
||||
newBuffer.append(stringBuffer);
|
||||
newBuffer.append(")");
|
||||
newBuffer.append(")");
|
||||
}
|
||||
|
||||
// Size 1 means that only '@class' property is present
|
||||
if(size > 1) {
|
||||
newBuffer.append(" WHERE ");
|
||||
addWhereConstraint(jsonNode, newBuffer, null);
|
||||
}
|
||||
|
||||
return newBuffer;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package org.gcube.informationsystem.resourceregistry.query.json;
|
||||
|
||||
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.gcube.informationsystem.base.reference.AccessType;
|
||||
import org.gcube.informationsystem.base.reference.Direction;
|
||||
import org.gcube.informationsystem.model.reference.relations.ConsistsOf;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.query.InvalidQueryException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR)
|
||||
*/
|
||||
public class JsonQueryIsRelatedTo extends JsonQueryERElement{
|
||||
|
||||
protected String requestedResourceType;
|
||||
|
||||
public JsonQueryIsRelatedTo(JsonNode jsonQuery) throws SchemaNotFoundException {
|
||||
super(jsonQuery, AccessType.IS_RELATED_TO);
|
||||
}
|
||||
|
||||
public String getRequestedResourceType() {
|
||||
return requestedResourceType;
|
||||
}
|
||||
|
||||
public void setRequestedResourceType(String requestedResourceType) {
|
||||
this.requestedResourceType = requestedResourceType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StringBuffer analize(StringBuffer stringBuffer) throws SchemaNotFoundException, InvalidQueryException {
|
||||
StringBuffer newBuffer = new StringBuffer();
|
||||
|
||||
int size = jsonNode.size();
|
||||
if(size > 2) {
|
||||
newBuffer.append("SELECT FROM ( ");
|
||||
}
|
||||
|
||||
JsonNode targetJsonNode = jsonNode.get(ConsistsOf.SOURCE_PROPERTY);
|
||||
JsonNode sourceJsonNode = jsonNode.get(ConsistsOf.TARGET_PROPERTY);
|
||||
|
||||
JsonNode resourceJsonNode = null;
|
||||
Direction direction = null;
|
||||
|
||||
if(targetJsonNode!=null) {
|
||||
newBuffer.append("TRAVERSE outE(\"");
|
||||
resourceJsonNode = targetJsonNode;
|
||||
// TODO Check
|
||||
direction = Direction.IN;
|
||||
}else if(sourceJsonNode!=null) {
|
||||
newBuffer.append("TRAVERSE inE(\"");
|
||||
resourceJsonNode = sourceJsonNode;
|
||||
// TODO Check
|
||||
direction = Direction.OUT;
|
||||
}
|
||||
|
||||
newBuffer.append(type);
|
||||
newBuffer.append("\") FROM ("); // Open (
|
||||
newBuffer.append(stringBuffer);
|
||||
newBuffer.append(")"); // Close )
|
||||
|
||||
JsonQueryResource jsonQueryResource = new JsonQueryResource(resourceJsonNode);
|
||||
jsonQueryResource.setDirection(direction);
|
||||
stringBuffer = jsonQueryResource.analize(newBuffer);
|
||||
|
||||
return stringBuffer;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package org.gcube.informationsystem.resourceregistry.query.json;
|
||||
|
||||
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import org.gcube.informationsystem.base.reference.AccessType;
|
||||
import org.gcube.informationsystem.model.reference.entities.Resource;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.query.InvalidQueryException;
|
||||
import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR)
|
||||
*/
|
||||
public class JsonQueryResource extends JsonQueryERElement {
|
||||
|
||||
public JsonQueryResource(JsonNode jsonQuery) throws SchemaNotFoundException {
|
||||
super(jsonQuery, AccessType.RESOURCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StringBuffer analize(StringBuffer stringBuffer) throws SchemaNotFoundException, InvalidQueryException {
|
||||
|
||||
ArrayNode consistsOfArray = (ArrayNode) jsonNode.get(Resource.CONSISTS_OF_PROPERTY);
|
||||
|
||||
boolean initFound = false;
|
||||
|
||||
if(consistsOfArray!=null && consistsOfArray.size()>0) {
|
||||
StringBuffer consistsOfBuffer = new StringBuffer();
|
||||
|
||||
initFound = true;
|
||||
|
||||
consistsOfBuffer.append("TRAVERSE ");
|
||||
consistsOfBuffer.append(direction.name().toLowerCase());
|
||||
consistsOfBuffer.append("V(\"");
|
||||
consistsOfBuffer.append(type);
|
||||
consistsOfBuffer.append("\") FROM (");
|
||||
|
||||
for(int i=0; i<consistsOfArray.size(); i++) {
|
||||
JsonNode consistsOfJsonNode = consistsOfArray.get(i);
|
||||
JsonQueryConsistsOf jsonQueryConsistsOf = new JsonQueryConsistsOf(consistsOfJsonNode);
|
||||
jsonQueryConsistsOf.setRequestedResourceType(type);
|
||||
jsonQueryConsistsOf.setEntryPoint(i==0);
|
||||
stringBuffer = jsonQueryConsistsOf.analize(stringBuffer);
|
||||
}
|
||||
|
||||
consistsOfBuffer.append(stringBuffer);
|
||||
consistsOfBuffer.append(")");
|
||||
|
||||
stringBuffer = consistsOfBuffer;
|
||||
}
|
||||
|
||||
ArrayNode isRelatedToArray = (ArrayNode) jsonNode.get(Resource.IS_RELATED_TO_PROPERTY);
|
||||
|
||||
if(isRelatedToArray!=null && isRelatedToArray.size()>0) {
|
||||
|
||||
StringBuffer isRelatedToBuffer = new StringBuffer();
|
||||
|
||||
for(int i=0; i<isRelatedToArray.size(); i++) {
|
||||
JsonNode isRelatedToJsonNode = isRelatedToArray.get(i);
|
||||
JsonQueryIsRelatedTo jsonQueryIsRelatedTo = new JsonQueryIsRelatedTo(isRelatedToJsonNode);
|
||||
jsonQueryIsRelatedTo.setRequestedResourceType(type);
|
||||
jsonQueryIsRelatedTo.setEntryPoint(!initFound && i==0);
|
||||
stringBuffer = jsonQueryIsRelatedTo.analize(stringBuffer);
|
||||
}
|
||||
|
||||
initFound = true;
|
||||
|
||||
isRelatedToBuffer.append(stringBuffer);
|
||||
|
||||
stringBuffer = isRelatedToBuffer;
|
||||
}
|
||||
|
||||
|
||||
if(!initFound) {
|
||||
if(entryPoint) {
|
||||
stringBuffer = new StringBuffer();
|
||||
stringBuffer.append("SELECT FROM ");
|
||||
stringBuffer.append(type);
|
||||
}else {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
}
|
|
@ -36,10 +36,9 @@ import org.gcube.informationsystem.resourceregistry.contexts.entities.ContextMan
|
|||
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagement;
|
||||
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagementUtility;
|
||||
import org.gcube.informationsystem.resourceregistry.instances.model.entities.ResourceManagement;
|
||||
import org.gcube.informationsystem.resourceregistry.query.JsonQuery;
|
||||
import org.gcube.informationsystem.resourceregistry.query.JsonQueryImpl;
|
||||
import org.gcube.informationsystem.resourceregistry.query.Query;
|
||||
import org.gcube.informationsystem.resourceregistry.query.QueryImpl;
|
||||
import org.gcube.informationsystem.resourceregistry.query.json.JsonQuery;
|
||||
import org.gcube.informationsystem.resourceregistry.types.SchemaManagement;
|
||||
import org.gcube.informationsystem.types.TypeMapper;
|
||||
import org.gcube.informationsystem.types.reference.Type;
|
||||
|
@ -305,7 +304,7 @@ public class Access extends BaseRest {
|
|||
checkHierarchicalMode();
|
||||
checkIncludeInstancesContexts();
|
||||
|
||||
JsonQuery jsonQueryManager = new JsonQueryImpl();
|
||||
JsonQuery jsonQueryManager = new JsonQuery();
|
||||
return jsonQueryManager.query(jsonQuery);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,14 @@ import java.net.URL;
|
|||
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.gcube.informationsystem.resourceregistry.ContextTest;
|
||||
import org.gcube.informationsystem.resourceregistry.query.json.JsonQuery;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Luca Frosini (ISTI - CNR)
|
||||
*/
|
||||
public class JsonQueryTest extends ContextTest {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(JsonQueryTest.class);
|
||||
|
@ -22,7 +26,7 @@ public class JsonQueryTest extends ContextTest {
|
|||
JsonNode jsonNode = objectMapper.readTree(queryFile);
|
||||
logger.info("Going to test the following JSON query {}", jsonNode.toString());
|
||||
|
||||
JsonQueryImpl jsonQuery = new JsonQueryImpl();
|
||||
JsonQuery jsonQuery = new JsonQuery();
|
||||
StringBuffer stringBuffer = jsonQuery.createQuery(jsonNode);
|
||||
|
||||
logger.info(stringBuffer.toString());
|
||||
|
@ -38,7 +42,7 @@ public class JsonQueryTest extends ContextTest {
|
|||
JsonNode jsonNode = objectMapper.readTree(queryFile);
|
||||
logger.info("Going to test the following JSON query {}", jsonNode.toString());
|
||||
|
||||
JsonQueryImpl jsonQuery = new JsonQueryImpl();
|
||||
JsonQuery jsonQuery = new JsonQuery();
|
||||
String res = jsonQuery.query(jsonNode, objectMapper);
|
||||
logger.info(res);
|
||||
}
|
||||
|
|
|
@ -27,13 +27,5 @@
|
|||
"endpoint": "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service"
|
||||
}
|
||||
}
|
||||
],
|
||||
"isRelatedTo" : [
|
||||
{
|
||||
"@class": "activates",
|
||||
"source": {
|
||||
"@class": "HostingNode"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue