diff options
author | Zoltan Ujhelyi | 2016-11-08 09:11:00 +0000 |
---|---|---|
committer | Laurent Fasani | 2018-02-21 08:19:03 +0000 |
commit | 14de3384380ebed1e40f4a8ad2e557efc0a6ebfb (patch) | |
tree | 4e5db6045dbd59ef3b6af68e02781e56b0a9efcd | |
parent | 16d4dca8e051c194f38a738782661df37909025a (diff) | |
download | org.eclipse.sirius-14de3384380ebed1e40f4a8ad2e557efc0a6ebfb.tar.gz org.eclipse.sirius-14de3384380ebed1e40f4a8ad2e557efc0a6ebfb.tar.xz org.eclipse.sirius-14de3384380ebed1e40f4a8ad2e557efc0a6ebfb.zip |
[513407] Ensure resource (re)loading happens in write transactions
* Resource loading was executed without transaction support; resource
reloading was executed in a read-only transaction. In case of languages
based on Xbase this caused problems, as Xbase modifies the models during
resolution (e.g. writes type information or similar steps). By moving
resource loading and reloading in write transactions, these issues are
handled correctly.
* Update the ValidateEditSupport used by Sirius
(ResourceModifiedFieldUpdater) to ensure that loaded resource are not
seen as modified.
Bug: 513407
Change-Id: I67c640fac8441647ae96005f265d1c2eb83548a6
Signed-off-by: Zoltan Ujhelyi <ujhelyiz@incquerylabs.com>
Signed-off-by: Laurent Fasani <laurent.fasani@obeo.fr>
3 files changed, 49 insertions, 29 deletions
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/resource/ResourceModifiedFieldUpdater.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/resource/ResourceModifiedFieldUpdater.java index 25a5743484..7dcebdb981 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/resource/ResourceModifiedFieldUpdater.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/resource/ResourceModifiedFieldUpdater.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014, Obeo. + * Copyright (c) 2014, 2018 Obeo. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -61,7 +61,10 @@ public class ResourceModifiedFieldUpdater extends DelegatingValidateEditSupport @Override public void handleResourceChange(Resource resource, Notification notification) { super.handleResourceChange(resource, notification); - if (!resource.isModified() && !isInLoad(resource) && !changedResources.contains(resource) && isResourceModelChange(notification)) { + if (isInLoad(resource)) { + // if the resource is loading, it is seen as unchanged whatever previous changes were. + changedResources.remove(resource); + } else if (!resource.isModified() && !isInLoad(resource) && !changedResources.contains(resource) && isResourceModelChange(notification)) { changedResources.add(resource); } } diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java index 458863c174..7194dcfe42 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java @@ -34,9 +34,10 @@ import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.Resource.Diagnostic; import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.Resource.Diagnostic; import org.eclipse.emf.transaction.NotificationFilter; +import org.eclipse.emf.transaction.RecordingCommand; import org.eclipse.emf.transaction.RunnableWithResult; import org.eclipse.emf.transaction.Transaction; import org.eclipse.emf.transaction.TransactionalEditingDomain; @@ -80,8 +81,8 @@ import org.eclipse.sirius.business.internal.session.SessionEventBrokerImpl; import org.eclipse.sirius.common.tools.DslCommonPlugin; import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter; import org.eclipse.sirius.common.tools.api.resource.ResourceSetSync; -import org.eclipse.sirius.common.tools.api.resource.ResourceSetSync.ResourceStatus; import org.eclipse.sirius.common.tools.api.resource.ResourceSyncClient; +import org.eclipse.sirius.common.tools.api.resource.ResourceSetSync.ResourceStatus; import org.eclipse.sirius.common.tools.api.util.ECrossReferenceAdapterWithUnproxyCapability; import org.eclipse.sirius.common.tools.api.util.EqualityHelper; import org.eclipse.sirius.common.tools.api.util.LazyCrossReferencer; @@ -1158,7 +1159,7 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements // ******************* @Override - public void open(IProgressMonitor monitor) { + public void open(final IProgressMonitor monitor) { try { monitor.beginTask(Messages.DAnalysisSessionImpl_openMsg, 33); SessionManager.INSTANCE.add(this); @@ -1172,7 +1173,15 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements this.representationNameListener = new RepresentationNameListener(this); monitor.worked(1); - tracker.initialize(monitor); + // Some modelers, as Xbase, modify the models during resolution. So we need to initialize the tracker in a + // write transaction + RecordingCommand initializeTrackerCommand = new RecordingCommand(transactionalEditingDomain) { + @Override + protected void doExecute() { + tracker.initialize(monitor); + } + }; + transactionalEditingDomain.getCommandStack().execute(initializeTrackerCommand); monitor.worked(1); setSynchronizeStatusofEveryResource(); diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SessionResourcesSynchronizer.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SessionResourcesSynchronizer.java index 87b62b7c2f..ba906c7e14 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SessionResourcesSynchronizer.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/SessionResourcesSynchronizer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2017 THALES GLOBAL SERVICES and Obeo. + * Copyright (c) 2007, 2018 THALES GLOBAL SERVICES and Obeo. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -21,11 +21,13 @@ import java.util.stream.Collectors; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; -import org.eclipse.emf.transaction.RunnableWithResult; +import org.eclipse.emf.transaction.RecordingCommand; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.emf.workspace.util.WorkspaceSynchronizer; import org.eclipse.sirius.business.api.dialect.DialectManager; @@ -189,10 +191,11 @@ public class SessionResourcesSynchronizer implements ResourceSyncClient { reloadingAnalysisCmd = new AnalysisResourceReloadedCommand(session, ted, resource); } List<Resource> resourcesBeforeReload = Lists.newArrayList(ted.getResourceSet().getResources()); - /* execute the reload operation as a read-only transaction */ - RunnableWithResult<?> reload = new RunnableWithResult.Impl<Object>() { + /* execute the reload operation as a write transaction */ + RecordingCommand reload = new RecordingCommand(ted) { + IStatus result; @Override - public void run() { + protected void doExecute() { session.disableCrossReferencerResolve(resource); resource.unload(); session.enableCrossReferencerResolve(resource); @@ -200,31 +203,36 @@ public class SessionResourcesSynchronizer implements ResourceSyncClient { resource.load(Collections.EMPTY_MAP); EcoreUtil.resolveAll(resource); session.getSemanticCrossReferencer().resolveProxyCrossReferences(resource); + result = Status.OK_STATUS; } catch (IOException e) { - setResult(e); + result = new Status(IStatus.ERROR, SiriusPlugin.ID, e.getMessage(), e); // $NON-NLS-1$ } } + @Override + public Collection<?> getResult() { + return Collections.singleton(result); + } }; - try { - ted.runExclusive(reload); - if (reload.getResult() != null) { - throw (IOException) reload.getResult(); - } else if (!reload.getStatus().isOK()) { - SiriusPlugin.getDefault().error(Messages.SessionResourcesSynchronizer_reloadOperationFailErrorMsg, null); + ted.getCommandStack().execute(reload); + + IStatus result = (IStatus) (reload.getResult().iterator().next()); + if (!result.isOK()) { + if (result.getException() instanceof IOException) { + throw (IOException) result.getException(); } else { - if (representationsResource) { - ted.getCommandStack().execute(reloadingAnalysisCmd); - if (resource.getURI().equals(session.getSessionResource().getURI())) { - session.sessionResourceReloaded(resource); - } + SiriusPlugin.getDefault().error(Messages.SessionResourcesSynchronizer_reloadOperationFailErrorMsg, null); + } + } else { + if (representationsResource) { + ted.getCommandStack().execute(reloadingAnalysisCmd); + if (resource.getURI().equals(session.getSessionResource().getURI())) { + session.sessionResourceReloaded(resource); } - // Analyze the unknown resources to detect new semantic or - // session resources. - session.discoverAutomaticallyLoadedResources(resourcesBeforeReload); - session.notifyListeners(SessionListener.REPLACED); } - } catch (InterruptedException e) { - // do nothing + // Analyze the unknown resources to detect new semantic or + // session resources. + session.discoverAutomaticallyLoadedResources(resourcesBeforeReload); + session.notifyListeners(SessionListener.REPLACED); } } |