resource-registry/src/main/java/org/gcube/informationsystem/resourceregistry/er/entity/EntityManagement.java

229 lines
7.5 KiB
Java
Raw Normal View History

/**
*
*/
package org.gcube.informationsystem.resourceregistry.er.entity;
import java.util.HashMap;
import java.util.Map;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import org.gcube.informationsystem.model.AccessType;
import org.gcube.informationsystem.model.entity.Entity;
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.entity.EntityAlreadyPresentException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.er.ERAvailableInAnotherContextException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.er.ERNotFoundException;
import org.gcube.informationsystem.resourceregistry.context.ContextUtility;
import org.gcube.informationsystem.resourceregistry.er.ERManagement;
import org.gcube.informationsystem.resourceregistry.er.ERManagementUtility;
import org.gcube.informationsystem.resourceregistry.er.relation.RelationManagement;
import org.gcube.informationsystem.resourceregistry.utils.Utility;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientGraph;
import com.tinkerpop.blueprints.impls.orient.OrientVertex;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public abstract class EntityManagement<E extends Entity> extends
ERManagement<E, Vertex> {
/**
* Provide a cache edge-internal-id -> RelationManagement
* this avoid to recreate the relationManagement of already visited
* edges
*/
@SuppressWarnings("rawtypes")
protected Map<String, RelationManagement> relationManagements;
protected EntityManagement(AccessType accessType) {
super(accessType);
this.ignoreKeys.add(Entity.HEADER_PROPERTY);
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());
this.relationManagements = new HashMap<>();
}
@SuppressWarnings("rawtypes")
protected RelationManagement getRelationManagement(Edge edge) throws ResourceRegistryException {
String id = edge.getId().toString();
RelationManagement relationManagement = relationManagements.get(id);
if(relationManagement==null) {
relationManagement = ERManagementUtility.getRelationManagement(orientGraph, edge);
}
return relationManagement;
}
protected EntityManagement(AccessType accessType, OrientGraph orientGraph) {
this(accessType);
this.orientGraph = orientGraph;
}
protected static JSONObject addRelation(JSONObject sourceResource,
JSONObject relation, String arrayKey)
throws ResourceRegistryException {
JSONArray relationArray = null;
try {
if (sourceResource.has(arrayKey)) {
relationArray = sourceResource.getJSONArray(arrayKey);
} else {
relationArray = new JSONArray();
}
relationArray.put(relation);
sourceResource.putOpt(arrayKey, relationArray);
} catch (Exception e) {
throw new ResourceRegistryException(e);
}
return sourceResource;
}
protected Vertex createVertex() throws EntityAlreadyPresentException,
ResourceRegistryException {
logger.trace("Going to create {} for {} ({}) using {}",
Vertex.class.getSimpleName(), accessType.getName(), erType, jsonNode);
try {
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.",
accessType.getName(), erType);
throw new ResourceRegistryException(error);
}
Vertex vertexEntity = orientGraph.addVertex("class:" + erType);
try {
if(uuid!=null){
Vertex v = getElement();
if (v != null) {
String error = String.format(
"A %s with UUID %s already exist", erType,
uuid.toString());
throw getSpecificERAlreadyPresentException(error);
}
}
} catch (ERNotFoundException e) {
try {
Element el = ERManagementUtility.getAnyElementByUUID(uuid);
String error = String.format(
"UUID %s is already used by another %s. This is not allowed.",
uuid.toString(), (el instanceof Vertex) ? Entity.NAME : Relation.NAME);
throw getSpecificERAvailableInAnotherContextException(error);
}catch (ERNotFoundException e1) {
// OK the UUID is not already used.
}
} catch (ERAvailableInAnotherContextException e) {
throw e;
}
this.element = vertexEntity;
if (accessType==AccessType.RESOURCE) {
// Facet and relation are created in calling method
} else {
ERManagement.updateProperties(oClass, element, jsonNode, ignoreKeys,
ignoreStartWithKeys);
}
/* This code has been moved in ERManagement.internalCreate()
Header entityHeader = HeaderUtility.getHeader(jsonNode, true);
if (entityHeader != null) {
element.setProperty(Entity.HEADER_PROPERTY, entityHeader);
} else {
entityHeader = HeaderUtility.addHeader(element, null);
}
ContextUtility.addToActualContext(orientGraph, element);
((OrientVertex) element).save();
*/
logger.info("Created {} is {}", Vertex.class.getSimpleName(),
Utility.toJsonString((OrientVertex) element, true));
return element;
} catch (ResourceRegistryException e) {
throw e;
} catch (Exception e) {
logger.trace("Error while creating {} for {} ({}) using {}",
Vertex.class.getSimpleName(), accessType.getName(), erType, jsonNode, e);
throw new ResourceRegistryException("Error Creating " + erType
+ " with " + jsonNode, e.getCause());
}
}
@Override
protected boolean reallyAddToContext() throws ContextException,
ResourceRegistryException {
ContextUtility.addToActualContext(orientGraph, getElement());
Iterable<Edge> edges = getElement().getEdges(Direction.OUT);
for (Edge edge : edges) {
@SuppressWarnings("rawtypes")
RelationManagement relationManagement = getRelationManagement(edge);
relationManagement.internalAddToContext();
}
return true;
}
@Override
protected boolean reallyRemoveFromContext() throws ContextException,
ResourceRegistryException {
ContextUtility.removeFromActualContext(orientGraph, getElement());
Iterable<Edge> edges = element.getEdges(Direction.OUT);
for (Edge edge : edges) {
@SuppressWarnings("rawtypes")
RelationManagement relationManagement = getRelationManagement(edge);
relationManagement.internalRemoveFromContext();
}
return true;
}
@Override
public String reallyGetAll(boolean polymorphic) throws ResourceRegistryException {
JSONArray jsonArray = new JSONArray();
Iterable<Vertex> iterable = orientGraph.getVerticesOfClass(erType, polymorphic);
for(Vertex vertex : iterable){
@SuppressWarnings("rawtypes")
EntityManagement entityManagement = ERManagementUtility.getEntityManagement(orientGraph, vertex);
try {
JSONObject jsonObject = entityManagement.serializeAsJson();
jsonArray.put(jsonObject);
}catch (ResourceRegistryException e) {
logger.error("Unable to correctly serialize {}. It will be excluded from results. This is really strange and should not occur.", vertex.toString());
}
}
return jsonArray.toString();
}
}