resource-registry/src/main/java/org/gcube/informationsystem/resourceregistry/queries/json/base/JsonQueryERElement.java

214 lines
7.1 KiB
Java

package org.gcube.informationsystem.resourceregistry.queries.json.base;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
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.com.fasterxml.jackson.databind.node.ObjectNode;
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.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.api.exceptions.types.SchemaNotFoundException;
import org.gcube.informationsystem.resourceregistry.queries.operators.QueryConditionalOperator;
import org.gcube.informationsystem.resourceregistry.queries.operators.QueryLogicalOperator;
import org.gcube.informationsystem.resourceregistry.types.TypesCache;
public abstract class JsonQueryERElement {
// private Logger logger = LoggerFactory.getLogger(this.getClass());
public static void validateType(String type, AccessType requiredAccessType) throws SchemaException, ResourceRegistryException {
AccessType accessType = TypesCache.getInstance().getCachedType(type).getAccessType();
if(!accessType.equals(requiredAccessType)) {
throw new InvalidQueryException(type + "is not an expected " + requiredAccessType.getName() + " type");
}
}
protected final ObjectMapper objectMapper;
protected final String type;
protected final JsonNode jsonNode;
protected final AccessType accessType;
protected final Set<String> fieldNamesToRemove;
protected Direction direction;
protected boolean entryPoint;
public JsonQueryERElement(JsonNode jsonQuery, AccessType accessType) throws SchemaException, ResourceRegistryException {
this.objectMapper = new ObjectMapper();
this.type = jsonQuery.get(Element.CLASS_PROPERTY).asText();
this.jsonNode = jsonQuery;
this.accessType = accessType;
this.entryPoint = false;
this.fieldNamesToRemove = new HashSet<>();
fieldNamesToRemove.add(Element.CLASS_PROPERTY);
fieldNamesToRemove.add(Element.SUPERCLASSES_PROPERTY);
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;
}
public abstract StringBuffer analize(StringBuffer stringBuffer) throws SchemaNotFoundException, InvalidQueryException, SchemaException, ResourceRegistryException;
protected StringBuffer addConstraints(JsonNode jsonNode, QueryLogicalOperator queryLogicalOperator, String fieldNamePrefix) throws InvalidQueryException {
StringBuffer stringBuffer = new StringBuffer();
if(queryLogicalOperator==null) {
queryLogicalOperator = QueryLogicalOperator.AND;
}
JsonNode copiedJsonNode = jsonNode.deepCopy();
if(jsonNode.isObject()) {
ObjectNode objectNode = (ObjectNode) copiedJsonNode;
objectNode.remove(fieldNamesToRemove);
Iterator<String> iterator = objectNode.fieldNames();
boolean first = true;
while(iterator.hasNext()) {
String fieldName = iterator.next();
if(first) {
first = false;
}else {
stringBuffer.append(queryLogicalOperator.getLogicalOperator());
}
JsonNode node = objectNode.get(fieldName);
stringBuffer.append(evaluateNode(node, fieldName, fieldNamePrefix));
}
}
if(jsonNode.isArray()) {
ArrayNode arrayNode = (ArrayNode) copiedJsonNode;
Iterator<JsonNode> iterator = arrayNode.iterator();
boolean first = true;
while(iterator.hasNext()) {
if(first) {
first = false;
}else {
stringBuffer.append(queryLogicalOperator.getLogicalOperator());
}
JsonNode node = iterator.next();
stringBuffer.append(evaluateNode(node, null, fieldNamePrefix));
}
}
return stringBuffer;
}
protected StringBuffer evaluateNode(JsonNode jsonNode, String fieldName, String fieldNamePrefix) throws InvalidQueryException {
StringBuffer stringBuffer = new StringBuffer();
if(QueryLogicalOperator.getOperators().contains(fieldName)) {
QueryLogicalOperator queryLogicalOperator = QueryLogicalOperator.getQueryLogicalOperator(fieldName);
stringBuffer.append("(");
stringBuffer.append(addConstraints(jsonNode, queryLogicalOperator, fieldNamePrefix));
stringBuffer.append(")");
return stringBuffer;
}
if(QueryConditionalOperator.getOperators().contains(fieldName)) {
QueryConditionalOperator queryConditionalOperator = QueryConditionalOperator.getQueryComparisonOperator(fieldName);
if(queryConditionalOperator == QueryConditionalOperator.IN) {
throw new UnsupportedOperationException();
}
StringBuffer key = getKey(null, fieldNamePrefix);
StringBuffer value = getValue(jsonNode);
stringBuffer.append(addCondition(queryConditionalOperator, key, value));
return stringBuffer;
}
if(jsonNode.isObject()) {
StringBuffer newPrefix = new StringBuffer();
if(fieldNamePrefix!=null && fieldNamePrefix.compareTo("")!=0) {
newPrefix.append(fieldNamePrefix);
if(fieldName!=null && fieldName.compareTo("")!=0) {
newPrefix.append(".");
}
}
if(fieldName!=null && fieldName.compareTo("")!=0) {
newPrefix.append(fieldName);
}
stringBuffer.append(addConstraints(jsonNode, null, newPrefix.toString()));
return stringBuffer;
}
if(jsonNode.isTextual() || jsonNode.isNumber()) {
StringBuffer key = getKey(fieldName, fieldNamePrefix);
StringBuffer value = getValue(jsonNode);
stringBuffer.append(addCondition(QueryConditionalOperator.EQ, key, value));
}
return stringBuffer;
}
protected StringBuffer addCondition(QueryConditionalOperator queryConditionalOperator, StringBuffer key, StringBuffer value) {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(key);
stringBuffer.append(queryConditionalOperator.getConditionalOperator());
stringBuffer.append(value);
return stringBuffer;
}
protected StringBuffer getKey(String fieldName, String fieldNamePrefix) {
StringBuffer stringBuffer = new StringBuffer();
if(fieldNamePrefix!=null) {
stringBuffer.append(fieldNamePrefix);
if(fieldName!=null && fieldName.compareTo("")!=0) {
stringBuffer.append(".");
}
}
if(fieldName!=null) {
stringBuffer.append(fieldName);
}
return stringBuffer;
}
protected StringBuffer getValue(JsonNode jsonNode) {
StringBuffer stringBuffer = new StringBuffer();
String value = jsonNode.asText();
if(jsonNode.isNumber()) {
stringBuffer.append(value);
} else {
stringBuffer.append("\"");
stringBuffer.append(value);
stringBuffer.append("\"");
}
return stringBuffer;
}
}