resource-registry/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/relations/BaseRelationManagement.java

218 lines
8.3 KiB
Java
Raw Normal View History

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.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;
2020-01-27 17:04:45 +01:00
import org.gcube.informationsystem.resourceregistry.contexts.SecurityContext;
import org.gcube.informationsystem.resourceregistry.instances.base.ERManagement;
import org.gcube.informationsystem.resourceregistry.instances.base.entities.BaseEntityManagement;
import org.gcube.informationsystem.resourceregistry.instances.model.entities.FacetManagement;
import org.gcube.informationsystem.resourceregistry.utils.Utility;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
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;
/**
* @author Luca Frosini (ISTI - CNR)
*/
2019-11-08 12:29:32 +01:00
public abstract class BaseRelationManagement<SEM extends BaseEntityManagement<? extends BaseEntity>, TEM extends BaseEntityManagement<? extends BaseEntity>>
extends ERManagement<OEdge> {
2019-11-08 12:29:32 +01:00
protected final Class<? extends BaseEntity> sourceEntityClass;
protected final Class<? extends BaseEntity> targetEntityClass;
protected SEM sourceEntityManagement;
protected TEM targetEntityManagement;
2019-11-08 12:29:32 +01:00
protected BaseRelationManagement(AccessType accessType, Class<? extends BaseEntity> sourceEntityClass, Class<? extends BaseEntity> targetEntityClass) {
super(accessType);
this.ignoreKeys.add(Relation.HEADER_PROPERTY);
this.ignoreKeys.add(Relation.SOURCE_PROPERTY);
this.ignoreKeys.add(Relation.TARGET_PROPERTY);
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());
this.sourceEntityClass = sourceEntityClass;
this.targetEntityClass = targetEntityClass;
this.sourceEntityManagement = null;
this.targetEntityManagement = null;
}
2019-11-08 12:29:32 +01:00
protected BaseRelationManagement(AccessType accessType, Class<? extends BaseEntity> sourceEntityClass, Class<? extends BaseEntity> targetEntityClass, SecurityContext workingContext, ODatabaseDocument orientGraph) {
this(accessType, sourceEntityClass, targetEntityClass);
this.oDatabaseDocument = orientGraph;
setWorkingContext(workingContext);
}
public SEM getSourceEntityManagement() throws ResourceRegistryException {
if(sourceEntityManagement == null) {
OVertex source = getElement().getVertex(ODirection.OUT);
sourceEntityManagement = newSourceEntityManagement();
sourceEntityManagement.setElement(source);
}
sourceEntityManagement.setReload(reload);
return sourceEntityManagement;
}
public TEM getTargetEntityManagement() throws ResourceRegistryException {
if(targetEntityManagement == null) {
OVertex target = getElement().getVertex(ODirection.IN);
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) {
2019-11-08 12:29:32 +01:00
BaseEntityManagement<? extends BaseEntity> sourceEntityManagement = getSourceEntityManagement();
((ObjectNode) relation).replace(Relation.SOURCE_PROPERTY, sourceEntityManagement.serializeSelfOnly());
}
if(includeTarget) {
2019-11-08 12:29:32 +01:00
BaseEntityManagement<? extends BaseEntity> 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
protected OEdge reallyCreate() throws ResourceRegistryException {
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());
OVertex source = (OVertex) getSourceEntityManagement().getElement();
OVertex target = (OVertex) getTargetEntityManagement().getElement();
element = oDatabaseDocument.newEdge(source, target, elementType);
ERManagement.updateProperties(oClass, element, jsonNode, ignoreKeys, ignoreStartWithKeys);
return element;
}
protected abstract SEM newSourceEntityManagement() throws ResourceRegistryException;
protected abstract TEM newTargetEntityManagement() throws ResourceRegistryException;
@Override
protected OEdge reallyUpdate() throws ResourceRegistryException {
logger.debug("Trying to update {} : {}", elementType, jsonNode);
OEdge edge = getElement();
ERManagement.updateProperties(oClass, edge, jsonNode, ignoreKeys, ignoreStartWithKeys);
if(accessType.compareTo(AccessType.CONSISTS_OF) == 0) {
JsonNode target = jsonNode.get(Relation.TARGET_PROPERTY);
if(target != null) {
FacetManagement fm = new FacetManagement(getWorkingContext(), oDatabaseDocument);
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());
getElement().delete();
return true;
}
}