2016-12-19 14:59:27 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2016-12-27 11:27:01 +01:00
|
|
|
package org.gcube.informationsystem.resourceregistry.er.relation;
|
2016-12-19 14:59:27 +01:00
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.UUID;
|
|
|
|
|
2016-12-19 16:25:29 +01:00
|
|
|
import org.codehaus.jettison.json.JSONException;
|
2016-12-19 14:59:27 +01:00
|
|
|
import org.codehaus.jettison.json.JSONObject;
|
|
|
|
import org.gcube.informationsystem.model.embedded.Header;
|
2016-12-20 16:51:57 +01:00
|
|
|
import org.gcube.informationsystem.model.embedded.PropagationConstraint;
|
2016-12-20 18:36:17 +01:00
|
|
|
import org.gcube.informationsystem.model.embedded.PropagationConstraint.AddConstraint;
|
2016-12-20 16:51:57 +01:00
|
|
|
import org.gcube.informationsystem.model.embedded.PropagationConstraint.RemoveConstraint;
|
2016-12-19 14:59:27 +01:00
|
|
|
import org.gcube.informationsystem.model.entity.Entity;
|
|
|
|
import org.gcube.informationsystem.model.entity.Facet;
|
|
|
|
import org.gcube.informationsystem.model.entity.Resource;
|
|
|
|
import org.gcube.informationsystem.model.relation.ConsistsOf;
|
|
|
|
import org.gcube.informationsystem.model.relation.IsRelatedTo;
|
|
|
|
import org.gcube.informationsystem.model.relation.Relation;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.context.ContextException;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationNotFoundException;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException;
|
2016-12-22 17:33:10 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.context.ContextUtility;
|
2016-12-19 14:59:27 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.context.SecurityContextMapper;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.context.SecurityContextMapper.PermissionMode;
|
2016-12-27 11:27:01 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.er.ERManagement;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.er.entity.EntityManagement;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.er.entity.FacetManagement;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.er.entity.ResourceManagement;
|
2016-12-22 17:27:26 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.schema.SchemaManagementImpl;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.utils.HeaderUtility;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.utils.Utility;
|
2016-12-19 14:59:27 +01:00
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
import com.tinkerpop.blueprints.Direction;
|
|
|
|
import com.tinkerpop.blueprints.Edge;
|
|
|
|
import com.tinkerpop.blueprints.Vertex;
|
|
|
|
import com.tinkerpop.blueprints.impls.orient.OrientBaseGraph;
|
|
|
|
import com.tinkerpop.blueprints.impls.orient.OrientEdge;
|
|
|
|
import com.tinkerpop.blueprints.impls.orient.OrientEdgeType;
|
|
|
|
import com.tinkerpop.blueprints.impls.orient.OrientGraph;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Luca Frosini (ISTI - CNR)
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
@SuppressWarnings("rawtypes")
|
|
|
|
public abstract class RelationManagement<R extends Relation> {
|
|
|
|
|
|
|
|
private static Logger logger = LoggerFactory
|
|
|
|
.getLogger(RelationManagement.class);
|
|
|
|
|
|
|
|
public final Set<String> ignoreKeys;
|
|
|
|
public final Set<String> ignoreStartWithKeys;
|
|
|
|
|
|
|
|
public static final String AT = "@";
|
|
|
|
public static final String UNDERSCORE = "_";
|
|
|
|
|
|
|
|
protected final Class<R> relationClass;
|
|
|
|
protected final String baseType;
|
|
|
|
protected final Class<? extends Entity> targetEntityClass;
|
|
|
|
|
|
|
|
protected OrientGraph orientGraph;
|
|
|
|
|
|
|
|
protected UUID uuid;
|
|
|
|
protected JsonNode jsonNode;
|
|
|
|
protected String relationType;
|
|
|
|
protected Edge edge;
|
|
|
|
|
|
|
|
protected RelationManagement(Class<R> relationClass) {
|
|
|
|
this.ignoreKeys = new HashSet<String>();
|
|
|
|
this.ignoreKeys.add(Relation.HEADER_PROPERTY);
|
|
|
|
this.ignoreKeys.add(Relation.TARGET_PROPERTY);
|
|
|
|
this.ignoreKeys.add(Relation.SOURCE_PROPERTY);
|
|
|
|
this.ignoreKeys.add(OrientBaseGraph.CONNECTION_IN.toLowerCase());
|
|
|
|
this.ignoreKeys.add(OrientBaseGraph.CONNECTION_OUT.toLowerCase());
|
|
|
|
this.ignoreKeys.add(OrientBaseGraph.CONNECTION_IN.toUpperCase());
|
|
|
|
this.ignoreKeys.add(OrientBaseGraph.CONNECTION_OUT.toUpperCase());
|
|
|
|
|
|
|
|
this.ignoreStartWithKeys = new HashSet<String>();
|
|
|
|
this.ignoreStartWithKeys.add(AT);
|
|
|
|
this.ignoreStartWithKeys.add(UNDERSCORE);
|
|
|
|
|
|
|
|
this.relationClass = relationClass;
|
|
|
|
|
|
|
|
if (ConsistsOf.class.isAssignableFrom(relationClass)) {
|
|
|
|
this.baseType = ConsistsOf.NAME;
|
|
|
|
this.targetEntityClass = Facet.class;
|
|
|
|
} else if (IsRelatedTo.class.isAssignableFrom(relationClass)) {
|
|
|
|
this.baseType = IsRelatedTo.NAME;
|
|
|
|
this.targetEntityClass = Resource.class;
|
|
|
|
} else {
|
|
|
|
this.baseType = Relation.NAME;
|
|
|
|
this.targetEntityClass = Resource.class;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected RelationManagement(Class<R> relationClass, OrientGraph orientGraph) {
|
|
|
|
this(relationClass);
|
|
|
|
this.orientGraph = orientGraph;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setEdge(Edge edge) {
|
|
|
|
this.edge = edge;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setUUID(UUID uuid) throws ResourceRegistryException {
|
|
|
|
this.uuid = uuid;
|
|
|
|
if (jsonNode != null) {
|
|
|
|
checkUUIDMatch();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void checkJSON() throws ResourceRegistryException {
|
|
|
|
if (uuid == null) {
|
|
|
|
try {
|
|
|
|
uuid = org.gcube.informationsystem.impl.utils.Utility
|
|
|
|
.getUUIDFromJsonNode(jsonNode);
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
checkUUIDMatch();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.relationType == null) {
|
|
|
|
this.relationType = ERManagement.getClassProperty(jsonNode);
|
|
|
|
} else {
|
|
|
|
checkEntityMatch();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setJSON(JsonNode jsonNode) throws ResourceRegistryException {
|
|
|
|
this.jsonNode = jsonNode;
|
|
|
|
checkJSON();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setJSON(String jsonRepresentation)
|
|
|
|
throws ResourceRegistryException {
|
|
|
|
ObjectMapper mapper = new ObjectMapper();
|
|
|
|
try {
|
|
|
|
this.jsonNode = mapper.readTree(jsonRepresentation);
|
|
|
|
} catch (IOException e) {
|
|
|
|
throw new ResourceRegistryException(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
checkJSON();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setRelationType(String relationType)
|
|
|
|
throws ResourceRegistryException {
|
|
|
|
this.relationType = relationType;
|
|
|
|
if (relationType == null || relationType.compareTo("") == 0) {
|
|
|
|
if (ConsistsOf.class.isAssignableFrom(relationClass)) {
|
|
|
|
this.relationType = ConsistsOf.NAME;
|
|
|
|
} else if (IsRelatedTo.class.isAssignableFrom(relationClass)) {
|
|
|
|
this.relationType = IsRelatedTo.NAME;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (jsonNode != null) {
|
|
|
|
checkEntityMatch();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void checkEntityMatch() throws ResourceRegistryException {
|
|
|
|
String type = ERManagement.getClassProperty(jsonNode);
|
|
|
|
if (type != null && type.compareTo(relationType) != 0) {
|
|
|
|
String error = String
|
|
|
|
.format("Declared resourceType does not match with json representation %s!=%s",
|
|
|
|
relationType, type);
|
|
|
|
logger.trace(error);
|
|
|
|
throw new ResourceRegistryException(error);
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
SchemaManagementImpl.getTypeSchema(relationType, baseType);
|
|
|
|
} catch (SchemaNotFoundException e) {
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void checkUUIDMatch() throws ResourceRegistryException {
|
|
|
|
Header header = null;
|
|
|
|
try {
|
|
|
|
header = HeaderUtility.getHeader(jsonNode, false);
|
|
|
|
} catch (Exception e) {
|
|
|
|
throw new ResourceRegistryException(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (header != null) {
|
|
|
|
UUID resourceUUID = header.getUUID();
|
|
|
|
if (resourceUUID.compareTo(uuid) != 0) {
|
|
|
|
String error = String
|
|
|
|
.format("UUID provided in header (%s) differs from the one (%s) used to identify the %s instance",
|
|
|
|
resourceUUID.toString(), uuid.toString(),
|
|
|
|
relationType);
|
|
|
|
throw new ResourceRegistryException(error);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Edge getEdge() throws ResourceRegistryException {
|
|
|
|
try {
|
|
|
|
if (edge == null) {
|
|
|
|
edge = Utility.getElementByUUID(orientGraph,
|
|
|
|
relationType == null ? baseType : relationType, uuid,
|
|
|
|
Edge.class);
|
|
|
|
}
|
|
|
|
return edge;
|
|
|
|
} catch (ResourceRegistryException e) {
|
2016-12-19 15:37:15 +01:00
|
|
|
throw new RelationNotFoundException(e);
|
2016-12-19 14:59:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public String serialize() throws ResourceRegistryException {
|
2016-12-19 16:25:29 +01:00
|
|
|
return serializeAsJson().toString();
|
2016-12-19 14:59:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public JSONObject serializeAsJson() throws ResourceRegistryException {
|
2016-12-19 16:25:29 +01:00
|
|
|
JSONObject ret = Utility.toJsonObject((OrientEdge) getEdge(), false);
|
|
|
|
|
|
|
|
Vertex vertex = edge.getVertex(Direction.IN);
|
|
|
|
EntityManagement entityManagement = EntityManagement
|
|
|
|
.getEntityManagement(orientGraph, vertex);
|
|
|
|
|
|
|
|
try {
|
|
|
|
ret.put(Relation.TARGET_PROPERTY,
|
|
|
|
entityManagement.serializeAsJson());
|
|
|
|
} catch (JSONException e) {
|
|
|
|
new ResourceRegistryException(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2016-12-19 14:59:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public Edge reallyCreate(UUID sourceUUID, UUID targetUUID)
|
|
|
|
throws ResourceRegistryException {
|
|
|
|
ResourceManagement srmSource = new ResourceManagement(orientGraph);
|
|
|
|
srmSource.setUUID(sourceUUID);
|
|
|
|
Vertex source = srmSource.getVertex();
|
|
|
|
|
2016-12-19 16:25:29 +01:00
|
|
|
EntityManagement entityManagement = getEntityManagement();
|
|
|
|
entityManagement.setUUID(targetUUID);
|
|
|
|
Vertex target = entityManagement.getVertex();
|
2016-12-19 14:59:27 +01:00
|
|
|
|
|
|
|
return reallyCreate(source, target);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
protected Edge reallyCreate(Vertex source, Vertex target)
|
|
|
|
throws ResourceRegistryException {
|
2016-12-20 18:36:17 +01:00
|
|
|
|
|
|
|
EntityManagement sourceEntityManagement = EntityManagement
|
|
|
|
.getEntityManagement(orientGraph, source);
|
|
|
|
EntityManagement targetEntityManagement = EntityManagement
|
|
|
|
.getEntityManagement(orientGraph, target);
|
|
|
|
if (!(sourceEntityManagement instanceof ResourceManagement)) {
|
|
|
|
String error = String.format(
|
|
|
|
"Any type of %s can have only a %s as %s. "
|
|
|
|
+ "Cannot instatiate %s beetween %s -> %s ",
|
|
|
|
Relation.NAME, Resource.NAME, Relation.SOURCE_PROPERTY,
|
|
|
|
relationType, sourceEntityManagement.serialize(),
|
|
|
|
targetEntityManagement.serialize());
|
|
|
|
throw new ResourceRegistryException(error);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this instanceof IsRelatedToManagement) {
|
|
|
|
if (!(targetEntityManagement instanceof ResourceManagement)) {
|
|
|
|
String error = String.format("A %s can have only a %s as %s. "
|
|
|
|
+ "Cannot instatiate %s beetween %s -> %s ", baseType,
|
|
|
|
Resource.NAME, Relation.TARGET_PROPERTY, relationType,
|
|
|
|
sourceEntityManagement.serialize(),
|
|
|
|
targetEntityManagement.serialize());
|
|
|
|
throw new ResourceRegistryException(error);
|
|
|
|
}
|
|
|
|
} else if (this instanceof ConsistsOfManagement) {
|
|
|
|
if (!(targetEntityManagement instanceof FacetManagement)) {
|
|
|
|
String error = String.format("A %s can have only a %s as %s. "
|
|
|
|
+ "Cannot instatiate %s beetween %s -> %s ", baseType,
|
|
|
|
Facet.NAME, Relation.TARGET_PROPERTY, relationType,
|
|
|
|
sourceEntityManagement.serialize(),
|
|
|
|
targetEntityManagement.serialize());
|
|
|
|
throw new ResourceRegistryException(error);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
String error = String.format("{%s is not a %s nor a %s. "
|
|
|
|
+ "This is really strange and should not occur. "
|
|
|
|
+ "Please Investigate it.", this,
|
|
|
|
IsRelatedToManagement.class.getSimpleName(),
|
|
|
|
ConsistsOfManagement.class.getSimpleName());
|
|
|
|
throw new ResourceRegistryException(error);
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.trace("Creating {} beetween {} -> {}", relationType,
|
|
|
|
sourceEntityManagement.serialize(),
|
|
|
|
targetEntityManagement.serialize());
|
2016-12-19 14:59:27 +01:00
|
|
|
|
|
|
|
edge = orientGraph.addEdge(null, source, target, relationType);
|
|
|
|
|
|
|
|
ERManagement.updateProperties(edge, jsonNode, ignoreKeys,
|
|
|
|
ignoreStartWithKeys);
|
|
|
|
|
|
|
|
HeaderUtility.addHeader(edge, null);
|
|
|
|
ContextUtility.addToActualContext(orientGraph, edge);
|
|
|
|
|
|
|
|
((OrientEdge) edge).save();
|
|
|
|
|
|
|
|
logger.info("{} successfully created", relationType);
|
|
|
|
|
|
|
|
return edge;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Edge reallyCreate(Vertex source) throws ResourceRegistryException {
|
|
|
|
Vertex target = null;
|
|
|
|
EntityManagement entityManagement = getEntityManagement();
|
|
|
|
|
|
|
|
if (!jsonNode.has(Relation.TARGET_PROPERTY)) {
|
|
|
|
throw new ResourceRegistryException(
|
|
|
|
"Error while creating relation. No target definition found");
|
|
|
|
}
|
|
|
|
entityManagement.setJSON(jsonNode.get(Relation.TARGET_PROPERTY));
|
|
|
|
try {
|
|
|
|
target = entityManagement.getVertex();
|
|
|
|
} catch (Exception e) {
|
|
|
|
target = entityManagement.reallyCreate();
|
|
|
|
}
|
|
|
|
return reallyCreate(source, target);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Edge reallyCreate(UUID sourceUUID) throws ResourceRegistryException {
|
|
|
|
ResourceManagement srmSource = new ResourceManagement(orientGraph);
|
|
|
|
srmSource.setUUID(sourceUUID);
|
|
|
|
Vertex source = srmSource.getVertex();
|
|
|
|
return reallyCreate(source);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Edge reallyUpdate() throws ResourceRegistryException {
|
|
|
|
|
2016-12-20 18:36:17 +01:00
|
|
|
logger.debug("Trying to update {} : {}", relationType, jsonNode);
|
2016-12-19 14:59:27 +01:00
|
|
|
|
|
|
|
Edge edge = getEdge();
|
2016-12-20 18:36:17 +01:00
|
|
|
ERManagement.updateProperties(edge, jsonNode, ignoreKeys, ignoreStartWithKeys);
|
2016-12-19 14:59:27 +01:00
|
|
|
|
|
|
|
if (ConsistsOf.class.isAssignableFrom(relationClass)) {
|
|
|
|
JsonNode target = jsonNode.get(Relation.TARGET_PROPERTY);
|
|
|
|
if (target != null) {
|
|
|
|
FacetManagement fm = new FacetManagement(orientGraph);
|
|
|
|
fm.setJSON(target);
|
|
|
|
fm.reallyUpdate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.info("{} {} successfully updated", relationType, jsonNode);
|
|
|
|
|
|
|
|
return edge;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean reallyAddToContext() throws ContextException,
|
|
|
|
ResourceRegistryException {
|
2016-12-27 15:31:39 +01:00
|
|
|
getEdge();
|
|
|
|
|
2016-12-20 18:36:17 +01:00
|
|
|
AddConstraint addConstraint = AddConstraint.unpropagate;
|
2016-12-19 14:59:27 +01:00
|
|
|
|
2016-12-20 18:36:17 +01:00
|
|
|
try {
|
|
|
|
PropagationConstraint propagationConstraint = Utility.getEmbedded(
|
|
|
|
PropagationConstraint.class, edge,
|
|
|
|
Relation.PROPAGATION_CONSTRAINT);
|
|
|
|
if (propagationConstraint.getAddConstraint() != null) {
|
|
|
|
addConstraint = propagationConstraint.getAddConstraint();
|
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
|
|
logger.warn("Error while getting {} from {}. Assuming {}. "
|
|
|
|
+ "This is really strange and should not occur. "
|
|
|
|
+ "Please Investigate it.",
|
|
|
|
Relation.PROPAGATION_CONSTRAINT,
|
|
|
|
Utility.toJsonString(edge, true), addConstraint);
|
|
|
|
}
|
|
|
|
|
|
|
|
Vertex target = edge.getVertex(Direction.IN);
|
|
|
|
|
|
|
|
switch (addConstraint) {
|
2016-12-27 15:31:39 +01:00
|
|
|
case propagate:
|
|
|
|
/*
|
|
|
|
* The relation must be added only in the case the target vertex
|
|
|
|
* must be added. Otherwise we have a relation which point
|
|
|
|
* to an entity outside of the context.
|
|
|
|
*/
|
|
|
|
ContextUtility.addToActualContext(orientGraph, getEdge());
|
|
|
|
EntityManagement entityManagement = EntityManagement
|
|
|
|
.getEntityManagement(orientGraph, target);
|
|
|
|
entityManagement.reallyAddToContext();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case unpropagate:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2016-12-20 18:36:17 +01:00
|
|
|
}
|
2016-12-19 14:59:27 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-12-20 18:36:17 +01:00
|
|
|
protected boolean removeFromContextTargetVertex(Vertex target)
|
|
|
|
throws ResourceRegistryException {
|
|
|
|
EntityManagement entityManagement = EntityManagement
|
|
|
|
.getEntityManagement(orientGraph, target);
|
|
|
|
if (entityManagement != null) {
|
|
|
|
entityManagement.reallyRemoveFromContext();
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-19 14:59:27 +01:00
|
|
|
public boolean reallyRemoveFromContext() throws ContextException,
|
|
|
|
ResourceRegistryException {
|
2016-12-20 18:36:17 +01:00
|
|
|
getEdge();
|
|
|
|
|
|
|
|
RemoveConstraint removeConstraint = RemoveConstraint.keep;
|
|
|
|
|
|
|
|
try {
|
|
|
|
PropagationConstraint propagationConstraint = Utility.getEmbedded(
|
|
|
|
PropagationConstraint.class, edge,
|
|
|
|
Relation.PROPAGATION_CONSTRAINT);
|
|
|
|
if (propagationConstraint.getRemoveConstraint() != null) {
|
|
|
|
removeConstraint = propagationConstraint.getRemoveConstraint();
|
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
|
|
logger.warn("Error while getting {} from {}. Assuming {}. "
|
|
|
|
+ "This is really strange and should not occur. "
|
|
|
|
+ "Please Investigate it.",
|
|
|
|
Relation.PROPAGATION_CONSTRAINT,
|
|
|
|
Utility.toJsonString(edge, true), removeConstraint);
|
|
|
|
}
|
|
|
|
|
|
|
|
Vertex target = edge.getVertex(Direction.IN);
|
2016-12-27 15:31:39 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* In any removeConstraint value the relation MUSt be removed from
|
|
|
|
* context to avoid to have edge having a source outside of the context.
|
|
|
|
*/
|
2016-12-20 18:36:17 +01:00
|
|
|
ContextUtility.removeFromActualContext(orientGraph, edge);
|
|
|
|
|
|
|
|
switch (removeConstraint) {
|
2016-12-27 15:31:39 +01:00
|
|
|
case cascade:
|
2016-12-20 18:36:17 +01:00
|
|
|
removeFromContextTargetVertex(target);
|
2016-12-27 15:31:39 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case cascadeWhenOrphan:
|
|
|
|
Iterable<Edge> iterable = target.getEdges(Direction.IN);
|
|
|
|
Iterator<Edge> iterator = iterable.iterator();
|
|
|
|
if (iterator.hasNext()) {
|
|
|
|
logger.trace(
|
|
|
|
"{} point to {} which is not orphan. Giving {} directive, it will be not remove from current context.",
|
|
|
|
edge, target, removeConstraint);
|
|
|
|
} else {
|
|
|
|
removeFromContextTargetVertex(target);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case keep:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2016-12-20 18:36:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2016-12-19 14:59:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected EntityManagement getEntityManagement()
|
|
|
|
throws ResourceRegistryException {
|
|
|
|
EntityManagement entityManagement;
|
|
|
|
if (ConsistsOf.class.isAssignableFrom(relationClass)) {
|
|
|
|
entityManagement = new FacetManagement(orientGraph);
|
|
|
|
} else if (IsRelatedTo.class.isAssignableFrom(relationClass)) {
|
|
|
|
entityManagement = new ResourceManagement(orientGraph);
|
|
|
|
} else {
|
|
|
|
String error = String.format("{%s is not a %s nor a %s. "
|
|
|
|
+ "This is really strange ad should not occur. "
|
|
|
|
+ "Please Investigate it.", relationClass, ConsistsOf.NAME,
|
|
|
|
IsRelatedTo.NAME);
|
|
|
|
throw new ResourceRegistryException(error);
|
|
|
|
}
|
|
|
|
return entityManagement;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static RelationManagement getRelationManagement(
|
|
|
|
OrientGraph orientGraph, Edge edge)
|
|
|
|
throws ResourceRegistryException {
|
|
|
|
OrientEdgeType orientEdgeType = ((OrientEdge) edge).getType();
|
|
|
|
RelationManagement relationManagement = null;
|
|
|
|
if (orientEdgeType.isSubClassOf(ConsistsOf.NAME)) {
|
|
|
|
relationManagement = new ConsistsOfManagement(orientGraph);
|
|
|
|
} else if (orientEdgeType.isSubClassOf(IsRelatedTo.NAME)) {
|
|
|
|
relationManagement = new IsRelatedToManagement(orientGraph);
|
|
|
|
} else {
|
|
|
|
String error = String.format("{%s is not a %s nor a %s. "
|
|
|
|
+ "This is really strange ad should not occur. "
|
|
|
|
+ "Please Investigate it.", edge, ConsistsOf.NAME,
|
|
|
|
IsRelatedTo.NAME);
|
|
|
|
throw new ResourceRegistryException(error);
|
|
|
|
}
|
|
|
|
relationManagement.setEdge(edge);
|
|
|
|
return relationManagement;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected boolean deleteTargetVertex(Vertex target)
|
|
|
|
throws ResourceRegistryException {
|
|
|
|
EntityManagement entityManagement = EntityManagement
|
|
|
|
.getEntityManagement(orientGraph, target);
|
|
|
|
if (entityManagement != null) {
|
|
|
|
entityManagement.reallyDelete();
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean reallyDelete() throws RelationNotFoundException,
|
|
|
|
ResourceRegistryException {
|
|
|
|
getEdge();
|
|
|
|
|
2016-12-20 16:51:57 +01:00
|
|
|
RemoveConstraint removeConstraint = RemoveConstraint.keep;
|
2016-12-19 14:59:27 +01:00
|
|
|
|
|
|
|
try {
|
2016-12-20 16:51:57 +01:00
|
|
|
PropagationConstraint propagationConstraint = Utility.getEmbedded(
|
2016-12-20 18:36:17 +01:00
|
|
|
PropagationConstraint.class, edge,
|
|
|
|
Relation.PROPAGATION_CONSTRAINT);
|
|
|
|
if (propagationConstraint.getRemoveConstraint() != null) {
|
2016-12-20 16:51:57 +01:00
|
|
|
removeConstraint = propagationConstraint.getRemoveConstraint();
|
|
|
|
}
|
2016-12-19 14:59:27 +01:00
|
|
|
} catch (Exception e) {
|
|
|
|
logger.warn("Error while getting {} from {}. Assuming {}. "
|
2016-12-20 16:51:57 +01:00
|
|
|
+ "This is really strange and should not occur. "
|
2016-12-19 14:59:27 +01:00
|
|
|
+ "Please Investigate it.",
|
2016-12-20 16:51:57 +01:00
|
|
|
Relation.PROPAGATION_CONSTRAINT,
|
2016-12-20 18:36:17 +01:00
|
|
|
Utility.toJsonString(edge, true), removeConstraint);
|
2016-12-19 14:59:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Vertex target = edge.getVertex(Direction.IN);
|
|
|
|
edge.remove();
|
|
|
|
|
2016-12-20 16:51:57 +01:00
|
|
|
switch (removeConstraint) {
|
|
|
|
case cascade:
|
2016-12-19 14:59:27 +01:00
|
|
|
deleteTargetVertex(target);
|
|
|
|
break;
|
|
|
|
|
2016-12-20 16:51:57 +01:00
|
|
|
case cascadeWhenOrphan:
|
2016-12-19 14:59:27 +01:00
|
|
|
Iterable<Edge> iterable = target.getEdges(Direction.IN);
|
|
|
|
Iterator<Edge> iterator = iterable.iterator();
|
|
|
|
if (iterator.hasNext()) {
|
|
|
|
logger.trace(
|
|
|
|
"{} point to {} which is not orphan. Giving {} directive, it will be keep.",
|
2016-12-20 16:51:57 +01:00
|
|
|
edge, target, removeConstraint);
|
2016-12-19 14:59:27 +01:00
|
|
|
} else {
|
|
|
|
deleteTargetVertex(target);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2016-12-20 16:51:57 +01:00
|
|
|
case keep:
|
2016-12-19 14:59:27 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String create(UUID sourceUUID, UUID targetUUID)
|
|
|
|
throws ResourceRegistryException {
|
|
|
|
try {
|
2016-12-19 16:25:29 +01:00
|
|
|
orientGraph = ContextUtility
|
|
|
|
.getActualSecurityContextGraph(PermissionMode.WRITER);
|
2016-12-19 14:59:27 +01:00
|
|
|
|
|
|
|
edge = reallyCreate(sourceUUID, targetUUID);
|
|
|
|
|
|
|
|
orientGraph.commit();
|
|
|
|
|
|
|
|
return serialize();
|
|
|
|
|
|
|
|
} catch (ResourceRegistryException e) {
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.rollback();
|
|
|
|
}
|
|
|
|
throw e;
|
|
|
|
} catch (Exception e) {
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.rollback();
|
|
|
|
}
|
|
|
|
throw new ResourceRegistryException(e);
|
|
|
|
} finally {
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.shutdown();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public String read() throws RelationNotFoundException,
|
|
|
|
ResourceRegistryException {
|
|
|
|
try {
|
2016-12-19 16:25:29 +01:00
|
|
|
|
|
|
|
orientGraph = ContextUtility
|
|
|
|
.getActualSecurityContextGraph(PermissionMode.WRITER);
|
2016-12-19 14:59:27 +01:00
|
|
|
|
|
|
|
return serialize();
|
|
|
|
|
|
|
|
} catch (ResourceRegistryException e) {
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.rollback();
|
|
|
|
}
|
|
|
|
throw e;
|
|
|
|
} catch (Exception e) {
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.rollback();
|
|
|
|
}
|
|
|
|
throw new ResourceRegistryException(e);
|
|
|
|
} finally {
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.shutdown();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public String update() throws RelationNotFoundException,
|
|
|
|
ResourceRegistryException {
|
|
|
|
try {
|
2016-12-19 16:25:29 +01:00
|
|
|
|
|
|
|
orientGraph = ContextUtility
|
|
|
|
.getActualSecurityContextGraph(PermissionMode.WRITER);
|
2016-12-19 14:59:27 +01:00
|
|
|
|
|
|
|
edge = reallyUpdate();
|
|
|
|
|
|
|
|
return serialize();
|
|
|
|
|
|
|
|
} catch (ResourceRegistryException e) {
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.rollback();
|
|
|
|
}
|
|
|
|
throw e;
|
|
|
|
} catch (Exception e) {
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.rollback();
|
|
|
|
}
|
|
|
|
throw new ResourceRegistryException(e);
|
|
|
|
} finally {
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.shutdown();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean delete() throws RelationNotFoundException,
|
|
|
|
ResourceRegistryException {
|
|
|
|
|
|
|
|
logger.debug(
|
|
|
|
"Going to remove {} with UUID {}. Related {}s will be detached.",
|
|
|
|
baseType, uuid, targetEntityClass.getSimpleName());
|
|
|
|
|
|
|
|
try {
|
2016-12-19 16:25:29 +01:00
|
|
|
orientGraph = ContextUtility
|
|
|
|
.getActualSecurityContextGraph(PermissionMode.WRITER);
|
2016-12-19 14:59:27 +01:00
|
|
|
|
|
|
|
boolean deleted = reallyDelete();
|
|
|
|
|
|
|
|
orientGraph.commit();
|
|
|
|
|
|
|
|
logger.info("{} {} with UUID {} successfully removed.", baseType,
|
|
|
|
uuid);
|
|
|
|
|
|
|
|
return deleted;
|
|
|
|
|
2016-12-19 16:25:29 +01:00
|
|
|
} catch (ResourceRegistryException e) {
|
2016-12-19 14:59:27 +01:00
|
|
|
logger.error("Unable to remove {} with UUID.", baseType, uuid);
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.rollback();
|
|
|
|
}
|
2016-12-19 16:25:29 +01:00
|
|
|
throw e;
|
2016-12-19 14:59:27 +01:00
|
|
|
} catch (Exception e) {
|
|
|
|
logger.error("Unable to remove {} with UUID {}.", baseType, uuid);
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.rollback();
|
|
|
|
}
|
|
|
|
throw new ResourceRegistryException(e);
|
|
|
|
} finally {
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.shutdown();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean addToContext() throws ContextException {
|
|
|
|
logger.debug("Going to add {} with UUID {} to actual Context",
|
|
|
|
baseType, uuid);
|
|
|
|
|
|
|
|
try {
|
2016-12-19 16:25:29 +01:00
|
|
|
orientGraph = SecurityContextMapper.getSecurityContextFactory(
|
|
|
|
SecurityContextMapper.ADMIN_SECURITY_CONTEXT_UUID,
|
|
|
|
PermissionMode.WRITER).getTx();
|
2016-12-19 14:59:27 +01:00
|
|
|
|
|
|
|
boolean added = reallyAddToContext();
|
|
|
|
|
|
|
|
orientGraph.commit();
|
|
|
|
logger.info("{} with UUID {} successfully added to actual Context",
|
|
|
|
baseType, uuid);
|
|
|
|
|
|
|
|
return added;
|
|
|
|
} catch (Exception e) {
|
|
|
|
logger.error("Unable to add {} with UUID {} to actual Context",
|
|
|
|
baseType, uuid, e);
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.rollback();
|
|
|
|
}
|
2016-12-19 16:25:29 +01:00
|
|
|
throw new ContextException(e);
|
2016-12-19 14:59:27 +01:00
|
|
|
} finally {
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.shutdown();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean removeFromContext() throws ContextException {
|
|
|
|
logger.debug("Going to remove {} with UUID {} from actual Context",
|
|
|
|
baseType, uuid);
|
|
|
|
|
|
|
|
try {
|
2016-12-19 16:25:29 +01:00
|
|
|
orientGraph = SecurityContextMapper.getSecurityContextFactory(
|
|
|
|
SecurityContextMapper.ADMIN_SECURITY_CONTEXT_UUID,
|
|
|
|
PermissionMode.WRITER).getTx();
|
2016-12-19 14:59:27 +01:00
|
|
|
|
|
|
|
boolean removed = reallyRemoveFromContext();
|
|
|
|
|
|
|
|
orientGraph.commit();
|
|
|
|
logger.info(
|
|
|
|
"{} with UUID {} successfully removed from actual Context",
|
|
|
|
baseType, uuid);
|
|
|
|
|
|
|
|
return removed;
|
|
|
|
} catch (Exception e) {
|
|
|
|
logger.error(
|
|
|
|
"Unable to remove {} with UUID {} from actual Context",
|
|
|
|
baseType, uuid, e);
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.rollback();
|
|
|
|
}
|
2016-12-19 16:25:29 +01:00
|
|
|
throw new ContextException(e);
|
2016-12-19 14:59:27 +01:00
|
|
|
} finally {
|
|
|
|
if (orientGraph != null) {
|
|
|
|
orientGraph.shutdown();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|