From 2b40d4058a149985ae942776caba9b5ce261347f Mon Sep 17 00:00:00 2001 From: Fabio Sinibaldi Date: Tue, 25 Oct 2022 13:03:14 +0200 Subject: [PATCH] Reverse relationships support --- .../engine/mongo/ProfiledMongoManager.java | 74 ++++++++++++++++--- 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/ProfiledMongoManager.java b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/ProfiledMongoManager.java index 9ed6dd1..b60b7ba 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/ProfiledMongoManager.java +++ b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/ProfiledMongoManager.java @@ -45,10 +45,7 @@ import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.gcube.application.geoportal.common.model.rest.QueryRequest; import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest; import org.gcube.application.geoportal.common.model.rest.TempFile; -import org.gcube.application.geoportal.common.model.useCaseDescriptor.DataAccessPolicy; -import org.gcube.application.geoportal.common.model.useCaseDescriptor.Field; -import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration; -import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.*; import org.gcube.application.geoportal.common.utils.ContextUtils; import org.gcube.application.geoportal.common.utils.StorageUtils; import org.gcube.application.geoportal.service.engine.providers.PluginManager; @@ -304,8 +301,18 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI< @Override public Project setRelation(String id, String relation, String targetUCD, String targetId) throws IOException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess, RegistrationException, ConfigurationException { - Project toUpdate=lock(id,"Set Relation"); + Project toUpdate=lock(id,"Set Relation "+relation+" toward "+targetUCD+":"+targetId); try{ + log.info(getUseCaseDescriptor().getId()+":"+id+" setting relation "+relation+" toward "+targetUCD+":"+targetId); + // Check if relation is defined + String toSetReverseRelation=null; + List existingDefinitions = getUseCaseDescriptor().getRelationshipDefinitions(); + for(RelationshipDefinition def : existingDefinitions) + if(def.getId().equals(relation)) + toSetReverseRelation =def.getReverseRelationId(); + + log.debug("{} reverse relation for {} is {}",getUseCaseDescriptor().getId(),relation,toSetReverseRelation); + // check if relation existing List relations = toUpdate.getRelationshipsByName(relation); if(!relations.isEmpty()){ @@ -317,14 +324,26 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI< // check if target exists ProfiledMongoManager otherManager = (targetUCD.equals(this.useCaseDescriptor.getId()))?this:new ProfiledMongoManager(targetUCD); Project other = getByID(targetId); + // add relation Relationship rel = new Relationship(); rel.setRelationshipName(relation); rel.setTargetID(targetId); rel.setTargetUCD(targetUCD); - - toUpdate =onUpdate(toUpdate.addRelation(rel)); + + // set reverse relation + if(toSetReverseRelation!=null){ + Relationship reverseRel = new Relationship(); + reverseRel.setRelationshipName(toSetReverseRelation); + reverseRel.setTargetID(id); + reverseRel.setTargetUCD(getUseCaseDescriptor().getId()); + log.info("Setting reverse relation {} ",reverseRel); + otherManager.lock(other.getId(),"Setting reverse relation "+reverseRel); + other.addRelation(reverseRel); + otherManager.unlockAndUpdate(other); + } + return unlockAndUpdate(toUpdate); }catch(Throwable t){ log.error("Unexpected exception ",t); @@ -335,21 +354,52 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI< @Override public Project deleteRelation(String id, String relation, String targetUCD, String targetId) throws IOException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess, RegistrationException, ConfigurationException { - log.debug("Delete relation {}:{}--{}-->{}:{} ",getUseCaseDescriptor().getId(),id,relation,targetUCD,targetId); + log.info("Delete relation {}:{}--{}-->{}:{} ",getUseCaseDescriptor().getId(),id,relation,targetUCD,targetId); Project toUpdate=lock(id,"Delete Relation"); try{ // SET target UCD to present UCD as default final String toUseTargetUCD = (targetUCD == null || targetUCD.equals(""))? getUseCaseDescriptor().getId():targetUCD; + String toDeleteReverseRelation=null; + List existingDefinitions = getUseCaseDescriptor().getRelationshipDefinitions(); + for(RelationshipDefinition def : existingDefinitions) + if(def.getId().equals(relation)) + toDeleteReverseRelation =def.getReverseRelationId(); + + log.debug("{} reverse relation for {} is {}",getUseCaseDescriptor().getId(),relation,toDeleteReverseRelation); + // check if relation existing List relations = toUpdate.getRelationships(); if(relations!=null && !relations.isEmpty()){ int beforeSize = relations.size(); - toUpdate.getRelationships().removeIf(r -> - r.getRelationshipName().equals(relation)&& - r.getTargetUCD().equals(toUseTargetUCD)&& - r.getTargetID().equals(targetId)); + + ArrayList toRemove = new ArrayList<>(); + for(Relationship r : toUpdate.getRelationships()){ + if(r.getRelationshipName().equals(relation)&& + r.getTargetUCD().equals(toUseTargetUCD)&& + r.getTargetID().equals(targetId)){ + // set to be remove + log.debug("Removing {} ",r); + toRemove.add(r); + + // delete reverse relation + if(toDeleteReverseRelation!=null){ + log.debug("Removing reverse of {} ",r); + ProfiledMongoManager otherManager = (targetUCD.equals(this.useCaseDescriptor.getId()))?this:new ProfiledMongoManager(targetUCD); + Project other = getByID(targetId); + otherManager.lock(other.getId(),"Remove reverse relation "+toDeleteReverseRelation + " toward "+getUseCaseDescriptor().getId()+":"+id); + final String finalToDeleteReverseRelation = toDeleteReverseRelation; + other.getRelationships().removeIf(revRel ->revRel.getRelationshipName().equals(finalToDeleteReverseRelation)&& + revRel.getTargetID().equals(id)&&revRel.getTargetUCD().equals(getUseCaseDescriptor().getId())); + otherManager.unlockAndUpdate(other); + } + + } + } + + toUpdate.getRelationships().removeAll(toRemove); + // update only if something changed if(toUpdate.getRelationships().size()!=beforeSize) { log.debug("Removed {} relations from {} ",(toUpdate.getRelationships().size()!=beforeSize),id);