package org.gcube.informationsystem.resourceregistry.types.entities; import java.util.HashMap; import org.gcube.informationsystem.base.reference.AccessType; 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.context.ContextException; import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.EntityAlreadyPresentException; import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaAlreadyPresentException; import org.gcube.informationsystem.resourceregistry.api.exceptions.schema.SchemaNotFoundException; import org.gcube.informationsystem.resourceregistry.contexts.ContextUtility; import org.gcube.informationsystem.resourceregistry.contexts.security.SecurityContext; import org.gcube.informationsystem.resourceregistry.dbinitialization.DatabaseEnvironment; import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagement; import org.gcube.informationsystem.resourceregistry.instances.base.entities.EntityElementManagement; import org.gcube.informationsystem.resourceregistry.utils.Utility; import org.gcube.informationsystem.types.TypeBinder; import org.gcube.informationsystem.types.reference.entities.EntityType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.databind.JsonNode; import com.orientechnologies.orient.core.db.document.ODatabaseDocument; import com.orientechnologies.orient.core.record.OVertex; import com.orientechnologies.orient.core.sql.executor.OResult; import com.orientechnologies.orient.core.sql.executor.OResultSet; public abstract class EntityTypeDefinitionManagement extends EntityElementManagement { private static Logger logger = LoggerFactory.getLogger(EntityTypeDefinitionManagement.class); protected String name; protected EntityTypeDefinitionManagement(Class clz) { super(AccessType.ENTITY_TYPE); this.elementType = TypeBinder.getType(clz); } protected EntityTypeDefinitionManagement(SecurityContext securityContext, ODatabaseDocument oDatabaseDocument, Class clz) throws ResourceRegistryException { this(clz); this.oDatabaseDocument = oDatabaseDocument; setWorkingContext(securityContext); } @Override protected SecurityContext getWorkingContext() throws ResourceRegistryException { if(workingContext == null) { workingContext = ContextUtility.getInstance() .getSecurityContextByUUID(DatabaseEnvironment.SCHEMA_SECURITY_CONTEXT_UUID); } 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(EntityType.NAME_PROPERTY).asText(); } } else { name = element.getProperty(EntityType.NAME_PROPERTY); } } return name; } @Override public String serialize() throws ResourceRegistryException { return serializeAsJson().toString(); } @Override public JsonNode serializeAsJson() throws ResourceRegistryException { return serializeSelfOnly(); // For Resources Definition include mandatory and suggested IsRelatedTo and ConsistsOf } @Override protected OVertex reallyCreate() throws AlreadyPresentException, ResourceRegistryException { logger.debug("Going to create {} for {}", this.elementType, getName()); return createVertex(); } @Override protected OVertex reallyUpdate() throws NotFoundException, ResourceRegistryException { logger.debug("Going to update {} for {}", this.elementType, getName()); OVertex entityTypeDefinition = getElement(); entityTypeDefinition = (OVertex) ElementManagement.updateProperties(oClass, entityTypeDefinition, jsonNode, ignoreKeys, ignoreStartWithKeys); return entityTypeDefinition; } @Override protected boolean reallyDelete() throws NotFoundException, ResourceRegistryException { logger.debug("Going to remove {} for {}", this.elementType, getName()); getElement().delete(); return true; } @Override public OVertex 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 OVertex retrieveElement() throws NotFoundException, ResourceRegistryException { try { if(getName() == null) { throw new NotFoundException("null name does not allow to retrieve the Element"); } String select = "SELECT FROM " + elementType + " WHERE " + EntityType.NAME_PROPERTY + " = \"" + getName() + "\""; OResultSet resultSet = oDatabaseDocument.query(select, new HashMap<>()); if(resultSet == null || !resultSet.hasNext()) { String error = String.format("No %s with name %s was found", elementType, getName()); logger.info(error); throw new NotFoundException(error); } OResult oResult = resultSet.next(); OVertex element = (OVertex) ElementManagement.getElementFromOptional(oResult.getElement()); logger.trace("{} with id {} is : {}", elementType, getName(), Utility.toJsonString(element, true)); if(resultSet.hasNext()) { throw new ResourceRegistryException("Found more than one " + elementType + " with name " + getName() + ". This is a fatal error please contact Admnistrator"); } return element; } catch(NotFoundException e) { throw getSpecificElementNotFoundException(e); } catch(ResourceRegistryException e) { throw e; } catch(Exception e) { throw new ResourceRegistryException(e); } } @Override protected OVertex createVertex() throws EntityAlreadyPresentException, ResourceRegistryException { logger.trace("Going to create {} for {} ({}) using {}", OVertex.class.getSimpleName(), accessType.getName(), elementType, jsonNode); try { this.element = oDatabaseDocument.newVertex(elementType); ElementManagement.updateProperties(oClass, element, jsonNode, ignoreKeys, ignoreStartWithKeys); logger.info("Created {} is {}", OVertex.class.getSimpleName(), Utility.toJsonString(element, true)); return element; } catch(ResourceRegistryException e) { throw e; } catch(Exception e) { logger.trace("Error while creating {} for {} ({}) using {}", OVertex.class.getSimpleName(), accessType.getName(), elementType, jsonNode, e); throw new ResourceRegistryException("Error Creating " + elementType + " with " + jsonNode, e.getCause()); } } @Override public String reallyGetAll(boolean polymorphic) throws ResourceRegistryException { throw new UnsupportedOperationException(); } @Override protected boolean reallyAddToContext(SecurityContext targetSecurityContext) throws ContextException, ResourceRegistryException { throw new UnsupportedOperationException(); } @Override protected boolean reallyRemoveFromContext(SecurityContext targetSecurityContext) throws ContextException, ResourceRegistryException { throw new UnsupportedOperationException(); } @Override protected NotFoundException getSpecificElementNotFoundException(NotFoundException e) { return new SchemaNotFoundException(e.getMessage(), e.getCause()); } @Override protected AlreadyPresentException getSpecificERAlreadyPresentException(String message) { return new SchemaAlreadyPresentException(message); } @Override protected AvailableInAnotherContextException getSpecificERAvailableInAnotherContextException(String message) { throw new UnsupportedOperationException(); } }