diff --git a/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/configuration/Registration.java b/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/configuration/Registration.java index f63e0f6b..0bfd1f0f 100644 --- a/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/configuration/Registration.java +++ b/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/configuration/Registration.java @@ -29,7 +29,6 @@ import com.sap.cds.feature.attachments.handler.draftservice.DraftActiveAttachmentsHandler; import com.sap.cds.feature.attachments.handler.draftservice.DraftCancelAttachmentsHandler; import com.sap.cds.feature.attachments.handler.draftservice.DraftPatchAttachmentsHandler; -import com.sap.cds.feature.attachments.handler.draftservice.modifier.ActiveEntityModifier; import com.sap.cds.feature.attachments.service.AttachmentService; import com.sap.cds.feature.attachments.service.AttachmentsServiceImpl; import com.sap.cds.feature.attachments.service.handler.DefaultAttachmentsServiceHandler; @@ -124,8 +123,7 @@ public void eventHandlers(CdsRuntimeConfigurer configurer) { boolean hasDraftServices = serviceCatalog.getServices(DraftService.class).findFirst().isPresent(); if (hasDraftServices) { configurer.eventHandler(new DraftPatchAttachmentsHandler(persistenceService, eventFactory)); - configurer.eventHandler(new DraftCancelAttachmentsHandler(attachmentsReader, deleteContentEvent, - ActiveEntityModifier::new)); + configurer.eventHandler(new DraftCancelAttachmentsHandler(attachmentsReader, deleteContentEvent)); configurer.eventHandler(new DraftActiveAttachmentsHandler(storage)); } else { logger.debug("No draft service is available. Draft event handlers will not be registered."); diff --git a/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/draftservice/modifier/ActiveEntityModifier.java b/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/draftservice/ActiveEntityModifier.java similarity index 84% rename from cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/draftservice/modifier/ActiveEntityModifier.java rename to cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/draftservice/ActiveEntityModifier.java index ae0d6284..39d48e1a 100644 --- a/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/draftservice/modifier/ActiveEntityModifier.java +++ b/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/draftservice/ActiveEntityModifier.java @@ -1,7 +1,7 @@ /************************************************************************** * (C) 2019-2025 SAP SE or an SAP affiliate company. All rights reserved. * **************************************************************************/ -package com.sap.cds.feature.attachments.handler.draftservice.modifier; +package com.sap.cds.feature.attachments.handler.draftservice; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,14 +24,14 @@ *
  • {@code fullEntityName}
  • * */ -public class ActiveEntityModifier implements Modifier { +class ActiveEntityModifier implements Modifier { private static final Logger logger = LoggerFactory.getLogger(ActiveEntityModifier.class); private final boolean isActiveEntity; private final String fullEntityName; - public ActiveEntityModifier(boolean isActiveEntity, String fullEntityName) { + ActiveEntityModifier(boolean isActiveEntity, String fullEntityName) { this.isActiveEntity = isActiveEntity; this.fullEntityName = fullEntityName; } @@ -44,10 +44,9 @@ public CqnStructuredTypeRef ref(CqnStructuredTypeRef original) { fullEntityName); rootSegment.id(fullEntityName); + Modifier modifier = new ActiveEntityModifier(isActiveEntity, fullEntityName); for (RefSegment segment : ref.segments()) { - if (segment.filter().isPresent()) { - segment.filter(CQL.copy(segment.filter().orElseThrow(), new ActiveEntityModifier(isActiveEntity, fullEntityName))); - } + segment.filter(segment.filter().map(filter -> CQL.copy(filter, modifier)).orElse(null)); } return ref.build(); } diff --git a/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/draftservice/DraftCancelAttachmentsHandler.java b/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/draftservice/DraftCancelAttachmentsHandler.java index fb354217..206cd565 100644 --- a/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/draftservice/DraftCancelAttachmentsHandler.java +++ b/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/draftservice/DraftCancelAttachmentsHandler.java @@ -16,7 +16,6 @@ import com.sap.cds.feature.attachments.handler.common.ApplicationHandlerHelper; import com.sap.cds.feature.attachments.handler.common.AttachmentsReader; import com.sap.cds.feature.attachments.handler.draftservice.constants.DraftConstants; -import com.sap.cds.feature.attachments.handler.draftservice.modifier.ActiveEntityModifierProvider; import com.sap.cds.ql.CQL; import com.sap.cds.reflect.CdsEntity; import com.sap.cds.reflect.CdsStructuredType; @@ -41,13 +40,11 @@ public class DraftCancelAttachmentsHandler implements EventHandler { private final AttachmentsReader attachmentsReader; private final ModifyAttachmentEvent deleteContentAttachmentEvent; - private final ActiveEntityModifierProvider activeEntityModifierProvider; public DraftCancelAttachmentsHandler(AttachmentsReader attachmentsReader, - ModifyAttachmentEvent deleteContentAttachmentEvent, ActiveEntityModifierProvider activeEntityModifierProvider) { + ModifyAttachmentEvent deleteContentAttachmentEvent) { this.attachmentsReader = attachmentsReader; this.deleteContentAttachmentEvent = deleteContentAttachmentEvent; - this.activeEntityModifierProvider = activeEntityModifierProvider; } @Before @@ -66,7 +63,6 @@ public void processBeforeDraftCancel(DraftCancelEventContext context) { var validator = buildDeleteContentValidator(context, activeCondensedAttachments); ApplicationHandlerHelper.callValidator(context.getTarget(), draftAttachments, filter, validator); } - } private Validator buildDeleteContentValidator(DraftCancelEventContext context, @@ -105,8 +101,7 @@ private boolean isDraftEntity(DraftCancelEventContext context) { private List readAttachments(DraftCancelEventContext context, CdsStructuredType entity, boolean isActiveEntity) { - var cqnInactiveEntity = CQL.copy(context.getCqn(), - activeEntityModifierProvider.getModifier(isActiveEntity, entity.getQualifiedName())); + var cqnInactiveEntity = CQL.copy(context.getCqn(), new ActiveEntityModifier(isActiveEntity, entity.getQualifiedName())); return attachmentsReader.readAttachments(context.getModel(), (CdsEntity) entity, cqnInactiveEntity); } diff --git a/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/draftservice/modifier/ActiveEntityModifierProvider.java b/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/draftservice/modifier/ActiveEntityModifierProvider.java deleted file mode 100644 index fa53268e..00000000 --- a/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/draftservice/modifier/ActiveEntityModifierProvider.java +++ /dev/null @@ -1,16 +0,0 @@ -/************************************************************************** - * (C) 2019-2025 SAP SE or an SAP affiliate company. All rights reserved. * - **************************************************************************/ -package com.sap.cds.feature.attachments.handler.draftservice.modifier; - -import com.sap.cds.ql.cqn.Modifier; - -/** - * The interface {@link ActiveEntityModifierProvider} is used to get the modifier - * for changing the fields {@code isActiveEntity} and {@code fullEntityName}. - */ -public interface ActiveEntityModifierProvider { - - Modifier getModifier(boolean isActiveEntity, String fullEntityName); - -} diff --git a/cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/handler/draftservice/modifier/ActiveEntityModifierTest.java b/cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/handler/draftservice/ActiveEntityModifierTest.java similarity index 97% rename from cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/handler/draftservice/modifier/ActiveEntityModifierTest.java rename to cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/handler/draftservice/ActiveEntityModifierTest.java index 7e300d47..b747a309 100644 --- a/cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/handler/draftservice/modifier/ActiveEntityModifierTest.java +++ b/cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/handler/draftservice/ActiveEntityModifierTest.java @@ -1,4 +1,4 @@ -package com.sap.cds.feature.attachments.handler.draftservice.modifier; +package com.sap.cds.feature.attachments.handler.draftservice; import static com.sap.cds.services.draft.Drafts.IS_ACTIVE_ENTITY; import static org.assertj.core.api.Assertions.assertThat; diff --git a/cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/handler/draftservice/DraftCancelAttachmentsHandlerTest.java b/cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/handler/draftservice/DraftCancelAttachmentsHandlerTest.java index d3f250a8..27a64f6b 100644 --- a/cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/handler/draftservice/DraftCancelAttachmentsHandlerTest.java +++ b/cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/handler/draftservice/DraftCancelAttachmentsHandlerTest.java @@ -1,9 +1,15 @@ package com.sap.cds.feature.attachments.handler.draftservice; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; import java.util.List; +import java.util.Optional; import java.util.UUID; import org.junit.jupiter.api.BeforeAll; @@ -18,13 +24,10 @@ import com.sap.cds.feature.attachments.handler.applicationservice.processor.modifyevents.ModifyAttachmentEvent; import com.sap.cds.feature.attachments.handler.common.AttachmentsReader; import com.sap.cds.feature.attachments.handler.draftservice.constants.DraftConstants; -import com.sap.cds.feature.attachments.handler.draftservice.modifier.ActiveEntityModifierProvider; import com.sap.cds.feature.attachments.handler.helper.RuntimeHelper; import com.sap.cds.ql.Delete; import com.sap.cds.ql.cqn.CqnDelete; -import com.sap.cds.ql.cqn.Modifier; import com.sap.cds.reflect.CdsEntity; -import com.sap.cds.reflect.CdsStructuredType; import com.sap.cds.services.draft.DraftCancelEventContext; import com.sap.cds.services.runtime.CdsRuntime; @@ -35,7 +38,6 @@ class DraftCancelAttachmentsHandlerTest { private DraftCancelAttachmentsHandler cut; private AttachmentsReader attachmentsReader; private ModifyAttachmentEvent deleteContentAttachmentEvent; - private ActiveEntityModifierProvider modifierProvider; private DraftCancelEventContext eventContext; private ArgumentCaptor deleteArgumentCaptor; private ArgumentCaptor dataArgumentCaptor; @@ -49,12 +51,9 @@ static void classSetup() { void setup() { attachmentsReader = mock(AttachmentsReader.class); deleteContentAttachmentEvent = mock(ModifyAttachmentEvent.class); - modifierProvider = mock(ActiveEntityModifierProvider.class); - cut = new DraftCancelAttachmentsHandler(attachmentsReader, deleteContentAttachmentEvent, modifierProvider); + cut = new DraftCancelAttachmentsHandler(attachmentsReader, deleteContentAttachmentEvent); eventContext = mock(DraftCancelEventContext.class); - when(modifierProvider.getModifier(anyBoolean(), anyString())).thenReturn(new Modifier() { - }); deleteArgumentCaptor = ArgumentCaptor.forClass(CqnDelete.class); dataArgumentCaptor = ArgumentCaptor.forClass(CdsData.class); } @@ -62,18 +61,18 @@ void setup() { @Test void whereConditionIncludedNothingHappens() { getEntityAndMockContext(RootTable_.CDS_NAME); - var delete = Delete.from(RootTable_.class).where(root -> root.ID().eq("test")); + CqnDelete delete = Delete.from(RootTable_.class).where(root -> root.ID().eq("test")); when(eventContext.getCqn()).thenReturn(delete); cut.processBeforeDraftCancel(eventContext); - verifyNoInteractions(attachmentsReader, deleteContentAttachmentEvent, modifierProvider); + verifyNoInteractions(attachmentsReader, deleteContentAttachmentEvent); } @Test void nothingSelectedNothingToDo() { getEntityAndMockContext(RootTable_.CDS_NAME); - var delete = Delete.from(RootTable_.class); + CqnDelete delete = Delete.from(RootTable_.class); when(eventContext.getCqn()).thenReturn(delete); when(eventContext.getModel()).thenReturn(runtime.getCdsModel()); @@ -85,63 +84,58 @@ void nothingSelectedNothingToDo() { @Test void attachmentReaderCorrectCalled() { getEntityAndMockContext(RootTable_.CDS_NAME); - var delete = Delete.from(RootTable_.class); + CqnDelete delete = Delete.from(RootTable_.class); when(eventContext.getCqn()).thenReturn(delete); when(eventContext.getModel()).thenReturn(runtime.getCdsModel()); cut.processBeforeDraftCancel(eventContext); - var target = eventContext.getTarget(); - verify(attachmentsReader).readAttachments(eq(runtime.getCdsModel()), eq(target), deleteArgumentCaptor.capture()); - var originDelete = deleteArgumentCaptor.getValue(); + CdsEntity target = eventContext.getTarget(); + verify(attachmentsReader).readAttachments(eq(runtime.getCdsModel()), eq(target), + deleteArgumentCaptor.capture()); + CqnDelete originDelete = deleteArgumentCaptor.getValue(); assertThat(originDelete.toJson()).isEqualTo(delete.toJson()); deleteArgumentCaptor = ArgumentCaptor.forClass(CqnDelete.class); - var siblingTarget = target.getTargetOf(DraftConstants.SIBLING_ENTITY); - verify(attachmentsReader).readAttachments(eq(runtime.getCdsModel()), eq((CdsEntity) siblingTarget), + CdsEntity siblingTarget = target.getTargetOf(DraftConstants.SIBLING_ENTITY); + verify(attachmentsReader).readAttachments(eq(runtime.getCdsModel()), eq(siblingTarget), deleteArgumentCaptor.capture()); - var siblingDelete = deleteArgumentCaptor.getValue(); - assertThat(siblingDelete.toJson()).isEqualTo(delete.toJson()); + CqnDelete siblingDelete = deleteArgumentCaptor.getValue(); + assertThat(siblingDelete.toJson()).isNotEqualTo(delete.toJson()); } @Test void modifierCalledWithCorrectEntitiesIfDraftIsInContext() { getEntityAndMockContext(RootTable_.CDS_NAME + DraftConstants.DRAFT_TABLE_POSTFIX); - var delete = Delete.from(RootTable_.class); + CqnDelete delete = Delete.from(RootTable_.class); when(eventContext.getCqn()).thenReturn(delete); when(eventContext.getModel()).thenReturn(runtime.getCdsModel()); cut.processBeforeDraftCancel(eventContext); - verify(modifierProvider).getModifier(false, RootTable_.CDS_NAME + DraftConstants.DRAFT_TABLE_POSTFIX); - verify(modifierProvider).getModifier(true, RootTable_.CDS_NAME); - } - - @Test - void modifierCalledWithCorrectEntitiesIfActiveEntityIsInContext() { - getEntityAndMockContext(RootTable_.CDS_NAME); - var delete = Delete.from(RootTable_.class); - when(eventContext.getCqn()).thenReturn(delete); - when(eventContext.getModel()).thenReturn(runtime.getCdsModel()); - - cut.processBeforeDraftCancel(eventContext); - - verify(modifierProvider).getModifier(false, RootTable_.CDS_NAME + DraftConstants.DRAFT_TABLE_POSTFIX); - verify(modifierProvider).getModifier(true, RootTable_.CDS_NAME); + CdsEntity target = eventContext.getTarget(); + verify(attachmentsReader).readAttachments(eq(runtime.getCdsModel()), eq(target), + deleteArgumentCaptor.capture()); + CdsEntity siblingTarget = target.getTargetOf(DraftConstants.SIBLING_ENTITY); + verify(attachmentsReader).readAttachments(eq(runtime.getCdsModel()), eq(siblingTarget), + deleteArgumentCaptor.capture()); + CqnDelete siblingDelete = deleteArgumentCaptor.getValue(); + assertThat(siblingDelete.toJson()).isEqualTo(delete.toJson()); } @Test void createdEntityNeedsToBeDeleted() { getEntityAndMockContext(Attachment_.CDS_NAME); - var delete = Delete.from(RootTable_.class); + CqnDelete delete = Delete.from(RootTable_.class); when(eventContext.getCqn()).thenReturn(delete); when(eventContext.getModel()).thenReturn(runtime.getCdsModel()); - var siblingTarget = eventContext.getTarget().getTargetOf(DraftConstants.SIBLING_ENTITY); - var attachment = buildAttachmentAndReturnByReader("test", siblingTarget, false, ""); + CdsEntity siblingTarget = eventContext.getTarget().getTargetOf(DraftConstants.SIBLING_ENTITY); + Attachment attachment = buildAttachmentAndReturnByReader("test", siblingTarget, false, ""); cut.processBeforeDraftCancel(eventContext); - verify(deleteContentAttachmentEvent).processEvent(any(), eq(null), dataArgumentCaptor.capture(), eq(eventContext)); + verify(deleteContentAttachmentEvent).processEvent(any(), eq(null), dataArgumentCaptor.capture(), + eq(eventContext)); assertThat(dataArgumentCaptor.getValue()).isEqualTo(attachment); } @@ -151,14 +145,15 @@ void updatedEntityNeedsToBeDeleted() { var delete = Delete.from(RootTable_.class); when(eventContext.getCqn()).thenReturn(delete); when(eventContext.getModel()).thenReturn(runtime.getCdsModel()); - var siblingTarget = eventContext.getTarget().getTargetOf(DraftConstants.SIBLING_ENTITY); + CdsEntity siblingTarget = eventContext.getTarget().getTargetOf(DraftConstants.SIBLING_ENTITY); var id = UUID.randomUUID().toString(); - var draftAttachment = buildAttachmentAndReturnByReader("test", siblingTarget, true, id); + Attachment draftAttachment = buildAttachmentAndReturnByReader("test", siblingTarget, true, id); buildAttachmentAndReturnByReader("test origin", eventContext.getTarget(), false, id); cut.processBeforeDraftCancel(eventContext); - verify(deleteContentAttachmentEvent).processEvent(any(), eq(null), dataArgumentCaptor.capture(), eq(eventContext)); + verify(deleteContentAttachmentEvent).processEvent(any(), eq(null), dataArgumentCaptor.capture(), + eq(eventContext)); assertThat(dataArgumentCaptor.getValue()).isEqualTo(draftAttachment); } @@ -168,7 +163,7 @@ void entityNotUpdatedNothingToDelete() { var delete = Delete.from(RootTable_.class); when(eventContext.getCqn()).thenReturn(delete); when(eventContext.getModel()).thenReturn(runtime.getCdsModel()); - var siblingTarget = eventContext.getTarget().getTargetOf(DraftConstants.SIBLING_ENTITY); + CdsEntity siblingTarget = eventContext.getTarget().getTargetOf(DraftConstants.SIBLING_ENTITY); var id = UUID.randomUUID().toString(); var contentId = UUID.randomUUID().toString(); buildAttachmentAndReturnByReader(contentId, siblingTarget, true, id); @@ -179,24 +174,20 @@ void entityNotUpdatedNothingToDelete() { verifyNoInteractions(deleteContentAttachmentEvent); } - private Attachment buildAttachmentAndReturnByReader(String contentId, CdsStructuredType target, - boolean hasActiveEntity, String id) { - var attachment = Attachment.create(); + private Attachment buildAttachmentAndReturnByReader(String contentId, CdsEntity target, boolean hasActiveEntity, + String id) { + Attachment attachment = Attachment.create(); attachment.setId(id); attachment.setContentId(contentId); attachment.setHasActiveEntity(hasActiveEntity); attachment.setContent(null); - when(attachmentsReader.readAttachments(any(), (CdsEntity) eq(target), any())).thenReturn(List.of(attachment)); + when(attachmentsReader.readAttachments(any(), eq(target), any())).thenReturn(List.of(attachment)); return attachment; } private void getEntityAndMockContext(String cdsName) { - var serviceEntity = runtime.getCdsModel().findEntity(cdsName); - mockTargetInUpdateContext(serviceEntity.orElseThrow()); - } - - private void mockTargetInUpdateContext(CdsEntity serviceEntity) { - when(eventContext.getTarget()).thenReturn(serviceEntity); + Optional serviceEntity = runtime.getCdsModel().findEntity(cdsName); + when(eventContext.getTarget()).thenReturn(serviceEntity.orElseThrow()); } }