2019-11-04 18:01:20 +01:00
|
|
|
package org.gcube.informationsystem.resourceregistry.instances.model.entity;
|
2016-12-19 14:59:27 +01:00
|
|
|
|
2018-06-08 18:18:48 +02:00
|
|
|
import java.util.ArrayList;
|
2017-11-17 15:59:25 +01:00
|
|
|
import java.util.HashMap;
|
2018-06-08 18:18:48 +02:00
|
|
|
import java.util.List;
|
2017-11-17 15:59:25 +01:00
|
|
|
import java.util.Map;
|
2018-06-08 15:05:47 +02:00
|
|
|
import java.util.UUID;
|
2017-11-17 15:59:25 +01:00
|
|
|
|
2019-10-25 17:45:59 +02:00
|
|
|
import org.gcube.informationsystem.base.reference.AccessType;
|
|
|
|
import org.gcube.informationsystem.base.reference.entities.BaseEntity;
|
|
|
|
import org.gcube.informationsystem.base.reference.properties.Header;
|
2019-02-13 12:33:29 +01:00
|
|
|
import org.gcube.informationsystem.model.reference.entities.Entity;
|
|
|
|
import org.gcube.informationsystem.model.reference.entities.Facet;
|
|
|
|
import org.gcube.informationsystem.model.reference.entities.Resource;
|
|
|
|
import org.gcube.informationsystem.model.reference.relations.ConsistsOf;
|
|
|
|
import org.gcube.informationsystem.model.reference.relations.Relation;
|
2018-06-04 15:31:13 +02:00
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.AvailableInAnotherContextException;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException;
|
2016-12-19 14:59:27 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextException;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityAlreadyPresentException;
|
2018-06-08 15:05:47 +02:00
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.query.InvalidQueryException;
|
2019-11-04 18:01:20 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.instances.base.ERManagement;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.instances.base.ERManagementUtility;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.instances.base.entities.BaseEntityManagement;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.instances.model.relation.RelationManagement;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.security.SecurityContext;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.security.SecurityContext.PermissionMode;
|
2016-12-22 17:27:26 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.utils.Utility;
|
2016-12-19 14:59:27 +01:00
|
|
|
|
2019-02-13 12:33:29 +01:00
|
|
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
|
|
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
2018-06-08 15:05:47 +02:00
|
|
|
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
|
2016-12-19 14:59:27 +01:00
|
|
|
import com.tinkerpop.blueprints.Direction;
|
|
|
|
import com.tinkerpop.blueprints.Edge;
|
2017-04-04 15:03:25 +02:00
|
|
|
import com.tinkerpop.blueprints.Element;
|
2016-12-19 14:59:27 +01:00
|
|
|
import com.tinkerpop.blueprints.Vertex;
|
2018-06-08 15:05:47 +02:00
|
|
|
import com.tinkerpop.blueprints.impls.orient.OrientEdge;
|
|
|
|
import com.tinkerpop.blueprints.impls.orient.OrientElement;
|
2016-12-19 14:59:27 +01:00
|
|
|
import com.tinkerpop.blueprints.impls.orient.OrientGraph;
|
|
|
|
import com.tinkerpop.blueprints.impls.orient.OrientVertex;
|
2018-06-08 15:05:47 +02:00
|
|
|
import com.tinkerpop.blueprints.impls.orient.OrientVertexType;
|
2016-12-19 14:59:27 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Luca Frosini (ISTI - CNR)
|
|
|
|
*/
|
2019-11-04 18:01:20 +01:00
|
|
|
public abstract class EntityManagement<E extends BaseEntity> extends BaseEntityManagement<E> {
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-17 15:59:25 +01:00
|
|
|
/**
|
2017-11-30 18:06:08 +01:00
|
|
|
* Provide a cache edge-internal-id -> RelationManagement
|
|
|
|
* this avoid to recreate the relationManagement of already visited edges
|
2017-11-17 15:59:25 +01:00
|
|
|
*/
|
|
|
|
@SuppressWarnings("rawtypes")
|
2017-11-30 18:06:08 +01:00
|
|
|
protected Map<String,RelationManagement> relationManagements;
|
2017-11-17 15:59:25 +01:00
|
|
|
|
2017-03-29 16:53:37 +02:00
|
|
|
protected EntityManagement(AccessType accessType) {
|
|
|
|
super(accessType);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2016-12-19 14:59:27 +01:00
|
|
|
this.ignoreKeys.add(Entity.HEADER_PROPERTY);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
|
|
|
this.ignoreStartWithKeys.add(OrientVertex.CONNECTION_IN_PREFIX.toLowerCase());
|
|
|
|
this.ignoreStartWithKeys.add(OrientVertex.CONNECTION_OUT_PREFIX.toLowerCase());
|
|
|
|
this.ignoreStartWithKeys.add(OrientVertex.CONNECTION_IN_PREFIX.toUpperCase());
|
|
|
|
this.ignoreStartWithKeys.add(OrientVertex.CONNECTION_OUT_PREFIX.toUpperCase());
|
2017-11-17 15:59:25 +01:00
|
|
|
|
|
|
|
this.relationManagements = new HashMap<>();
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2016-12-19 14:59:27 +01:00
|
|
|
}
|
2017-11-17 15:59:25 +01:00
|
|
|
|
2017-11-28 17:34:43 +01:00
|
|
|
protected EntityManagement(AccessType accessType, SecurityContext workingContext, OrientGraph orientGraph) {
|
|
|
|
this(accessType);
|
|
|
|
this.orientGraph = orientGraph;
|
|
|
|
setWorkingContext(workingContext);
|
|
|
|
}
|
|
|
|
|
2017-11-17 15:59:25 +01:00
|
|
|
@SuppressWarnings("rawtypes")
|
2017-11-17 18:41:02 +01:00
|
|
|
/*
|
2017-11-30 18:06:08 +01:00
|
|
|
* It works perfectly in case of any kind of update. In case of use from create
|
|
|
|
* the cache does not work by using the ID because until commit the edge has a
|
|
|
|
* fake id starting with - (minus) sign. This not imply any collateral effect
|
|
|
|
* but a better solution is a desiderata.
|
2017-11-17 18:41:02 +01:00
|
|
|
*/
|
2017-11-17 15:59:25 +01:00
|
|
|
protected RelationManagement getRelationManagement(Edge edge) throws ResourceRegistryException {
|
|
|
|
String id = edge.getId().toString();
|
|
|
|
RelationManagement relationManagement = relationManagements.get(id);
|
2017-11-30 18:06:08 +01:00
|
|
|
if(relationManagement == null) {
|
2017-11-28 17:34:43 +01:00
|
|
|
relationManagement = ERManagementUtility.getRelationManagement(getWorkingContext(), orientGraph, edge);
|
2017-11-17 18:10:35 +01:00
|
|
|
relationManagements.put(id, relationManagement);
|
2017-11-17 15:59:25 +01:00
|
|
|
}
|
|
|
|
return relationManagement;
|
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
|
|
|
protected void addToRelationManagement(@SuppressWarnings("rawtypes") RelationManagement relationManagement)
|
|
|
|
throws ResourceRegistryException {
|
2017-11-17 18:10:35 +01:00
|
|
|
Element elem = relationManagement.getElement();
|
|
|
|
String id = elem.getId().toString();
|
2017-11-30 18:06:08 +01:00
|
|
|
if(relationManagements.get(id) != null && relationManagements.get(id) != relationManagement) {
|
2017-11-17 18:10:35 +01:00
|
|
|
StringBuilder errorMessage = new StringBuilder();
|
|
|
|
errorMessage.append("Two different instance of ");
|
|
|
|
errorMessage.append(relationManagement.getClass().getSimpleName());
|
|
|
|
errorMessage.append(" point to the same ");
|
|
|
|
errorMessage.append(elem.getClass().getSimpleName());
|
|
|
|
errorMessage.append(". ");
|
|
|
|
errorMessage.append(Utility.SHOULD_NOT_OCCUR_ERROR_MESSAGE);
|
|
|
|
throw new ResourceRegistryException(errorMessage.toString());
|
|
|
|
}
|
|
|
|
relationManagements.put(id, relationManagement);
|
|
|
|
}
|
|
|
|
|
2019-02-13 12:33:29 +01:00
|
|
|
protected static JsonNode addRelation(JsonNode sourceResource, JsonNode relation, String arrayKey)
|
2017-11-15 19:31:49 +01:00
|
|
|
throws ResourceRegistryException {
|
2019-02-13 12:33:29 +01:00
|
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
ArrayNode relationArray = objectMapper.createArrayNode();
|
2017-11-15 19:31:49 +01:00
|
|
|
try {
|
2017-11-30 18:06:08 +01:00
|
|
|
if(sourceResource.has(arrayKey)) {
|
2019-02-13 12:33:29 +01:00
|
|
|
relationArray = (ArrayNode) sourceResource.get(arrayKey);
|
2017-11-15 19:31:49 +01:00
|
|
|
}
|
2019-02-13 12:33:29 +01:00
|
|
|
relationArray.add(relation);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2019-02-13 12:33:29 +01:00
|
|
|
((ObjectNode) sourceResource).replace(arrayKey, relationArray);
|
2017-11-30 18:06:08 +01:00
|
|
|
} catch(Exception e) {
|
2017-11-15 19:31:49 +01:00
|
|
|
throw new ResourceRegistryException(e);
|
|
|
|
}
|
|
|
|
return sourceResource;
|
|
|
|
}
|
|
|
|
|
2017-11-30 18:06:08 +01:00
|
|
|
protected Vertex createVertex() throws EntityAlreadyPresentException, ResourceRegistryException {
|
|
|
|
|
|
|
|
logger.trace("Going to create {} for {} ({}) using {}", Vertex.class.getSimpleName(), accessType.getName(),
|
2018-06-08 18:18:48 +02:00
|
|
|
elementType, jsonNode);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2016-12-19 14:59:27 +01:00
|
|
|
try {
|
2017-11-30 18:06:08 +01:00
|
|
|
|
|
|
|
if(oClass.isAbstract()) {
|
|
|
|
String error = String.format(
|
|
|
|
"Trying to create an instance of %s of type %s which is abstract. The operation will be aborted.",
|
2018-06-08 18:18:48 +02:00
|
|
|
accessType.getName(), elementType);
|
2017-03-28 16:02:23 +02:00
|
|
|
throw new ResourceRegistryException(error);
|
|
|
|
}
|
|
|
|
|
2018-06-08 18:18:48 +02:00
|
|
|
Vertex vertexEntity = orientGraph.addVertex("class:" + elementType);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2016-12-19 14:59:27 +01:00
|
|
|
try {
|
2017-11-30 18:06:08 +01:00
|
|
|
if(uuid != null) {
|
2017-04-04 15:03:25 +02:00
|
|
|
Vertex v = getElement();
|
2017-11-30 18:06:08 +01:00
|
|
|
if(v != null) {
|
2018-06-08 18:18:48 +02:00
|
|
|
String error = String.format("A %s with UUID %s already exist", elementType, uuid.toString());
|
2017-05-02 11:56:24 +02:00
|
|
|
throw getSpecificERAlreadyPresentException(error);
|
2017-04-04 15:03:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-04 15:31:13 +02:00
|
|
|
} catch(NotFoundException e) {
|
2017-04-04 15:03:25 +02:00
|
|
|
try {
|
2017-11-17 12:31:22 +01:00
|
|
|
Element el = ERManagementUtility.getAnyElementByUUID(uuid);
|
2017-11-30 18:06:08 +01:00
|
|
|
String error = String.format("UUID %s is already used by another %s. This is not allowed.",
|
2017-04-04 15:03:25 +02:00
|
|
|
uuid.toString(), (el instanceof Vertex) ? Entity.NAME : Relation.NAME);
|
2017-05-02 14:25:06 +02:00
|
|
|
throw getSpecificERAvailableInAnotherContextException(error);
|
2017-04-04 15:03:25 +02:00
|
|
|
|
2018-06-04 15:31:13 +02:00
|
|
|
} catch(NotFoundException e1) {
|
2017-04-04 15:03:25 +02:00
|
|
|
// OK the UUID is not already used.
|
2016-12-19 14:59:27 +01:00
|
|
|
}
|
2018-06-04 15:31:13 +02:00
|
|
|
} catch(AvailableInAnotherContextException e) {
|
2016-12-19 14:59:27 +01:00
|
|
|
throw e;
|
2017-11-30 18:06:08 +01:00
|
|
|
}
|
2017-05-02 14:25:06 +02:00
|
|
|
|
2016-12-30 17:31:12 +01:00
|
|
|
this.element = vertexEntity;
|
2017-11-30 18:06:08 +01:00
|
|
|
|
|
|
|
if(accessType == AccessType.RESOURCE) {
|
2016-12-19 14:59:27 +01:00
|
|
|
// Facet and relation are created in calling method
|
|
|
|
} else {
|
2017-11-30 18:06:08 +01:00
|
|
|
ERManagement.updateProperties(oClass, element, jsonNode, ignoreKeys, ignoreStartWithKeys);
|
2016-12-19 14:59:27 +01:00
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2016-12-19 14:59:27 +01:00
|
|
|
logger.info("Created {} is {}", Vertex.class.getSimpleName(),
|
2016-12-30 17:31:12 +01:00
|
|
|
Utility.toJsonString((OrientVertex) element, true));
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2016-12-30 17:31:12 +01:00
|
|
|
return element;
|
2017-11-30 18:06:08 +01:00
|
|
|
} catch(ResourceRegistryException e) {
|
2016-12-19 14:59:27 +01:00
|
|
|
throw e;
|
2017-11-30 18:06:08 +01:00
|
|
|
} catch(Exception e) {
|
|
|
|
logger.trace("Error while creating {} for {} ({}) using {}", Vertex.class.getSimpleName(),
|
2018-06-08 18:18:48 +02:00
|
|
|
accessType.getName(), elementType, jsonNode, e);
|
|
|
|
throw new ResourceRegistryException("Error Creating " + elementType + " with " + jsonNode, e.getCause());
|
2016-12-19 14:59:27 +01:00
|
|
|
}
|
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2016-12-30 17:31:12 +01:00
|
|
|
@Override
|
2018-06-08 15:05:47 +02:00
|
|
|
protected boolean reallyAddToContext(SecurityContext targetSecurityContext)
|
|
|
|
throws ContextException, ResourceRegistryException {
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2018-06-06 19:26:19 +02:00
|
|
|
targetSecurityContext.addElement(getElement(), orientGraph);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-17 16:26:49 +01:00
|
|
|
Iterable<Edge> edges = getElement().getEdges(Direction.OUT);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
|
|
|
for(Edge edge : edges) {
|
2016-12-19 14:59:27 +01:00
|
|
|
@SuppressWarnings("rawtypes")
|
2017-11-17 15:59:25 +01:00
|
|
|
RelationManagement relationManagement = getRelationManagement(edge);
|
2018-06-06 19:26:19 +02:00
|
|
|
relationManagement.internalAddToContext(targetSecurityContext);
|
2016-12-19 14:59:27 +01:00
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2016-12-19 14:59:27 +01:00
|
|
|
return true;
|
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2016-12-30 17:31:12 +01:00
|
|
|
@Override
|
2018-06-08 15:05:47 +02:00
|
|
|
protected boolean reallyRemoveFromContext(SecurityContext targetSecurityContext)
|
|
|
|
throws ContextException, ResourceRegistryException {
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2017-11-17 17:34:29 +01:00
|
|
|
Iterable<Edge> edges = getElement().getEdges(Direction.OUT);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
|
|
|
for(Edge edge : edges) {
|
2016-12-20 18:36:17 +01:00
|
|
|
@SuppressWarnings("rawtypes")
|
2017-11-17 15:59:25 +01:00
|
|
|
RelationManagement relationManagement = getRelationManagement(edge);
|
2018-06-06 19:26:19 +02:00
|
|
|
relationManagement.internalRemoveFromContext(targetSecurityContext);
|
2016-12-20 18:36:17 +01:00
|
|
|
}
|
2017-11-17 17:34:29 +01:00
|
|
|
|
2018-06-06 19:26:19 +02:00
|
|
|
targetSecurityContext.removeElement(getElement(), orientGraph);
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2016-12-20 18:36:17 +01:00
|
|
|
return true;
|
2016-12-19 14:59:27 +01:00
|
|
|
}
|
2017-11-17 15:59:25 +01:00
|
|
|
|
2017-01-11 12:06:50 +01:00
|
|
|
@Override
|
|
|
|
public String reallyGetAll(boolean polymorphic) throws ResourceRegistryException {
|
2019-02-13 12:33:29 +01:00
|
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
ArrayNode arrayNode = objectMapper.createArrayNode();
|
|
|
|
|
2018-06-08 18:18:48 +02:00
|
|
|
Iterable<Vertex> iterable = orientGraph.getVerticesOfClass(elementType, polymorphic);
|
2017-11-30 18:06:08 +01:00
|
|
|
for(Vertex vertex : iterable) {
|
2017-01-11 12:06:50 +01:00
|
|
|
@SuppressWarnings("rawtypes")
|
2017-11-30 18:06:08 +01:00
|
|
|
EntityManagement entityManagement = ERManagementUtility.getEntityManagement(getWorkingContext(),
|
|
|
|
orientGraph, vertex);
|
2017-03-28 16:02:23 +02:00
|
|
|
try {
|
2019-02-13 12:33:29 +01:00
|
|
|
JsonNode jsonNode = entityManagement.serializeAsJson();
|
|
|
|
arrayNode.add(jsonNode);
|
2017-11-30 18:06:08 +01:00
|
|
|
} catch(ResourceRegistryException e) {
|
|
|
|
logger.error("Unable to correctly serialize {}. It will be excluded from results. {}",
|
2017-11-23 09:39:21 +01:00
|
|
|
vertex.toString(), Utility.SHOULD_NOT_OCCUR_ERROR_MESSAGE);
|
2017-03-28 16:02:23 +02:00
|
|
|
}
|
2017-01-11 12:06:50 +01:00
|
|
|
}
|
2019-02-13 12:33:29 +01:00
|
|
|
try {
|
|
|
|
return objectMapper.writeValueAsString(arrayNode);
|
|
|
|
} catch(JsonProcessingException e) {
|
|
|
|
throw new ResourceRegistryException(e);
|
|
|
|
}
|
2017-01-11 12:06:50 +01:00
|
|
|
}
|
2017-11-30 18:06:08 +01:00
|
|
|
|
2018-06-08 18:18:48 +02:00
|
|
|
public String reallyQuery(String relationType, String referenceType, UUID referenceUUID, Direction direction,
|
|
|
|
boolean polymorphic, Map<String,String> constraint) throws ResourceRegistryException {
|
2019-02-13 12:33:29 +01:00
|
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
ArrayNode arrayNode = objectMapper.createArrayNode();
|
2018-06-08 15:05:47 +02:00
|
|
|
|
2018-06-08 18:18:48 +02:00
|
|
|
Iterable<Vertex> references = null;
|
|
|
|
|
|
|
|
if(referenceUUID != null) {
|
|
|
|
Element element = ERManagementUtility.getAnyElementByUUID(referenceUUID);
|
|
|
|
if(element instanceof Vertex) {
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
EntityManagement<Entity> entityManagement = ERManagementUtility.getEntityManagement(getWorkingContext(),
|
|
|
|
orientGraph, (Vertex) element);
|
|
|
|
|
|
|
|
OrientVertexType orientVertexType = ((OrientVertex) element).getType();
|
|
|
|
|
|
|
|
String elementType = entityManagement.getElementType();
|
|
|
|
if(elementType.compareTo(referenceType) != 0) {
|
|
|
|
if(polymorphic && orientVertexType.isSubClassOf(referenceType)) {
|
|
|
|
// OK
|
|
|
|
} else {
|
|
|
|
String error = String.format("Referenced instace with UUID %s is not a %s", referenceUUID,
|
|
|
|
referenceType);
|
|
|
|
throw new InvalidQueryException(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
List<Vertex> vertexes = new ArrayList<>();
|
|
|
|
vertexes.add((Vertex) element);
|
|
|
|
references = vertexes;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
String error = String.format("Referenced instace with UUID %s is not an %s", referenceUUID, Entity.NAME);
|
|
|
|
throw new InvalidQueryException(error);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
references = orientGraph.getVerticesOfClass(referenceType, polymorphic);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(Vertex v : references) {
|
|
|
|
List<Direction> directions = new ArrayList<>();
|
|
|
|
if(direction==Direction.BOTH) {
|
|
|
|
directions.add(Direction.IN);
|
|
|
|
directions.add(Direction.OUT);
|
|
|
|
}else {
|
|
|
|
directions.add(direction);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(Direction d : directions) {
|
|
|
|
|
|
|
|
Iterable<Edge> edges = v.getEdges(d.opposite(), relationType);
|
|
|
|
for(Edge edge : edges) {
|
|
|
|
Vertex vertex = ((OrientEdge) edge).getVertex(d);
|
|
|
|
OrientVertex orientVertex = (OrientVertex) vertex;
|
|
|
|
|
|
|
|
if(((OrientVertex) v).getIdentity().compareTo(orientVertex.getIdentity()) == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(elementType.compareTo(orientVertex.getLabel()) != 0) {
|
|
|
|
OrientVertexType orientVertexType = orientVertex.getType();
|
|
|
|
|
|
|
|
if(polymorphic && orientVertexType.isSubClassOf(elementType)) {
|
|
|
|
// OK
|
|
|
|
} else {
|
|
|
|
// excluding from results
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@SuppressWarnings("rawtypes")
|
|
|
|
EntityManagement entityManagement = ERManagementUtility.getEntityManagement(getWorkingContext(),
|
|
|
|
orientGraph, vertex);
|
|
|
|
try {
|
|
|
|
if(entityManagement.getUUID().compareTo(referenceUUID) == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
2019-02-13 12:33:29 +01:00
|
|
|
JsonNode jsonNode = entityManagement.serializeAsJson();
|
|
|
|
arrayNode.add(jsonNode);
|
2018-06-08 18:18:48 +02:00
|
|
|
} catch(ResourceRegistryException e) {
|
|
|
|
logger.error("Unable to correctly serialize {}. It will be excluded from results. {}",
|
|
|
|
vertex.toString(), Utility.SHOULD_NOT_OCCUR_ERROR_MESSAGE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-02-13 12:33:29 +01:00
|
|
|
|
|
|
|
try {
|
|
|
|
return objectMapper.writeValueAsString(arrayNode);
|
|
|
|
} catch(JsonProcessingException e) {
|
|
|
|
throw new ResourceRegistryException(e);
|
|
|
|
}
|
2018-06-08 18:18:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public String reallyQueryTraversal(String relationType, String referenceType, UUID referenceUUID,
|
|
|
|
Direction direction, boolean polymorphic, Map<String,String> constraint) throws ResourceRegistryException {
|
2019-02-13 12:33:29 +01:00
|
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
ArrayNode arrayNode = objectMapper.createArrayNode();
|
2018-06-08 18:18:48 +02:00
|
|
|
|
|
|
|
if(referenceUUID != null) {
|
|
|
|
constraint.put(Entity.HEADER_PROPERTY + "." + Header.UUID_PROPERTY, referenceUUID.toString());
|
|
|
|
}
|
|
|
|
|
2018-06-08 15:05:47 +02:00
|
|
|
// TODO check types
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SELECT FROM (TRAVERSE inE('isIdentifiedBy'), outV('EService') FROM (SELECT
|
|
|
|
* FROM SoftwareFacet WHERE group='VREManagement' AND name='SmartExecutor'))
|
|
|
|
*
|
|
|
|
* WHERE @class='EService' // Only is not polymorphic
|
|
|
|
*/
|
|
|
|
|
|
|
|
StringBuilder selectStringBuilder = new StringBuilder("SELECT FROM (TRAVERSE ");
|
|
|
|
selectStringBuilder.append(direction.name().toLowerCase());
|
|
|
|
selectStringBuilder.append("E('");
|
|
|
|
selectStringBuilder.append(relationType);
|
|
|
|
selectStringBuilder.append("'), ");
|
|
|
|
selectStringBuilder.append(direction.opposite().name().toLowerCase());
|
|
|
|
selectStringBuilder.append("V('");
|
2018-06-08 18:18:48 +02:00
|
|
|
selectStringBuilder.append(elementType);
|
2018-06-08 15:05:47 +02:00
|
|
|
selectStringBuilder.append("') FROM (SELECT FROM ");
|
|
|
|
selectStringBuilder.append(referenceType);
|
2018-06-08 15:39:04 +02:00
|
|
|
boolean first = true;
|
2018-06-08 15:05:47 +02:00
|
|
|
for(String key : constraint.keySet()) {
|
|
|
|
if(first) {
|
|
|
|
selectStringBuilder.append(" WHERE ");
|
|
|
|
first = false;
|
|
|
|
} else {
|
|
|
|
selectStringBuilder.append(" AND ");
|
|
|
|
}
|
|
|
|
selectStringBuilder.append(key);
|
|
|
|
selectStringBuilder.append("=");
|
|
|
|
String value = constraint.get(key).trim();
|
|
|
|
selectStringBuilder.append("'");
|
|
|
|
selectStringBuilder.append(value);
|
|
|
|
selectStringBuilder.append("'");
|
|
|
|
}
|
|
|
|
selectStringBuilder.append(" ))");
|
|
|
|
|
|
|
|
if(!polymorphic) {
|
|
|
|
selectStringBuilder.append(" WHERE @class='");
|
2018-06-08 18:18:48 +02:00
|
|
|
selectStringBuilder.append(elementType);
|
2018-06-08 15:05:47 +02:00
|
|
|
selectStringBuilder.append("'");
|
|
|
|
}
|
|
|
|
|
|
|
|
String select = selectStringBuilder.toString();
|
|
|
|
logger.trace(select);
|
|
|
|
|
|
|
|
OSQLSynchQuery<Element> osqlSynchQuery = new OSQLSynchQuery<Element>(select);
|
|
|
|
Iterable<Element> elements = orientGraph.command(osqlSynchQuery).execute();
|
|
|
|
|
|
|
|
for(Element element : elements) {
|
|
|
|
|
|
|
|
if(polymorphic) {
|
|
|
|
OrientVertexType orientVertexType = null;
|
|
|
|
try {
|
|
|
|
OrientElement orientElement = ((OrientElement) element);
|
|
|
|
if(orientElement instanceof OrientEdge) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
orientVertexType = ((OrientVertex) orientElement).getType();
|
|
|
|
} catch(Exception e) {
|
|
|
|
String error = String.format("Unable to detect type of %s. %s", element.toString(),
|
|
|
|
Utility.SHOULD_NOT_OCCUR_ERROR_MESSAGE);
|
|
|
|
logger.error(error, e);
|
|
|
|
throw new ResourceRegistryException(error);
|
|
|
|
}
|
|
|
|
|
2018-06-08 18:18:48 +02:00
|
|
|
if(orientVertexType.getName().compareTo(elementType) != 0) {
|
|
|
|
if(!orientVertexType.isSubClassOf(elementType)) {
|
2018-06-08 15:05:47 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Vertex vertex = (Vertex) element;
|
|
|
|
|
|
|
|
@SuppressWarnings("rawtypes")
|
|
|
|
EntityManagement entityManagement = ERManagementUtility.getEntityManagement(getWorkingContext(),
|
|
|
|
orientGraph, vertex);
|
|
|
|
try {
|
2018-06-08 18:18:48 +02:00
|
|
|
if(constraint.containsKey(Entity.HEADER_PROPERTY + "." + Header.UUID_PROPERTY)) {
|
|
|
|
String uuid = constraint.get(Entity.HEADER_PROPERTY + "." + Header.UUID_PROPERTY);
|
|
|
|
if(entityManagement.getUUID().compareTo(UUID.fromString(uuid)) == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2019-02-13 12:33:29 +01:00
|
|
|
JsonNode jsonNode = entityManagement.serializeAsJson();
|
|
|
|
arrayNode.add(jsonNode);
|
2018-06-08 15:05:47 +02:00
|
|
|
} catch(ResourceRegistryException e) {
|
|
|
|
logger.error("Unable to correctly serialize {}. It will be excluded from results. {}",
|
|
|
|
vertex.toString(), Utility.SHOULD_NOT_OCCUR_ERROR_MESSAGE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-13 12:33:29 +01:00
|
|
|
try {
|
|
|
|
return objectMapper.writeValueAsString(arrayNode);
|
|
|
|
} catch(JsonProcessingException e) {
|
|
|
|
throw new ResourceRegistryException(e);
|
|
|
|
}
|
2018-06-08 15:05:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public String query(String relationType, String referenceType, UUID referenceUUID, Direction direction,
|
|
|
|
boolean polymorphic, Map<String,String> constraint) throws ResourceRegistryException {
|
|
|
|
try {
|
|
|
|
orientGraph = getWorkingContext().getGraph(PermissionMode.READER);
|
|
|
|
|
|
|
|
AccessType relationAccessType = ERManagementUtility.getBaseAccessType(relationType);
|
2018-06-08 18:18:48 +02:00
|
|
|
if(relationAccessType != AccessType.IS_RELATED_TO && relationAccessType != AccessType.CONSISTS_OF) {
|
2018-06-08 15:05:47 +02:00
|
|
|
String error = String.format("%s must be a relation type", relationType);
|
|
|
|
throw new ResourceRegistryException(error);
|
|
|
|
}
|
|
|
|
|
|
|
|
AccessType referenceAccessType = ERManagementUtility.getBaseAccessType(referenceType);
|
2018-06-08 18:18:48 +02:00
|
|
|
if(referenceAccessType != AccessType.RESOURCE && referenceAccessType != AccessType.FACET) {
|
2018-06-08 15:05:47 +02:00
|
|
|
String error = String.format("%s must be a en entity type", referenceType);
|
|
|
|
throw new ResourceRegistryException(error);
|
|
|
|
}
|
|
|
|
|
2018-06-08 15:39:04 +02:00
|
|
|
if(constraint == null) {
|
2018-06-08 15:05:47 +02:00
|
|
|
constraint = new HashMap<>();
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(accessType) {
|
|
|
|
case RESOURCE:
|
|
|
|
|
|
|
|
if(relationAccessType == AccessType.CONSISTS_OF) {
|
|
|
|
|
|
|
|
if(direction != Direction.OUT) {
|
|
|
|
String error = String.format("%s can only goes %s from %s.", relationType,
|
2018-06-08 18:18:48 +02:00
|
|
|
Direction.OUT.name(), elementType);
|
2018-06-08 15:05:47 +02:00
|
|
|
throw new InvalidQueryException(error);
|
|
|
|
} else {
|
|
|
|
if(referenceAccessType != AccessType.FACET) {
|
|
|
|
String error = String.format("%s can only has as target a %s. Provided instead %s : %s",
|
|
|
|
relationType, Facet.NAME, referenceAccessType, referenceType);
|
|
|
|
throw new InvalidQueryException(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FACET:
|
|
|
|
if(relationAccessType != AccessType.CONSISTS_OF || direction != Direction.IN
|
|
|
|
|| referenceAccessType != AccessType.RESOURCE) {
|
2018-06-08 18:18:48 +02:00
|
|
|
String error = String.format("%s can only has %s %s from a %s.", elementType,
|
|
|
|
Direction.IN.name(), ConsistsOf.NAME, Resource.NAME);
|
2018-06-08 15:05:47 +02:00
|
|
|
throw new InvalidQueryException(error);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-06-08 18:18:48 +02:00
|
|
|
return reallyQuery(relationType, referenceType, referenceUUID, direction, polymorphic, constraint);
|
2018-06-08 15:05:47 +02:00
|
|
|
|
|
|
|
} catch(ResourceRegistryException e) {
|
|
|
|
throw e;
|
|
|
|
} catch(Exception e) {
|
|
|
|
throw new ResourceRegistryException(e);
|
|
|
|
} finally {
|
|
|
|
if(orientGraph != null) {
|
|
|
|
orientGraph.shutdown();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-19 14:59:27 +01:00
|
|
|
}
|