2019-11-04 18:01:20 +01:00
|
|
|
package org.gcube.informationsystem.resourceregistry.instances.base.relations;
|
|
|
|
|
|
|
|
import java.util.UUID;
|
|
|
|
|
|
|
|
import org.gcube.informationsystem.base.reference.AccessType;
|
|
|
|
import org.gcube.informationsystem.base.reference.entities.BaseEntity;
|
|
|
|
import org.gcube.informationsystem.base.reference.relations.BaseRelation;
|
|
|
|
import org.gcube.informationsystem.model.reference.relations.Relation;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.relation.RelationNotFoundException;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaException;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.instances.base.ERManagement;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.instances.base.entities.BaseEntityManagement;
|
2019-11-06 12:13:19 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.instances.model.entities.FacetManagement;
|
2019-11-04 18:01:20 +01:00
|
|
|
import org.gcube.informationsystem.resourceregistry.security.SecurityContext;
|
|
|
|
import org.gcube.informationsystem.resourceregistry.utils.Utility;
|
|
|
|
|
|
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
|
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
2019-11-05 18:36:44 +01:00
|
|
|
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
|
|
|
|
import com.orientechnologies.orient.core.record.ODirection;
|
|
|
|
import com.orientechnologies.orient.core.record.OEdge;
|
|
|
|
import com.orientechnologies.orient.core.record.OVertex;
|
2019-11-04 18:01:20 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Luca Frosini (ISTI - CNR)
|
|
|
|
*/
|
|
|
|
public abstract class BaseRelationManagement<R extends BaseRelation<S, T>, SEM extends BaseEntityManagement<S>, TEM extends BaseEntityManagement<T>, S extends BaseEntity, T extends BaseEntity>
|
2019-11-05 18:36:44 +01:00
|
|
|
extends ERManagement<OEdge> {
|
2019-11-04 18:01:20 +01:00
|
|
|
|
|
|
|
protected final Class<S> sourceEntityClass;
|
|
|
|
protected final Class<T> targetEntityClass;
|
|
|
|
|
|
|
|
protected SEM sourceEntityManagement;
|
|
|
|
protected TEM targetEntityManagement;
|
|
|
|
|
|
|
|
protected BaseRelationManagement(AccessType accessType, Class<S> sourceEntityClass, Class<T> targetEntityClass) {
|
|
|
|
super(accessType);
|
|
|
|
|
|
|
|
this.ignoreKeys.add(Relation.HEADER_PROPERTY);
|
|
|
|
this.ignoreKeys.add(Relation.SOURCE_PROPERTY);
|
|
|
|
this.ignoreKeys.add(Relation.TARGET_PROPERTY);
|
2019-11-05 18:36:44 +01:00
|
|
|
this.ignoreKeys.add(com.tinkerpop.blueprints.impls.orient.OrientBaseGraph.CONNECTION_OUT.toLowerCase());
|
|
|
|
this.ignoreKeys.add(com.tinkerpop.blueprints.impls.orient.OrientBaseGraph.CONNECTION_IN.toLowerCase());
|
|
|
|
this.ignoreKeys.add(com.tinkerpop.blueprints.impls.orient.OrientBaseGraph.CONNECTION_OUT.toUpperCase());
|
|
|
|
this.ignoreKeys.add(com.tinkerpop.blueprints.impls.orient.OrientBaseGraph.CONNECTION_IN.toUpperCase());
|
2019-11-04 18:01:20 +01:00
|
|
|
|
|
|
|
this.sourceEntityClass = sourceEntityClass;
|
|
|
|
this.targetEntityClass = targetEntityClass;
|
|
|
|
|
|
|
|
this.sourceEntityManagement = null;
|
|
|
|
this.targetEntityManagement = null;
|
|
|
|
}
|
|
|
|
|
2019-11-05 18:36:44 +01:00
|
|
|
protected BaseRelationManagement(AccessType accessType, Class<S> sourceEntityClass, Class<T> targetEntityClass, SecurityContext workingContext, ODatabaseDocument orientGraph) {
|
2019-11-04 18:01:20 +01:00
|
|
|
this(accessType, sourceEntityClass, targetEntityClass);
|
2019-11-05 18:36:44 +01:00
|
|
|
this.oDatabaseDocument = orientGraph;
|
2019-11-04 18:01:20 +01:00
|
|
|
setWorkingContext(workingContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
public SEM getSourceEntityManagement() throws ResourceRegistryException {
|
|
|
|
if(sourceEntityManagement == null) {
|
2019-11-05 18:36:44 +01:00
|
|
|
OVertex source = getElement().getVertex(ODirection.OUT);
|
2019-11-04 18:01:20 +01:00
|
|
|
sourceEntityManagement = newSourceEntityManagement();
|
|
|
|
sourceEntityManagement.setElement(source);
|
|
|
|
}
|
|
|
|
sourceEntityManagement.setReload(reload);
|
|
|
|
return sourceEntityManagement;
|
|
|
|
}
|
|
|
|
|
|
|
|
public TEM getTargetEntityManagement() throws ResourceRegistryException {
|
|
|
|
if(targetEntityManagement == null) {
|
2019-11-05 18:36:44 +01:00
|
|
|
OVertex target = getElement().getVertex(ODirection.IN);
|
2019-11-04 18:01:20 +01:00
|
|
|
targetEntityManagement = newTargetEntityManagement();
|
|
|
|
targetEntityManagement.setElement(target);
|
|
|
|
}
|
|
|
|
targetEntityManagement.setReload(reload);
|
|
|
|
return targetEntityManagement;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setSourceEntityManagement(SEM sourceEntityManagement) {
|
|
|
|
this.sourceEntityManagement = sourceEntityManagement;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setTargetEntityManagement(TEM targetEntityManagement) {
|
|
|
|
this.targetEntityManagement = targetEntityManagement;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String serialize() throws ResourceRegistryException {
|
|
|
|
return serializeAsJson().toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public JsonNode serializeAsJson() throws ResourceRegistryException {
|
|
|
|
return serializeAsJson(true, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
public JsonNode serializeAsJson(boolean includeSource, boolean includeTarget) throws ResourceRegistryException {
|
|
|
|
JsonNode relation = serializeSelfOnly();
|
|
|
|
|
|
|
|
try {
|
|
|
|
if(includeSource) {
|
|
|
|
BaseEntityManagement<S> sourceEntityManagement = getSourceEntityManagement();
|
|
|
|
((ObjectNode) relation).replace(Relation.SOURCE_PROPERTY, sourceEntityManagement.serializeSelfOnly());
|
|
|
|
}
|
|
|
|
|
|
|
|
if(includeTarget) {
|
|
|
|
BaseEntityManagement<T> targetEntityManagement = getTargetEntityManagement();
|
|
|
|
((ObjectNode) relation).replace(Relation.TARGET_PROPERTY, targetEntityManagement.serializeAsJson());
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch(ResourceRegistryException e) {
|
|
|
|
logger.error("Unable to correctly serialize {}. {}", element, Utility.SHOULD_NOT_OCCUR_ERROR_MESSAGE, e);
|
|
|
|
throw e;
|
|
|
|
} catch(Exception e) {
|
|
|
|
logger.error("Unable to correctly serialize {}. {}", element, Utility.SHOULD_NOT_OCCUR_ERROR_MESSAGE, e);
|
|
|
|
throw new ResourceRegistryException(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
return relation;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2019-11-05 18:36:44 +01:00
|
|
|
protected OEdge reallyCreate() throws ResourceRegistryException {
|
2019-11-04 18:01:20 +01:00
|
|
|
|
|
|
|
if(sourceEntityManagement == null) {
|
|
|
|
|
|
|
|
if(!jsonNode.has(Relation.SOURCE_PROPERTY)) {
|
|
|
|
throw new ResourceRegistryException("Error while creating relation. No source definition found");
|
|
|
|
}
|
|
|
|
|
|
|
|
UUID sourceUUID = org.gcube.informationsystem.utils.Utility
|
|
|
|
.getUUIDFromJsonNode(jsonNode.get(Relation.SOURCE_PROPERTY));
|
|
|
|
|
|
|
|
sourceEntityManagement = newSourceEntityManagement();
|
|
|
|
sourceEntityManagement.setUUID(sourceUUID);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(targetEntityManagement == null) {
|
|
|
|
targetEntityManagement = newTargetEntityManagement();
|
|
|
|
|
|
|
|
if(!jsonNode.has(Relation.TARGET_PROPERTY)) {
|
|
|
|
throw new ResourceRegistryException(
|
|
|
|
"Error while creating " + elementType + ". No target definition found");
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
targetEntityManagement.setJsonNode(jsonNode.get(Relation.TARGET_PROPERTY));
|
|
|
|
} catch(SchemaException e) {
|
|
|
|
StringBuilder errorMessage = new StringBuilder();
|
|
|
|
errorMessage.append("A ");
|
|
|
|
errorMessage.append(elementType);
|
|
|
|
errorMessage.append(" can be only created beetween ");
|
|
|
|
errorMessage.append(sourceEntityManagement.getAccessType().getName());
|
|
|
|
errorMessage.append(" and ");
|
|
|
|
errorMessage.append(targetEntityManagement.getAccessType().getName());
|
|
|
|
throw new ResourceRegistryException(errorMessage.toString(), e);
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
targetEntityManagement.getElement();
|
|
|
|
} catch(Exception e) {
|
|
|
|
targetEntityManagement.internalCreate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.trace("Creating {} beetween {} -> {}", elementType, getSourceEntityManagement().serialize(),
|
|
|
|
getTargetEntityManagement().serialize());
|
|
|
|
|
2019-11-05 18:36:44 +01:00
|
|
|
OVertex source = (OVertex) getSourceEntityManagement().getElement();
|
|
|
|
OVertex target = (OVertex) getTargetEntityManagement().getElement();
|
2019-11-04 18:01:20 +01:00
|
|
|
|
2019-11-05 18:36:44 +01:00
|
|
|
element = oDatabaseDocument.newEdge(source, target, elementType);
|
2019-11-04 18:01:20 +01:00
|
|
|
|
|
|
|
ERManagement.updateProperties(oClass, element, jsonNode, ignoreKeys, ignoreStartWithKeys);
|
|
|
|
|
|
|
|
return element;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected abstract SEM newSourceEntityManagement() throws ResourceRegistryException;
|
|
|
|
|
|
|
|
protected abstract TEM newTargetEntityManagement() throws ResourceRegistryException;
|
|
|
|
|
|
|
|
@Override
|
2019-11-05 18:36:44 +01:00
|
|
|
protected OEdge reallyUpdate() throws ResourceRegistryException {
|
2019-11-04 18:01:20 +01:00
|
|
|
|
|
|
|
logger.debug("Trying to update {} : {}", elementType, jsonNode);
|
|
|
|
|
2019-11-05 18:36:44 +01:00
|
|
|
OEdge edge = getElement();
|
2019-11-04 18:01:20 +01:00
|
|
|
ERManagement.updateProperties(oClass, edge, jsonNode, ignoreKeys, ignoreStartWithKeys);
|
|
|
|
|
|
|
|
if(accessType.compareTo(AccessType.CONSISTS_OF) == 0) {
|
|
|
|
JsonNode target = jsonNode.get(Relation.TARGET_PROPERTY);
|
|
|
|
if(target != null) {
|
2019-11-05 18:36:44 +01:00
|
|
|
FacetManagement fm = new FacetManagement(getWorkingContext(), oDatabaseDocument);
|
2019-11-04 18:01:20 +01:00
|
|
|
fm.setJsonNode(target);
|
|
|
|
fm.internalUpdate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.info("{} {} successfully updated", elementType, jsonNode);
|
|
|
|
|
|
|
|
return edge;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected boolean reallyDelete() throws RelationNotFoundException, ResourceRegistryException {
|
|
|
|
logger.debug("Going to remove {} with UUID {}. Related {}s will be detached.", accessType.getName(), uuid,
|
|
|
|
targetEntityClass.getSimpleName());
|
|
|
|
|
2019-11-05 18:36:44 +01:00
|
|
|
getElement().delete();
|
2019-11-04 18:01:20 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|