From a008bdd582dfc4afda1e4c3ce1cd7e52aa726006 Mon Sep 17 00:00:00 2001 From: sofyenne Date: Mon, 18 Nov 2024 11:03:46 +0100 Subject: [PATCH] feat: Implement attachment copying and moving - EXO-74754 - Meeds-io/MIPs#145 --- .../social/attachment/AttachmentService.java | 23 +++++ .../attachment/AttachmentServiceImpl.java | 93 +++++++++++++++++-- .../attachment/AttachmentServiceTest.java | 47 ++++++++++ 3 files changed, 157 insertions(+), 6 deletions(-) diff --git a/component/api/src/main/java/org/exoplatform/social/attachment/AttachmentService.java b/component/api/src/main/java/org/exoplatform/social/attachment/AttachmentService.java index 504d3e46c82..4d216a22965 100644 --- a/component/api/src/main/java/org/exoplatform/social/attachment/AttachmentService.java +++ b/component/api/src/main/java/org/exoplatform/social/attachment/AttachmentService.java @@ -292,4 +292,27 @@ InputStream getAttachmentInputStream(String objectType, */ Map getAttachmentPlugins(); + /** + * Copies attachments from a specified source object type to a specified destination object type. + * + * @param sourceObjectType the type of the source object + * @param sourceObjectId the ID of the source object + * @param destinationObjectType the type of the destination object + * @param destinationObjectId the ID of the destination object + * @param destinationParentObjectId the ID of the destination's parent object + * @param userIdentityId the ID of the user performing the operation + */ + void copyAttachments(String sourceObjectType, String sourceObjectId, String destinationObjectType, String destinationObjectId, String destinationParentObjectId, long userIdentityId); + + /** + * Moves attachments from a specified source object type to a specified destination object type. + * + * @param sourceObjectType the type of the source object + * @param sourceObjectId the ID of the source object + * @param destinationObjectType the type of the destination object + * @param destinationObjectId the ID of the destination object + * @param destinationParentObjectId the ID of the destination's parent object + * @param userIdentityId the ID of the user performing the operation + */ + void moveAttachments(String sourceObjectType, String sourceObjectId, String destinationObjectType, String destinationObjectId, String destinationParentObjectId, long userIdentityId); } diff --git a/component/core/src/main/java/org/exoplatform/social/core/attachment/AttachmentServiceImpl.java b/component/core/src/main/java/org/exoplatform/social/core/attachment/AttachmentServiceImpl.java index 3e06c3c9657..b3c4ddaa6a2 100644 --- a/component/core/src/main/java/org/exoplatform/social/core/attachment/AttachmentServiceImpl.java +++ b/component/core/src/main/java/org/exoplatform/social/core/attachment/AttachmentServiceImpl.java @@ -59,7 +59,11 @@ public class AttachmentServiceImpl implements AttachmentService { - private static final Log LOG = ExoLogger.getLogger(AttachmentServiceImpl.class); + private static final Log LOG = ExoLogger.getLogger(AttachmentServiceImpl.class); + + private static final String ATTACHMENT_ALT_TEXT = "alt"; + + private static final String ATTACHMENT_FORMAT = "format"; private final Map attachmentPlugins = new HashMap<>(); @@ -163,8 +167,8 @@ public void saveAttachment(UploadedAttachmentDetail uploadedAttachmentDetail, String altText = uploadedAttachmentDetail.getAltText(); String format = uploadedAttachmentDetail.getFormat(); Map properties = new HashMap<>(); - properties.put("alt", altText); - properties.put("format", format); + properties.put(ATTACHMENT_ALT_TEXT, altText); + properties.put(ATTACHMENT_FORMAT, format); Long attachmentId = !(StringUtils.isBlank(uploadedAttachmentDetail.getId())) ? @@ -187,6 +191,7 @@ public void saveAttachment(UploadedAttachmentDetail uploadedAttachmentDetail, userIdentityId); if (attachmentId == null) { createAttachment(fileId, objectType, objectId, parentObjectId, userIdentityId, properties); + uploadedAttachmentDetail.setId(fileId); } else { updateAttachment(fileId, objectType, objectId, userIdentityId, properties); } @@ -254,10 +259,10 @@ public ObjectAttachmentList getAttachments(String objectType, String objectId) { 0, 0); if (CollectionUtils.isNotEmpty(attachmentItem) && attachmentItem.get(0).getProperties() != null - && attachmentItem.get(0).getProperties().containsKey("alt")) { + && attachmentItem.get(0).getProperties().containsKey(ATTACHMENT_ALT_TEXT)) { Map metadataItemProperties = attachmentItem.get(0).getProperties(); - attachment.setAltText(metadataItemProperties.get("alt")); - attachment.setFormat(metadataItemProperties.get("format")); + attachment.setAltText(metadataItemProperties.get(ATTACHMENT_ALT_TEXT)); + attachment.setFormat(metadataItemProperties.get(ATTACHMENT_FORMAT)); } }); } @@ -322,6 +327,82 @@ public boolean hasEditPermission(Identity userIdentity, String objectType, Strin return attachmentPlugin != null && attachmentPlugin.hasEditPermission(userIdentity, objectId); } + @Override + public void copyAttachments(String sourceObjectType, + String sourceObjectId, + String destinationObjectType, + String destinationObjectId, + String destinationParentObjectId, + long userIdentityId) { + ObjectAttachmentList objectAttachmentList = getAttachments(sourceObjectType, sourceObjectId); + List attachments = objectAttachmentList.getAttachments(); + if (CollectionUtils.isNotEmpty(attachments)) { + attachments.forEach(attachment -> { + String altText = attachment.getAltText(); + String format = attachment.getFormat(); + Map properties = new HashMap<>(); + properties.put(ATTACHMENT_ALT_TEXT, altText); + properties.put(ATTACHMENT_FORMAT, format); + try { + createAttachment(attachment.getId(), + destinationObjectType, + destinationObjectId, + destinationParentObjectId, + userIdentityId, + properties); + } catch (Exception e) { + LOG.error("Error when creating attachment", e); + } + }); + } + } + + @Override + public void moveAttachments(String sourceObjectType, + String sourceObjectId, + String destinationObjectType, + String destinationObjectId, + String destinationParentObjectId, + long userIdentityId) { + ObjectAttachmentList objectAttachmentList = getAttachments(sourceObjectType, sourceObjectId); + List attachments = objectAttachmentList.getAttachments(); + if (CollectionUtils.isNotEmpty(attachments)) { + attachments.forEach(attachment -> { + String altText = attachment.getAltText(); + String format = attachment.getFormat(); + Map properties = new HashMap<>(); + properties.put(ATTACHMENT_ALT_TEXT, altText); + properties.put(ATTACHMENT_FORMAT, format); + try { + createAttachment(attachment.getId(), + destinationObjectType, + destinationObjectId, + destinationParentObjectId, + userIdentityId, + properties); + List metadataItemToDelete = + metadataService.getMetadataItemsByMetadataNameAndTypeAndObject(attachment.getId(), + AttachmentService.METADATA_TYPE.getName(), + sourceObjectType, + sourceObjectId, + 0, + 0); + if (CollectionUtils.isNotEmpty(metadataItemToDelete)) { + metadataItemToDelete.forEach(metadataItem -> { + try { + metadataService.deleteMetadataItem(metadataItem.getId(), true); + } catch (ObjectNotFoundException e) { + LOG.error("Error when deleting metadata item", e); + } + }); + } + } catch (Exception e) { + LOG.error("Error when creating attachment", e); + } + }); + } + } + private org.exoplatform.social.core.identity.model.Identity checkAccessPermission(String objectType, String objectId, String fileId, diff --git a/component/core/src/test/java/org/exoplatform/social/attachment/AttachmentServiceTest.java b/component/core/src/test/java/org/exoplatform/social/attachment/AttachmentServiceTest.java index d875383e6d5..00972b5d62f 100644 --- a/component/core/src/test/java/org/exoplatform/social/attachment/AttachmentServiceTest.java +++ b/component/core/src/test/java/org/exoplatform/social/attachment/AttachmentServiceTest.java @@ -66,6 +66,8 @@ public class AttachmentServiceTest extends AbstractCoreTest { private static final String OBJECT_TYPE = "objectType"; + private static final String DEST_OBJECT_TYPE = "destinationObjectType"; + private static final Random RANDOM = new Random(); private Map eventCounts = new HashMap<>(); @@ -390,4 +392,49 @@ private void assertListenerCount(long createdCount, assertEquals(deletedListCount, eventCounts.getOrDefault(ATTACHMENTS_DELETED_EVENT, 0l).longValue()); } + public void testMoveAttachments() throws Exception { // NOSONAR + startSessionAndRegisterAs(USERNAME); + String identityId = identityManager.getOrCreateUserIdentity(USERNAME).getId(); + String fileId = createAttachment(USERNAME); + + String destinationObjectId = "destinationObjectId" + System.currentTimeMillis(); + String destinationParentObjectId = null; + + attachmentService.moveAttachments(OBJECT_TYPE, objectId, DEST_OBJECT_TYPE, destinationObjectId, destinationParentObjectId, Long.parseLong(identityId)); + + // Verify the attachments are moved to the destination object + ObjectAttachmentList destinationObjectAttachmentList = attachmentService.getAttachments(DEST_OBJECT_TYPE, destinationObjectId); + assertNotNull(destinationObjectAttachmentList); + assertEquals(1, destinationObjectAttachmentList.getAttachments().size()); + assertEquals(fileId, destinationObjectAttachmentList.getAttachments().get(0).getId()); + + // Verify the attachments are removed from the source object + ObjectAttachmentList sourceObjectAttachmentList = attachmentService.getAttachments(OBJECT_TYPE, objectId); + assertNotNull(sourceObjectAttachmentList); + assertEquals(0, sourceObjectAttachmentList.getAttachments().size()); + } + + public void testCopyAttachments() throws Exception { // NOSONAR + startSessionAndRegisterAs(USERNAME); + String identityId = identityManager.getOrCreateUserIdentity(USERNAME).getId(); + String fileId = createAttachment(USERNAME); + + String destinationObjectId = "destinationObjectId" + System.currentTimeMillis(); + String destinationParentObjectId = null; + + attachmentService.copyAttachments(OBJECT_TYPE, objectId, DEST_OBJECT_TYPE, destinationObjectId, destinationParentObjectId, Long.parseLong(identityId)); + + // Verify the attachments are copied to the destination object + ObjectAttachmentList destinationObjectAttachmentList = attachmentService.getAttachments(DEST_OBJECT_TYPE, destinationObjectId); + assertNotNull(destinationObjectAttachmentList); + assertEquals(1, destinationObjectAttachmentList.getAttachments().size()); + assertEquals(fileId, destinationObjectAttachmentList.getAttachments().get(0).getId()); + + // Verify the attachments are still present in the source object + ObjectAttachmentList sourceObjectAttachmentList = attachmentService.getAttachments(OBJECT_TYPE, objectId); + assertNotNull(sourceObjectAttachmentList); + assertEquals(1, sourceObjectAttachmentList.getAttachments().size()); + assertEquals(fileId, destinationObjectAttachmentList.getAttachments().get(0).getId()); + } + }