diff --git a/bundles/tools.vitruv.framework.views/META-INF/MANIFEST.MF b/bundles/tools.vitruv.framework.views/META-INF/MANIFEST.MF index e96ea43e0..8865f6a33 100644 --- a/bundles/tools.vitruv.framework.views/META-INF/MANIFEST.MF +++ b/bundles/tools.vitruv.framework.views/META-INF/MANIFEST.MF @@ -15,3 +15,4 @@ Require-Bundle: org.apache.log4j, Export-Package: tools.vitruv.framework.views, tools.vitruv.framework.views.changederivation Bundle-Vendor: vitruv.tools +Import-Package: tools.vitruv.change.changederivation diff --git a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/View.java b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/View.java index 210fa714f..cf0b784f2 100644 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/View.java +++ b/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/View.java @@ -8,8 +8,8 @@ import com.google.common.annotations.Beta; import com.google.common.collect.FluentIterable; -import tools.vitruv.framework.views.changederivation.DefaultStateBasedChangeResolutionStrategy; -import tools.vitruv.framework.views.changederivation.StateBasedChangeResolutionStrategy; +import tools.vitruv.change.changederivation.DefaultStateBasedChangeResolutionStrategy; +import tools.vitruv.change.changederivation.StateBasedChangeResolutionStrategy; /** * A Vitruv view on an underlying {@link ChangeableViewSource}. 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 deleted file mode 100644 index 9a5f99118..000000000 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/DefaultStateBasedChangeResolutionStrategy.xtend +++ /dev/null @@ -1,118 +0,0 @@ -package tools.vitruv.framework.views.changederivation - -import org.eclipse.emf.common.notify.Notifier -import org.eclipse.emf.common.util.BasicMonitor -import org.eclipse.emf.compare.EMFCompare -import org.eclipse.emf.compare.match.impl.MatchEngineFactoryImpl -import org.eclipse.emf.compare.match.impl.MatchEngineFactoryRegistryImpl -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.resource.Resource -import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl -import org.eclipse.emf.ecore.util.EcoreUtil -import tools.vitruv.change.composite.description.VitruviusChangeResolver -import tools.vitruv.change.composite.recording.ChangeRecorder - -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 edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceCopier - -/** - * This default strategy for diff based state changes uses EMFCompare to resolve a - * diff to a sequence of individual changes. - */ -class DefaultStateBasedChangeResolutionStrategy implements StateBasedChangeResolutionStrategy { - /** The identifier matching behavior used by this strategy */ - public val UseIdentifiers useIdentifiers - - /** - * Creates a new instance with the default identifier matching behavior - * which is match by identifier when available. - */ - new() { - this(UseIdentifiers.WHEN_AVAILABLE) - } - - /** - * Creates a new instance with the provided identifier matching behavior. - * @param useIdentifiers The identifier matching behavior to use. - */ - new(UseIdentifiers useIdentifiers) { - this.useIdentifiers = useIdentifiers - } - - private def checkNoProxies(Resource resource, String stateNotice) { - val proxies = resource.referencedProxies - checkArgument(proxies.empty, "%s '%s' should not contain proxies, but contains the following: %s", stateNotice, - resource.URI, String.join(", ", proxies.map[toString])) - } - - override getChangeSequenceBetween(Resource newState, Resource oldState) { - checkArgument(oldState !== null && newState !== null, "old state or new state must not be null!") - newState.checkNoProxies("new state") - oldState.checkNoProxies("old state") - val monitoredResourceSet = new ResourceSetImpl() - val currentStateCopy = ResourceCopier.copyViewResource(oldState, monitoredResourceSet) - return currentStateCopy.record [ - if (oldState.URI != newState.URI) { - currentStateCopy.URI = newState.URI - } - compareStatesAndReplayChanges(newState, currentStateCopy) - ] - } - - override getChangeSequenceForCreated(Resource newState) { - checkArgument(newState !== null, "new state must not be null!") - newState.checkNoProxies("new state") - // It is possible that root elements are automatically generated during resource creation (e.g., Java packages). - // Thus, we create the resource and then monitor the re-insertion of the elements - val monitoredResourceSet = new ResourceSetImpl() - val newResource = monitoredResourceSet.createResource(newState.URI) - newResource.contents.clear() - return newResource.record [ - newResource.contents += EcoreUtil.copyAll(newState.contents) - ] - } - - override getChangeSequenceForDeleted(Resource oldState) { - checkArgument(oldState !== null, "old state must not be null!") - oldState.checkNoProxies("old state") - // Setup resolver and copy state: - val monitoredResourceSet = new ResourceSetImpl() - val currentStateCopy = ResourceCopier.copyViewResource(oldState, monitoredResourceSet) - return currentStateCopy.record [ - currentStateCopy.contents.clear() - ] - } - - private def record(Resource resource, ()=>void function) { - try (val changeRecorder = new ChangeRecorder(resource.resourceSet)) { - changeRecorder.beginRecording - changeRecorder.addToRecording(resource) - function.apply() - val recordedChanges = changeRecorder.endRecording - val changeResolver = VitruviusChangeResolver.forHierarchicalIds(resource.resourceSet) - return changeResolver.assignIds(recordedChanges) - } - } - - /** - * Compares states using EMFCompare and replays the changes to the current state. - */ - private def compareStatesAndReplayChanges(Notifier newState, Notifier currentState) { - val scope = new DefaultComparisonScope(newState, currentState, null) - val emfCompare = (EMFCompare.builder => [ - matchEngineFactoryRegistry = MatchEngineFactoryRegistryImpl.createStandaloneInstance => [ - add(new MatchEngineFactoryImpl(useIdentifiers)) - ] - ]).build - val differences = emfCompare.compare(scope).differences - // Replay the EMF compare differences - val mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance() - val merger = new BatchMerger(mergerRegistry) - merger.copyAllLeftToRight(differences, new BasicMonitor) - } -} 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 deleted file mode 100644 index fa5d130cd..000000000 --- a/bundles/tools.vitruv.framework.views/src/tools/vitruv/framework/views/changederivation/StateBasedChangeResolutionStrategy.java +++ /dev/null @@ -1,54 +0,0 @@ -package tools.vitruv.framework.views.changederivation; - -import org.eclipse.emf.ecore.resource.Resource; - -import tools.vitruv.change.atomic.hid.HierarchicalId; -import tools.vitruv.change.composite.description.VitruviusChange; - -/** - * Strategy for resolving state-based changes to individual change sequences. - * This strategy is used by the domains when there are no change sequences - * available and changes need to be propagated based on the difference between - * the old and new state. - */ -public interface StateBasedChangeResolutionStrategy { - - /** - * Resolves the state-based delta of two resources and returns the correlating - * change sequences. Changes must use hierarchical IDs and are returned - * unresolved. The {@code oldState} remains unmodified from calling this method. - * - * @param newState is the new state of the resource, must not be - * null and must not contain proxies. - * @param oldState is the current or old state of the resource, must not be - * null and must not contain proxies. - * @return a unresolved {@link VitruviusChange} that contains the individual - * change sequence. - */ - VitruviusChange getChangeSequenceBetween(Resource newState, Resource oldState); - - /** - * Resolves the state-based delta for creating the given resource and returns - * the correlating change sequences. Changes must use hierarchical IDs and are - * returned unresolved. - * - * @param newState is the new state of the resource, must not be - * null and must not contain proxies. - * @return a unresolved {@link VitruviusChange} that contains the individual - * change sequence. - */ - VitruviusChange getChangeSequenceForCreated(Resource newState); - - /** - * Resolves the state-based delta for deleting the given resource and returns - * the correlating change sequences. Changes must use hierarchical IDs and are - * returned unresolved. The {@code oldState} remains unmodified from calling - * this method. - * - * @param oldState is the new state of the resource, must not be - * null and must not contain proxies. - * @return a unresolved {@link VitruviusChange} that contains the individual - * change sequence. - */ - 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 65ac02e0e..8fef15038 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 @@ -17,13 +17,12 @@ import tools.vitruv.change.composite.propagation.ChangePropagationListener import tools.vitruv.framework.views.ChangeableViewSource import tools.vitruv.framework.views.ViewSelection import tools.vitruv.framework.views.ViewSelector -import tools.vitruv.framework.views.changederivation.StateBasedChangeResolutionStrategy +import tools.vitruv.change.changederivation.StateBasedChangeResolutionStrategy +import tools.vitruv.change.changederivation.DeltaBasedResourceUtil import static com.google.common.base.Preconditions.checkArgument import static com.google.common.base.Preconditions.checkState -import static extension edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceSetUtil.withGlobalFactories - package class BasicView implements ModifiableView, ChangePropagationListener { @Accessors(PUBLIC_GETTER, PROTECTED_SETTER) var ViewSelection selection @@ -47,7 +46,7 @@ package class BasicView implements ModifiableView, ChangePropagationListener { this.viewSource = viewSource this.selection = selection viewSource.addChangePropagationListener(this) - viewResourceSet = new ResourceSetImpl().withGlobalFactories + viewResourceSet = DeltaBasedResourceUtil.withDeltaFactory(new ResourceSetImpl()) update } 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 e4d9688e9..caeb8e469 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 @@ -12,8 +12,7 @@ import tools.vitruv.change.composite.description.VitruviusChange import tools.vitruv.change.composite.description.VitruviusChangeFactory import tools.vitruv.framework.views.CommittableView import tools.vitruv.framework.views.View -import tools.vitruv.framework.views.changederivation.StateBasedChangeResolutionStrategy - +import tools.vitruv.change.changederivation.StateBasedChangeResolutionStrategy import static com.google.common.base.Preconditions.checkArgument import static com.google.common.base.Preconditions.checkState 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 7187b96da..8405187a4 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 @@ -5,7 +5,7 @@ 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 -import tools.vitruv.framework.views.changederivation.StateBasedChangeResolutionStrategy +import tools.vitruv.change.changederivation.StateBasedChangeResolutionStrategy import static com.google.common.base.Preconditions.checkArgument import static com.google.common.base.Preconditions.checkState 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 f8d7c7ed1..133ef6466 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 @@ -18,6 +18,7 @@ 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.changederivation.DeltaBasedResourceUtil; import tools.vitruv.change.composite.description.VitruviusChange; import tools.vitruv.change.composite.description.VitruviusChangeResolver; import tools.vitruv.framework.views.ChangeableViewSource; @@ -66,8 +67,9 @@ public void updateView(ModifiableView view) { @Override public void commitViewChanges(ModifiableView view, VitruviusChange viewChange) { - ResourceSet viewSourceCopyResourceSet = withGlobalFactories(new ResourceSetImpl()); + ResourceSet viewSourceCopyResourceSet = DeltaBasedResourceUtil.withDeltaFactory(new ResourceSetImpl()); VitruviusChangeResolver idChangeResolver = VitruviusChangeResolver.forHierarchicalIds(viewSourceCopyResourceSet); + UuidResolver viewSourceCopyUuidResolver = UuidResolver.create(viewSourceCopyResourceSet); VitruviusChangeResolver uuidChangeResolver = VitruviusChangeResolver.forUuids(viewSourceCopyUuidResolver); Map mapping = createViewResources(view, viewSourceCopyResourceSet); diff --git a/bundles/tools.vitruv.framework.vsum/META-INF/MANIFEST.MF b/bundles/tools.vitruv.framework.vsum/META-INF/MANIFEST.MF index 4abb89d0e..311a33da0 100644 --- a/bundles/tools.vitruv.framework.vsum/META-INF/MANIFEST.MF +++ b/bundles/tools.vitruv.framework.vsum/META-INF/MANIFEST.MF @@ -13,7 +13,9 @@ Require-Bundle: org.apache.log4j, org.eclipse.emf.ecore.xmi, edu.kit.ipd.sdq.activextendannotations, edu.kit.ipd.sdq.commons.util.emf, - edu.kit.ipd.sdq.commons.util.java + edu.kit.ipd.sdq.commons.util.java, + tools.vitruv.change.changederivation Export-Package: tools.vitruv.framework.vsum, + tools.vitruv.framework.vsum.helper, tools.vitruv.framework.vsum.internal;x-internal:=true Bundle-Vendor: vitruv.tools diff --git a/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ModelInstance.xtend b/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ModelInstance.xtend index 0475e803c..e3be249e1 100644 --- a/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ModelInstance.xtend +++ b/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ModelInstance.xtend @@ -1,65 +1,32 @@ package tools.vitruv.framework.vsum.internal import java.io.IOException +import java.util.Map import org.apache.log4j.Logger import org.eclipse.emf.common.util.URI import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.resource.Resource -import org.eclipse.xtend.lib.annotations.Accessors +import tools.vitruv.change.changederivation.DeltaBasedResource -import static com.google.common.base.Preconditions.checkArgument - -class ModelInstance { +class ModelInstance extends DeltaBasedResource { static val LOGGER = Logger.getLogger(ModelInstance) - @Accessors(PUBLIC_GETTER) - Resource resource - - new(Resource resource) { - checkArgument(resource !== null, "cannot create a model instance for a null resource") - this.resource = resource - LOGGER.debug('''Create model instance for resource with URI: «URI»''') - } - def URI getURI() { - return resource.URI + new(URI uri) { + super(uri) + LOGGER.debug('''Create model instance for resource with URI: «uri»''') } def void addRoot(EObject root) { - resource.contents += root - resource.modified = true - LOGGER.debug('''Add root to resource: «resource»''') - } - - def void markModified() { - resource.modified = true + this.contents += root + this.modified = true + LOGGER.debug('''Add root to model instance: «this»''') } - + def boolean isEmpty() { - resource.contents.isEmpty + this.contents.isEmpty } - - def void save() { - if (!resource.modified) { - return - } - LOGGER.debug('''Save resource: «resource»''') - try { - resource.save(null) - resource.modified = false - } catch (IOException e) { - LOGGER.error('''Model could not be saved: «URI»''', e) - throw new IllegalStateException('''Could not save URI «URI»''', e) - } + + override delete(Map options) throws IOException { + LOGGER.debug('''Delete model instance: «this»''') + super.delete(null) } - - def void delete() { - LOGGER.debug('''Delete resource: «resource»''') - try { - resource.delete(null) - } catch (IOException e) { - LOGGER.error('''Deletion of resource «resource» did not work.''', e) - throw new IllegalStateException('''Could not delete URI «URI»''', e) - } - } - -} +} \ No newline at end of file diff --git a/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ModelInstanceFactory.java b/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ModelInstanceFactory.java new file mode 100644 index 000000000..899dbb7e7 --- /dev/null +++ b/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/ModelInstanceFactory.java @@ -0,0 +1,11 @@ +package tools.vitruv.framework.vsum.internal; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; + +public class ModelInstanceFactory implements Resource.Factory { + @Override + public Resource createResource(URI uri) { + return new ModelInstance(uri); + } +} diff --git a/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/PathmapAwareModelInstanceFactory.java b/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/PathmapAwareModelInstanceFactory.java new file mode 100644 index 000000000..9b4946d7e --- /dev/null +++ b/bundles/tools.vitruv.framework.vsum/src/tools/vitruv/framework/vsum/internal/PathmapAwareModelInstanceFactory.java @@ -0,0 +1,27 @@ +package tools.vitruv.framework.vsum.internal; + +import static edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceSetUtil.loadOrCreateResource; + +import org.eclipse.emf.common.util.URI; +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 edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceSetUtil; + +public class PathmapAwareModelInstanceFactory implements Resource.Factory { + @Override + public Resource createResource(URI uri) { + if (uri.toString().contains("pathmap")) { + ResourceSet stateBasedResourceSet = ResourceSetUtil.withGlobalFactories(new ResourceSetImpl()); + loadOrCreateResource(stateBasedResourceSet, uri); + ModelInstance modelInstance = new ModelInstance(uri); + Resource stateBasedResource = stateBasedResourceSet.getResource(uri, false); + modelInstance.getContents().addAll(EcoreUtil.copyAll(stateBasedResource.getContents())); + modelInstance.setModified(false); + return modelInstance; + } + return new ModelInstance(uri); + } +} \ No newline at end of file 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 27a1b8d79..a963b2ae1 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 @@ -2,7 +2,6 @@ import static edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceSetUtil.getOrCreateResource; import static edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceSetUtil.loadOrCreateResource; -import static edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceSetUtil.withGlobalFactories; import static tools.vitruv.change.correspondence.model.CorrespondenceModelFactory.createPersistableCorrespondenceModel; import java.io.IOException; @@ -21,7 +20,9 @@ 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 edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceSetUtil; import tools.vitruv.change.atomic.uuid.Uuid; import tools.vitruv.change.atomic.uuid.UuidResolver; import tools.vitruv.change.composite.description.TransactionalChange; @@ -37,8 +38,8 @@ class ResourceRepositoryImpl implements ModelRepository { private static final Logger LOGGER = Logger.getLogger(ResourceRepositoryImpl.class); - - private final ResourceSet modelsResourceSet = withGlobalFactories(new ResourceSetImpl()); + + private final ResourceSet modelsResourceSet = new ResourceSetImpl(); private final Map modelInstances = new HashMap<>(); private final PersistableCorrespondenceModel correspondenceModel; private UuidResolver uuidResolver = UuidResolver.create(modelsResourceSet); @@ -53,8 +54,11 @@ class ResourceRepositoryImpl implements ModelRepository { ResourceRepositoryImpl(VsumFileSystemLayout fileSystemLayout) { this.fileSystemLayout = fileSystemLayout; this.correspondenceModel = createPersistableCorrespondenceModel(fileSystemLayout.getCorrespondencesURI()); - modelsResourceSet.eAdapters() - .add(new ResourceRegistrationAdapter(resource -> getCreateOrLoadModelUnlessLoading(resource.getURI()))); + modelsResourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", + new PathmapAwareModelInstanceFactory()); + modelsResourceSet.eAdapters().add(new ResourceRegistrationAdapter(resource -> { + getCreateOrLoadModelUnlessLoading(resource.getURI()); + })); } @Override @@ -70,16 +74,15 @@ public void loadExistingModels() { } private void writeModelsFile() throws IOException { - Files.write(fileSystemLayout.getModelsNamesFilesPath(), modelsResourceSet.getResources().stream() - .map(Resource::getURI).map(URI::toString).toList()); + Files.write(fileSystemLayout.getModelsNamesFilesPath(), + modelsResourceSet.getResources().stream().map(Resource::getURI).map(URI::toString).toList()); } - + private void readModelsFile() throws IOException { List modelUris; try { modelUris = Files.readAllLines(fileSystemLayout.getModelsNamesFilesPath()).stream().map(URI::createURI) .toList(); - } catch (NoSuchFileException e) { // There are no existing models, so don't do anything return; @@ -120,22 +123,34 @@ private ModelInstance getCreateOrLoadModel(URI modelUri) { } private ModelInstance createOrLoadModel(URI modelUri) { - Resource resource; - if (modelUri.isFile() || modelUri.isPlatform()) { - resource = getOrCreateResource(modelsResourceSet, modelUri); + ModelInstance modelInstance; + if (modelUri.toString().contains("pathmap")) { + // loadOrCreateResource + if(modelsResourceSet.getResources().stream().anyMatch(resource -> resource.getURI().equals(modelUri))) { + modelInstance = (ModelInstance) modelsResourceSet.getResource(modelUri, false); + } else { + ResourceSet stdResourceSet = ResourceSetUtil.withGlobalFactories(new ResourceSetImpl()); + Resource pathMapResource = getOrCreateResource(stdResourceSet, modelUri); + modelInstance = new ModelInstance(modelUri); + modelInstance.getContents().addAll(EcoreUtil.copyAll(pathMapResource.getContents())); + modelsResourceSet.getResources().add(modelInstance); + } + } else if (modelUri.isFile() || modelUri.isPlatform()) { + modelInstance = (ModelInstance) getOrCreateResource(modelsResourceSet, modelUri); } else { - resource = loadOrCreateResource(modelsResourceSet, modelUri); + modelInstance = (ModelInstance) loadOrCreateResource(modelsResourceSet, modelUri); } - ModelInstance modelInstance = new ModelInstance(resource); + modelInstances.put(modelUri, modelInstance); registerRecorder(modelInstance); + modelInstance.setModified(false); return modelInstance; } private void registerRecorder(ModelInstance modelInstance) { // Only monitor modifiable models (file / platform URIs, not pathmap URIs) if (modelInstance.getURI().isFile() || modelInstance.getURI().isPlatform()) { - changeRecorder.addToRecording(modelInstance.getResource()); + changeRecorder.addToRecording(modelInstance); if (isRecording && !changeRecorder.isRecording()) { changeRecorder.beginRecording(); } @@ -156,10 +171,23 @@ public void saveOrDeleteModels() { while (modelInstancesIterator.hasNext()) { ModelInstance modelInstance = modelInstancesIterator.next().getValue(); if (modelInstance.isEmpty()) { - modelInstance.delete(); + try { + modelInstance.delete(null); + } catch (IOException e) { + LOGGER.error("Model could not be deleted: " + modelInstance.getURI(), e); + throw new IllegalStateException("Could not delete URI " + modelInstance.getURI(), e); + } modelInstancesIterator.remove(); } else { - modelInstance.save(); + try { + // move to modelInstance? + if(modelInstance.isModified()) { + modelInstance.save(null); + } + } catch (IOException e) { + LOGGER.error("Model could not be saved: " + modelInstance.getURI(), e); + throw new IllegalStateException("Could not save URI " + modelInstance.getURI(), e); + } } } correspondenceModel.save(); @@ -170,7 +198,7 @@ public void saveOrDeleteModels() { throw new IllegalStateException(e); } } - + @Override public Iterable> recordChanges(Runnable changeApplicator) { changeRecorder.beginRecording(); @@ -189,22 +217,22 @@ public Iterable> recordChanges(Runnable changeAppli public VitruviusChange applyChange(VitruviusChange change) { return changeResolver.resolveAndApply(change); } - + @Override public URI getMetadataModelURI(String... metadataKey) { return fileSystemLayout.getConsistencyMetadataModelURI(metadataKey); } - + @Override public Resource getModelResource(URI uri) { - return getCreateOrLoadModel(uri).getResource(); + return getCreateOrLoadModel(uri); } @Override public Collection getModelResources() { return modelsResourceSet.getResources(); } - + @Override public void close() { changeRecorder.close(); @@ -212,4 +240,4 @@ public void close() { modelsResourceSet.getResources().clear(); uuidResolver = null; } -} +} \ No newline at end of file diff --git a/bundles/tools.vitruv.testutils.vsum/META-INF/MANIFEST.MF b/bundles/tools.vitruv.testutils.vsum/META-INF/MANIFEST.MF index 6d62fbad5..7cd757162 100644 --- a/bundles/tools.vitruv.testutils.vsum/META-INF/MANIFEST.MF +++ b/bundles/tools.vitruv.testutils.vsum/META-INF/MANIFEST.MF @@ -7,7 +7,8 @@ Bundle-Vendor: tools.vitruv Automatic-Module-Name: tools.vitruv.testutils.vsum Bundle-RequiredExecutionEnvironment: JavaSE-17 Import-Package: org.junit.jupiter.api, - org.junit.jupiter.api.extension + org.junit.jupiter.api.extension, + tools.vitruv.change.changederivation Require-Bundle: com.google.guava, org.eclipse.xtext.xbase.lib, org.eclipse.xtend.lib, diff --git a/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/DefaultVirtualModelBasedTestView.xtend b/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/DefaultVirtualModelBasedTestView.xtend index 21b0c31a1..f61504afb 100644 --- a/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/DefaultVirtualModelBasedTestView.xtend +++ b/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/DefaultVirtualModelBasedTestView.xtend @@ -31,6 +31,8 @@ class DefaultVirtualModelBasedTestView implements VirtualModelBasedTestView, Non private def InternalVirtualModel generateVirtualModel(Path testProjectPath, Path vsumPath, TestUserInteraction userInteraction) { + TestDeltaMigrator.makeVsumModelsDeltaBased(vsumPath.resolve("models.models")) + new VirtualModelBuilder() // .withStorageFolder(vsumPath) // .withUserInteractorForResultProvider(new TestUserInteraction.ResultProvider(userInteraction)) // @@ -39,7 +41,7 @@ class DefaultVirtualModelBasedTestView implements VirtualModelBasedTestView, Non private def NonTransactionalTestView generateTestView(Path testProjectPath, TestUserInteraction userInteraction) { new ChangePublishingTestView(testProjectPath, userInteraction, this.uriMode, virtualModel, - virtualModel.uuidResolver)[virtualModel.getModelInstance(it)?.resource] + virtualModel.uuidResolver)[virtualModel.getModelInstance(it)] } override getVirtualModel() { 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 ef7280498..401c092bd 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 @@ -52,7 +52,7 @@ abstract class LegacyVitruvApplicationTest extends VitruvApplicationTest impleme private def dispatch EObject resolveInVirtualModel(EObject object) { if (object.eResource !== null) { - internalVirtualModel.getModelInstance(object.eResource.URI).resource.getEObject( + internalVirtualModel.getModelInstance(object.eResource.URI).getEObject( object.hierarchicUriFragment) } } diff --git a/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/TestDeltaMigrator.java b/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/TestDeltaMigrator.java new file mode 100644 index 000000000..afcd8315f --- /dev/null +++ b/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/TestDeltaMigrator.java @@ -0,0 +1,59 @@ +package tools.vitruv.testutils; + +import static edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceSetUtil.getOrCreateResource; +import static edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceSetUtil.loadOrCreateResource; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.util.List; + +import org.eclipse.emf.common.util.URI; +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 edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceSetUtil; +import tools.vitruv.change.changederivation.DeltaBasedResourceFactory; + +public class TestDeltaMigrator { + + private TestDeltaMigrator() {}; + + public static void makeVsumModelsDeltaBased(Path modelsNamesFilesPath) throws IllegalStateException, IOException { + ResourceSet stateBasedResourceSet = ResourceSetUtil.withGlobalFactories(new ResourceSetImpl()); + List modelUris; + try { + modelUris = Files.readAllLines(modelsNamesFilesPath).stream().map(URI::createURI).toList(); + } catch (NoSuchFileException e) { + // There are no existing models, so don't do anything + return; + } + modelUris.forEach(uri -> createOrLoadResourceStateBased(stateBasedResourceSet, uri)); + modelUris.forEach(uri -> { + try { + saveResourceDeltaBased(stateBasedResourceSet, uri); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + }); + } + + private static void createOrLoadResourceStateBased(ResourceSet stateBasedResourceSet, URI resourceUri) { + if (resourceUri.isFile() || resourceUri.isPlatform()) { + getOrCreateResource(stateBasedResourceSet, resourceUri); + } else { + loadOrCreateResource(stateBasedResourceSet, resourceUri); + } + } + + private static void saveResourceDeltaBased(ResourceSet stateBasedResourceSet, URI uri) throws IOException { + Resource deltaBasedResource = new DeltaBasedResourceFactory().createResource(uri); + Resource stateBasedResource = stateBasedResourceSet.getResource(uri, false); + deltaBasedResource.getContents().addAll(EcoreUtil.copyAll(stateBasedResource.getContents())); + deltaBasedResource.save(null); + } +} diff --git a/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/TestViewFactory.java b/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/TestViewFactory.java index 42854a80a..9fb0a36b0 100644 --- a/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/TestViewFactory.java +++ b/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/TestViewFactory.java @@ -7,12 +7,12 @@ import java.util.Collection; import java.util.function.Consumer; +import tools.vitruv.change.changederivation.StateBasedChangeResolutionStrategy; import tools.vitruv.framework.views.CommittableView; import tools.vitruv.framework.views.View; import tools.vitruv.framework.views.ViewProvider; import tools.vitruv.framework.views.ViewSelector; import tools.vitruv.framework.views.ViewTypeFactory; -import tools.vitruv.framework.views.changederivation.StateBasedChangeResolutionStrategy; public class TestViewFactory { private final ViewProvider viewProvider; diff --git a/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/ViewBasedVitruvApplicationTest.xtend b/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/ViewBasedVitruvApplicationTest.xtend index 9e50da0a8..9d33f3874 100644 --- a/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/ViewBasedVitruvApplicationTest.xtend +++ b/bundles/tools.vitruv.testutils.vsum/src/tools/vitruv/testutils/ViewBasedVitruvApplicationTest.xtend @@ -40,7 +40,9 @@ abstract class ViewBasedVitruvApplicationTest { /** * Determines which {@link UriMode} should be used for this test. */ - def protected UriMode getUriMode() { UriMode.FILE_URIS } + def protected UriMode getUriMode() { + UriMode.FILE_URIS + } @BeforeEach def final package void prepareVirtualModel(TestInfo testInfo, @TestProject Path testProjectPath, @@ -48,6 +50,9 @@ abstract class ViewBasedVitruvApplicationTest { val changePropagationSpecifications = this.changePropagationSpecifications val changePropagationMode = enableTransitiveCyclicChangePropagation ? ChangePropagationMode.TRANSITIVE_CYCLIC : ChangePropagationMode.SINGLE_STEP userInteraction = new TestUserInteraction + + TestDeltaMigrator.makeVsumModelsDeltaBased(vsumPath.resolve("models.models")) + virtualModel = new VirtualModelBuilder() // .withStorageFolder(vsumPath) // .withUserInteractorForResultProvider(new TestUserInteraction.ResultProvider(userInteraction)) // diff --git a/tests/tools.vitruv.framework.views.tests/META-INF/MANIFEST.MF b/tests/tools.vitruv.framework.views.tests/META-INF/MANIFEST.MF index 212b391ed..b654679fc 100644 --- a/tests/tools.vitruv.framework.views.tests/META-INF/MANIFEST.MF +++ b/tests/tools.vitruv.framework.views.tests/META-INF/MANIFEST.MF @@ -10,7 +10,8 @@ Import-Package: org.junit.jupiter.api, org.junit.jupiter.api.extension, org.junit.jupiter.api.function, org.junit.jupiter.params, - org.junit.jupiter.params.provider + org.junit.jupiter.params.provider, + tools.vitruv.change.changederivation Require-Bundle: org.apache.log4j, tools.vitruv.testutils.vsum, tools.vitruv.testutils.metamodels, 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 3175d6170..76fc1df43 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 @@ -23,6 +23,8 @@ import static tools.vitruv.testutils.metamodels.AllElementTypesCreators.aet import static extension edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceSetUtil.withGlobalFactories import static extension tools.vitruv.testutils.Capture.operator_doubleGreaterThan +import tools.vitruv.change.changederivation.StateBasedChangeResolutionStrategy +import tools.vitruv.change.changederivation.DefaultStateBasedChangeResolutionStrategy class BasicStateChangePropagationTest extends StateChangePropagationTest { private def getTestUri() { diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/EdgeCaseStateChangeTest.xtend b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/EdgeCaseStateChangeTest.xtend index e5d30778e..46b8086c0 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/EdgeCaseStateChangeTest.xtend +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/EdgeCaseStateChangeTest.xtend @@ -5,6 +5,7 @@ import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource import static org.junit.jupiter.api.Assertions.assertThrows +import tools.vitruv.change.changederivation.StateBasedChangeResolutionStrategy class EdgeCaseStateChangeTest extends StateChangePropagationTest { diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/PcmStateChangeTest.xtend b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/PcmStateChangeTest.xtend index 64ac2d08d..a0d7d8a6b 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/PcmStateChangeTest.xtend +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/PcmStateChangeTest.xtend @@ -4,6 +4,7 @@ import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource import static tools.vitruv.testutils.metamodels.PcmMockupCreators.pcm +import tools.vitruv.change.changederivation.StateBasedChangeResolutionStrategy class PcmStateChangeTest extends StateChangePropagationTest { @ParameterizedTest() 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 a30d64e74..4b5f9ff8b 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 @@ -31,6 +31,8 @@ import static tools.vitruv.testutils.metamodels.UmlMockupCreators.uml import static extension edu.kit.ipd.sdq.commons.util.org.eclipse.emf.common.util.URIUtil.createFileURI import static extension edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceSetUtil.withGlobalFactories +import tools.vitruv.change.changederivation.DefaultStateBasedChangeResolutionStrategy +import tools.vitruv.change.changederivation.StateBasedChangeResolutionStrategy @ExtendWith(TestProjectManager, TestLogging, RegisterMetamodelsInStandalone) abstract class StateChangePropagationTest { diff --git a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/UmlStateChangeTest.xtend b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/UmlStateChangeTest.xtend index c21e11d99..01cc780c3 100644 --- a/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/UmlStateChangeTest.xtend +++ b/tests/tools.vitruv.framework.views.tests/src/tools/vitruv/framework/views/changederivation/UmlStateChangeTest.xtend @@ -6,6 +6,8 @@ import org.junit.jupiter.params.provider.EnumSource import org.junit.jupiter.params.provider.MethodSource import static tools.vitruv.testutils.metamodels.UmlMockupCreators.uml +import tools.vitruv.change.changederivation.StateBasedChangeResolutionStrategy +import tools.vitruv.change.changederivation.DefaultStateBasedChangeResolutionStrategy class UmlStateChangeTest extends StateChangePropagationTest { @ParameterizedTest() 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 6157548b8..6bf83253a 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 @@ -34,11 +34,11 @@ 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.changederivation.DefaultStateBasedChangeResolutionStrategy; 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; import tools.vitruv.testutils.RegisterMetamodelsInStandalone; import tools.vitruv.testutils.TestLogging; 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 a90f4b059..4011ba510 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 @@ -65,7 +65,7 @@ class VirtualModelTest { val recordedChange = changeRecorder.endRecording(uuidResolver) virtualModel.propagateChange(recordedChange) val vsumModel = virtualModel.getModelInstance(createTestModelResourceUri("")) - assertThat(vsumModel.resource, containsModelOf(monitoredResource)) + assertThat(vsumModel, containsModelOf(monitoredResource)) } @Test @@ -87,9 +87,9 @@ class VirtualModelTest { val sorceModel = virtualModel.getModelInstance(createTestModelResourceUri("")) val targetModel = virtualModel.getModelInstance( RedundancyChangePropagationSpecification.getTargetResourceUri(createTestModelResourceUri(""))) - assertThat(targetModel.resource, containsModelOf(monitoredResource)) + assertThat(targetModel, containsModelOf(monitoredResource)) assertEquals(1, - virtualModel.correspondenceModel.getCorrespondingEObjects(sorceModel.resource.contents.get(0)).size) + virtualModel.correspondenceModel.getCorrespondingEObjects(sorceModel.contents.get(0)).size) } @Test @@ -177,8 +177,7 @@ class VirtualModelTest { ] val recordedChange = changeRecorder.endRecording(uuidResolver) virtualModel.propagateChange(recordedChange) - val reloadedResource = new ResourceSetImpl().withGlobalFactories.getResource(createTestModelResourceUri(""), - true) + val reloadedResource = createAndLoadTestVirtualModelWithConsistencyPreservation(pathToVirtualModelProjectFolder).getModelInstance(createTestModelResourceUri("")) assertThat(reloadedResource, containsModelOf(monitoredResource)) } @@ -202,7 +201,7 @@ class VirtualModelTest { val originalModel = virtualModel.getModelInstance(createTestModelResourceUri("")) val reloadedVirtualModel = createAndLoadTestVirtualModel(pathToVirtualModelProjectFolder) val reloadedModel = reloadedVirtualModel.getModelInstance(createTestModelResourceUri("")) - assertThat(reloadedModel.resource, containsModelOf(monitoredResource)) + assertThat(reloadedModel, containsModelOf(monitoredResource)) assertNotEquals(originalModel, reloadedModel) // Propagate another change to reloaded virtual model to ensure that everything is loaded correctly changeRecorder.beginRecording @@ -232,13 +231,13 @@ class VirtualModelTest { val originalModel = virtualModel.getModelInstance(createTestModelResourceUri("")) val reloadedVirtualModel = createAndLoadTestVirtualModel(pathToVirtualModelProjectFolder) val reloadedModel = reloadedVirtualModel.getModelInstance(createTestModelResourceUri("")) - assertThat(reloadedModel.resource, containsModelOf(monitoredResource)) + assertThat(reloadedModel, containsModelOf(monitoredResource)) assertNotEquals(originalModel, reloadedModel) val reloadedTargetModel = reloadedVirtualModel.getModelInstance( RedundancyChangePropagationSpecification.getTargetResourceUri(createTestModelResourceUri(""))) - assertThat(reloadedTargetModel.resource, containsModelOf(monitoredResource)) + assertThat(reloadedTargetModel, containsModelOf(monitoredResource)) assertEquals(1, - reloadedVirtualModel.correspondenceModel.getCorrespondingEObjects(reloadedModel.resource.contents.get(0)). + reloadedVirtualModel.correspondenceModel.getCorrespondingEObjects(reloadedModel.contents.get(0)). size) }