diff options
author | Arthur Daussy | 2014-10-08 12:10:17 +0000 |
---|---|---|
committer | Laurent Goubet | 2014-10-14 10:00:31 +0000 |
commit | 6acbbf5dff9ed36bdc2b411db5352b2815c0cd9b (patch) | |
tree | b5d1210b15a60f89776450c849aa5935a457cc55 | |
parent | b32dfec137438c9242a1e674e9fec19ac659681d (diff) | |
download | org.eclipse.emf.compare-6acbbf5dff9ed36bdc2b411db5352b2815c0cd9b.tar.gz org.eclipse.emf.compare-6acbbf5dff9ed36bdc2b411db5352b2815c0cd9b.tar.xz org.eclipse.emf.compare-6acbbf5dff9ed36bdc2b411db5352b2815c0cd9b.zip |
Adds onDispose method on the resource set hooks.
The resources are unloaded and removed from the resource set on a
compare input change event using this mechanism.
Change-Id: Ifed4997876456ff0f70f4cb4e072526d5f310347
8 files changed, 316 insertions, 53 deletions
diff --git a/plugins/org.eclipse.emf.compare.diagram.ide.ui.papyrus/src/org/eclipse/emf/compare/diagram/ide/ui/papyrus/internal/CssInstallationHook.java b/plugins/org.eclipse.emf.compare.diagram.ide.ui.papyrus/src/org/eclipse/emf/compare/diagram/ide/ui/papyrus/internal/CssInstallationHook.java index 7a693092e..5d5b60446 100644 --- a/plugins/org.eclipse.emf.compare.diagram.ide.ui.papyrus/src/org/eclipse/emf/compare/diagram/ide/ui/papyrus/internal/CssInstallationHook.java +++ b/plugins/org.eclipse.emf.compare.diagram.ide.ui.papyrus/src/org/eclipse/emf/compare/diagram/ide/ui/papyrus/internal/CssInstallationHook.java @@ -13,22 +13,24 @@ package org.eclipse.emf.compare.diagram.ide.ui.papyrus.internal; import java.util.Collection; import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.compare.ide.hook.IResourceSetHook; +import org.eclipse.emf.compare.ide.hook.AbstractResourceSetHooks; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.papyrus.infra.gmfdiag.css.helper.CSSHelper; /** - * Hook in the EMF Compare {@link ResourceSet} in order to make it able to handle papyrus CSS features. + * Hook in the EMF Compare {@link org.eclipse.emf.ecore.resource.ResourceSet} in order to make it able to + * handle papyrus CSS features. * * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> */ -public class CssInstallationHook implements IResourceSetHook { +public class CssInstallationHook extends AbstractResourceSetHooks { /** * {@inheritDoc} * * @see org.eclipse.emf.compare.ide.internal.utils.IResourceSetHook#handle(java.lang.Iterable) */ + @Override public boolean isHookFor(Collection<? extends URI> uris) { // Looks for a papyrus notation file. for (URI uri : uris) { @@ -46,24 +48,14 @@ public class CssInstallationHook implements IResourceSetHook { /** * {@inheritDoc} * - * @see org.eclipse.emf.compare.ide.hook.IResourceSetHook#preLoadingHook(org.eclipse.emf.ecore.resource.ResourceSet, + * @see org.eclipse.emf.compare.ide.hook.AbstractResourceSetHooks#preLoadingHook(org.eclipse.emf.ecore.resource.ResourceSet, * java.util.Collection) */ + @Override public void preLoadingHook(ResourceSet resourceSet, Collection<? extends URI> uris) { if (!CSSHelper.isCSSSupported(resourceSet)) { CSSHelper.installCSSSupport(resourceSet); } - - } - - /** - * {@inheritDoc} - * - * @see org.eclipse.emf.compare.ide.hook.IResourceSetHook#postLoadingHook(org.eclipse.emf.ecore.resource.ResourceSet, - * java.util.Collection) - */ - public void postLoadingHook(ResourceSet resourceSet, Collection<? extends URI> uris) { - // Nothing to do } } diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java index dc5bc3529..2164fd630 100644 --- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java +++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java @@ -70,6 +70,7 @@ import org.eclipse.emf.compare.Match; import org.eclipse.emf.compare.command.ICompareCopyCommand; import org.eclipse.emf.compare.domain.ICompareEditingDomain; import org.eclipse.emf.compare.domain.impl.EMFCompareEditingDomain; +import org.eclipse.emf.compare.ide.internal.utils.DisposableResourceSet; import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIMessages; import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin; import org.eclipse.emf.compare.ide.ui.internal.configuration.EMFCompareConfiguration; @@ -221,7 +222,7 @@ public class EMFCompareStructureMergeViewer extends AbstractStructuredViewerWrap * When comparing EObjects from a resource, the resource involved doesn't need to be unload by EMF * Compare. */ - private boolean resourcesShouldBeUnload; + private boolean resourceSetShouldBeDisposed; private DependencyData dependencyData; @@ -867,13 +868,13 @@ public class EMFCompareStructureMergeViewer extends AbstractStructuredViewerWrap void compareInputChanged(final ICompareInput input, IProgressMonitor monitor) { if (input != null) { if (input instanceof CompareInputAdapter) { - resourcesShouldBeUnload = false; + resourceSetShouldBeDisposed = false; compareInputChanged((CompareInputAdapter)input, monitor); } else if (input instanceof ComparisonScopeInput) { - resourcesShouldBeUnload = false; + resourceSetShouldBeDisposed = false; compareInputChanged((ComparisonScopeInput)input, monitor); } else { - resourcesShouldBeUnload = true; + resourceSetShouldBeDisposed = true; SubMonitor subMonitor = SubMonitor.convert(monitor, 100); final ITypedElement left = input.getLeft(); @@ -1058,10 +1059,10 @@ public class EMFCompareStructureMergeViewer extends AbstractStructuredViewerWrap editingDomainChange(getCompareConfiguration().getEditingDomain(), null); - if (resourcesShouldBeUnload) { - unload(leftResourceSet); - unload(rightResourceSet); - unload(originResourceSet); + if (resourceSetShouldBeDisposed) { + disposeResourceSet(leftResourceSet); + disposeResourceSet(rightResourceSet); + disposeResourceSet(originResourceSet); } if (getCompareConfiguration() != null) { @@ -1071,6 +1072,20 @@ public class EMFCompareStructureMergeViewer extends AbstractStructuredViewerWrap } /** + * Disposes the {@link ResourceSet}. + * + * @param resourceSet + * that need to be disposed. + */ + protected void disposeResourceSet(ResourceSet resourceSet) { + if (resourceSet instanceof DisposableResourceSet) { + ((DisposableResourceSet)resourceSet).dispose(); + } else { + unload(resourceSet); + } + } + + /** * Handle the erase item event. When select a difference in the structure merge viewer, highlight required * differences with a specific color, and highlight unmergeable differences with another color. * diff --git a/plugins/org.eclipse.emf.compare.ide/plugin.xml b/plugins/org.eclipse.emf.compare.ide/plugin.xml index 52622d754..3d034df54 100644 --- a/plugins/org.eclipse.emf.compare.ide/plugin.xml +++ b/plugins/org.eclipse.emf.compare.ide/plugin.xml @@ -14,4 +14,10 @@ <plugin> <extension-point id="resourceSetHook" name="Resource Set Hook" schema="schema/resourceSetHook.exsd"/> + <extension + point="org.eclipse.emf.compare.ide.resourceSetHook"> + <resourceSetHook + class="org.eclipse.emf.compare.ide.internal.utils.UnloadingResourceSetHook"> + </resourceSetHook> + </extension> </plugin> diff --git a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/hook/AbstractResourceSetHooks.java b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/hook/AbstractResourceSetHooks.java new file mode 100644 index 000000000..8d505e247 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/hook/AbstractResourceSetHooks.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2014 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.ide.hook; + +import java.util.Collection; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; + +/** + * Abstract implementation of {@link IResourceSetHook}. + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + */ +public abstract class AbstractResourceSetHooks implements IResourceSetHook { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.ide.hook.IResourceSetHook#isHookFor(java.util.Collection) + */ + public boolean isHookFor(Collection<? extends URI> uris) { + return true; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.ide.hook.IResourceSetHook#preLoadingHook(org.eclipse.emf.ecore.resource.ResourceSet, + * java.util.Collection) + */ + public void preLoadingHook(ResourceSet resourceSet, Collection<? extends URI> uris) { + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.ide.hook.IResourceSetHook#postLoadingHook(org.eclipse.emf.ecore.resource.ResourceSet, + * java.util.Collection) + */ + public void postLoadingHook(ResourceSet resourceSet, Collection<? extends URI> uris) { + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.ide.hook.IResourceSetHook#onDispose(java.lang.Iterable) + */ + public void onDispose(Iterable<Resource> resources) { + } +} diff --git a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/hook/IResourceSetHook.java b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/hook/IResourceSetHook.java index 6a4d7c930..9774060f9 100644 --- a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/hook/IResourceSetHook.java +++ b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/hook/IResourceSetHook.java @@ -13,6 +13,7 @@ package org.eclipse.emf.compare.ide.hook; import java.util.Collection; import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; /** @@ -56,4 +57,18 @@ public interface IResourceSetHook { */ void postLoadingHook(ResourceSet resourceSet, Collection<? extends URI> uris); + /** + * This will be called when the resource set is disposed (if it is). + * <p> + * By default, EMF Compare will not unload any resource. Still some resources might need to be unloaded. + * This method could be a good way to do it. Hooks are called in unspecified order, so resources may + * already have been unloaded by other hooks when yours is called. + * </p> + * + * @see org.eclipse.emf.compare.ide.internal.utils.DisposableResourceSet + * @param resources + * List of {@link Resource}s currently in the resource set. + */ + void onDispose(Iterable<Resource> resources); + } diff --git a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/DisposableResourceSet.java b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/DisposableResourceSet.java new file mode 100644 index 000000000..8122e465b --- /dev/null +++ b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/DisposableResourceSet.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2014 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.ide.internal.utils; + +import org.eclipse.emf.ecore.resource.ResourceSet; + +/** + * A {@link ResourceSet} that offers a dispose method. + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + */ +public interface DisposableResourceSet extends ResourceSet { + + /** + * This method should be called when the resource set is no longer needed. + */ + void dispose(); + +} diff --git a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/NotLoadingResourceSet.java b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/NotLoadingResourceSet.java index 36907e987..60058db5e 100644 --- a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/NotLoadingResourceSet.java +++ b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/NotLoadingResourceSet.java @@ -37,7 +37,9 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.common.util.WrappedException; import org.eclipse.emf.compare.ide.EMFCompareIDEPlugin; @@ -67,7 +69,7 @@ import org.eclipse.emf.ecore.util.InternalEList; * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a> */ @Beta -public final class NotLoadingResourceSet extends ResourceSetImpl { +public final class NotLoadingResourceSet extends ResourceSetImpl implements DisposableResourceSet { /** * Function to transform a {@link IStorage} in an {@link URI}. @@ -85,13 +87,26 @@ public final class NotLoadingResourceSet extends ResourceSetImpl { private final StorageTraversal storageTranversal; /** + * Registry holding {@link IResourceSetHook}s. + */ + private final ResourceSetHookRegistry hookRegistry; + + /** + * Holds <code>true</code> if the resource set has been disposed. + */ + private boolean isDisposed; + + /** * Constructor. * * @param storageTranversal * see {@link #storageTranversal}. + * @param hookRegistry + * Registry holding {@link IResourceSetHook}s. */ - private NotLoadingResourceSet(StorageTraversal storageTranversal) { + private NotLoadingResourceSet(StorageTraversal storageTranversal, ResourceSetHookRegistry hookRegistry) { this.storageTranversal = storageTranversal; + this.hookRegistry = hookRegistry; } /** @@ -110,41 +125,24 @@ public final class NotLoadingResourceSet extends ResourceSetImpl { ResourceSetHookRegistry resourceSetHookRegistry) { SubMonitor progress = SubMonitor.convert(monitor, 100); progress.subTask(EMFCompareIDEMessages.getString("NotLoadingResourceSet.monitor.resolve")); //$NON-NLS-1$ - final NotLoadingResourceSet resourceSet = new NotLoadingResourceSet(traversals); + final NotLoadingResourceSet resourceSet = new NotLoadingResourceSet(traversals, + resourceSetHookRegistry); final Set<? extends IStorage> storages = traversals.getStorages(); resourceSet.setURIResourceMap(new HashMap<URI, Resource>(storages.size() << 1)); - final Collection<URI> urisToLoad = ImmutableList.copyOf(transform(storages, TO_URI)); - - final Collection<IResourceSetHook> hooks = getMatchingHooks(resourceSetHookRegistry, urisToLoad); - - for (IResourceSetHook hook : hooks) { - hook.preLoadingHook(resourceSet, urisToLoad); - } - // loading is 60% of the total work? final int loadWorkPercentage = 60; SubMonitor subMonitor = progress.newChild(loadWorkPercentage).setWorkRemaining( traversals.getStorages().size()); - for (URI uri : urisToLoad) { - if (monitor.isCanceled()) { - throw new OperationCanceledException(); - } - // Forces the loading of the selected resources. - resourceSet.loadResource(uri); - subMonitor.worked(1); - } - - for (IResourceSetHook hook : hooks) { - hook.postLoadingHook(resourceSet, urisToLoad); - } + resourceSet.load(subMonitor); final int resolveWorkPercentage = 40; subMonitor = progress.newChild(resolveWorkPercentage).setWorkRemaining( resourceSet.getResources().size()); + // Then resolve all proxies between our "loaded" resources. List<Resource> resourcesCopy = newArrayList(resourceSet.getResources()); for (Resource res : resourcesCopy) { @@ -162,19 +160,16 @@ public final class NotLoadingResourceSet extends ResourceSetImpl { /** * Retrieves the hooks that need to be hooked on this resource set. * - * @param resourceSetHookRegistry - * Registry holding the hooks. * @param urisToLoad * The collection of uris that will be loaded. * @return {@link Collection} of {@link IResourceSetHook}s that need to be hocked. */ - private static Collection<IResourceSetHook> getMatchingHooks( - ResourceSetHookRegistry resourceSetHookRegistry, final Collection<URI> urisToLoad) { + private Collection<IResourceSetHook> getMatchingHooks(final Collection<URI> urisToLoad) { final Collection<IResourceSetHook> hooks; - if (resourceSetHookRegistry == null) { + if (hookRegistry == null) { hooks = Collections.emptyList(); } else { - hooks = Collections2.filter(resourceSetHookRegistry.getResourceSetHooks(), + hooks = Collections2.filter(hookRegistry.getResourceSetHooks(), new Predicate<IResourceSetHook>() { public boolean apply(IResourceSetHook input) { @@ -186,7 +181,7 @@ public final class NotLoadingResourceSet extends ResourceSetImpl { } /** - * Adds ResourceSetHook extension point. {@inheritDoc} + * {@inheritDoc} * * @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#demandLoadHelper(org.eclipse.emf.ecore.resource.Resource) */ @@ -308,6 +303,8 @@ public final class NotLoadingResourceSet extends ResourceSetImpl { */ @Override public Resource getResource(URI uri, boolean loadOnDemand) { + checkNotDisposed(); + ILoadOnDemandPolicy.Registry registry = EMFCompareRCPPlugin.getDefault() .getLoadOnDemandPolicyRegistry(); if (registry.hasAnyAuthorizingPolicy(uri)) { @@ -381,4 +378,118 @@ public final class NotLoadingResourceSet extends ResourceSetImpl { } } } + + /** + * Loads resources from the {@link StorageTraversal}. + * + * @see #storageTranversal + * @param monitor + * {@link IProgressMonitor} reporting progress. + */ + private void load(IProgressMonitor monitor) { + checkNotDisposed(); + + final Collection<URI> urisToLoad = ImmutableList.copyOf(transform(storageTranversal.getStorages(), + TO_URI)); + + final Collection<IResourceSetHook> hooks = getMatchingHooks(urisToLoad); + + for (IResourceSetHook hook : hooks) { + hook.preLoadingHook(this, urisToLoad); + } + + for (URI uri : urisToLoad) { + if (monitor.isCanceled()) { + throw new OperationCanceledException(); + } + // Forces the loading of the selected resources. + loadResource(uri); + monitor.worked(1); + } + + for (IResourceSetHook hook : hooks) { + hook.postLoadingHook(this, urisToLoad); + } + + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.ide.internal.utils.DisposableResourceSet#dispose() + */ + public void dispose() { + ImmutableList<Resource> currentResources = ImmutableList.copyOf(getResources()); + isDisposed = true; + Collection<URI> resourceSetUris = newArrayList(transform(currentResources, + new Function<Resource, URI>() { + + public URI apply(Resource input) { + return input.getURI(); + } + })); + for (IResourceSetHook hook : getMatchingHooks(resourceSetUris)) { + hook.onDispose(currentResources); + } + getResources().clear(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#createResource(org.eclipse.emf.common.util.URI, + * java.lang.String) + */ + @Override + public Resource createResource(URI uri, String contentType) { + checkNotDisposed(); + return super.createResource(uri, contentType); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#getEObject(org.eclipse.emf.common.util.URI, + * boolean) + */ + @Override + public EObject getEObject(URI uri, boolean loadOnDemand) { + checkNotDisposed(); + return super.getEObject(uri, loadOnDemand); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#getAllContents() + */ + @Override + public TreeIterator<Notifier> getAllContents() { + checkNotDisposed(); + return super.getAllContents(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#getResources() + */ + @Override + public EList<Resource> getResources() { + checkNotDisposed(); + return super.getResources(); + } + + /** + * Checks that the resource set is not disposed. If it is throws an {@link IllegalStateException}. + * + * @throws IllegalStateException + * If the resource set is disposed. + */ + private void checkNotDisposed() { + if (isDisposed) { + throw new IllegalStateException("The resource set is disposed"); //$NON-NLS-1$ + } + } + } diff --git a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/UnloadingResourceSetHook.java b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/UnloadingResourceSetHook.java new file mode 100644 index 000000000..fe95f17de --- /dev/null +++ b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/UnloadingResourceSetHook.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2014 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.ide.internal.utils; + +import org.eclipse.emf.compare.ide.hook.AbstractResourceSetHooks; +import org.eclipse.emf.ecore.resource.Resource; + +/** + * Hook that unloads resources from the resource set on dipose. + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + */ +public class UnloadingResourceSetHook extends AbstractResourceSetHooks { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.ide.hook.AbstractResourceSetHooks#onDispose(java.lang.Iterable) + */ + @Override + public void onDispose(Iterable<Resource> resources) { + for (Resource resource : resources) { + if (resource.isLoaded()) { + resource.unload(); + } + } + } + +} |