From 6cc9dafa19f6ee246500ad0aadb8a6fbde17711e Mon Sep 17 00:00:00 2001 From: Jan Wittler Date: Sat, 15 Apr 2023 17:51:08 +0200 Subject: [PATCH 1/4] adapt to VitruviusChange being generic --- ...ltStateBasedChangeResolutionStrategy.xtend | 9 +- .../StateBasedChangeResolutionStrategy.java | 7 +- .../framework/views/impl/BasicView.xtend | 3 +- .../views/impl/ChangeDerivingView.xtend | 3 +- .../views/impl/ChangeRecordingView.xtend | 13 ++- .../views/impl/IdentityMappingViewType.java | 11 +- .../views/impl/ViewCreatingViewType.java | 3 +- .../vsum/internal/ResourceRepositoryImpl.java | 10 +- .../vsum/internal/VirtualModelImpl.java | 14 +-- .../BasicStateChangePropagationTest.xtend | 19 ++-- .../StateChangePropagationTest.xtend | 8 +- .../views/impl/ChangeDerivingViewTest.java | 15 ++- .../views/impl/ChangeRecordingViewTest.java | 106 ++++++++++++------ .../impl/IdentityMappingViewTypeTest.java | 24 ++-- .../framework/vsum/VirtualModelTest.xtend | 3 +- .../framework/vsum/VirtualModelTestUtil.xtend | 6 +- 16 files changed, 163 insertions(+), 91 deletions(-) diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/DefaultStateBasedChangeResolutionStrategy.xtend b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/DefaultStateBasedChangeResolutionStrategy.xtend index 9d1fcb7269..7f4495d93f 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/DefaultStateBasedChangeResolutionStrategy.xtend +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/DefaultStateBasedChangeResolutionStrategy.xtend @@ -9,13 +9,16 @@ import org.eclipse.emf.compare.merge.BatchMerger import org.eclipse.emf.compare.merge.IMerger import org.eclipse.emf.compare.scope.DefaultComparisonScope import org.eclipse.emf.compare.utils.UseIdentifiers +import org.eclipse.emf.ecore.EObject import org.eclipse.emf.ecore.resource.Resource import org.eclipse.emf.ecore.resource.ResourceSet import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl import org.eclipse.emf.ecore.util.EcoreUtil import tools.vitruv.change.atomic.EChangeIdManager +import tools.vitruv.change.atomic.id.Id import tools.vitruv.change.atomic.id.IdResolver import tools.vitruv.change.composite.description.VitruviusChange +import tools.vitruv.change.composite.description.VitruviusChangeResolver import tools.vitruv.change.composite.recording.ChangeRecorder import tools.vitruv.framework.views.util.ResourceCopier @@ -99,12 +102,11 @@ class DefaultStateBasedChangeResolutionStrategy implements StateBasedChangeResol changeRecorder.addToRecording(resource) function.apply() val recordedChanges = changeRecorder.endRecording - assignIds(recordedChanges, resource.resourceSet) - return recordedChanges.unresolve + return assignIds(recordedChanges, resource.resourceSet) } } - private def void assignIds(VitruviusChange recordedChange, ResourceSet resourceSet) { + private def VitruviusChange assignIds(VitruviusChange recordedChange, ResourceSet resourceSet) { val changes = recordedChange.EChanges val idResolver = IdResolver.create(resourceSet) val eChangeIdManager = new EChangeIdManager(idResolver) @@ -113,6 +115,7 @@ class DefaultStateBasedChangeResolutionStrategy implements StateBasedChangeResol eChangeIdManager.setOrGenerateIds(change) change.applyForward(idResolver) ] + return VitruviusChangeResolver.unresolve(recordedChange, idResolver) } /** diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/StateBasedChangeResolutionStrategy.java b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/StateBasedChangeResolutionStrategy.java index a0cbe75393..2276960345 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/StateBasedChangeResolutionStrategy.java +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/StateBasedChangeResolutionStrategy.java @@ -2,6 +2,7 @@ import org.eclipse.emf.ecore.resource.Resource; +import tools.vitruv.change.atomic.id.Id; import tools.vitruv.change.composite.description.VitruviusChange; /** @@ -24,7 +25,7 @@ public interface StateBasedChangeResolutionStrategy { * @return a unresolved {@link VitruviusChange} that contains the individual * change sequence. */ - VitruviusChange getChangeSequenceBetween(Resource newState, Resource oldState); + VitruviusChange getChangeSequenceBetween(Resource newState, Resource oldState); /** * Resolves the state-based delta for creating the given resource and returns @@ -36,7 +37,7 @@ public interface StateBasedChangeResolutionStrategy { * @return a unresolved {@link VitruviusChange} that contains the individual * change sequence. */ - VitruviusChange getChangeSequenceForCreated(Resource newState); + VitruviusChange getChangeSequenceForCreated(Resource newState); /** * Resolves the state-based delta for deleting the given resource and returns @@ -49,5 +50,5 @@ public interface StateBasedChangeResolutionStrategy { * @return a unresolved {@link VitruviusChange} that contains the individual * change sequence. */ - VitruviusChange getChangeSequenceForDeleted(Resource oldState); + VitruviusChange getChangeSequenceForDeleted(Resource oldState); } diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/BasicView.xtend b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/BasicView.xtend index a73a0c50d5..2d458473f0 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/BasicView.xtend +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/BasicView.xtend @@ -9,6 +9,7 @@ import org.eclipse.emf.ecore.resource.Resource import org.eclipse.emf.ecore.resource.ResourceSet import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl import org.eclipse.xtend.lib.annotations.Accessors +import tools.vitruv.change.atomic.uuid.Uuid import tools.vitruv.change.composite.description.PropagatedChange import tools.vitruv.change.composite.description.VitruviusChange import tools.vitruv.change.composite.propagation.ChangePropagationListener @@ -89,7 +90,7 @@ package class BasicView implements ModifiableView, ChangePropagationListener { modelChanged = true } - override startedChangePropagation(VitruviusChange changeToPropagate) { + override startedChangePropagation(VitruviusChange changeToPropagate) { // do nothing } diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeDerivingView.xtend b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeDerivingView.xtend index cd49ae4d48..d6d798c81a 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeDerivingView.xtend +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeDerivingView.xtend @@ -7,6 +7,7 @@ import org.eclipse.emf.ecore.resource.Resource import org.eclipse.emf.ecore.resource.ResourceSet import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl import org.eclipse.xtend.lib.annotations.Delegate +import tools.vitruv.change.atomic.id.Id import tools.vitruv.change.composite.description.VitruviusChange import tools.vitruv.change.composite.description.VitruviusChangeFactory import tools.vitruv.framework.views.CommittableView @@ -75,7 +76,7 @@ class ChangeDerivingView implements ModifiableView, CommittableView { view.close } - private def VitruviusChange generateChange(Resource newState, Resource referenceState) { + private def VitruviusChange generateChange(Resource newState, Resource referenceState) { if (referenceState === null) { return changeResolutionStrategy.getChangeSequenceForCreated(newState) } else if (newState === null) { diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeRecordingView.xtend b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeRecordingView.xtend index d8c0938d6e..db870b0332 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeRecordingView.xtend +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeRecordingView.xtend @@ -1,10 +1,11 @@ package tools.vitruv.framework.views.impl -import java.util.List +import org.eclipse.emf.ecore.EObject import org.eclipse.xtend.lib.annotations.Delegate -import tools.vitruv.change.atomic.EChange import tools.vitruv.change.atomic.EChangeIdManager import tools.vitruv.change.atomic.id.IdResolver +import tools.vitruv.change.composite.description.VitruviusChange +import tools.vitruv.change.composite.description.VitruviusChangeResolver import tools.vitruv.change.composite.recording.ChangeRecorder import tools.vitruv.framework.views.CommittableView import tools.vitruv.framework.views.View @@ -43,7 +44,8 @@ class ChangeRecordingView implements ModifiableView, CommittableView { changeRecorder.addToRecording(view.viewResourceSet) changeRecorder.beginRecording() } - def private void assignIds(List changes) { + def private assignIds(VitruviusChange recordedChange) { + val changes = recordedChange.EChanges val idResolver = IdResolver.create(view.viewResourceSet) val idManager = new EChangeIdManager(idResolver) changes.toList.reverseView.forEach[applyBackward] @@ -51,13 +53,14 @@ class ChangeRecordingView implements ModifiableView, CommittableView { idManager.setOrGenerateIds(it) it.applyForward(idResolver) ] + return VitruviusChangeResolver.unresolve(recordedChange, idResolver) } override commitChanges() { view.checkNotClosed() val recordedChange = changeRecorder.endRecording() - assignIds(recordedChange.EChanges) - view.viewType.commitViewChanges(this, recordedChange) + val unresolvedChanges = assignIds(recordedChange) + view.viewType.commitViewChanges(this, unresolvedChanges) view.viewChanged = false changeRecorder.beginRecording() } diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java index 21af16be71..681d17dd87 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java @@ -9,14 +9,18 @@ import java.util.function.Function; import java.util.stream.Stream; +import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import tools.vitruv.change.atomic.EChangeUuidManager; +import tools.vitruv.change.atomic.id.Id; import tools.vitruv.change.atomic.id.IdResolver; +import tools.vitruv.change.atomic.uuid.Uuid; import tools.vitruv.change.atomic.uuid.UuidResolver; import tools.vitruv.change.composite.description.VitruviusChange; +import tools.vitruv.change.composite.description.VitruviusChangeResolver; import tools.vitruv.framework.views.ChangeableViewSource; import tools.vitruv.framework.views.View; import tools.vitruv.framework.views.ViewSelection; @@ -63,16 +67,17 @@ public void updateView(ModifiableView view) { } @Override - public void commitViewChanges(ModifiableView view, VitruviusChange viewChange) { + public void commitViewChanges(ModifiableView view, VitruviusChange viewChange) { ResourceSet viewSourceCopyResourceSet = withGlobalFactories(new ResourceSetImpl()); IdResolver viewSourceCopyIdResolver = IdResolver.create(viewSourceCopyResourceSet); UuidResolver viewSourceCopyUuidResolver = UuidResolver.create(viewSourceCopyResourceSet); Map mapping = createViewResources(view, viewSourceCopyResourceSet); view.getViewSource().getUuidResolver().resolveResources(mapping, viewSourceCopyUuidResolver); - VitruviusChange resolvedChange = viewChange.unresolve().resolveAndApply(viewSourceCopyIdResolver); + VitruviusChange resolvedChange = VitruviusChangeResolver.resolveAndApply(viewChange, viewSourceCopyIdResolver); EChangeUuidManager.setOrGenerateIds(resolvedChange.getEChanges(), viewSourceCopyUuidResolver); - view.getViewSource().propagateChange(resolvedChange.unresolve()); + VitruviusChange unresolvedChanges = VitruviusChangeResolver.unresolve(resolvedChange, viewSourceCopyUuidResolver); + view.getViewSource().propagateChange(unresolvedChanges); } private Map createViewResources(ModifiableView view, ResourceSet viewResourceSet) { diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java index 15604c0043..48efba3229 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java @@ -1,5 +1,6 @@ package tools.vitruv.framework.views.impl; +import tools.vitruv.change.atomic.id.Id; import tools.vitruv.change.composite.description.VitruviusChange; import tools.vitruv.framework.views.ChangeableViewSource; import tools.vitruv.framework.views.ViewSelector; @@ -41,5 +42,5 @@ public interface ViewCreatingViewType extends ViewType viewChange); } diff --git a/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ResourceRepositoryImpl.java b/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ResourceRepositoryImpl.java index f34d8a4c5d..446cb6c801 100644 --- a/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ResourceRepositoryImpl.java +++ b/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ResourceRepositoryImpl.java @@ -23,9 +23,11 @@ import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import tools.vitruv.change.atomic.EChangeUuidManager; +import tools.vitruv.change.atomic.uuid.Uuid; import tools.vitruv.change.atomic.uuid.UuidResolver; import tools.vitruv.change.composite.description.TransactionalChange; import tools.vitruv.change.composite.description.VitruviusChange; +import tools.vitruv.change.composite.description.VitruviusChangeResolver; import tools.vitruv.change.composite.recording.ChangeRecorder; import tools.vitruv.change.correspondence.Correspondence; import tools.vitruv.change.correspondence.model.PersistableCorrespondenceModel; @@ -170,7 +172,7 @@ public void saveOrDeleteModels() { } @Override - public Iterable recordChanges(Runnable changeApplicator) { + public Iterable> recordChanges(Runnable changeApplicator) { changeRecorder.beginRecording(); isRecording = true; LOGGER.debug("Start recording virtual model"); @@ -178,14 +180,14 @@ public Iterable recordChanges(Runnable changeApplicator) { LOGGER.debug("End recording virtual model"); isRecording = false; changeRecorder.endRecording(); - TransactionalChange change = changeRecorder.getChange(); + TransactionalChange change = changeRecorder.getChange(); EChangeUuidManager.setOrGenerateIds(change.getEChanges(), uuidResolver); return change.containsConcreteChange() ? List.of(change) : List.of(); } @Override - public VitruviusChange applyChange(VitruviusChange change) { - return change.resolveAndApply(uuidResolver); + public VitruviusChange applyChange(VitruviusChange change) { + return VitruviusChangeResolver.resolveAndApply(change, uuidResolver); } @Override diff --git a/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/VirtualModelImpl.java b/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/VirtualModelImpl.java index e0154c8c04..0f09d7d5a5 100644 --- a/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/VirtualModelImpl.java +++ b/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/VirtualModelImpl.java @@ -12,6 +12,7 @@ import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; +import tools.vitruv.change.atomic.uuid.Uuid; import tools.vitruv.change.atomic.uuid.UuidResolver; import tools.vitruv.change.composite.description.PropagatedChange; import tools.vitruv.change.composite.description.VitruviusChange; @@ -75,37 +76,36 @@ private synchronized void save() { } @Override - public synchronized List propagateChange(VitruviusChange change) { + public synchronized List propagateChange(VitruviusChange change) { checkNotNull(change, "change to propagate"); checkArgument(change.containsConcreteChange(), "This change contains no concrete change:%s%s", System.lineSeparator(), change); - VitruviusChange unresolvedChange = change.unresolve(); LOGGER.info("Starting change propagation"); - startChangePropagation(unresolvedChange); + startChangePropagation(change); ChangePropagator changePropagator = new ChangePropagator(resourceRepository, changePropagationSpecificationProvider, userInteractor, changePropagationMode); - List result = changePropagator.propagateChange(unresolvedChange); + List result = changePropagator.propagateChange(change); save(); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Propagated changes: " + result); } - finishChangePropagation(unresolvedChange, result); + finishChangePropagation(change, result); LOGGER.info("Finished change propagation"); return result; } - private void startChangePropagation(VitruviusChange change) { + private void startChangePropagation(VitruviusChange change) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Started synchronizing change: " + change); } changePropagationListeners.stream().forEach(it -> it.startedChangePropagation(change)); } - private void finishChangePropagation(VitruviusChange inputChange, Iterable generatedChanges) { + private void finishChangePropagation(VitruviusChange inputChange, Iterable generatedChanges) { changePropagationListeners.stream().forEach(it -> it.finishedChangePropagation(generatedChanges)); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Finished synchronizing change: " + inputChange); diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/BasicStateChangePropagationTest.xtend b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/BasicStateChangePropagationTest.xtend index 72de3cdc17..5ea63ffe26 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/BasicStateChangePropagationTest.xtend +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/BasicStateChangePropagationTest.xtend @@ -12,6 +12,7 @@ import tools.vitruv.change.atomic.feature.attribute.ReplaceSingleValuedEAttribut import tools.vitruv.change.atomic.id.IdResolver import tools.vitruv.change.atomic.root.InsertRootEObject import tools.vitruv.change.atomic.root.RemoveRootEObject +import tools.vitruv.change.composite.description.VitruviusChangeResolver import tools.vitruv.testutils.Capture import static org.hamcrest.CoreMatchers.instanceOf @@ -47,7 +48,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { // Create empty resource to apply generated changes to val validationResourceSet = new ResourceSetImpl() - changes.resolveAndApply(IdResolver.create(validationResourceSet)) + VitruviusChangeResolver.resolveAndApply(changes, IdResolver.create(validationResourceSet)) modelResource.save(null) assertEquals(1, validationResourceSet.resources.size) @@ -75,7 +76,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { // Load resource to apply generated changes to val validationResourceSet = new ResourceSetImpl() validationResourceSet.getResource(testUri, true) - changes.resolveAndApply(IdResolver.create(validationResourceSet)) + VitruviusChangeResolver.resolveAndApply(changes, IdResolver.create(validationResourceSet)) assertEquals(1, validationResourceSet.resources.size) assertTrue(validationResourceSet.resources.get(0).contents.empty) @@ -106,7 +107,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { val oldState = validationResourceSet.getResource(testUri, true) val changes = strategyToTest.getChangeSequenceBetween(-modelResource, oldState) - changes.resolveAndApply(IdResolver.create(validationResourceSet)) + VitruviusChangeResolver.resolveAndApply(changes, IdResolver.create(validationResourceSet)) assertEquals(1, validationResourceSet.resources.size) assertThat(validationResourceSet.resources.get(0), containsModelOf(-modelResource)) @@ -137,7 +138,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { assertEquals(1, changes.EChanges.size) assertEquals(1, changes.EChanges.filter(ReplaceSingleValuedEAttribute).size) - changes.resolveAndApply(IdResolver.create(validationResourceSet)) + VitruviusChangeResolver.resolveAndApply(changes, IdResolver.create(validationResourceSet)) assertEquals(1, validationResourceSet.resources.size) assertThat(validationResourceSet.resources.get(0), containsModelOf(-modelResource)) @@ -165,7 +166,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { val validationResourceSet = new ResourceSetImpl().withGlobalFactories() val oldState = validationResourceSet.getResource(testUri, true) val unresolvedChanges = strategyToTest.getChangeSequenceBetween(-modelResource, oldState) - val changes = unresolvedChanges.resolveAndApply(IdResolver.create(validationResourceSet)) + val changes = VitruviusChangeResolver.resolveAndApply(unresolvedChanges, IdResolver.create(validationResourceSet)) switch (strategyToTest.useIdentifiers) { case ONLY, case WHEN_AVAILABLE: { @@ -219,7 +220,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { assertEquals(1, changes.EChanges.size) assertEquals(1, changes.EChanges.filter(ReplaceSingleValuedEAttribute).size) - changes.resolveAndApply(IdResolver.create(validationResourceSet)) + VitruviusChangeResolver.resolveAndApply(changes, IdResolver.create(validationResourceSet)) assertEquals(1, validationResourceSet.resources.size) assertThat(validationResourceSet.resources.get(0), containsModelOf(-modelResource)) @@ -252,7 +253,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { val validationResourceSet = new ResourceSetImpl().withGlobalFactories() val oldState = validationResourceSet.getResource(testUri, true) val unresolvedChanges = strategyToTest.getChangeSequenceBetween(-modelResource, oldState) - val changes = unresolvedChanges.resolveAndApply(IdResolver.create(validationResourceSet)) + val changes = VitruviusChangeResolver.resolveAndApply(unresolvedChanges, IdResolver.create(validationResourceSet)) switch (strategyToTest.useIdentifiers) { case ONLY, case WHEN_AVAILABLE: { @@ -306,7 +307,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { assertEquals(1, changes.EChanges.filter(RemoveRootEObject).size) assertEquals(1, changes.EChanges.filter(InsertRootEObject).size) - changes.resolveAndApply(IdResolver.create(validationResourceSet)) + VitruviusChangeResolver.resolveAndApply(changes, IdResolver.create(validationResourceSet)) (-modelResource).save(null) assertEquals(2, validationResourceSet.resources.size) @@ -346,7 +347,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { assertEquals(1, changes.EChanges.filter(InsertRootEObject).size) assertEquals(1, changes.EChanges.filter(ReplaceSingleValuedEAttribute).size) - changes.resolveAndApply(IdResolver.create(validationResourceSet)) + VitruviusChangeResolver.resolveAndApply(changes, IdResolver.create(validationResourceSet)) (-modelResource).save(null) assertEquals(2, validationResourceSet.resources.size) diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/StateChangePropagationTest.xtend b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/StateChangePropagationTest.xtend index a03126e8f9..a524cb5e47 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/StateChangePropagationTest.xtend +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/StateChangePropagationTest.xtend @@ -5,6 +5,7 @@ import java.util.stream.Stream import org.eclipse.emf.common.notify.Notifier import org.eclipse.emf.common.util.URI import org.eclipse.emf.compare.utils.UseIdentifiers +import org.eclipse.emf.ecore.EObject import org.eclipse.emf.ecore.resource.Resource import org.eclipse.emf.ecore.resource.ResourceSet import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl @@ -17,6 +18,7 @@ import org.junit.jupiter.api.^extension.ExtendWith import pcm_mockup.Repository import tools.vitruv.change.atomic.id.IdResolver import tools.vitruv.change.composite.description.VitruviusChange +import tools.vitruv.change.composite.description.VitruviusChangeResolver import tools.vitruv.change.composite.recording.ChangeRecorder import tools.vitruv.testutils.RegisterMetamodelsInStandalone import tools.vitruv.testutils.TestLogging @@ -100,7 +102,7 @@ abstract class StateChangePropagationTest { val deltaBasedChange = resourceSet.endRecording val unresolvedStateBasedChange = strategyToTest.getChangeSequenceBetween(model, checkpoint) assertNotNull(unresolvedStateBasedChange) - val stateBasedChange = unresolvedStateBasedChange.resolveAndApply(IdResolver.create(checkpoint.resourceSet)) + val stateBasedChange = VitruviusChangeResolver.resolveAndApply(unresolvedStateBasedChange, IdResolver.create(checkpoint.resourceSet)) val message = getTextualRepresentation(stateBasedChange, deltaBasedChange) val stateBasedChangedObjects = stateBasedChange.affectedAndReferencedEObjects val deltaBasedChangedObjects = deltaBasedChange.affectedAndReferencedEObjects @@ -119,12 +121,12 @@ abstract class StateChangePropagationTest { /** * Returns the recorded change sequences (the "original" changes) for a specific model instance. */ - private def VitruviusChange endRecording(Notifier notifier) { + private def VitruviusChange endRecording(Notifier notifier) { changeRecorder.removeFromRecording(notifier) return changeRecorder.endRecording } - private def String getTextualRepresentation(VitruviusChange stateBasedChange, VitruviusChange deltaBasedChange) ''' + private def String getTextualRepresentation(VitruviusChange stateBasedChange, VitruviusChange deltaBasedChange) ''' State-based «stateBasedChange» Delta-based «deltaBasedChange» ''' diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java index d51d20b8d0..3e1866bf62 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java @@ -24,6 +24,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -31,11 +32,13 @@ import allElementTypes.Root; import tools.vitruv.change.atomic.eobject.EobjectPackage; import tools.vitruv.change.atomic.feature.attribute.ReplaceSingleValuedEAttribute; +import tools.vitruv.change.atomic.id.Id; import tools.vitruv.change.atomic.id.IdResolver; import tools.vitruv.change.atomic.root.InsertRootEObject; import tools.vitruv.change.atomic.root.RootFactory; import tools.vitruv.change.atomic.root.RootPackage; import tools.vitruv.change.composite.description.VitruviusChange; +import tools.vitruv.change.composite.description.VitruviusChangeResolver; import tools.vitruv.framework.views.ChangeableViewSource; import tools.vitruv.framework.views.ModifiableViewSelection; import tools.vitruv.framework.views.changederivation.DefaultStateBasedChangeResolutionStrategy; @@ -207,11 +210,11 @@ public void commitChanges() throws Exception { view.registerRoot(root, URI.createURI(testResourceUriString)); assertThat(view.getRootObjects(), hasItem(root)); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeDerivingView.class); - ArgumentCaptor changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChanges(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); - VitruviusChange change = changeArgument.getValue().resolveAndApply(IdResolver.create(root.eResource().getResourceSet())); + VitruviusChange change = VitruviusChangeResolver.resolveAndApply(changeArgument.getValue(), IdResolver.create(root.eResource().getResourceSet())); InsertRootEObject expectedChange = RootFactory.eINSTANCE.createInsertRootEObject(); expectedChange.setNewValue(root); expectedChange.setUri(testResourceUriString); @@ -285,7 +288,7 @@ public void commitChanges() throws Exception { view.moveRoot(root, URI.createURI(movedResourceUriString)); assertThat(view.getRootObjects(), hasItem(root)); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeDerivingView.class); - ArgumentCaptor changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChangesAndUpdate(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); @@ -325,7 +328,7 @@ public void once() { nonRoot.setId("nonRoot"); root.setSingleValuedContainmentEReference(nonRoot); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeDerivingView.class); - ArgumentCaptor changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChangesAndUpdate(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); @@ -348,7 +351,7 @@ public void twice() { secondNonRoot.setId("second"); root.setSingleValuedContainmentEReference(secondNonRoot); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeDerivingView.class); - ArgumentCaptor changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChangesAndUpdate(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); @@ -363,7 +366,7 @@ public void twice() { @DisplayName("without changes") public void withoutChanges() { ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeDerivingView.class); - ArgumentCaptor changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChangesAndUpdate(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java index 01bb50a503..2405ea7d70 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java @@ -17,6 +17,9 @@ import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -30,7 +33,6 @@ import allElementTypes.AllElementTypesPackage; import allElementTypes.NonRoot; import allElementTypes.Root; -import tools.vitruv.change.composite.description.VitruviusChange; import tools.vitruv.change.atomic.EChange; import tools.vitruv.change.atomic.eobject.CreateEObject; import tools.vitruv.change.atomic.eobject.DeleteEObject; @@ -40,9 +42,13 @@ import tools.vitruv.change.atomic.feature.attribute.AttributePackage; import tools.vitruv.change.atomic.feature.attribute.ReplaceSingleValuedEAttribute; import tools.vitruv.change.atomic.feature.reference.ReplaceSingleValuedEReference; +import tools.vitruv.change.atomic.id.Id; +import tools.vitruv.change.atomic.id.IdResolver; import tools.vitruv.change.atomic.root.InsertRootEObject; import tools.vitruv.change.atomic.root.RootFactory; import tools.vitruv.change.atomic.root.RootPackage; +import tools.vitruv.change.composite.description.VitruviusChange; +import tools.vitruv.change.composite.description.VitruviusChangeResolver; import tools.vitruv.framework.views.ChangeableViewSource; import tools.vitruv.framework.views.ModifiableViewSelection; import tools.vitruv.testutils.RegisterMetamodelsInStandalone; @@ -68,14 +74,14 @@ public class Initialize { @Test @DisplayName("with null view") public void withNullViewType() { - assertThrows(IllegalArgumentException.class, - () -> new ChangeRecordingView(null)); + assertThrows(IllegalArgumentException.class, () -> new ChangeRecordingView(null)); } @Test @DisplayName("with proper arguments") public void withEmptySource() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { assertThat(view.isClosed(), is(false)); assertThat(view.getRootObjects(), not(hasItem(anything()))); } @@ -88,7 +94,8 @@ public class RetrieveRootElements { @Test @DisplayName("all of same type") public void allOfSameType() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { Root root = aet.Root(); view.registerRoot(root, URI.createURI("test://test.aet")); Root root2 = aet.Root(); @@ -105,7 +112,8 @@ public void allOfSameType() throws Exception { @Test @DisplayName("all of one out of two types") public void containingAllOfOneType() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { Root root = aet.Root(); view.registerRoot(root, URI.createURI("test://test.aet")); NonRoot otherRoot = aet.NonRoot(); @@ -121,7 +129,8 @@ public void containingAllOfOneType() throws Exception { @Test @DisplayName("containing none of a type") public void containingNoneOfType() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { Root root = aet.Root(); view.registerRoot(root, URI.createURI("test://test.aet")); Root otherRoot = aet.Root(); @@ -140,7 +149,8 @@ public class Update { @Test @DisplayName("without previous modification") public void withoutPreviousModification() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { view.update(); } } @@ -148,7 +158,8 @@ public void withoutPreviousModification() throws Exception { @Test @DisplayName("with previous modification") public void withPreviousModification() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { view.modifyContents((resourceSet) -> resourceSet.createResource(URI.createURI("test://test.aet"))); assertThrows(IllegalStateException.class, () -> view.update()); } @@ -161,7 +172,8 @@ public class AddRoot { @Test @DisplayName("being null") public void nullElement() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { assertThrows(IllegalArgumentException.class, () -> view.registerRoot(null, URI.createURI("test://test.aet"))); } @@ -170,7 +182,8 @@ public void nullElement() throws Exception { @Test @DisplayName("with null URI") public void nullUri() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { Root root = aet.Root(); assertThrows(IllegalArgumentException.class, () -> view.registerRoot(root, null)); } @@ -179,7 +192,8 @@ public void nullUri() throws Exception { @Test @DisplayName("with proper arguments") public void properArguments() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { Root root = aet.Root(); String testResourceUriString = "test://test.aet"; view.registerRoot(root, URI.createURI(testResourceUriString)); @@ -190,27 +204,31 @@ public void properArguments() throws Exception { @Test @DisplayName("committing changes") public void commitChanges() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { Root root = aet.Root(); root.setId("root"); String testResourceUriString = "test://test.aet"; view.registerRoot(root, URI.createURI(testResourceUriString)); assertThat(view.getRootObjects(), hasItem(root)); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeRecordingView.class); - ArgumentCaptor changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChanges(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); + assertThat(viewArgument.getValue(), is(view)); - VitruviusChange recordedChange = changeArgument.getValue(); + ResourceSet resolveInResourceSet = new ResourceSetImpl(); + VitruviusChange resolvedChange = VitruviusChangeResolver + .resolveAndApply(changeArgument.getValue(), IdResolver.create(resolveInResourceSet)); InsertRootEObject expectedChange = RootFactory.eINSTANCE.createInsertRootEObject(); expectedChange.setNewValue(root); expectedChange.setUri(testResourceUriString); - assertThat(recordedChange.getEChanges().size(), is(3)); // Create, Insert, ReplaceId - assertThat(recordedChange.getEChanges().get(1), + assertThat(resolvedChange.getEChanges().size(), is(3)); // Create, Insert, ReplaceId + assertThat(resolvedChange.getEChanges().get(1), equalsDeeply(expectedChange, ignoringFeatures(EobjectPackage.eINSTANCE.getEObjectAddedEChange_NewValueID(), RootPackage.eINSTANCE.getRootEChange_Resource()))); - assertThat(recordedChange.getEChanges().get(2), instanceOf(ReplaceSingleValuedEAttribute.class)); + assertThat(resolvedChange.getEChanges().get(2), instanceOf(ReplaceSingleValuedEAttribute.class)); } } } @@ -221,7 +239,8 @@ public class MoveRoot { @Test @DisplayName("being null") public void nullElement() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { assertThrows(IllegalArgumentException.class, () -> view.moveRoot(null, URI.createURI("test://test.aet"))); } @@ -230,7 +249,8 @@ public void nullElement() throws Exception { @Test @DisplayName("with null URI") public void nullUri() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { Root root = aet.Root(); view.registerRoot(root, URI.createURI("test://test.aet")); assertThrows(IllegalArgumentException.class, () -> view.moveRoot(root, null)); @@ -240,7 +260,8 @@ public void nullUri() throws Exception { @Test @DisplayName("with element not beeing root") public void notBeingRoot() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { Root root = aet.Root(); assertThrows(IllegalStateException.class, () -> view.moveRoot(root, URI.createURI("test://test.aet"))); } @@ -249,7 +270,8 @@ public void notBeingRoot() throws Exception { @Test @DisplayName("with proper arguments") public void properArguments() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { Root root = aet.Root(); view.registerRoot(root, URI.createURI("test://test.aet")); view.moveRoot(root, URI.createURI("test://test2.aet")); @@ -261,20 +283,29 @@ public void properArguments() throws Exception { @Test @DisplayName("committing changes") public void commitChanges() throws Exception { - try (ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { + try (ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection))) { Root root = aet.Root(); String movedResourceUriString = "test://test2.aet"; view.registerRoot(root, URI.createURI("test://test.aet")); view.commitChanges(); reset(mockChangeableViewSource, mockViewType); + + ResourceSet resolveInResourceSet = new ResourceSetImpl(); + resolveInResourceSet.createResource(root.eResource().getURI()); + resolveInResourceSet.getResource(root.eResource().getURI(), false).getContents() + .add(EcoreUtil.copy(root)); + view.moveRoot(root, URI.createURI(movedResourceUriString)); assertThat(view.getRootObjects(), hasItem(root)); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeRecordingView.class); - ArgumentCaptor changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChanges(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); - List capturedEChanges = changeArgument.getValue().getEChanges(); + VitruviusChange resolvedChange = VitruviusChangeResolver + .resolveAndApply(changeArgument.getValue(), IdResolver.create(resolveInResourceSet)); + List capturedEChanges = resolvedChange.getEChanges(); InsertRootEObject expectedChange = RootFactory.eINSTANCE.createInsertRootEObject(); expectedChange.setNewValue(root); expectedChange.setUri(movedResourceUriString); @@ -314,7 +345,7 @@ public void once() { nonRoot.setId("nonRoot"); root.setSingleValuedContainmentEReference(nonRoot); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeRecordingView.class); - ArgumentCaptor changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChanges(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); @@ -332,15 +363,23 @@ public void twice() { firstNonRoot.setId("first"); root.setSingleValuedContainmentEReference(firstNonRoot); view.commitChanges(); + + ResourceSet resolveInResourceSet = new ResourceSetImpl(); + resolveInResourceSet.createResource(root.eResource().getURI()); + resolveInResourceSet.getResource(root.eResource().getURI(), false).getContents().add(EcoreUtil.copy(root)); + reset(mockChangeableViewSource, mockViewType); NonRoot secondNonRoot = aet.NonRoot(); secondNonRoot.setId("second"); root.setSingleValuedContainmentEReference(secondNonRoot); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeRecordingView.class); - ArgumentCaptor changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChanges(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); - List capturedEChanges = changeArgument.getValue().getEChanges(); + + VitruviusChange resolvedChange = VitruviusChangeResolver.resolveAndApply(changeArgument.getValue(), + IdResolver.create(resolveInResourceSet)); + List capturedEChanges = resolvedChange.getEChanges(); assertThat(capturedEChanges.size(), is(4)); // Create, Insert, ReplaceValue, Delete assertThat(capturedEChanges.get(0), instanceOf(CreateEObject.class)); assertThat(capturedEChanges.get(1), instanceOf(ReplaceSingleValuedEReference.class)); @@ -360,7 +399,7 @@ public void twice() { @DisplayName("without changes") public void withoutChanges() { ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeRecordingView.class); - ArgumentCaptor changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChanges(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); @@ -374,7 +413,8 @@ public class Close { @Test @DisplayName("and is closed afterwards") public void isClosed() throws Exception { - ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection)); + ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection)); view.close(); assertThat("view should be closed", view.isClosed()); } @@ -382,7 +422,8 @@ public void isClosed() throws Exception { @Test @DisplayName("can be called multiple times") public void callMultipleTimes() throws Exception { - ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection)); + ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection)); view.close(); view.close(); assertThat("view should be closed", view.isClosed()); @@ -391,7 +432,8 @@ public void callMultipleTimes() throws Exception { @Test @DisplayName("and does not allow further operations") public void noOperations() throws Exception { - ChangeRecordingView view = new ChangeRecordingView(new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection)); + ChangeRecordingView view = new ChangeRecordingView( + new BasicView(mockViewType, mockChangeableViewSource, mockViewSelection)); view.close(); assertThrows(IllegalStateException.class, () -> view.getRootObjects()); assertThrows(IllegalStateException.class, () -> view.getRootObjects(Root.class)); diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java index 1bd50cc174..0fc4ecd376 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java @@ -45,10 +45,13 @@ import tools.vitruv.change.atomic.EChange; import tools.vitruv.change.atomic.EChangeIdManager; import tools.vitruv.change.atomic.feature.attribute.ReplaceSingleValuedEAttribute; +import tools.vitruv.change.atomic.id.Id; import tools.vitruv.change.atomic.id.IdResolver; +import tools.vitruv.change.atomic.uuid.Uuid; import tools.vitruv.change.atomic.uuid.UuidResolver; import tools.vitruv.change.composite.description.VitruviusChange; import tools.vitruv.change.composite.description.VitruviusChangeFactory; +import tools.vitruv.change.composite.description.VitruviusChangeResolver; import tools.vitruv.change.composite.recording.ChangeRecorder; import tools.vitruv.framework.views.ChangeableViewSource; import tools.vitruv.framework.views.View; @@ -410,21 +413,21 @@ void withNull() { @Test @DisplayName("with null view") void withNullView() { - VitruviusChange someChange = VitruviusChangeFactory.getInstance().createTransactionalChange(Set.of()); + VitruviusChange someChange = VitruviusChangeFactory.getInstance().createTransactionalChange(Set.of()); assertThrows(NullPointerException.class, () -> basicViewType.commitViewChanges(null, someChange)); } @ParameterizedTest @MethodSource("testEmptyChanges") @DisplayName("with empty changes") - void withEmptyChanges(VitruviusChange change) { - ArgumentCaptor changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + void withEmptyChanges(VitruviusChange change) { + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); basicViewType.commitViewChanges(view, change); verify(viewSource).propagateChange(changeArgument.capture()); assertEquals(changeArgument.getValue(), change); } - private static Stream testEmptyChanges() { + private static Stream> testEmptyChanges() { VitruviusChangeFactory factory = VitruviusChangeFactory.getInstance(); return Stream.of( factory.createTransactionalChange(Set.of()), @@ -441,13 +444,13 @@ void withNonEmptyChange() { changeRecorder.beginRecording(); root.setId("testid2"); changeRecorder.endRecording(); - VitruviusChange change = changeRecorder.getChange(); - assignIds(change); + VitruviusChange change = changeRecorder.getChange(); + VitruviusChange idAssignedChange = assignIds(change); - ArgumentCaptor changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); - basicViewType.commitViewChanges(view, change); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + basicViewType.commitViewChanges(view, idAssignedChange); verify(viewSource).propagateChange(changeArgument.capture()); - List eChanges = changeArgument.getValue().unresolve().getEChanges(); + List eChanges = changeArgument.getValue().getEChanges(); assertThat(eChanges.size(), is(1)); assertThat(eChanges.get(0), instanceOf(ReplaceSingleValuedEAttribute.class)); var attributeChange = (ReplaceSingleValuedEAttribute)eChanges.get(0); @@ -456,7 +459,7 @@ void withNonEmptyChange() { } } - private void assignIds(VitruviusChange change) { + private VitruviusChange assignIds(VitruviusChange change) { IdResolver idResolver = IdResolver.create(viewResourceSet); EChangeIdManager idManager = new EChangeIdManager(idResolver); for (int i = change.getEChanges().size() - 1; i >= 0; i--) { @@ -466,6 +469,7 @@ private void assignIds(VitruviusChange change) { idManager.setOrGenerateIds(eChange); applyForward(eChange, idResolver); }); + return VitruviusChangeResolver.unresolve(change, idResolver); } } } diff --git a/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTest.xtend b/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTest.xtend index d505b0b25c..cd2dbaf6f2 100644 --- a/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTest.xtend +++ b/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTest.xtend @@ -15,6 +15,7 @@ import tools.vitruv.change.atomic.feature.attribute.ReplaceSingleValuedEAttribut import tools.vitruv.change.atomic.feature.reference.ReplaceSingleValuedEReference import tools.vitruv.change.atomic.root.InsertRootEObject import tools.vitruv.change.atomic.uuid.UuidResolver +import tools.vitruv.change.composite.description.VitruviusChangeResolver import tools.vitruv.change.composite.recording.ChangeRecorder import tools.vitruv.framework.views.View import tools.vitruv.framework.views.ViewTypeFactory @@ -373,7 +374,7 @@ class VirtualModelTest { private def endRecording(ChangeRecorder changeRecorder, UuidResolver uuidResolver) { val change = changeRecorder.endRecording EChangeUuidManager.setOrGenerateIds(change.EChanges, uuidResolver) - return change + return VitruviusChangeResolver.unresolve(change, uuidResolver) } def private createAndPropagateRoot(VirtualModel virtualModel, ResourceSet resourceSet, UuidResolver uuidResolver, String rootId) { diff --git a/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTestUtil.xtend b/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTestUtil.xtend index 3686b162fb..baaf633270 100644 --- a/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTestUtil.xtend +++ b/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTestUtil.xtend @@ -9,9 +9,11 @@ import org.eclipse.emf.ecore.resource.ResourceSet import tools.vitruv.change.atomic.EChange import tools.vitruv.change.atomic.EChangeUuidManager import tools.vitruv.change.atomic.root.InsertRootEObject +import tools.vitruv.change.atomic.uuid.Uuid import tools.vitruv.change.atomic.uuid.UuidResolver import tools.vitruv.change.composite.MetamodelDescriptor import tools.vitruv.change.composite.description.VitruviusChange +import tools.vitruv.change.composite.description.VitruviusChangeResolver import tools.vitruv.change.composite.recording.ChangeRecorder import tools.vitruv.change.correspondence.Correspondence import tools.vitruv.change.correspondence.view.EditableCorrespondenceModelView @@ -31,7 +33,7 @@ class VirtualModelTestUtil { /** * Create a recorder, start recording a resource set, apply changes, stop and return the recorded changes. */ - def static VitruviusChange recordChanges(ResourceSet resourceSet, UuidResolver uuidResolver, Runnable changesToPerform) { + def static VitruviusChange recordChanges(ResourceSet resourceSet, UuidResolver uuidResolver, Runnable changesToPerform) { val recorder = new ChangeRecorder(resourceSet) recorder.addToRecording(resourceSet) recorder.beginRecording @@ -39,7 +41,7 @@ class VirtualModelTestUtil { val result = recorder.endRecording EChangeUuidManager.setOrGenerateIds(result.EChanges, uuidResolver) recorder.close - return result + return VitruviusChangeResolver.unresolve(result, uuidResolver) } /** From ac4e9ded8ebcd3043c8c2cfd3ad291be13811042 Mon Sep 17 00:00:00 2001 From: Jan Wittler Date: Tue, 4 Jul 2023 19:47:21 +0200 Subject: [PATCH 2/4] adapt to generic EChanges --- ...ltStateBasedChangeResolutionStrategy.xtend | 23 +------- .../StateBasedChangeResolutionStrategy.java | 8 +-- .../views/impl/ChangeDerivingView.xtend | 4 +- .../views/impl/ChangeRecordingView.xtend | 21 +------ .../views/impl/IdentityMappingViewType.java | 14 ++--- .../views/impl/ViewCreatingViewType.java | 4 +- .../vsum/internal/ResourceRepositoryImpl.java | 6 +- .../BasicStateChangePropagationTest.xtend | 35 ++++++----- .../StateChangePropagationTest.xtend | 3 +- .../views/impl/ChangeDerivingViewTest.java | 20 +++---- .../views/impl/ChangeRecordingViewTest.java | 54 ++++++++--------- .../impl/IdentityMappingViewTypeTest.java | 59 ++++++++----------- .../framework/vsum/VirtualModelTest.xtend | 5 +- .../framework/vsum/VirtualModelTestUtil.xtend | 15 ++--- 14 files changed, 105 insertions(+), 166 deletions(-) diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/DefaultStateBasedChangeResolutionStrategy.xtend b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/DefaultStateBasedChangeResolutionStrategy.xtend index 7f4495d93f..ff3360f606 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/DefaultStateBasedChangeResolutionStrategy.xtend +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/DefaultStateBasedChangeResolutionStrategy.xtend @@ -9,15 +9,9 @@ import org.eclipse.emf.compare.merge.BatchMerger import org.eclipse.emf.compare.merge.IMerger import org.eclipse.emf.compare.scope.DefaultComparisonScope import org.eclipse.emf.compare.utils.UseIdentifiers -import org.eclipse.emf.ecore.EObject import org.eclipse.emf.ecore.resource.Resource -import org.eclipse.emf.ecore.resource.ResourceSet import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl import org.eclipse.emf.ecore.util.EcoreUtil -import tools.vitruv.change.atomic.EChangeIdManager -import tools.vitruv.change.atomic.id.Id -import tools.vitruv.change.atomic.id.IdResolver -import tools.vitruv.change.composite.description.VitruviusChange import tools.vitruv.change.composite.description.VitruviusChangeResolver import tools.vitruv.change.composite.recording.ChangeRecorder import tools.vitruv.framework.views.util.ResourceCopier @@ -25,8 +19,6 @@ import tools.vitruv.framework.views.util.ResourceCopier import static com.google.common.base.Preconditions.checkArgument import static extension edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceUtil.getReferencedProxies -import static extension tools.vitruv.change.atomic.resolve.EChangeIdResolverAndApplicator.applyBackward -import static extension tools.vitruv.change.atomic.resolve.EChangeIdResolverAndApplicator.applyForward /** * This default strategy for diff based state changes uses EMFCompare to resolve a @@ -102,21 +94,10 @@ class DefaultStateBasedChangeResolutionStrategy implements StateBasedChangeResol changeRecorder.addToRecording(resource) function.apply() val recordedChanges = changeRecorder.endRecording - return assignIds(recordedChanges, resource.resourceSet) + val changeResolver = VitruviusChangeResolver.forHierarchicalIds(resource.resourceSet) + return changeResolver.assignIds(recordedChanges) } } - - private def VitruviusChange assignIds(VitruviusChange recordedChange, ResourceSet resourceSet) { - val changes = recordedChange.EChanges - val idResolver = IdResolver.create(resourceSet) - val eChangeIdManager = new EChangeIdManager(idResolver) - changes.toList.reverseView.forEach[applyBackward] - changes.forEach[ change | - eChangeIdManager.setOrGenerateIds(change) - change.applyForward(idResolver) - ] - return VitruviusChangeResolver.unresolve(recordedChange, idResolver) - } /** * Compares states using EMFCompare and replays the changes to the current state. diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/StateBasedChangeResolutionStrategy.java b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/StateBasedChangeResolutionStrategy.java index 2276960345..c3459e7539 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/StateBasedChangeResolutionStrategy.java +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/StateBasedChangeResolutionStrategy.java @@ -2,7 +2,7 @@ import org.eclipse.emf.ecore.resource.Resource; -import tools.vitruv.change.atomic.id.Id; +import tools.vitruv.change.atomic.id.HierarchicalId; import tools.vitruv.change.composite.description.VitruviusChange; /** @@ -25,7 +25,7 @@ public interface StateBasedChangeResolutionStrategy { * @return a unresolved {@link VitruviusChange} that contains the individual * change sequence. */ - VitruviusChange getChangeSequenceBetween(Resource newState, Resource oldState); + VitruviusChange getChangeSequenceBetween(Resource newState, Resource oldState); /** * Resolves the state-based delta for creating the given resource and returns @@ -37,7 +37,7 @@ public interface StateBasedChangeResolutionStrategy { * @return a unresolved {@link VitruviusChange} that contains the individual * change sequence. */ - VitruviusChange getChangeSequenceForCreated(Resource newState); + VitruviusChange getChangeSequenceForCreated(Resource newState); /** * Resolves the state-based delta for deleting the given resource and returns @@ -50,5 +50,5 @@ public interface StateBasedChangeResolutionStrategy { * @return a unresolved {@link VitruviusChange} that contains the individual * change sequence. */ - VitruviusChange getChangeSequenceForDeleted(Resource oldState); + VitruviusChange getChangeSequenceForDeleted(Resource oldState); } diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeDerivingView.xtend b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeDerivingView.xtend index d6d798c81a..e4d66545ea 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeDerivingView.xtend +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeDerivingView.xtend @@ -7,7 +7,7 @@ import org.eclipse.emf.ecore.resource.Resource import org.eclipse.emf.ecore.resource.ResourceSet import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl import org.eclipse.xtend.lib.annotations.Delegate -import tools.vitruv.change.atomic.id.Id +import tools.vitruv.change.atomic.id.HierarchicalId import tools.vitruv.change.composite.description.VitruviusChange import tools.vitruv.change.composite.description.VitruviusChangeFactory import tools.vitruv.framework.views.CommittableView @@ -76,7 +76,7 @@ class ChangeDerivingView implements ModifiableView, CommittableView { view.close } - private def VitruviusChange generateChange(Resource newState, Resource referenceState) { + private def VitruviusChange generateChange(Resource newState, Resource referenceState) { if (referenceState === null) { return changeResolutionStrategy.getChangeSequenceForCreated(newState) } else if (newState === null) { diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeRecordingView.xtend b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeRecordingView.xtend index db870b0332..7187b96da5 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeRecordingView.xtend +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeRecordingView.xtend @@ -1,10 +1,6 @@ package tools.vitruv.framework.views.impl -import org.eclipse.emf.ecore.EObject import org.eclipse.xtend.lib.annotations.Delegate -import tools.vitruv.change.atomic.EChangeIdManager -import tools.vitruv.change.atomic.id.IdResolver -import tools.vitruv.change.composite.description.VitruviusChange import tools.vitruv.change.composite.description.VitruviusChangeResolver import tools.vitruv.change.composite.recording.ChangeRecorder import tools.vitruv.framework.views.CommittableView @@ -14,9 +10,6 @@ import tools.vitruv.framework.views.changederivation.StateBasedChangeResolutionS import static com.google.common.base.Preconditions.checkArgument import static com.google.common.base.Preconditions.checkState -import static extension tools.vitruv.change.atomic.resolve.EChangeIdResolverAndApplicator.applyBackward -import static extension tools.vitruv.change.atomic.resolve.EChangeIdResolverAndApplicator.applyForward - /** * A {@link View} that records changes to its resources and allows to propagate them * back to the underlying models using the {@link #commitChanges} method. @@ -44,22 +37,12 @@ class ChangeRecordingView implements ModifiableView, CommittableView { changeRecorder.addToRecording(view.viewResourceSet) changeRecorder.beginRecording() } - def private assignIds(VitruviusChange recordedChange) { - val changes = recordedChange.EChanges - val idResolver = IdResolver.create(view.viewResourceSet) - val idManager = new EChangeIdManager(idResolver) - changes.toList.reverseView.forEach[applyBackward] - changes.forEach[ - idManager.setOrGenerateIds(it) - it.applyForward(idResolver) - ] - return VitruviusChangeResolver.unresolve(recordedChange, idResolver) - } override commitChanges() { view.checkNotClosed() val recordedChange = changeRecorder.endRecording() - val unresolvedChanges = assignIds(recordedChange) + val changeResolver = VitruviusChangeResolver.forHierarchicalIds(view.viewResourceSet) + val unresolvedChanges = changeResolver.assignIds(recordedChange) view.viewType.commitViewChanges(this, unresolvedChanges) view.viewChanged = false changeRecorder.beginRecording() diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java index 681d17dd87..b820d4bc42 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java @@ -14,9 +14,7 @@ import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; -import tools.vitruv.change.atomic.EChangeUuidManager; -import tools.vitruv.change.atomic.id.Id; -import tools.vitruv.change.atomic.id.IdResolver; +import tools.vitruv.change.atomic.id.HierarchicalId; import tools.vitruv.change.atomic.uuid.Uuid; import tools.vitruv.change.atomic.uuid.UuidResolver; import tools.vitruv.change.composite.description.VitruviusChange; @@ -67,16 +65,16 @@ public void updateView(ModifiableView view) { } @Override - public void commitViewChanges(ModifiableView view, VitruviusChange viewChange) { + public void commitViewChanges(ModifiableView view, VitruviusChange viewChange) { ResourceSet viewSourceCopyResourceSet = withGlobalFactories(new ResourceSetImpl()); - IdResolver viewSourceCopyIdResolver = IdResolver.create(viewSourceCopyResourceSet); + VitruviusChangeResolver idChangeResolver = VitruviusChangeResolver.forHierarchicalIds(viewSourceCopyResourceSet); UuidResolver viewSourceCopyUuidResolver = UuidResolver.create(viewSourceCopyResourceSet); + VitruviusChangeResolver uuidChangeResolver = VitruviusChangeResolver.forUuids(viewSourceCopyUuidResolver); Map mapping = createViewResources(view, viewSourceCopyResourceSet); view.getViewSource().getUuidResolver().resolveResources(mapping, viewSourceCopyUuidResolver); - VitruviusChange resolvedChange = VitruviusChangeResolver.resolveAndApply(viewChange, viewSourceCopyIdResolver); - EChangeUuidManager.setOrGenerateIds(resolvedChange.getEChanges(), viewSourceCopyUuidResolver); - VitruviusChange unresolvedChanges = VitruviusChangeResolver.unresolve(resolvedChange, viewSourceCopyUuidResolver); + VitruviusChange resolvedChange = idChangeResolver.resolveAndApply(viewChange); + VitruviusChange unresolvedChanges = uuidChangeResolver.assignIds(resolvedChange); view.getViewSource().propagateChange(unresolvedChanges); } diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java index 48efba3229..45d3de5cfc 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java @@ -1,6 +1,6 @@ package tools.vitruv.framework.views.impl; -import tools.vitruv.change.atomic.id.Id; +import tools.vitruv.change.atomic.id.HierarchicalId; import tools.vitruv.change.composite.description.VitruviusChange; import tools.vitruv.framework.views.ChangeableViewSource; import tools.vitruv.framework.views.ViewSelector; @@ -42,5 +42,5 @@ public interface ViewCreatingViewType extends ViewType viewChange); + void commitViewChanges(ModifiableView view, VitruviusChange viewChange); } diff --git a/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ResourceRepositoryImpl.java b/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ResourceRepositoryImpl.java index 446cb6c801..302ed0bf8d 100644 --- a/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ResourceRepositoryImpl.java +++ b/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ResourceRepositoryImpl.java @@ -22,7 +22,6 @@ import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; -import tools.vitruv.change.atomic.EChangeUuidManager; import tools.vitruv.change.atomic.uuid.Uuid; import tools.vitruv.change.atomic.uuid.UuidResolver; import tools.vitruv.change.composite.description.TransactionalChange; @@ -44,6 +43,7 @@ class ResourceRepositoryImpl implements ModelRepository { private final PersistableCorrespondenceModel correspondenceModel; private final UuidResolver uuidResolver = UuidResolver.create(modelsResourceSet); private final ChangeRecorder changeRecorder = new ChangeRecorder(modelsResourceSet); + private final VitruviusChangeResolver changeResolver = VitruviusChangeResolver.forUuids(uuidResolver); private final VsumFileSystemLayout fileSystemLayout; @@ -181,13 +181,13 @@ public Iterable> recordChanges(Runnable changeAppli isRecording = false; changeRecorder.endRecording(); TransactionalChange change = changeRecorder.getChange(); - EChangeUuidManager.setOrGenerateIds(change.getEChanges(), uuidResolver); + changeResolver.assignIds(change); return change.containsConcreteChange() ? List.of(change) : List.of(); } @Override public VitruviusChange applyChange(VitruviusChange change) { - return VitruviusChangeResolver.resolveAndApply(change, uuidResolver); + return changeResolver.resolveAndApply(change); } @Override diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/BasicStateChangePropagationTest.xtend b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/BasicStateChangePropagationTest.xtend index 5ea63ffe26..3175d61706 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/BasicStateChangePropagationTest.xtend +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/BasicStateChangePropagationTest.xtend @@ -9,7 +9,6 @@ import org.junit.jupiter.params.provider.MethodSource import tools.vitruv.change.atomic.eobject.CreateEObject import tools.vitruv.change.atomic.eobject.DeleteEObject import tools.vitruv.change.atomic.feature.attribute.ReplaceSingleValuedEAttribute -import tools.vitruv.change.atomic.id.IdResolver import tools.vitruv.change.atomic.root.InsertRootEObject import tools.vitruv.change.atomic.root.RemoveRootEObject import tools.vitruv.change.composite.description.VitruviusChangeResolver @@ -48,7 +47,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { // Create empty resource to apply generated changes to val validationResourceSet = new ResourceSetImpl() - VitruviusChangeResolver.resolveAndApply(changes, IdResolver.create(validationResourceSet)) + VitruviusChangeResolver.forHierarchicalIds(validationResourceSet).resolveAndApply(changes) modelResource.save(null) assertEquals(1, validationResourceSet.resources.size) @@ -76,7 +75,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { // Load resource to apply generated changes to val validationResourceSet = new ResourceSetImpl() validationResourceSet.getResource(testUri, true) - VitruviusChangeResolver.resolveAndApply(changes, IdResolver.create(validationResourceSet)) + VitruviusChangeResolver.forHierarchicalIds(validationResourceSet).resolveAndApply(changes) assertEquals(1, validationResourceSet.resources.size) assertTrue(validationResourceSet.resources.get(0).contents.empty) @@ -107,7 +106,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { val oldState = validationResourceSet.getResource(testUri, true) val changes = strategyToTest.getChangeSequenceBetween(-modelResource, oldState) - VitruviusChangeResolver.resolveAndApply(changes, IdResolver.create(validationResourceSet)) + VitruviusChangeResolver.forHierarchicalIds(validationResourceSet).resolveAndApply(changes) assertEquals(1, validationResourceSet.resources.size) assertThat(validationResourceSet.resources.get(0), containsModelOf(-modelResource)) @@ -138,7 +137,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { assertEquals(1, changes.EChanges.size) assertEquals(1, changes.EChanges.filter(ReplaceSingleValuedEAttribute).size) - VitruviusChangeResolver.resolveAndApply(changes, IdResolver.create(validationResourceSet)) + VitruviusChangeResolver.forHierarchicalIds(validationResourceSet).resolveAndApply(changes) assertEquals(1, validationResourceSet.resources.size) assertThat(validationResourceSet.resources.get(0), containsModelOf(-modelResource)) @@ -166,19 +165,19 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { val validationResourceSet = new ResourceSetImpl().withGlobalFactories() val oldState = validationResourceSet.getResource(testUri, true) val unresolvedChanges = strategyToTest.getChangeSequenceBetween(-modelResource, oldState) - val changes = VitruviusChangeResolver.resolveAndApply(unresolvedChanges, IdResolver.create(validationResourceSet)) + val changes = VitruviusChangeResolver.forHierarchicalIds(validationResourceSet).resolveAndApply(unresolvedChanges) switch (strategyToTest.useIdentifiers) { case ONLY, case WHEN_AVAILABLE: { val Iterable> deleteChanges = newArrayList(changes.EChanges.filter(DeleteEObject)) assertEquals(1, deleteChanges.size) - assertThat(deleteChanges.head.affectedEObject, instanceOf(Root)) - assertEquals("Root", (deleteChanges.head.affectedEObject as Root).id) + assertThat(deleteChanges.head.affectedElement, instanceOf(Root)) + assertEquals("Root", (deleteChanges.head.affectedElement as Root).id) val Iterable> createChanges = newArrayList(changes.EChanges.filter(CreateEObject)) assertEquals(1, createChanges.size) - assertThat(createChanges.head.affectedEObject, instanceOf(Root)) - assertEquals("Root2", (createChanges.head.affectedEObject as Root).id) + assertThat(createChanges.head.affectedElement, instanceOf(Root)) + assertEquals("Root2", (createChanges.head.affectedElement as Root).id) } case NEVER: { assertEquals(1, changes.EChanges.size) @@ -220,7 +219,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { assertEquals(1, changes.EChanges.size) assertEquals(1, changes.EChanges.filter(ReplaceSingleValuedEAttribute).size) - VitruviusChangeResolver.resolveAndApply(changes, IdResolver.create(validationResourceSet)) + VitruviusChangeResolver.forHierarchicalIds(validationResourceSet).resolveAndApply(changes) assertEquals(1, validationResourceSet.resources.size) assertThat(validationResourceSet.resources.get(0), containsModelOf(-modelResource)) @@ -253,19 +252,19 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { val validationResourceSet = new ResourceSetImpl().withGlobalFactories() val oldState = validationResourceSet.getResource(testUri, true) val unresolvedChanges = strategyToTest.getChangeSequenceBetween(-modelResource, oldState) - val changes = VitruviusChangeResolver.resolveAndApply(unresolvedChanges, IdResolver.create(validationResourceSet)) + val changes = VitruviusChangeResolver.forHierarchicalIds(validationResourceSet).resolveAndApply(unresolvedChanges) switch (strategyToTest.useIdentifiers) { case ONLY, case WHEN_AVAILABLE: { val Iterable> deleteChanges = newArrayList(changes.EChanges.filter(DeleteEObject)) assertEquals(1, deleteChanges.size) - assertThat(deleteChanges.head.affectedEObject, instanceOf(Root)) - assertEquals("ContainedRoot", (deleteChanges.head.affectedEObject as Root).id) + assertThat(deleteChanges.head.affectedElement, instanceOf(Root)) + assertEquals("ContainedRoot", (deleteChanges.head.affectedElement as Root).id) val Iterable> createChanges = newArrayList(changes.EChanges.filter(CreateEObject)) assertEquals(1, createChanges.size) - assertThat(createChanges.head.affectedEObject, instanceOf(Root)) - assertEquals("ContainedRoot2", (createChanges.head.affectedEObject as Root).id) + assertThat(createChanges.head.affectedElement, instanceOf(Root)) + assertEquals("ContainedRoot2", (createChanges.head.affectedElement as Root).id) } case NEVER: { assertEquals(1, changes.EChanges.size) @@ -307,7 +306,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { assertEquals(1, changes.EChanges.filter(RemoveRootEObject).size) assertEquals(1, changes.EChanges.filter(InsertRootEObject).size) - VitruviusChangeResolver.resolveAndApply(changes, IdResolver.create(validationResourceSet)) + VitruviusChangeResolver.forHierarchicalIds(validationResourceSet).resolveAndApply(changes) (-modelResource).save(null) assertEquals(2, validationResourceSet.resources.size) @@ -347,7 +346,7 @@ class BasicStateChangePropagationTest extends StateChangePropagationTest { assertEquals(1, changes.EChanges.filter(InsertRootEObject).size) assertEquals(1, changes.EChanges.filter(ReplaceSingleValuedEAttribute).size) - VitruviusChangeResolver.resolveAndApply(changes, IdResolver.create(validationResourceSet)) + VitruviusChangeResolver.forHierarchicalIds(validationResourceSet).resolveAndApply(changes) (-modelResource).save(null) assertEquals(2, validationResourceSet.resources.size) diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/StateChangePropagationTest.xtend b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/StateChangePropagationTest.xtend index a524cb5e47..a30d64e748 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/StateChangePropagationTest.xtend +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/StateChangePropagationTest.xtend @@ -16,7 +16,6 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Named import org.junit.jupiter.api.^extension.ExtendWith import pcm_mockup.Repository -import tools.vitruv.change.atomic.id.IdResolver import tools.vitruv.change.composite.description.VitruviusChange import tools.vitruv.change.composite.description.VitruviusChangeResolver import tools.vitruv.change.composite.recording.ChangeRecorder @@ -102,7 +101,7 @@ abstract class StateChangePropagationTest { val deltaBasedChange = resourceSet.endRecording val unresolvedStateBasedChange = strategyToTest.getChangeSequenceBetween(model, checkpoint) assertNotNull(unresolvedStateBasedChange) - val stateBasedChange = VitruviusChangeResolver.resolveAndApply(unresolvedStateBasedChange, IdResolver.create(checkpoint.resourceSet)) + val stateBasedChange = VitruviusChangeResolver.forHierarchicalIds(checkpoint.resourceSet).resolveAndApply(unresolvedStateBasedChange) val message = getTextualRepresentation(stateBasedChange, deltaBasedChange) val stateBasedChangedObjects = stateBasedChange.affectedAndReferencedEObjects val deltaBasedChangedObjects = deltaBasedChange.affectedAndReferencedEObjects diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java index 3e1866bf62..13b26a4fbf 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java @@ -24,16 +24,13 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; -import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import allElementTypes.NonRoot; import allElementTypes.Root; -import tools.vitruv.change.atomic.eobject.EobjectPackage; import tools.vitruv.change.atomic.feature.attribute.ReplaceSingleValuedEAttribute; -import tools.vitruv.change.atomic.id.Id; -import tools.vitruv.change.atomic.id.IdResolver; +import tools.vitruv.change.atomic.id.HierarchicalId; import tools.vitruv.change.atomic.root.InsertRootEObject; import tools.vitruv.change.atomic.root.RootFactory; import tools.vitruv.change.atomic.root.RootPackage; @@ -210,19 +207,18 @@ public void commitChanges() throws Exception { view.registerRoot(root, URI.createURI(testResourceUriString)); assertThat(view.getRootObjects(), hasItem(root)); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeDerivingView.class); - ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChanges(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); - VitruviusChange change = VitruviusChangeResolver.resolveAndApply(changeArgument.getValue(), IdResolver.create(root.eResource().getResourceSet())); + VitruviusChange change = VitruviusChangeResolver.forHierarchicalIds(root.eResource().getResourceSet()).resolveAndApply(changeArgument.getValue()); InsertRootEObject expectedChange = RootFactory.eINSTANCE.createInsertRootEObject(); expectedChange.setNewValue(root); expectedChange.setUri(testResourceUriString); assertThat(change.getEChanges().size(), is(3)); // Create, Insert, ReplaceId assertThat(change.getEChanges().get(1), equalsDeeply(expectedChange, - ignoringFeatures(EobjectPackage.eINSTANCE.getEObjectAddedEChange_NewValueID(), - RootPackage.eINSTANCE.getRootEChange_Resource()))); + ignoringFeatures(RootPackage.eINSTANCE.getRootEChange_Resource()))); assertThat(change.getEChanges().get(2), instanceOf(ReplaceSingleValuedEAttribute.class)); } } @@ -288,7 +284,7 @@ public void commitChanges() throws Exception { view.moveRoot(root, URI.createURI(movedResourceUriString)); assertThat(view.getRootObjects(), hasItem(root)); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeDerivingView.class); - ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChangesAndUpdate(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); @@ -328,7 +324,7 @@ public void once() { nonRoot.setId("nonRoot"); root.setSingleValuedContainmentEReference(nonRoot); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeDerivingView.class); - ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChangesAndUpdate(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); @@ -351,7 +347,7 @@ public void twice() { secondNonRoot.setId("second"); root.setSingleValuedContainmentEReference(secondNonRoot); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeDerivingView.class); - ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChangesAndUpdate(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); @@ -366,7 +362,7 @@ public void twice() { @DisplayName("without changes") public void withoutChanges() { ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeDerivingView.class); - ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); view.commitChangesAndUpdate(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java index 2405ea7d70..8db0bf278c 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java @@ -36,14 +36,11 @@ import tools.vitruv.change.atomic.EChange; import tools.vitruv.change.atomic.eobject.CreateEObject; import tools.vitruv.change.atomic.eobject.DeleteEObject; -import tools.vitruv.change.atomic.eobject.EobjectPackage; -import tools.vitruv.change.atomic.feature.FeaturePackage; import tools.vitruv.change.atomic.feature.attribute.AttributeFactory; import tools.vitruv.change.atomic.feature.attribute.AttributePackage; import tools.vitruv.change.atomic.feature.attribute.ReplaceSingleValuedEAttribute; import tools.vitruv.change.atomic.feature.reference.ReplaceSingleValuedEReference; -import tools.vitruv.change.atomic.id.Id; -import tools.vitruv.change.atomic.id.IdResolver; +import tools.vitruv.change.atomic.id.HierarchicalId; import tools.vitruv.change.atomic.root.InsertRootEObject; import tools.vitruv.change.atomic.root.RootFactory; import tools.vitruv.change.atomic.root.RootPackage; @@ -212,22 +209,21 @@ public void commitChanges() throws Exception { view.registerRoot(root, URI.createURI(testResourceUriString)); assertThat(view.getRootObjects(), hasItem(root)); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeRecordingView.class); - ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor + .forClass(VitruviusChange.class); view.commitChanges(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); ResourceSet resolveInResourceSet = new ResourceSetImpl(); VitruviusChange resolvedChange = VitruviusChangeResolver - .resolveAndApply(changeArgument.getValue(), IdResolver.create(resolveInResourceSet)); + .forHierarchicalIds(resolveInResourceSet).resolveAndApply(changeArgument.getValue()); InsertRootEObject expectedChange = RootFactory.eINSTANCE.createInsertRootEObject(); expectedChange.setNewValue(root); expectedChange.setUri(testResourceUriString); assertThat(resolvedChange.getEChanges().size(), is(3)); // Create, Insert, ReplaceId - assertThat(resolvedChange.getEChanges().get(1), - equalsDeeply(expectedChange, - ignoringFeatures(EobjectPackage.eINSTANCE.getEObjectAddedEChange_NewValueID(), - RootPackage.eINSTANCE.getRootEChange_Resource()))); + assertThat(resolvedChange.getEChanges().get(1), equalsDeeply(expectedChange, + ignoringFeatures(RootPackage.eINSTANCE.getRootEChange_Resource()))); assertThat(resolvedChange.getEChanges().get(2), instanceOf(ReplaceSingleValuedEAttribute.class)); } } @@ -299,21 +295,20 @@ public void commitChanges() throws Exception { view.moveRoot(root, URI.createURI(movedResourceUriString)); assertThat(view.getRootObjects(), hasItem(root)); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeRecordingView.class); - ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor + .forClass(VitruviusChange.class); view.commitChanges(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); VitruviusChange resolvedChange = VitruviusChangeResolver - .resolveAndApply(changeArgument.getValue(), IdResolver.create(resolveInResourceSet)); - List capturedEChanges = resolvedChange.getEChanges(); + .forHierarchicalIds(resolveInResourceSet).resolveAndApply(changeArgument.getValue()); + List> capturedEChanges = resolvedChange.getEChanges(); InsertRootEObject expectedChange = RootFactory.eINSTANCE.createInsertRootEObject(); expectedChange.setNewValue(root); expectedChange.setUri(movedResourceUriString); assertThat(capturedEChanges.size(), is(2)); // Remove, Insert - assertThat(capturedEChanges.get(1), - equalsDeeply(expectedChange, - ignoringFeatures(EobjectPackage.eINSTANCE.getEObjectAddedEChange_NewValueID(), - RootPackage.eINSTANCE.getRootEChange_Resource()))); + assertThat(capturedEChanges.get(1), equalsDeeply(expectedChange, + ignoringFeatures(RootPackage.eINSTANCE.getRootEChange_Resource()))); } } } @@ -345,11 +340,12 @@ public void once() { nonRoot.setId("nonRoot"); root.setSingleValuedContainmentEReference(nonRoot); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeRecordingView.class); - ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor + .forClass(VitruviusChange.class); view.commitChanges(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); - List capturedEChanges = changeArgument.getValue().getEChanges(); + List> capturedEChanges = changeArgument.getValue().getEChanges(); assertThat(capturedEChanges.size(), is(3)); // Create, Insert, ReplaceId assertThat(capturedEChanges.get(0), instanceOf(CreateEObject.class)); assertThat(capturedEChanges.get(1), instanceOf(ReplaceSingleValuedEReference.class)); @@ -373,25 +369,24 @@ public void twice() { secondNonRoot.setId("second"); root.setSingleValuedContainmentEReference(secondNonRoot); ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeRecordingView.class); - ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor + .forClass(VitruviusChange.class); view.commitChanges(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); - VitruviusChange resolvedChange = VitruviusChangeResolver.resolveAndApply(changeArgument.getValue(), - IdResolver.create(resolveInResourceSet)); - List capturedEChanges = resolvedChange.getEChanges(); + VitruviusChange resolvedChange = VitruviusChangeResolver.forHierarchicalIds(resolveInResourceSet) + .resolveAndApply(changeArgument.getValue()); + List> capturedEChanges = resolvedChange.getEChanges(); assertThat(capturedEChanges.size(), is(4)); // Create, Insert, ReplaceValue, Delete assertThat(capturedEChanges.get(0), instanceOf(CreateEObject.class)); assertThat(capturedEChanges.get(1), instanceOf(ReplaceSingleValuedEReference.class)); ReplaceSingleValuedEAttribute replaceIdChange = AttributeFactory.eINSTANCE .createReplaceSingleValuedEAttribute(); - replaceIdChange.setAffectedEObject(secondNonRoot); + replaceIdChange.setAffectedElement(secondNonRoot); replaceIdChange.setAffectedFeature(AllElementTypesPackage.eINSTANCE.getIdentified_Id()); replaceIdChange.setNewValue("second"); - assertThat(capturedEChanges.get(2), - equalsDeeply(replaceIdChange, - ignoringFeatures(AttributePackage.eINSTANCE.getSubtractiveAttributeEChange_OldValue(), - FeaturePackage.eINSTANCE.getFeatureEChange_AffectedEObjectID()))); + assertThat(capturedEChanges.get(2), equalsDeeply(replaceIdChange, + ignoringFeatures(AttributePackage.eINSTANCE.getSubtractiveAttributeEChange_OldValue()))); assertThat(capturedEChanges.get(3), instanceOf(DeleteEObject.class)); } @@ -399,7 +394,8 @@ public void twice() { @DisplayName("without changes") public void withoutChanges() { ArgumentCaptor viewArgument = ArgumentCaptor.forClass(ChangeRecordingView.class); - ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); + ArgumentCaptor> changeArgument = ArgumentCaptor + .forClass(VitruviusChange.class); view.commitChanges(); verify(mockViewType).commitViewChanges(viewArgument.capture(), changeArgument.capture()); assertThat(viewArgument.getValue(), is(view)); diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java index 0fc4ecd376..4fe8d2659c 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java @@ -15,8 +15,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static tools.vitruv.change.atomic.resolve.EChangeIdResolverAndApplicator.applyBackward; -import static tools.vitruv.change.atomic.resolve.EChangeIdResolverAndApplicator.applyForward; import static tools.vitruv.testutils.matchers.ModelMatchers.equalsDeeply; import static tools.vitruv.testutils.metamodels.AllElementTypesCreators.aet; @@ -43,10 +41,8 @@ import allElementTypes.Root; import tools.vitruv.change.atomic.EChange; -import tools.vitruv.change.atomic.EChangeIdManager; import tools.vitruv.change.atomic.feature.attribute.ReplaceSingleValuedEAttribute; -import tools.vitruv.change.atomic.id.Id; -import tools.vitruv.change.atomic.id.IdResolver; +import tools.vitruv.change.atomic.id.HierarchicalId; import tools.vitruv.change.atomic.uuid.Uuid; import tools.vitruv.change.atomic.uuid.UuidResolver; import tools.vitruv.change.composite.description.VitruviusChange; @@ -363,7 +359,7 @@ public void removingUnselectedRoot() throws Exception { } } } - + @Nested @DisplayName("commit view changes") class CommitViewChanges { @@ -390,51 +386,49 @@ void initializeViewTypeAndResourceSetAndViewSource() { when(viewSource.getUuidResolver()).thenReturn(uuidResolver); when(viewSelection.isViewObjectSelected(any(EObject.class))).thenReturn(true); } - + private Root createResourceWithSingleRoot(URI uri) { Resource resource = viewSourceResourceSet.createResource(uri); Root rootElement = aet.Root(); uuidResolver.registerEObject(rootElement); rootElement.setId("testid"); resource.getContents().add(rootElement); - + Resource viewResource = viewResourceSet.createResource(uri); Root viewRootElement = EcoreUtil.copy(rootElement); viewResource.getContents().add(viewRootElement); return viewRootElement; } - + @Test @DisplayName("with null changes") void withNull() { assertThrows(NullPointerException.class, () -> basicViewType.commitViewChanges(view, null)); } - + @Test @DisplayName("with null view") void withNullView() { - VitruviusChange someChange = VitruviusChangeFactory.getInstance().createTransactionalChange(Set.of()); + VitruviusChange someChange = VitruviusChangeFactory.getInstance() + .createTransactionalChange(Set.of()); assertThrows(NullPointerException.class, () -> basicViewType.commitViewChanges(null, someChange)); } - + @ParameterizedTest @MethodSource("testEmptyChanges") @DisplayName("with empty changes") - void withEmptyChanges(VitruviusChange change) { + void withEmptyChanges(VitruviusChange change) { ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); basicViewType.commitViewChanges(view, change); verify(viewSource).propagateChange(changeArgument.capture()); assertEquals(changeArgument.getValue(), change); } - - private static Stream> testEmptyChanges() { + + private static Stream> testEmptyChanges() { VitruviusChangeFactory factory = VitruviusChangeFactory.getInstance(); - return Stream.of( - factory.createTransactionalChange(Set.of()), - factory.createCompositeChange(Set.of()) - ); + return Stream.of(factory.createTransactionalChange(Set.of()), factory.createCompositeChange(Set.of())); } - + @Test @DisplayName("with non-empty change") void withNonEmptyChange() { @@ -445,31 +439,24 @@ void withNonEmptyChange() { root.setId("testid2"); changeRecorder.endRecording(); VitruviusChange change = changeRecorder.getChange(); - VitruviusChange idAssignedChange = assignIds(change); - + VitruviusChange idAssignedChange = assignIds(change); + ArgumentCaptor> changeArgument = ArgumentCaptor.forClass(VitruviusChange.class); basicViewType.commitViewChanges(view, idAssignedChange); verify(viewSource).propagateChange(changeArgument.capture()); - List eChanges = changeArgument.getValue().getEChanges(); + List> eChanges = changeArgument.getValue().getEChanges(); assertThat(eChanges.size(), is(1)); assertThat(eChanges.get(0), instanceOf(ReplaceSingleValuedEAttribute.class)); - var attributeChange = (ReplaceSingleValuedEAttribute)eChanges.get(0); + var attributeChange = (ReplaceSingleValuedEAttribute) eChanges.get(0); assertThat(attributeChange.getOldValue(), is("testid")); assertThat(attributeChange.getNewValue(), is("testid2")); } } - - private VitruviusChange assignIds(VitruviusChange change) { - IdResolver idResolver = IdResolver.create(viewResourceSet); - EChangeIdManager idManager = new EChangeIdManager(idResolver); - for (int i = change.getEChanges().size() - 1; i >= 0; i--) { - applyBackward(change.getEChanges().get(i)); - } - change.getEChanges().forEach(eChange -> { - idManager.setOrGenerateIds(eChange); - applyForward(eChange, idResolver); - }); - return VitruviusChangeResolver.unresolve(change, idResolver); + + private VitruviusChange assignIds(VitruviusChange change) { + VitruviusChangeResolver idChangeResolver = VitruviusChangeResolver + .forHierarchicalIds(viewResourceSet); + return idChangeResolver.assignIds(change); } } } diff --git a/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTest.xtend b/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTest.xtend index cd2dbaf6f2..a90f4b059b 100644 --- a/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTest.xtend +++ b/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTest.xtend @@ -9,7 +9,6 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test import org.junit.jupiter.api.^extension.ExtendWith -import tools.vitruv.change.atomic.EChangeUuidManager import tools.vitruv.change.atomic.eobject.CreateEObject import tools.vitruv.change.atomic.feature.attribute.ReplaceSingleValuedEAttribute import tools.vitruv.change.atomic.feature.reference.ReplaceSingleValuedEReference @@ -373,8 +372,8 @@ class VirtualModelTest { private def endRecording(ChangeRecorder changeRecorder, UuidResolver uuidResolver) { val change = changeRecorder.endRecording - EChangeUuidManager.setOrGenerateIds(change.EChanges, uuidResolver) - return VitruviusChangeResolver.unresolve(change, uuidResolver) + val changeResolver = VitruviusChangeResolver.forUuids(uuidResolver) + return changeResolver.assignIds(change) } def private createAndPropagateRoot(VirtualModel virtualModel, ResourceSet resourceSet, UuidResolver uuidResolver, String rootId) { diff --git a/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTestUtil.xtend b/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTestUtil.xtend index baaf633270..6eb6031b19 100644 --- a/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTestUtil.xtend +++ b/tests/tools.vitruv.framework.vsum.tests/src/tools/vitruv/framework/vsum/VirtualModelTestUtil.xtend @@ -5,9 +5,9 @@ import allElementTypes.Root import edu.kit.ipd.sdq.activextendannotations.Utility import java.nio.file.Path import org.eclipse.emf.common.util.URI +import org.eclipse.emf.ecore.EObject import org.eclipse.emf.ecore.resource.ResourceSet import tools.vitruv.change.atomic.EChange -import tools.vitruv.change.atomic.EChangeUuidManager import tools.vitruv.change.atomic.root.InsertRootEObject import tools.vitruv.change.atomic.uuid.Uuid import tools.vitruv.change.atomic.uuid.UuidResolver @@ -35,13 +35,14 @@ class VirtualModelTestUtil { */ def static VitruviusChange recordChanges(ResourceSet resourceSet, UuidResolver uuidResolver, Runnable changesToPerform) { val recorder = new ChangeRecorder(resourceSet) + val changeResolver = VitruviusChangeResolver.forUuids(uuidResolver) recorder.addToRecording(resourceSet) recorder.beginRecording changesToPerform.run() val result = recorder.endRecording - EChangeUuidManager.setOrGenerateIds(result.EChanges, uuidResolver) + val resolvedChange = changeResolver.assignIds(result) recorder.close - return VitruviusChangeResolver.unresolve(result, uuidResolver) + return resolvedChange } /** @@ -88,20 +89,20 @@ class VirtualModelTestUtil { super(sourceMetamodelDescriptor, targetMetamodelDescriptor) } - override doesHandleChange(EChange change, EditableCorrespondenceModelView correspondenceModel) { + override doesHandleChange(EChange change, EditableCorrespondenceModelView correspondenceModel) { if(change instanceof InsertRootEObject) { return change.newValue instanceof Root } return false } - override propagateChange(EChange change, EditableCorrespondenceModelView correspondenceModel, + override propagateChange(EChange change, EditableCorrespondenceModelView correspondenceModel, extension ResourceAccess resourceAccess) { if(!doesHandleChange(change, correspondenceModel)) { return } - val typedChange = change as InsertRootEObject - val insertedRoot = typedChange.newValue + val typedChange = change as InsertRootEObject + val insertedRoot = typedChange.newValue as Root // If there is a corresponding element, reuse it, otherwise create one val correspondingRoots = correspondenceModel.getCorrespondingEObjects(insertedRoot).filter(Root) val correspondingRoot = if(correspondingRoots.size == 1) { From f4bbf353470c6c8e229b77a4e8919e6c03e61abd Mon Sep 17 00:00:00 2001 From: Jan Wittler Date: Tue, 4 Jul 2023 21:04:48 +0200 Subject: [PATCH 3/4] adapt to package name changes --- .../changederivation/StateBasedChangeResolutionStrategy.java | 2 +- .../tools/vitruv/framework/views/impl/ChangeDerivingView.xtend | 2 +- .../vitruv/framework/views/impl/IdentityMappingViewType.java | 2 +- .../tools/vitruv/framework/views/impl/ViewCreatingViewType.java | 2 +- .../tools/vitruv/testutils/LegacyVitruvApplicationTest.xtend | 2 +- .../vitruv/framework/views/impl/ChangeDerivingViewTest.java | 2 +- .../vitruv/framework/views/impl/ChangeRecordingViewTest.java | 2 +- .../framework/views/impl/IdentityMappingViewTypeTest.java | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/StateBasedChangeResolutionStrategy.java b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/StateBasedChangeResolutionStrategy.java index c3459e7539..fa5d130cd5 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/StateBasedChangeResolutionStrategy.java +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/StateBasedChangeResolutionStrategy.java @@ -2,7 +2,7 @@ import org.eclipse.emf.ecore.resource.Resource; -import tools.vitruv.change.atomic.id.HierarchicalId; +import tools.vitruv.change.atomic.hid.HierarchicalId; import tools.vitruv.change.composite.description.VitruviusChange; /** diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeDerivingView.xtend b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeDerivingView.xtend index e4d66545ea..133d816f5d 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeDerivingView.xtend +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ChangeDerivingView.xtend @@ -7,7 +7,7 @@ import org.eclipse.emf.ecore.resource.Resource import org.eclipse.emf.ecore.resource.ResourceSet import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl import org.eclipse.xtend.lib.annotations.Delegate -import tools.vitruv.change.atomic.id.HierarchicalId +import tools.vitruv.change.atomic.hid.HierarchicalId import tools.vitruv.change.composite.description.VitruviusChange import tools.vitruv.change.composite.description.VitruviusChangeFactory import tools.vitruv.framework.views.CommittableView diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java index b820d4bc42..83bd71a79a 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java @@ -14,7 +14,7 @@ import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; -import tools.vitruv.change.atomic.id.HierarchicalId; +import tools.vitruv.change.atomic.hid.HierarchicalId; import tools.vitruv.change.atomic.uuid.Uuid; import tools.vitruv.change.atomic.uuid.UuidResolver; import tools.vitruv.change.composite.description.VitruviusChange; diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java index 45d3de5cfc..109cea5e94 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java @@ -1,6 +1,6 @@ package tools.vitruv.framework.views.impl; -import tools.vitruv.change.atomic.id.HierarchicalId; +import tools.vitruv.change.atomic.hid.HierarchicalId; import tools.vitruv.change.composite.description.VitruviusChange; import tools.vitruv.framework.views.ChangeableViewSource; import tools.vitruv.framework.views.ViewSelector; diff --git a/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/LegacyVitruvApplicationTest.xtend b/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/LegacyVitruvApplicationTest.xtend index a8eac4e23c..ef72804982 100644 --- a/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/LegacyVitruvApplicationTest.xtend +++ b/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/LegacyVitruvApplicationTest.xtend @@ -10,7 +10,7 @@ import tools.vitruv.testutils.views.TestView import static com.google.common.base.Preconditions.checkArgument -import static extension tools.vitruv.change.atomic.id.ObjectResolutionUtil.getHierarchicUriFragment +import static extension tools.vitruv.change.atomic.hid.ObjectResolutionUtil.getHierarchicUriFragment /** * DO NOT USE THIS CLASS! Use {@link VitruvApplicationTest} instead. diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java index 13b26a4fbf..fe9b75faae 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java @@ -30,7 +30,7 @@ import allElementTypes.NonRoot; import allElementTypes.Root; import tools.vitruv.change.atomic.feature.attribute.ReplaceSingleValuedEAttribute; -import tools.vitruv.change.atomic.id.HierarchicalId; +import tools.vitruv.change.atomic.hid.HierarchicalId; import tools.vitruv.change.atomic.root.InsertRootEObject; import tools.vitruv.change.atomic.root.RootFactory; import tools.vitruv.change.atomic.root.RootPackage; diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java index 8db0bf278c..033178dca3 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java @@ -40,7 +40,7 @@ import tools.vitruv.change.atomic.feature.attribute.AttributePackage; import tools.vitruv.change.atomic.feature.attribute.ReplaceSingleValuedEAttribute; import tools.vitruv.change.atomic.feature.reference.ReplaceSingleValuedEReference; -import tools.vitruv.change.atomic.id.HierarchicalId; +import tools.vitruv.change.atomic.hid.HierarchicalId; import tools.vitruv.change.atomic.root.InsertRootEObject; import tools.vitruv.change.atomic.root.RootFactory; import tools.vitruv.change.atomic.root.RootPackage; diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java index 4fe8d2659c..55cb741cae 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java @@ -42,7 +42,7 @@ import allElementTypes.Root; import tools.vitruv.change.atomic.EChange; import tools.vitruv.change.atomic.feature.attribute.ReplaceSingleValuedEAttribute; -import tools.vitruv.change.atomic.id.HierarchicalId; +import tools.vitruv.change.atomic.hid.HierarchicalId; import tools.vitruv.change.atomic.uuid.Uuid; import tools.vitruv.change.atomic.uuid.UuidResolver; import tools.vitruv.change.composite.description.VitruviusChange; From 9b88e9efc5319ce2fd406853f4e3581fffe11bbd Mon Sep 17 00:00:00 2001 From: Jan Wittler Date: Fri, 7 Jul 2023 23:34:58 +0200 Subject: [PATCH 4/4] allow arbitrary Id type in `ViewCreatingViewType` --- .../views/impl/AbstractViewType.xtend | 2 +- .../framework/views/impl/BasicView.xtend | 5 ++-- .../views/impl/IdentityMappingViewType.java | 8 ++--- .../views/impl/ViewCreatingViewType.java | 11 ++++--- .../selectors/DirectViewElementSelector.xtend | 6 ++-- .../framework/views/impl/BasicViewTest.java | 3 +- .../views/impl/ChangeDerivingViewTest.java | 2 +- .../views/impl/ChangeRecordingViewTest.java | 2 +- .../impl/IdentityMappingViewTypeTest.java | 30 ++++++++++--------- .../DirectViewElementSelectorTest.java | 23 +++++++------- 10 files changed, 49 insertions(+), 43 deletions(-) diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/AbstractViewType.xtend b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/AbstractViewType.xtend index 07e2e4cf92..7eea1879ff 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/AbstractViewType.xtend +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/AbstractViewType.xtend @@ -5,7 +5,7 @@ import tools.vitruv.framework.views.ViewSelector import static com.google.common.base.Preconditions.checkArgument -abstract package class AbstractViewType implements ViewCreatingViewType { +abstract package class AbstractViewType implements ViewCreatingViewType { @Accessors(PUBLIC_GETTER) val String name diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/BasicView.xtend b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/BasicView.xtend index 2d458473f0..65ac02e0ee 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/BasicView.xtend +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/BasicView.xtend @@ -9,6 +9,7 @@ import org.eclipse.emf.ecore.resource.Resource import org.eclipse.emf.ecore.resource.ResourceSet import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl import org.eclipse.xtend.lib.annotations.Accessors +import tools.vitruv.change.atomic.hid.HierarchicalId import tools.vitruv.change.atomic.uuid.Uuid import tools.vitruv.change.composite.description.PropagatedChange import tools.vitruv.change.composite.description.VitruviusChange @@ -27,7 +28,7 @@ package class BasicView implements ModifiableView, ChangePropagationListener { @Accessors(PUBLIC_GETTER, PROTECTED_SETTER) var ViewSelection selection @Accessors(PUBLIC_GETTER, PROTECTED_SETTER) - var ViewCreatingViewType viewType + var ViewCreatingViewType viewType @Accessors(PUBLIC_GETTER, PROTECTED_SETTER) var ChangeableViewSource viewSource @Accessors(PROTECTED_GETTER) @@ -37,7 +38,7 @@ package class BasicView implements ModifiableView, ChangePropagationListener { boolean viewChanged boolean closed - protected new(ViewCreatingViewType viewType, ChangeableViewSource viewSource, + protected new(ViewCreatingViewType viewType, ChangeableViewSource viewSource, ViewSelection selection) { checkArgument(viewType !== null, "view type must not be null") checkArgument(viewSource !== null, "view selection must not be null") diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java index 83bd71a79a..a2cb338847 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/IdentityMappingViewType.java @@ -31,14 +31,14 @@ * selection mechanism and providing a one-to-one (identity) mapping of elements * within the {@link ViewSource} to a created {@link View}. */ -public class IdentityMappingViewType extends AbstractViewType { +public class IdentityMappingViewType extends AbstractViewType, HierarchicalId> { public IdentityMappingViewType(String name) { super(name); } @Override - public DirectViewElementSelector createSelector(ChangeableViewSource viewSource) { - return new DirectViewElementSelector(this, viewSource, + public DirectViewElementSelector createSelector(ChangeableViewSource viewSource) { + return new DirectViewElementSelector<>(this, viewSource, viewSource.getViewSourceModels().stream().map(resource -> { if (!resource.getContents().isEmpty() && ResourceCopier.requiresFullCopy(resource)) { // Some resources (like UML) can only be copied as a whole, so no option to select @@ -50,7 +50,7 @@ public DirectViewElementSelector createSelector(ChangeableViewSource viewSource) } @Override - public ModifiableView createView(DirectViewElementSelector selector) { + public ModifiableView createView(DirectViewElementSelector selector) { checkArgument(selector.getViewType() == this, "cannot create view with selector for different view type"); return new BasicView(selector.getViewType(), selector.getViewSource(), selector.getSelection()); } diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java index 109cea5e94..b11791df43 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/impl/ViewCreatingViewType.java @@ -1,6 +1,5 @@ package tools.vitruv.framework.views.impl; -import tools.vitruv.change.atomic.hid.HierarchicalId; import tools.vitruv.change.composite.description.VitruviusChange; import tools.vitruv.framework.views.ChangeableViewSource; import tools.vitruv.framework.views.ViewSelector; @@ -10,9 +9,10 @@ * A specific view type that is able to create and update views. This is not its * public interface but only for internal usage by views and their selectors. * - * @param the type of view selector this view type uses + * @param the type of view selector this view type uses. + * @param the type of Id the changes to commit must have. */ -public interface ViewCreatingViewType extends ViewType { +public interface ViewCreatingViewType extends ViewType { /** * Creates a view for the given {@link ViewSelector}. The selector must have * been created by calling the {@link #createSelector} method of the same @@ -36,11 +36,10 @@ public interface ViewCreatingViewType extends ViewType viewChange); + void commitViewChanges(ModifiableView view, VitruviusChange viewChange); } diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/selectors/DirectViewElementSelector.xtend b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/selectors/DirectViewElementSelector.xtend index 10d296b48e..50add0b64f 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/selectors/DirectViewElementSelector.xtend +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/selectors/DirectViewElementSelector.xtend @@ -20,7 +20,7 @@ import static com.google.common.base.Preconditions.checkState * and view elements (such as selecting types but providing instances in the view), * but a selection is performed on the view elements themselves. */ -class DirectViewElementSelector implements ViewSelector { +class DirectViewElementSelector implements ViewSelector { @Delegate val ModifiableViewSelection viewSelection @@ -28,7 +28,7 @@ class DirectViewElementSelector implements ViewSelector { val ChangeableViewSource viewSource @Accessors(PUBLIC_GETTER) - val ViewCreatingViewType viewType + val ViewCreatingViewType, Id> viewType /** * Creates a new selector based on the given collection of selectable elements @@ -43,7 +43,7 @@ class DirectViewElementSelector implements ViewSelector { * @param selectableElements - the elements to select from to be used by the * {@link ViewType} when creating a view */ - new(ViewCreatingViewType viewType, ChangeableViewSource viewSource, + new(ViewCreatingViewType, Id> viewType, ChangeableViewSource viewSource, Collection selectableElements) { checkArgument(selectableElements !== null, "selectable elements must not be null") checkArgument(viewType !== null, "view type must not be null") diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/BasicViewTest.java b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/BasicViewTest.java index cda335aa31..97616f2b03 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/BasicViewTest.java +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/BasicViewTest.java @@ -21,6 +21,7 @@ import allElementTypes.NonRoot; import allElementTypes.Root; +import tools.vitruv.change.atomic.hid.HierarchicalId; import tools.vitruv.framework.views.ChangeableViewSource; import tools.vitruv.framework.views.ModifiableViewSelection; import tools.vitruv.testutils.RegisterMetamodelsInStandalone; @@ -29,7 +30,7 @@ @ExtendWith({ TestLogging.class, RegisterMetamodelsInStandalone.class }) public class BasicViewTest { @Mock - ViewCreatingViewType mockViewType; + ViewCreatingViewType mockViewType; @Mock ChangeableViewSource mockChangeableViewSource; @Mock diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java index fe9b75faae..6157548b81 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeDerivingViewTest.java @@ -45,7 +45,7 @@ @ExtendWith({ TestLogging.class, RegisterMetamodelsInStandalone.class }) public class ChangeDerivingViewTest { @Mock - ViewCreatingViewType mockViewType; + ViewCreatingViewType mockViewType; @Mock ChangeableViewSource mockChangeableViewSource; @Mock diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java index 033178dca3..c08fa2557a 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/ChangeRecordingViewTest.java @@ -54,7 +54,7 @@ @ExtendWith({ TestLogging.class, RegisterMetamodelsInStandalone.class }) public class ChangeRecordingViewTest { @Mock - ViewCreatingViewType mockViewType; + ViewCreatingViewType mockViewType; @Mock ChangeableViewSource mockChangeableViewSource; @Mock diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java index 55cb741cae..fd65a9f53a 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/impl/IdentityMappingViewTypeTest.java @@ -96,7 +96,8 @@ public void initializeViewType() { @Test @DisplayName("for empty source") public void forEmptySource() { - DirectViewElementSelector selector = basicViewType.createSelector(mock(ChangeableViewSource.class)); + DirectViewElementSelector selector = basicViewType + .createSelector(mock(ChangeableViewSource.class)); assertThat(selector.getSelectableElements(), is(emptySet())); } @@ -109,7 +110,7 @@ public void forSourceContainingElement() { resource.getContents().add(rootElement); ChangeableViewSource viewSource = mock(ChangeableViewSource.class); when(viewSource.getViewSourceModels()).thenReturn(Set.of(resource)); - DirectViewElementSelector selector = basicViewType.createSelector(viewSource); + DirectViewElementSelector selector = basicViewType.createSelector(viewSource); assertThat(selector.getSelectableElements(), is(Set.of(rootElement))); } @@ -123,7 +124,7 @@ public void forSourceContainingNonRootElements() { resource.getContents().add(rootElement); ChangeableViewSource viewSource = mock(ChangeableViewSource.class); when(viewSource.getViewSourceModels()).thenReturn(Set.of(resource)); - DirectViewElementSelector selector = basicViewType.createSelector(viewSource); + DirectViewElementSelector selector = basicViewType.createSelector(viewSource); assertThat(selector.getSelectableElements(), is(Set.of(rootElement))); } } @@ -144,7 +145,7 @@ public void initializeViewTypeAndResourceSet() { @DisplayName("with empty source") public void withNoElements() throws Exception { ChangeableViewSource viewSource = mock(ChangeableViewSource.class); - DirectViewElementSelector selector = basicViewType.createSelector(viewSource); + DirectViewElementSelector selector = basicViewType.createSelector(viewSource); try (View view = basicViewType.createView(selector)) { assertThat(view.getRootObjects(), not(hasItem(anything()))); } @@ -154,7 +155,8 @@ public void withNoElements() throws Exception { @DisplayName("with selector from other view type") public void withSelectorFromOtherViewtype() { ChangeableViewSource viewSource = mock(ChangeableViewSource.class); - DirectViewElementSelector selector = new IdentityMappingViewType("other").createSelector(viewSource); + DirectViewElementSelector selector = new IdentityMappingViewType("other") + .createSelector(viewSource); assertThrows(IllegalArgumentException.class, () -> basicViewType.createView(selector)); } @@ -167,7 +169,7 @@ public void withNoSelectedElement() throws Exception { resource.getContents().add(rootElement); ChangeableViewSource viewSource = mock(ChangeableViewSource.class); when(viewSource.getViewSourceModels()).thenReturn(Set.of(resource)); - DirectViewElementSelector selector = basicViewType.createSelector(viewSource); + DirectViewElementSelector selector = basicViewType.createSelector(viewSource); try (View view = basicViewType.createView(selector)) { assertThat(view.getRootObjects(), not(hasItem(anything()))); } @@ -182,7 +184,7 @@ public void withSingleSelectedElement() throws Exception { resource.getContents().add(rootElement); ChangeableViewSource viewSource = mock(ChangeableViewSource.class); when(viewSource.getViewSourceModels()).thenReturn(Set.of(resource)); - DirectViewElementSelector selector = basicViewType.createSelector(viewSource); + DirectViewElementSelector selector = basicViewType.createSelector(viewSource); selector.setSelected(rootElement, true); try (View view = basicViewType.createView(selector)) { assertThat(view.getRootObjects().size(), is(1)); @@ -203,7 +205,7 @@ public void withOneOfTwoElementsSelected() throws Exception { secondResource.getContents().add(secondRootElement); ChangeableViewSource viewSource = mock(ChangeableViewSource.class); when(viewSource.getViewSourceModels()).thenReturn(Set.of(firstResource, secondResource)); - DirectViewElementSelector selector = basicViewType.createSelector(viewSource); + DirectViewElementSelector selector = basicViewType.createSelector(viewSource); selector.setSelected(firstRootElement, true); try (View view = basicViewType.createView(selector)) { assertThat(view.getRootObjects().size(), is(1)); @@ -224,7 +226,7 @@ public void withBothOfTwoElementsSelected() throws Exception { secondResource.getContents().add(secondRootElement); ChangeableViewSource viewSource = mock(ChangeableViewSource.class); when(viewSource.getViewSourceModels()).thenReturn(Set.of(firstResource, secondResource)); - DirectViewElementSelector selector = basicViewType.createSelector(viewSource); + DirectViewElementSelector selector = basicViewType.createSelector(viewSource); selector.setSelected(firstRootElement, true); selector.setSelected(secondRootElement, true); try (View view = basicViewType.createView(selector)) { @@ -257,7 +259,7 @@ public void forTwoResourcesWithContainmentInBetween() throws Exception { secondResource.getContents().add(secondRootElement); ChangeableViewSource viewSource = mock(ChangeableViewSource.class); when(viewSource.getViewSourceModels()).thenReturn(Set.of(firstResource, secondResource)); - DirectViewElementSelector selector = basicViewType.createSelector(viewSource); + DirectViewElementSelector selector = basicViewType.createSelector(viewSource); selector.setSelected(firstRootElement, true); selector.setSelected(secondRootElement, true); try (View view = basicViewType.createView(selector)) { @@ -301,7 +303,7 @@ private Root createResourceWithSingleRoot(URI uri) { @DisplayName("adding a non-root element") public void addingANonRootElement() throws Exception { Root root = createResourceWithSingleRoot(URI.createURI("test://test.aet")); - DirectViewElementSelector selector = basicViewType.createSelector(viewSource); + DirectViewElementSelector selector = basicViewType.createSelector(viewSource); selector.getSelectableElements().forEach((element) -> selector.setSelected(element, true)); try (ModifiableView view = basicViewType.createView(selector)) { root.setSingleValuedContainmentEReference(aet.NonRoot()); @@ -318,7 +320,7 @@ public void addingANonRootElement() throws Exception { @DisplayName("adding a root element") public void addingARootElement() throws Exception { Root root = createResourceWithSingleRoot(URI.createURI("test://test.aet")); - DirectViewElementSelector selector = basicViewType.createSelector(viewSource); + DirectViewElementSelector selector = basicViewType.createSelector(viewSource); selector.getSelectableElements().forEach((element) -> selector.setSelected(element, true)); try (ModifiableView view = basicViewType.createView(selector)) { root.setId("secondId"); @@ -333,7 +335,7 @@ public void addingARootElement() throws Exception { @DisplayName("removing a selected root element") public void removingSelectedRoot() throws Exception { Root root = createResourceWithSingleRoot(URI.createURI("test://test.aet")); - DirectViewElementSelector selector = basicViewType.createSelector(viewSource); + DirectViewElementSelector selector = basicViewType.createSelector(viewSource); selector.getSelectableElements().forEach((element) -> selector.setSelected(element, true)); try (ModifiableView view = basicViewType.createView(selector)) { EcoreUtil.delete(root); @@ -348,7 +350,7 @@ public void removingSelectedRoot() throws Exception { public void removingUnselectedRoot() throws Exception { Root firstRoot = createResourceWithSingleRoot(URI.createURI("test://test.aet")); Root secondRoot = createResourceWithSingleRoot(URI.createURI("test://test2.aet")); - DirectViewElementSelector selector = basicViewType.createSelector(viewSource); + DirectViewElementSelector selector = basicViewType.createSelector(viewSource); selector.setSelected(firstRoot, true); try (ModifiableView view = basicViewType.createView(selector)) { EcoreUtil.delete(secondRoot); diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/selectors/DirectViewElementSelectorTest.java b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/selectors/DirectViewElementSelectorTest.java index 55eba440f6..a099cef99d 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/selectors/DirectViewElementSelectorTest.java +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/selectors/DirectViewElementSelectorTest.java @@ -22,6 +22,7 @@ import org.mockito.MockitoAnnotations; import allElementTypes.Root; +import tools.vitruv.change.atomic.hid.HierarchicalId; import tools.vitruv.framework.views.ChangeableViewSource; import tools.vitruv.framework.views.ViewSelector; import tools.vitruv.framework.views.impl.ModifiableView; @@ -32,7 +33,7 @@ @ExtendWith({ TestLogging.class, RegisterMetamodelsInStandalone.class }) public class DirectViewElementSelectorTest { @Mock - ViewCreatingViewType mockViewType; + ViewCreatingViewType, HierarchicalId> mockViewType; @Mock ChangeableViewSource mockViewSource; @@ -52,28 +53,28 @@ class WithNullElements { @DisplayName("with null view type") public void nullViewType() { assertThrows(IllegalArgumentException.class, - () -> new DirectViewElementSelector(null, mockViewSource, emptySet())); + () -> new DirectViewElementSelector<>(null, mockViewSource, emptySet())); } @Test @DisplayName("with null view source") public void nullViewSource() { assertThrows(IllegalArgumentException.class, - () -> new DirectViewElementSelector(mockViewType, null, emptySet())); + () -> new DirectViewElementSelector<>(mockViewType, null, emptySet())); } @Test @DisplayName("with null selectable elements") public void nullElements() { assertThrows(IllegalArgumentException.class, - () -> new DirectViewElementSelector(mockViewType, mockViewSource, null)); + () -> new DirectViewElementSelector<>(mockViewType, mockViewSource, null)); } } @Test @DisplayName("with no selectable elements") public void empty() { - ViewSelector selector = new DirectViewElementSelector(mockViewType, mockViewSource, emptySet()); + ViewSelector selector = new DirectViewElementSelector<>(mockViewType, mockViewSource, emptySet()); assertThat(selector.getSelectableElements(), is(emptySet())); assertThat("BasicViewElementSelectors must always be valid", selector.isValid()); } @@ -82,7 +83,7 @@ public void empty() { @DisplayName("with single selectable element") public void withSingleSelectableElement() { Root root = aet.Root(); - ViewSelector selector = new DirectViewElementSelector(mockViewType, mockViewSource, Set.of(root)); + ViewSelector selector = new DirectViewElementSelector<>(mockViewType, mockViewSource, Set.of(root)); assertThat(selector.getSelectableElements(), is(Set.of(root))); assertThat("BasicViewElementSelectors must always be valid", selector.isValid()); } @@ -92,7 +93,7 @@ public void withSingleSelectableElement() { public void withMultipleSelectableElements() { Root firstRoot = aet.Root(); Root secondRoot = aet.Root(); - ViewSelector selector = new DirectViewElementSelector(mockViewType, mockViewSource, + ViewSelector selector = new DirectViewElementSelector<>(mockViewType, mockViewSource, Set.of(firstRoot, secondRoot)); assertThat(selector.getSelectableElements(), is(Set.of(firstRoot, secondRoot))); assertThat("BasicViewElementSelectors must always be valid", selector.isValid()); @@ -111,7 +112,7 @@ public void setupSelectionWithFirstOfTwoElementsSelected() { selectableElements = new ArrayList<>(); selectableElements.add(aet.Root()); selectableElements.add(aet.Root()); - selector = new DirectViewElementSelector(mockViewType, mockViewSource, selectableElements); + selector = new DirectViewElementSelector<>(mockViewType, mockViewSource, selectableElements); selector.setSelected(selectableElements.get(0), true); assertThat("BasicViewElementSelectors must always be valid", selector.isValid()); } @@ -144,7 +145,8 @@ class Returns { @Test @DisplayName("view created from view type") public void createView() { - DirectViewElementSelector selector = new DirectViewElementSelector(mockViewType, mockViewSource, emptySet()); + DirectViewElementSelector selector = new DirectViewElementSelector<>(mockViewType, + mockViewSource, emptySet()); ModifiableView view = mock(ModifiableView.class); when(mockViewType.createView(selector)).thenReturn(view); assertThat(selector.createView(), is(view)); @@ -153,7 +155,8 @@ public void createView() { @Test @DisplayName("view source") public void getViewSource() { - DirectViewElementSelector selector = new DirectViewElementSelector(mockViewType, mockViewSource, emptySet()); + DirectViewElementSelector selector = new DirectViewElementSelector<>(mockViewType, + mockViewSource, emptySet()); assertThat(selector.getViewSource(), is(mockViewSource)); }