From 54a1f4ae74f0bca91c4626216c11eea7806d4265 Mon Sep 17 00:00:00 2001 From: Christian W. Damus Date: Thu, 5 Sep 2013 14:40:58 -0400 Subject: 416655: [CDO] Failing JUnit test ModelValidationMarkersTest::testMemoryLeaksInValidation https://bugs.eclipse.org/bugs/show_bug.cgi?id=416655 Do the ModelSet disposal sequence before closing the CDO transaction. However, this requires preventing removal of the CDOViewSet adapter from the CDOAwareModelSet until such time as the transaction is closed. --- .../cdo/core/resource/CDOAwareModelSet.java | 79 +++++++++++++++++++--- 1 file changed, 68 insertions(+), 11 deletions(-) diff --git a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/resource/CDOAwareModelSet.java b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/resource/CDOAwareModelSet.java index 5d3a70a41b0..150bb5e73fe 100644 --- a/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/resource/CDOAwareModelSet.java +++ b/extraplugins/cdo/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/resource/CDOAwareModelSet.java @@ -12,12 +12,15 @@ package org.eclipse.papyrus.cdo.core.resource; import java.io.IOException; +import java.util.Collections; import org.eclipse.emf.cdo.dawn.gmf.util.DawnDiagramUpdater; import org.eclipse.emf.cdo.util.CDOUtil; import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent; import org.eclipse.emf.cdo.view.CDOViewSet; +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; @@ -31,6 +34,7 @@ import org.eclipse.papyrus.cdo.internal.core.CDOUtils; import org.eclipse.papyrus.infra.core.resource.ModelMultiException; import org.eclipse.papyrus.infra.services.resourceloading.OnDemandLoadingModelSet; +import com.google.common.base.Predicates; import com.google.common.collect.Iterables; /** @@ -146,20 +150,25 @@ public class CDOAwareModelSet extends OnDemandLoadingModelSet { @Override public void unload() { - if((repository != null) && (getCDOView() != null)) { - CDOView view = getCDOView(); - if(view != null) { - view.removeListener(getInvalidationListener()); - } - invalidationListener = null; + try { + super.unload(); + } finally { + if((repository != null) && (getCDOView() != null)) { + CDOView view = getCDOView(); + if(view != null) { + view.removeListener(getInvalidationListener()); + } + invalidationListener = null; - // dispose the transaction - repository.close(this); - } + // dispose the transaction + repository.close(this); - repository = null; + // now, we can remove the CDOViewSet adapter + eAdapters().clear(); + } - super.unload(); + repository = null; + } } protected final IListener getInvalidationListener() { @@ -182,4 +191,52 @@ public class CDOAwareModelSet extends OnDemandLoadingModelSet { } }; } + + @Override + public EList eAdapters() { + if(eAdapters == null) { + eAdapters = new EAdapterList(this) { + + private static final long serialVersionUID = 1L; + + @Override + public Adapter remove(int index) { + Adapter toRemove = primitiveGet(index); + if((toRemove instanceof CDOViewSet) && isViewActive()) { + // don't allow its removal if my view is still open! + // (Papyrus attempts to clear the resource set's adapters when disposing a ModelSet) + return null; + } + + return super.remove(index); + } + + @Override + public void clear() { + if(isViewActive()) { + // we can remove everything but the view-set adapter + Adapter viewSetAdapter = getViewSetAdapter(); + if(viewSetAdapter != null) { + retainAll(Collections.singleton(viewSetAdapter)); + } else { + super.clear(); + } + } else { + super.clear(); + } + } + + private Adapter getViewSetAdapter() { + return Iterables.find(this, Predicates.instanceOf(CDOViewSet.class), null); + } + }; + } + + return eAdapters; + } + + private boolean isViewActive() { + CDOView view = getCDOView(); + return (view != null) && !view.isClosed(); + } } -- cgit v1.2.3