package org.gcube.informationsystem.resourceregistry.types.relations; import java.util.Map; import java.util.UUID; import org.gcube.com.fasterxml.jackson.databind.JsonNode; import org.gcube.informationsystem.base.reference.AccessType; import org.gcube.informationsystem.model.reference.relations.Relation; import org.gcube.informationsystem.resourceregistry.api.exceptions.AlreadyPresentException; import org.gcube.informationsystem.resourceregistry.api.exceptions.AvailableInAnotherContextException; import org.gcube.informationsystem.resourceregistry.api.exceptions.NotFoundException; import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException; import org.gcube.informationsystem.resourceregistry.api.exceptions.relations.RelationNotFoundException; import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaAlreadyPresentException; import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaNotFoundException; import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaViolationException; import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext; import org.gcube.informationsystem.resourceregistry.contexts.security.TypeSecurityContext; import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagementUtility; import org.gcube.informationsystem.resourceregistry.instances.base.relations.RelationElementManagement; import org.gcube.informationsystem.resourceregistry.types.entities.EntityTypeDefinitionManagement; import org.gcube.informationsystem.resourceregistry.types.entities.ResourceTypeDefinitionManagement; import org.gcube.informationsystem.resourceregistry.utils.DBUtility; import org.gcube.informationsystem.types.reference.entities.EntityType; import org.gcube.informationsystem.types.reference.entities.ResourceType; import org.gcube.informationsystem.types.reference.relations.RelationType; import com.arcadedb.graph.Edge; import com.arcadedb.graph.Vertex; import com.arcadedb.query.sql.executor.Result; import com.arcadedb.query.sql.executor.ResultSet; import com.arcadedb.remote.RemoteDatabase; /** * @author Luca Frosini (ISTI - CNR) */ public abstract class RelationTypeDefinitionManagement, TT extends EntityType> extends RelationElementManagement { protected String name; public RelationTypeDefinitionManagement(Class clz) { super(AccessType.RELATION_TYPE, ResourceType.class, clz); this.typeName = RelationType.NAME; this.forceIncludeAllMeta = true; } public RelationTypeDefinitionManagement(SecurityContext securityContext, RemoteDatabase database, Class clz) throws ResourceRegistryException { this(clz); this.database = database; setWorkingContext(securityContext); } @Override public Map getAffectedInstances() { throw new UnsupportedOperationException(); } @Override protected SecurityContext getWorkingContext() throws ResourceRegistryException { if (workingContext == null) { this.workingContext = TypeSecurityContext.getInstance(); } return workingContext; } public void setName(String name) { this.name = name; } public String getName() { if (name == null) { if (element == null) { if (jsonNode != null) { name = jsonNode.get(RelationType.NAME_PROPERTY).asText(); } } else { name = element.getString(RelationType.NAME_PROPERTY); } } return name; } @Override protected Edge reallyCreate() throws ResourceRegistryException { logger.debug("Going to create {} for {}", RelationType.NAME, getName()); if (sourceEntityManagement == null) { if (!jsonNode.has(Relation.SOURCE_PROPERTY)) { throw new ResourceRegistryException("Error while creating relation. No source definition found"); } sourceEntityManagement = newSourceEntityManagement(); // sourceEntityManagement.setElementType(EntityTypeDefinition.NAME); sourceEntityManagement.setJsonNode(jsonNode.get(Relation.SOURCE_PROPERTY)); } if (targetEntityManagement == null) { if (!jsonNode.has(Relation.TARGET_PROPERTY)) { throw new ResourceRegistryException( "Error while creating " + typeName + ". No target definition found"); } targetEntityManagement = newTargetEntityManagement(); // targetEntityManagement.setElementType(EntityTypeDefinition.NAME); targetEntityManagement.setJsonNode(jsonNode.get(Relation.TARGET_PROPERTY)); } Vertex source = (Vertex) getSourceEntityManagement().getElement(); Vertex target = (Vertex) getTargetEntityManagement().getElement(); logger.trace("Creating {} beetween {} -> {}", typeName, source.toString(), target.toString()); element = source.newEdge(typeName, target, true); updateProperties(documentType, element, jsonNode, ignoreKeys, ignoreStartWithKeys); return element; } @Override protected Edge reallyUpdate() throws NotFoundException, ResourceRegistryException { logger.debug("Going to update {} for {}", RelationType.NAME, getName()); Edge relationTypeDefinition = getElement(); relationTypeDefinition = (Edge) updateProperties(documentType, relationTypeDefinition, jsonNode, ignoreKeys, ignoreStartWithKeys); return relationTypeDefinition; } @Override protected void reallyDelete() throws RelationNotFoundException, ResourceRegistryException { logger.debug("Going to remove {} for {}", RelationType.NAME, getName()); getElement().delete(); } @Override public Edge getElement() throws NotFoundException, ResourceRegistryException { if (element == null) { try { element = retrieveElement(); } catch (NotFoundException e) { throw e; } catch (ResourceRegistryException e) { throw e; } catch (Exception e) { throw new ResourceRegistryException(e); } } else { if (reload) { element.reload(); } } return element; } @Override public Edge retrieveElement() throws NotFoundException, ResourceRegistryException { try { if (getName() == null) { throw new NotFoundException("null name does not allow to retrieve the Element"); } String select = "SELECT FROM " + typeName + " WHERE " + RelationType.NAME_PROPERTY + " = \"" + getName() + "\""; ResultSet resultSet = database.query("sql",select); if (resultSet == null || !resultSet.hasNext()) { String error = String.format("No %s with name %s was found", typeName, getName()); logger.info(error); throw new NotFoundException(error); } Result oResult = resultSet.next(); Edge element = (Edge) ElementManagementUtility.getElementFromOptional(oResult.getElement()); logger.trace("{} with id {} is : {}", typeName, getName(), DBUtility.getAsStringForLogging(element)); if (resultSet.hasNext()) { throw new ResourceRegistryException("Found more than one " + typeName + " with name " + getName() + ". This is a fatal error please contact Admnistrator"); } return element; } catch (NotFoundException e) { throw getSpecificNotFoundException(e); } catch (ResourceRegistryException e) { throw e; } catch (Exception e) { throw new ResourceRegistryException(e); } } @Override public String reallyGetAll(boolean polymorphic) throws ResourceRegistryException { throw new UnsupportedOperationException(); } @Override protected NotFoundException getSpecificNotFoundException(NotFoundException e) { return new SchemaNotFoundException(e.getMessage(), e.getCause()); } @Override protected AlreadyPresentException getSpecificAlreadyPresentException(String message) { return new SchemaAlreadyPresentException(message); } @Override protected ResourceTypeDefinitionManagement newSourceEntityManagement() throws ResourceRegistryException { ResourceTypeDefinitionManagement rtdm = new ResourceTypeDefinitionManagement(); rtdm.setWorkingContext(getWorkingContext()); rtdm.setDatabase(database); return rtdm; } @Override protected void checksourceAndTargetEntityCompliancy() throws NotFoundException, AvailableInAnotherContextException, SchemaViolationException, ResourceRegistryException { // The compliancy is ensured by the code } }