package org.gcube.informationsystem.resourceregistry.instances.model.relations; import java.util.Iterator; import org.gcube.informationsystem.base.reference.AccessType; import org.gcube.informationsystem.model.impl.properties.PropagationConstraintImpl; import org.gcube.informationsystem.model.reference.entities.Facet; import org.gcube.informationsystem.model.reference.properties.PropagationConstraint; import org.gcube.informationsystem.model.reference.properties.PropagationConstraint.AddConstraint; import org.gcube.informationsystem.model.reference.properties.PropagationConstraint.DeleteConstraint; import org.gcube.informationsystem.model.reference.properties.PropagationConstraint.RemoveConstraint; import org.gcube.informationsystem.model.reference.relations.ConsistsOf; import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException; import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.consistsof.ConsistsOfAlreadyPresentException; import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.consistsof.ConsistsOfAvailableInAnotherContextException; import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.consistsof.ConsistsOfNotFoundException; import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaViolationException; import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext.PermissionMode; import org.gcube.informationsystem.resourceregistry.instances.model.Operation; import org.gcube.informationsystem.resourceregistry.instances.model.entities.FacetManagement; import org.gcube.informationsystem.resourceregistry.instances.model.entities.ResourceManagement; import org.gcube.informationsystem.types.reference.entities.FacetType; import com.arcadedb.graph.Edge; import com.arcadedb.graph.Vertex; import com.arcadedb.graph.Vertex.DIRECTION; import com.arcadedb.remote.RemoteDatabase; /** * @author Luca Frosini (ISTI - CNR) */ public class ConsistsOfManagement extends RelationManagement { public static final PropagationConstraint DEFAULT_CONSISTS_OF_PC; static { DEFAULT_CONSISTS_OF_PC = new PropagationConstraintImpl(); DEFAULT_CONSISTS_OF_PC.setDeleteConstraint(DeleteConstraint.cascade); DEFAULT_CONSISTS_OF_PC.setRemoveConstraint(RemoveConstraint.cascade); DEFAULT_CONSISTS_OF_PC.setAddConstraint(AddConstraint.propagate); } public ConsistsOfManagement() { super(AccessType.CONSISTS_OF, Facet.class, DEFAULT_CONSISTS_OF_PC); } @Override protected ConsistsOfNotFoundException getSpecificNotFoundException(NotFoundException e) { return new ConsistsOfNotFoundException(e.getMessage(), e.getCause()); } @Override public ConsistsOfAvailableInAnotherContextException getSpecificAvailableInAnotherContextException( String message) { return new ConsistsOfAvailableInAnotherContextException(message); } @Override protected ConsistsOfAlreadyPresentException getSpecificAlreadyPresentException(String message) { return new ConsistsOfAlreadyPresentException(message); } @Override protected FacetManagement newTargetEntityManagement() throws ResourceRegistryException { FacetManagement facetManagement = new FacetManagement(); facetManagement.setDatabase(database); facetManagement.setWorkingContext(getWorkingContext()); return facetManagement; } @Override protected Edge reallyCreate() throws ResourceRegistryException { Edge thisEdge = super.reallyCreate(); Vertex target = (Vertex) getTargetEntityManagement().getElement(); int count = 0; Iterable iterable = target.getEdges(DIRECTION.IN); Iterator iterator = iterable.iterator(); while(iterator.hasNext()) { iterator.next(); ++count; } if(count > 1) { throw new SchemaViolationException("It is not possible to create multiple " + ConsistsOf.NAME + " between the same " + Facet.NAME); } return thisEdge; } protected void checkResource() throws SchemaViolationException, ResourceRegistryException { if(!entryPoint) { return; } if(operation.isSafe()) { /* * The sanity check is not required for a safe operation. */ return; } if(operation == Operation.UPDATE) { // an update to the Facet only modify the ConsistsOf properties, no need to check the source resource return; } RemoteDatabase targetSecurityContextDatabase = null; try { ResourceManagement resourceManagement = getSourceEntityManagement(); switch (operation) { case CREATE: case DELETE: break; case ADD_TO_CONTEXT: case REMOVE_FROM_CONTEXT: resourceManagement = new ResourceManagement(); resourceManagement.setElementType(sourceEntityManagement.getTypeName()); resourceManagement.setUUID(sourceEntityManagement.getUUID()); if(operation == Operation.ADD_TO_CONTEXT) { resourceManagement.setSourceSecurityContext(sourceSecurityContext); } resourceManagement.setTargetSecurityContext(targetSecurityContext); resourceManagement.setWorkingContext(targetSecurityContext); targetSecurityContextDatabase = targetSecurityContext.getRemoteDatabase(PermissionMode.READER); resourceManagement.setDatabase(targetSecurityContextDatabase); break; default: // You should not be here return; } resourceManagement.setOperation(operation); resourceManagement.addToRelationManagements(this); resourceManagement.sanityCheck(); }catch (ResourceRegistryException e) { throw e; }catch (Exception e) { throw new ResourceRegistryException(e); }finally { if(targetSecurityContextDatabase!=null) { targetSecurityContextDatabase.close(); // database.activateOnCurrentThread(); } } } @Override public void sanityCheck() throws SchemaViolationException, ResourceRegistryException { super.sanityCheck(); checkResource(); } }