330 lines
10 KiB
Java
330 lines
10 KiB
Java
package org.gcube.informationsystem.resourceregistry.queries.json.base.relations;
|
|
|
|
import java.util.List;
|
|
|
|
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;
|
|
import org.gcube.informationsystem.model.reference.relations.ConsistsOf;
|
|
import org.gcube.informationsystem.model.reference.relations.IsRelatedTo;
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
|
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.JsonQueryERElement;
|
|
import org.gcube.informationsystem.resourceregistry.queries.json.base.entities.JsonQueryResource;
|
|
import org.gcube.informationsystem.resourceregistry.utils.OrientDBUtility;
|
|
|
|
/**
|
|
* @author Luca Frosini (ISTI - CNR)
|
|
*/
|
|
public class JsonQueryIsRelatedTo extends JsonQueryRelation {
|
|
|
|
protected String requestedResourceType;
|
|
|
|
public JsonQueryIsRelatedTo(JsonNode jsonQuery) throws SchemaException, ResourceRegistryException {
|
|
super(jsonQuery, AccessType.IS_RELATED_TO);
|
|
direction = null;
|
|
}
|
|
|
|
public String getRequestedResourceType() {
|
|
return requestedResourceType;
|
|
}
|
|
|
|
public void setRequestedResourceType(String requestedResourceType) {
|
|
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;
|
|
}
|
|
|
|
public void setDirectionByJson() throws InvalidQueryException {
|
|
setDirectionByJson(false);
|
|
}
|
|
|
|
public void setDirectionByJson(boolean matchQuery) 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)) {
|
|
logger.trace("{} for type {} has {} property", IsRelatedTo.NAME, type, IsRelatedTo.SOURCE_PROPERTY);
|
|
direction = Direction.OUT;
|
|
found = true;
|
|
}
|
|
|
|
if(jsonNode.has(IsRelatedTo.TARGET_PROPERTY)) {
|
|
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;
|
|
}
|
|
|
|
if(matchQuery) {
|
|
direction = direction.opposite();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public StringBuffer createTraversalQuery(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. ");
|
|
}
|
|
|
|
boolean wrapInnerQuery = false;
|
|
|
|
if(traverseBack) {
|
|
StringBuffer buffer = new StringBuffer();
|
|
buffer.append("TRAVERSE ");
|
|
buffer.append(direction.opposite().name().toLowerCase());
|
|
buffer.append("E(\"");
|
|
buffer.append(type);
|
|
buffer.append("\") FROM ( ");
|
|
buffer.append(stringBuffer);
|
|
buffer.append(")");
|
|
stringBuffer = buffer;
|
|
wrapInnerQuery = true;
|
|
}
|
|
|
|
Direction wrapDirection = direction;
|
|
|
|
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.createTraversalQuery(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;
|
|
}
|
|
|
|
--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.createTraversalQuery(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;
|
|
}
|
|
|
|
@Override
|
|
protected StringBuffer getSpecificMatchQuery(List<JsonQueryERElement> childrenBreadcrumb) 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. ");
|
|
}
|
|
|
|
int childrenPosition = 0;
|
|
|
|
boolean traverseBack = this.traverseBack;
|
|
|
|
StringBuffer newBuffer = new StringBuffer();
|
|
if(jsonNode.has(ConsistsOf.TARGET_PROPERTY)) {
|
|
--size;
|
|
JsonNode targetJsonNode = jsonNode.get(IsRelatedTo.TARGET_PROPERTY);
|
|
JsonQueryResource jsonQueryResource = new JsonQueryResource(targetJsonNode);
|
|
Direction direction = Direction.IN;
|
|
jsonQueryResource.setDirection(direction);
|
|
jsonQueryResource.setBreadcrumb(childrenBreadcrumb);
|
|
jsonQueryResource.setPosition(childrenPosition++);
|
|
jsonQueryResource.setTraverseBack(true);
|
|
newBuffer = jsonQueryResource.createMatchQuery(newBuffer);
|
|
|
|
newBuffer.append("\n\t");
|
|
newBuffer.append(".");
|
|
newBuffer.append(direction.name().toLowerCase());
|
|
newBuffer.append("E('");
|
|
newBuffer.append(type);
|
|
newBuffer.append("') ");
|
|
newBuffer.append(" { where: ($matched.");
|
|
newBuffer.append(getAlias(true));
|
|
newBuffer.append(" == $currentMatch)}");
|
|
|
|
traverseBack = false;
|
|
|
|
}
|
|
|
|
if(jsonNode.has(ConsistsOf.SOURCE_PROPERTY)) {
|
|
--size;
|
|
JsonNode sourceJsonNode = jsonNode.get(IsRelatedTo.SOURCE_PROPERTY);
|
|
JsonQueryResource jsonQueryResource = new JsonQueryResource(sourceJsonNode);
|
|
Direction direction = Direction.OUT;
|
|
jsonQueryResource.setDirection(direction);
|
|
jsonQueryResource.setBreadcrumb(childrenBreadcrumb);
|
|
jsonQueryResource.setPosition(childrenPosition++);
|
|
jsonQueryResource.setTraverseBack(true);
|
|
newBuffer = jsonQueryResource.createMatchQuery(newBuffer);
|
|
|
|
newBuffer.append("\n\t");
|
|
newBuffer.append(".");
|
|
newBuffer.append(direction.name().toLowerCase());
|
|
newBuffer.append("E('");
|
|
newBuffer.append(type);
|
|
newBuffer.append("') ");
|
|
newBuffer.append(" { where: ($matched.");
|
|
newBuffer.append(getAlias(true));
|
|
newBuffer.append(" == $currentMatch)}");
|
|
|
|
traverseBack = false;
|
|
}
|
|
|
|
StringBuffer buffer = new StringBuffer();
|
|
|
|
if(!entryPoint) {
|
|
buffer.append("\n\t");
|
|
buffer.append(".");
|
|
buffer.append(direction.name().toLowerCase());
|
|
buffer.append("E('");
|
|
buffer.append(type);
|
|
buffer.append("')");
|
|
|
|
|
|
alias = getAlias(true);
|
|
StringBuffer sb = null;
|
|
if(size > 0) {
|
|
sb = addConstraints(jsonNode, null, alias);
|
|
}
|
|
|
|
buffer.append(" {");
|
|
buffer.append(" as: ");
|
|
buffer.append(alias);
|
|
buffer.append(",");
|
|
buffer.append(" where: ");
|
|
if(sb!=null && sb.length()>0) {
|
|
buffer.append("(");
|
|
}
|
|
buffer.append("($currentMatch['@class'] INSTANCEOF '");
|
|
buffer.append(type);
|
|
buffer.append("')");
|
|
|
|
if(sb!=null && sb.length()>0) {
|
|
buffer.append(" AND (");
|
|
buffer.append(sb);
|
|
buffer.append(")");
|
|
buffer.append(")");
|
|
}
|
|
|
|
buffer.append("}");
|
|
|
|
|
|
}
|
|
|
|
buffer.append(newBuffer);
|
|
|
|
if(traverseBack) {
|
|
buffer.append("\n\t");
|
|
buffer.append(".");
|
|
buffer.append(direction.opposite().name().toLowerCase());
|
|
buffer.append("E('");
|
|
buffer.append(type);
|
|
buffer.append("') ");
|
|
buffer.append(" { where: ($matched.");
|
|
buffer.append(getAlias(true));
|
|
buffer.append(" == $currentMatch)}");
|
|
}
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
|
}
|