diff --git a/src/main/java/org/gcube/gcat/persistence/ckan/CKANPackage.java b/src/main/java/org/gcube/gcat/persistence/ckan/CKANPackage.java index 7059720..61472dd 100644 --- a/src/main/java/org/gcube/gcat/persistence/ckan/CKANPackage.java +++ b/src/main/java/org/gcube/gcat/persistence/ckan/CKANPackage.java @@ -543,13 +543,18 @@ public class CKANPackage extends CKAN implements Moderated { return result.get(AUTHOR_EMAIL_KEY).asText().compareTo(ckanUser.getPortalUser().getEMail())==0; } + protected void readItem() throws Exception { + String ret = super.read(); + result = mapper.readTree(ret); + result = cleanResult(result); + this.itemID = result.get(ID_KEY).asText(); + } + @Override public String read() { try { - String ret = super.read(); - result = mapper.readTree(ret); - result = cleanResult(result); + readItem(); checkModerationRead(); @@ -582,10 +587,7 @@ public class CKANPackage extends CKAN implements Moderated { JsonNode jsonNode = validateJson(json); - boolean moderationEnabled = isModerationEnabled(); - if(moderationEnabled) { - setToPending(jsonNode); - } + setItemToPending(jsonNode); ArrayNode resourcesToBeCreated = mapper.createArrayNode(); if(jsonNode.has(RESOURCES_KEY)) { @@ -611,10 +613,7 @@ public class CKANPackage extends CKAN implements Moderated { sendSocialPost(title, catalogueItemURL); } - if(moderationEnabled) { - createNewStream(); - postItemCreatedToStream(); - } + createZulipStream(); result = cleanResult(result); @@ -634,8 +633,7 @@ public class CKANPackage extends CKAN implements Moderated { try { JsonNode jsonNode = validateJson(json); - read(); - this.itemID = result.get(ID_KEY).asText(); + readItem(); jsonNode = checkModerationUpdate(jsonNode); @@ -687,6 +685,8 @@ public class CKANPackage extends CKAN implements Moderated { result = cleanResult(result); + postItemUpdatedToStream(); + return getAsString(result); } catch(WebApplicationException e) { rollbackManagedResources(); @@ -701,11 +701,9 @@ public class CKANPackage extends CKAN implements Moderated { @Override public String patch(String json) { try { - read(); + readItem(); JsonNode jsonNode = checkBaseInformation(json, true); - - this.itemID = result.get(ID_KEY).asText(); ((ObjectNode)jsonNode).put(ID_KEY, this.itemID); jsonNode = checkModerationUpdate(jsonNode); @@ -758,6 +756,8 @@ public class CKANPackage extends CKAN implements Moderated { result = cleanResult(result); + postItemUpdatedToStream(); + return getAsString(result); } catch(WebApplicationException e) { rollbackManagedResources(); @@ -787,23 +787,29 @@ public class CKANPackage extends CKAN implements Moderated { } } - setApiKey(CKANUtility.getSysAdminAPI()); - read(); - - if(ckanUser.getRole()!=Role.ADMIN && !isItemCreator()) { - throw new ForbiddenException("Only " + Role.ADMIN.getPortalRole() + "s and item creator are entitled to purge an the item"); - } - - if(result.has(RESOURCES_KEY)) { - itemID = result.get(ID_KEY).asText(); - ArrayNode arrayNode = (ArrayNode) result.get(RESOURCES_KEY); - for(JsonNode jsonNode : arrayNode) { - CKANResource ckanResource = new CKANResource(itemID); - ckanResource.setPreviousRepresentation(jsonNode); - ckanResource.deleteFile(); // Only delete file is required because the item has been deleted + try { + setApiKey(CKANUtility.getSysAdminAPI()); + readItem(); + + if(ckanUser.getRole()!=Role.ADMIN && !isItemCreator()) { + throw new ForbiddenException("Only " + Role.ADMIN.getPortalRole() + "s and item creator are entitled to purge an the item"); } + + if(result.has(RESOURCES_KEY)) { + itemID = result.get(ID_KEY).asText(); + ArrayNode arrayNode = (ArrayNode) result.get(RESOURCES_KEY); + for(JsonNode jsonNode : arrayNode) { + CKANResource ckanResource = new CKANResource(itemID); + ckanResource.setPreviousRepresentation(jsonNode); + ckanResource.deleteFile(); // Only delete file is required because the item has been deleted + } + } + super.purge(); + } catch(WebApplicationException e) { + throw e; + } catch(Exception e) { + throw new InternalServerErrorException(e); } - super.purge(); } /** @@ -872,6 +878,7 @@ public class CKANPackage extends CKAN implements Moderated { boolean moderationEnabled = ckanInstance.isModerationEnabled(); if(moderationEnabled && zulipStream==null) { zulipStream = new ZulipStream(); + zulipStream.setCKANUser(ckanUser); } return moderationEnabled; } @@ -997,7 +1004,7 @@ public class CKANPackage extends CKAN implements Moderated { } if(setToPending) { - setToPending(jsonNode); + setItemToPending(jsonNode); } } @@ -1006,46 +1013,52 @@ public class CKANPackage extends CKAN implements Moderated { } protected void checkModerationDelete() { - if(isModerationEnabled()) { - read(); - - PortalUser portalUser = ckanUser.getPortalUser(); - - if(ckanUser.getRole() == Role.ADMIN) { - // Ad Admin can delete any item independently from the status - return; - } - - CMItemStatus cmItemStatus = getCMItemStatus(); - - switch (cmItemStatus) { - case APPROVED: - if(isItemCreator()) { - break; - } - throw new ForbiddenException("Only " + Role.ADMIN.getPortalRole() + "s and item creator are entitled to delete an " + cmItemStatus.getValue() + " item"); - - case REJECTED: - if(isItemCreator()) { - break; - } - if(portalUser.isCatalogueModerator()) { - break; - } - throw new ForbiddenException("You are not entitled to delete a " + cmItemStatus.getValue() + " item"); - - case PENDING: - if(isItemCreator()) { - break; - } - if(portalUser.isCatalogueModerator()) { - break; - } - throw new ForbiddenException("You are not entitled to update a " + cmItemStatus.getValue() + " item"); + try { + if(isModerationEnabled()) { + readItem(); - default: - break; - } + PortalUser portalUser = ckanUser.getPortalUser(); + + if(ckanUser.getRole() == Role.ADMIN) { + // Ad Admin can delete any item independently from the status + return; + } + + CMItemStatus cmItemStatus = getCMItemStatus(); + + switch (cmItemStatus) { + case APPROVED: + if(isItemCreator()) { + break; + } + throw new ForbiddenException("Only " + Role.ADMIN.getPortalRole() + "s and item creator are entitled to delete an " + cmItemStatus.getValue() + " item"); + + case REJECTED: + if(isItemCreator()) { + break; + } + if(portalUser.isCatalogueModerator()) { + break; + } + throw new ForbiddenException("You are not entitled to delete a " + cmItemStatus.getValue() + " item"); + + case PENDING: + if(isItemCreator()) { + break; + } + if(portalUser.isCatalogueModerator()) { + break; + } + throw new ForbiddenException("You are not entitled to update a " + cmItemStatus.getValue() + " item"); + + default: + break; + } + } + } catch(WebApplicationException e) { + throw e; + } catch(Exception e) { + throw new InternalServerErrorException(e); } } @@ -1053,21 +1066,23 @@ public class CKANPackage extends CKAN implements Moderated { addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_STATUS, CMItemStatus.REJECTED.getValue()); } - protected void setToPending(JsonNode jsonNode) { - addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_STATUS, CMItemStatus.PENDING.getValue()); - - CMItemVisibility cmItemVisibility = CMItemVisibility.PUBLIC; - - if(jsonNode.has(PRIVATE_KEY)) { - boolean privatePackage = jsonNode.get(PRIVATE_KEY).asBoolean(); - if(privatePackage) { - cmItemVisibility = CMItemVisibility.RESTRICTED; + protected void setItemToPending(JsonNode jsonNode) { + if(isModerationEnabled()) { + addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_STATUS, CMItemStatus.PENDING.getValue()); + + CMItemVisibility cmItemVisibility = CMItemVisibility.PUBLIC; + + if(jsonNode.has(PRIVATE_KEY)) { + boolean privatePackage = jsonNode.get(PRIVATE_KEY).asBoolean(); + if(privatePackage) { + cmItemVisibility = CMItemVisibility.RESTRICTED; + } } + addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_VISIBILITY, cmItemVisibility.getValue()); + + ((ObjectNode) jsonNode).put(PRIVATE_KEY, true); + ((ObjectNode) jsonNode).put(SEARCHABLE_KEY, false); } - addExtraField(jsonNode, GCatConstants.SYSTEM_CM_ITEM_VISIBILITY, cmItemVisibility.getValue()); - - ((ObjectNode) jsonNode).put(PRIVATE_KEY, true); - ((ObjectNode) jsonNode).put(SEARCHABLE_KEY, false); } protected void setToApproved(JsonNode jsonNode) { @@ -1101,21 +1116,37 @@ public class CKANPackage extends CKAN implements Moderated { ((ObjectNode) jsonNode).put(SEARCHABLE_KEY, true); } - private void createNewStream() throws Exception { - zulipStream.setItemCoordinates(itemID, name); - zulipStream.setCKANUser(ckanUser); - zulipStream.create(); + private void createZulipStream() throws Exception { + try { + if(isModerationEnabled()) { + zulipStream.setItemCoordinates(itemID, name); + zulipStream.create(); + } + } catch(WebApplicationException e) { + throw e; + } catch(Exception e) { + throw new InternalServerErrorException(e); + } } - private void postItemCreatedToStream() { - zulipStream.postItemCreatedToStream(); + private void postItemUpdatedToStream() { + try { + if(isModerationEnabled()) { + zulipStream.setItemCoordinates(itemID, name); + zulipStream.postItemUpdated(); + } + } catch(WebApplicationException e) { + throw e; + } catch(Exception e) { + throw new InternalServerErrorException(e); + } } @Override public String approve(String moderatorMessage) { try { if(isModerationEnabled()) { - String ret = read(); + readItem(); PortalUser portalUser = ckanUser.getPortalUser(); CMItemStatus cmItemStatus = getCMItemStatus(); switch (cmItemStatus) { @@ -1131,22 +1162,22 @@ public class CKANPackage extends CKAN implements Moderated { throw new MethodNotSupportedException("Only catalogue moderator can approve a pending item."); } setToApproved(result); - ret = sendPostRequest(ITEM_PATCH, getAsString(result)); + String ret = sendPostRequest(ITEM_PATCH, getAsString(result)); + result = mapper.readTree(ret); + result = cleanResult(result); + + zulipStream.setItemCoordinates(itemID, name); + zulipStream.postItemApproved(); + if(moderatorMessage!=null && moderatorMessage.compareTo("")!=0) { + zulipStream.postMessageToStream(CMItemStatus.PENDING, moderatorMessage); + } break; default: break; } - result = mapper.readTree(ret); - result = cleanResult(result); - ZulipStream zulipStream = new ZulipStream(); - zulipStream.setItemCoordinates(itemID, name); - zulipStream.postItemCreatedToStream(); - if(moderatorMessage!=null && moderatorMessage.compareTo("")!=0) { - zulipStream.postMessageToStream(CMItemStatus.PENDING, moderatorMessage); - } return getAsString(result); } @@ -1162,8 +1193,7 @@ public class CKANPackage extends CKAN implements Moderated { public String reject(String moderatorMessage) { try { if(isModerationEnabled()) { - String ret = read(); - PortalUser portalUser = ckanUser.getPortalUser(); + readItem(); CMItemStatus cmItemStatus = getCMItemStatus(); switch (cmItemStatus) { case APPROVED: @@ -1174,26 +1204,28 @@ public class CKANPackage extends CKAN implements Moderated { break; case PENDING: + PortalUser portalUser = ckanUser.getPortalUser(); if(!portalUser.isCatalogueModerator()) { throw new MethodNotSupportedException("Only catalogue moderator can reject a pending item."); } + setToRejected(result); - ret = sendPostRequest(ITEM_PATCH, getAsString(result)); + String ret = sendPostRequest(ITEM_PATCH, getAsString(result)); + result = mapper.readTree(ret); + result = cleanResult(result); + + zulipStream.setItemCoordinates(itemID, name); + zulipStream.postItemRejected(); + if(moderatorMessage!=null && moderatorMessage.compareTo("")!=0) { + zulipStream.postMessageToStream(CMItemStatus.REJECTED, moderatorMessage); + } break; default: break; } - result = mapper.readTree(ret); - result = cleanResult(result); - ZulipStream zulipStream = new ZulipStream(); - zulipStream.setItemCoordinates(itemID, name); - zulipStream.postItemRejectedToStream(); - if(moderatorMessage!=null && moderatorMessage.compareTo("")!=0) { - zulipStream.postMessageToStream(CMItemStatus.REJECTED, moderatorMessage); - } return getAsString(result); } @@ -1213,7 +1245,7 @@ public class CKANPackage extends CKAN implements Moderated { return; } - read(); + readItem(); // Catalogue Moderators are allowed to post message to the dedicated Stream if(!ckanUser.getPortalUser().isCatalogueModerator()) { @@ -1222,10 +1254,10 @@ public class CKANPackage extends CKAN implements Moderated { throw new NotAllowedException("Only item creator and " + GCatConstants.CATALOGUE_MODERATOR + "s are entitled to partecipate to the moderation discussion thread."); } } + - ZulipStream zulipStream = new ZulipStream(); - zulipStream.setItemCoordinates(itemID, name); CMItemStatus cmItemStatus = getCMItemStatus(); + zulipStream.setItemCoordinates(itemID, name); zulipStream.postMessageToStream(cmItemStatus, message); } throw new MethodNotSupportedException("The message operation is available only in moderation mode"); diff --git a/src/main/java/org/gcube/gcat/zulip/ZulipStream.java b/src/main/java/org/gcube/gcat/zulip/ZulipStream.java index ff1d08c..2209dc2 100644 --- a/src/main/java/org/gcube/gcat/zulip/ZulipStream.java +++ b/src/main/java/org/gcube/gcat/zulip/ZulipStream.java @@ -121,6 +121,8 @@ public class ZulipStream { executeZulipCall(postCreateStream); + postItemCreated(); + } protected void postMessageToStream(ZulipRestExecutor zulipRestExecutor, CMItemStatus cmItemStatus, String message) { @@ -133,14 +135,25 @@ public class ZulipStream { postMessageToStream(getUserZulipRestExecutor(), cmItemStatus, message); } - public void postItemCreatedToStream(){ + public void postItemCreated(){ String message = ""; postMessageToStream(gCatZulipRestExecutor, CMItemStatus.PENDING, message); } - public void postItemRejectedToStream() { + public void postItemUpdated(){ + String message = ""; + postMessageToStream(gCatZulipRestExecutor, CMItemStatus.PENDING, message); + } + + public void postItemRejected() { String message = ""; postMessageToStream(gCatZulipRestExecutor, CMItemStatus.REJECTED, message); } + public void postItemApproved(){ + String message = ""; + postMessageToStream(gCatZulipRestExecutor, CMItemStatus.PENDING, message); + } + + }