diff options
author | Florian Noyrit | 2020-11-16 11:14:26 +0000 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org | 2020-11-16 11:14:26 +0000 |
commit | ea60f8632885b1f425b2a17e6b42e396a2d1122d (patch) | |
tree | dfb9d2b9de0c672cfcdca18c88bf04d4582573cd | |
parent | f7b8b482de2a6c66c44c8e759be213bc8ca0d914 (diff) | |
parent | ab85a7c5a44282ba808a84bf2104f0262204dee3 (diff) | |
download | org.eclipse.papyrus-collaborativemodeling-ea60f8632885b1f425b2a17e6b42e396a2d1122d.tar.gz org.eclipse.papyrus-collaborativemodeling-ea60f8632885b1f425b2a17e6b42e396a2d1122d.tar.xz org.eclipse.papyrus-collaborativemodeling-ea60f8632885b1f425b2a17e6b42e396a2d1122d.zip |
Merge "[CDO] Various improvements to CDOAwareModelSet, CDOSashModelProvider, and CDOContextStorageProvider"
3 files changed, 142 insertions, 144 deletions
diff --git a/cdo/bundles/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/resource/CDOAwareModelSet.java b/cdo/bundles/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/resource/CDOAwareModelSet.java index bfbda810..0dd6b936 100755 --- a/cdo/bundles/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/resource/CDOAwareModelSet.java +++ b/cdo/bundles/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/core/resource/CDOAwareModelSet.java @@ -21,7 +21,6 @@ package org.eclipse.papyrus.cdo.core.resource; import java.io.IOException; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; @@ -38,10 +37,6 @@ import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; import org.eclipse.emf.cdo.dawn.gmf.util.DawnDiagramUpdater; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.eresource.CDOResourceNode; -import org.eclipse.emf.cdo.explorer.CDOExplorerUtil; -import org.eclipse.emf.cdo.explorer.checkouts.CDOCheckout; -import org.eclipse.emf.cdo.explorer.checkouts.ResourceSetConfigurer; -import org.eclipse.emf.cdo.internal.explorer.checkouts.CDOCheckoutViewProvider; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.util.CDOUtil; import org.eclipse.emf.cdo.util.CommitException; @@ -49,6 +44,8 @@ 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.notify.Notification; +import org.eclipse.emf.common.notify.impl.AdapterImpl; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; @@ -57,9 +54,10 @@ import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.spi.cdo.FSMUtil; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gmf.runtime.notation.Diagram; +import org.eclipse.net4j.util.collection.AbstractFilteredIterator; +import org.eclipse.net4j.util.event.EventUtil; import org.eclipse.net4j.util.event.IEvent; import org.eclipse.net4j.util.event.IListener; -import org.eclipse.net4j.util.lifecycle.LifecycleUtil; import org.eclipse.papyrus.cdo.internal.core.CDOUtils; import org.eclipse.papyrus.cdo.internal.core.controlmode.CDOControlModeParticipant; import org.eclipse.papyrus.cdo.internal.core.controlmode.CDOProxyManager; @@ -67,7 +65,6 @@ import org.eclipse.papyrus.infra.core.Activator; 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.ImmutableList; import com.google.common.collect.Iterables; @@ -76,6 +73,9 @@ import com.google.common.collect.Iterables; */ public class CDOAwareModelSet extends OnDemandLoadingModelSet { + @SuppressWarnings("restriction") + private static final String SCHEME = org.eclipse.emf.cdo.internal.explorer.checkouts.CDOCheckoutViewProvider.SCHEME; + private static final Set<CDOState> DIRTY_STATES = EnumSet.of(CDOState.NEW, CDOState.DIRTY, CDOState.CONFLICT, CDOState.INVALID_CONFLICT); private final ThreadLocal<Boolean> inGetResource = new ThreadLocal<Boolean>(); @@ -83,21 +83,26 @@ public class CDOAwareModelSet extends OnDemandLoadingModelSet { private final CDOProxyManager proxyManager = new CDOProxyManager(this); private final PapyrusCDOResourceFactory resourceFactory = new PapyrusCDOResourceFactory(this); - - private CDOCheckout checkout; + + private final Adapter viewSetAdapter = new ViewSetAdapter(); + + private final IListener invalidationListener = new InvalidationListener(); private CDOView view; - private IListener invalidationListener; + private boolean unloading; - public CDOAwareModelSet() { - super(); + public CDOAwareModelSet() { this.resources = new SafeResourceList(); Map<String, Object> map = getResourceFactoryRegistry().getProtocolToFactoryMap(); map.put(CDOProtocolConstants.PROTOCOL_NAME, resourceFactory); - map.put(CDOCheckoutViewProvider.SCHEME, resourceFactory); + map.put(SCHEME, resourceFactory); + } + + public final IListener getInvalidationListener() { + return invalidationListener; } @Override @@ -110,7 +115,7 @@ public class CDOAwareModelSet extends OnDemandLoadingModelSet { if (CDOUtils.isCDOURI(uri)) { return getCDOObject(uri, loadOnDemand); } - + return super.getEObject(uri, loadOnDemand); } @@ -120,8 +125,8 @@ public class CDOAwareModelSet extends OnDemandLoadingModelSet { // instance that it needs (otherwise the 'non-null constraint' of // all kinds of reference lists will be violated) return proxyManager.getProxy(uri); - } - + } + return super.getEObject(uri, loadOnDemand); } @@ -144,18 +149,13 @@ public class CDOAwareModelSet extends OnDemandLoadingModelSet { @Override public Resource createResource(URI uri, String contentType) { Resource resource = super.createResource(uri, contentType); - initTransaction(resource); + initView(resource); return resource; } @Override protected void demandLoad(Resource resource) throws IOException { URI uri = resource.getURI(); - - // if (CDOCheckoutViewProvider.SCHEME.equals(uri.scheme())) { - // - // } else - if (CDOUtils.isCDOURI(uri)) { // XML options not applicable to CDO resources resource.load(null); @@ -165,7 +165,7 @@ public class CDOAwareModelSet extends OnDemandLoadingModelSet { super.demandLoad(resource); } - initTransaction(resource); + initView(resource); } @Override @@ -217,130 +217,64 @@ public class CDOAwareModelSet extends OnDemandLoadingModelSet { } } - protected void initTransaction(Resource resource) { - if (resource instanceof CDOResource) { - CDOResource cdoResource = (CDOResource) resource; - view = cdoResource.cdoView(); - + protected void initView(Resource resource) { + if (view == null && resource instanceof CDOResource) { + view = ((CDOResource) resource).cdoView(); if (view != null) { - final IListener invalidationListener = getInvalidationListener(); - if (false == Arrays.asList(view.getListeners()).contains(invalidationListener)) { - view.addListener(getInvalidationListener()); - checkout = CDOExplorerUtil.getCheckout(view); - ResourceSetConfigurer.Registry.INSTANCE.configureResourceSet(this, checkout); + CDOViewSet viewSet = view.getViewSet(); + + for (CDOView v : viewSet.getViews()) { + EventUtil.addUniqueListener(v, invalidationListener); } - // URI from = URI.createURI("cdo://" + view.getSession().getRepositoryInfo().getName() + "/"); - // URI to = URI.createURI("cdo.checkout://" + checkout.getID() + "/" + checkout.getRepository().getID() + "/"); - // getURIConverter().getURIMap().put(from, to); + viewSet.eAdapters().add(viewSetAdapter); + + // Don't clear adapters of the resource because ECrossReferenceAdapters would try to crawl the contents. + viewSet.setDefaultClearAdapterPolicy((object, adapter) -> !(object instanceof CDOResourceNode)); } } } @Override public void unload() { - boolean logError = true; + boolean logError = view == null || !view.isClosed(); + try { - logError = view == null || !view.isClosed(); + if (view != null) { + CDOViewSet viewSet = view.getViewSet(); + viewSet.eAdapters().remove(viewSetAdapter); + + for (CDOView v : viewSet.getViews()) { + EventUtil.removeListener(v, invalidationListener); + } + } - // CDOResources don't implement unload(), but we can remove adapters from - // all of the objects that we have loaded in this view - if (view != null && !view.isClosed()) { - CDOUtils.unload(view); + unloading = true; + super.unload(); + } catch (Exception ex) { + if (logError) { + Activator.log.error(ex); } } finally { - try { - super.unload(); - } catch (Exception ex) { - if (logError) { - Activator.log.error(ex); - } - } finally { - LifecycleUtil.deactivate(view); - CDOCheckoutViewProvider.disposeResourceSet(this); + unloading = false; - // now, we can remove the CDOViewSet adapter - eAdapters().clear(); + // Unload and remove the resources that were omitted in super.unload() + // because of CDOAwareModelSet.SafeResourceList.iterator(). + EList<Resource> resources = getResources(); + for (Resource resource : resources) { + resource.unload(); } - } - } - protected final IListener getInvalidationListener() { - if (invalidationListener == null) { - invalidationListener = createInvalidationListener(); + resources.clear(); } - return invalidationListener; } - protected IListener createInvalidationListener() { - return new InvalidationListener(); - } - - private class InvalidationListener implements IListener { - @Override - public void notifyEvent(IEvent event) { - if (event instanceof CDOViewInvalidationEvent) { - TransactionalEditingDomain domain = getTransactionalEditingDomain(); - if (domain instanceof CDOAwareTransactionalEditingDomain) { - ((CDOAwareTransactionalEditingDomain) domain).fireResourceSetChanged((CDOViewInvalidationEvent) event); - } - } - } - } @Override public boolean isUserModelResource(URI uri) { return super.isUserModelResource(uri) || CDOUtils.isCDOURI(uri); } - @Override - public EList<Adapter> eAdapters() { - if (eAdapters == null) { - eAdapters = new EAdapterList<Adapter>(this) { - - private static final long serialVersionUID = 1L; - - @Override - public Adapter remove(int index) { - Adapter toRemove = primitiveGet(index); - if ((toRemove instanceof CDOViewSet) && !canDisconnectCDOViewSet()) { - // 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 (!canDisconnectCDOViewSet()) { - // 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 canDisconnectCDOViewSet() { - CDOView view = getCDOView(); - return ((view == null) || view.isClosed()) && getResources().isEmpty(); - } - boolean isDirty(Resource resource) { return (resource instanceof CDOResource) && DIRTY_STATES.contains(((CDOResource) resource).cdoState()); } @@ -475,22 +409,85 @@ public class CDOAwareModelSet extends OnDemandLoadingModelSet { // /** - * CDO doesn't permit resources to be removed from the resource set if they are {@linkplain CDOState#DIRTY dirty}, so this specialized list - * prevents that. + * CDO doesn't permit resources to be removed from the resource set if they are {@linkplain CDOState#DIRTY dirty}, + * so this specialized list prevents that. + * + * It also prevents early removal of CDOResources during {@link CDOAwareModelSet#unload() unload()}. + * + * @author Eike Stepper */ private class SafeResourceList extends ResourcesEList<Resource> { - private static final long serialVersionUID = 1L; + public SafeResourceList() { + } + @Override public boolean remove(Object object) { - boolean result = !(object instanceof CDOResource) || !isDirty((CDOResource) object); + if (object instanceof CDOResource && isDirty((CDOResource) object)) { + return false; + } + + return super.remove(object); + } + + @Override + public Iterator<Resource> iterator() { + Iterator<Resource> delegate = super.iterator(); + + if (unloading) { + return new AbstractFilteredIterator<Resource>(delegate) { + @Override + protected boolean isValid(Resource resource) { + return !(resource instanceof CDOResource); + } + }; + } + + return delegate; + } + } + + /** + * @author Eike Stepper + */ + private final class ViewSetAdapter extends AdapterImpl { + + public ViewSetAdapter() { + } + + @Override + public void notifyChanged(Notification notification) { + switch (notification.getEventType()) { + case Notification.ADD: + CDOView newView = (CDOView) notification.getNewValue(); + EventUtil.addUniqueListener(newView, invalidationListener); + break; - if (result) { - result = super.remove(object); + case Notification.REMOVE: + CDOView oldView = (CDOView) notification.getOldValue(); + EventUtil.removeListener(oldView, invalidationListener); + break; } + } + } - return result; + /** + * @author Eike Stepper + */ + private final class InvalidationListener implements IListener { + + public InvalidationListener() { + } + + @Override + public void notifyEvent(IEvent event) { + if (event instanceof CDOViewInvalidationEvent) { + TransactionalEditingDomain domain = getTransactionalEditingDomain(); + if (domain instanceof CDOAwareTransactionalEditingDomain) { + ((CDOAwareTransactionalEditingDomain) domain).fireResourceSetChanged((CDOViewInvalidationEvent) event); + } + } } } } diff --git a/cdo/bundles/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/resource/CDOSashModelProvider.java b/cdo/bundles/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/resource/CDOSashModelProvider.java index 0424340e..297cfd87 100755 --- a/cdo/bundles/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/resource/CDOSashModelProvider.java +++ b/cdo/bundles/org.eclipse.papyrus.cdo.core/src/org/eclipse/papyrus/cdo/internal/core/resource/CDOSashModelProvider.java @@ -13,7 +13,8 @@ *****************************************************************************/ package org.eclipse.papyrus.cdo.internal.core.resource; -import org.eclipse.core.runtime.IPath; +import java.io.File; + import org.eclipse.emf.cdo.explorer.CDOExplorerUtil; import org.eclipse.emf.cdo.explorer.checkouts.CDOCheckout; import org.eclipse.emf.cdo.util.CDOURIUtil; @@ -29,12 +30,11 @@ import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModel; */ public class CDOSashModelProvider extends AbstractSashModelProvider { - private static final IPath SASH_MODEL_STORAGE_ROOT = Activator.getDefault().getStateLocation().append("sashidx"); //$NON-NLS-1$ + private static final String BASE_FOLDER_NAME = "sashidx"; // $NON-NLS-1$ - private IPath indexFolder; + private File indexFolder; public CDOSashModelProvider() { - super(); } @Override @@ -43,23 +43,23 @@ public class CDOSashModelProvider extends AbstractSashModelProvider { CDOCheckout checkout = CDOExplorerUtil.getCheckout(modelSet); if (checkout != null) { - initialize(checkout); + indexFolder = checkout.getStateFolder(BASE_FOLDER_NAME, true); } else { - // Model probably is in the workspace if null - indexFolder = SASH_MODEL_STORAGE_ROOT; + indexFolder = new File(Activator.getDefault().getStateLocation().toFile(), BASE_FOLDER_NAME); + Activator.log.debug("CDOSashModelProvider can not find a checkout for model set " + modelSet + ". Storing sash models in " + indexFolder); } } - public CDOSashModelProvider initialize(CDOCheckout checkout) { - indexFolder = SASH_MODEL_STORAGE_ROOT.append(checkout.getView().getSession().getRepositoryInfo().getUUID()); - return this; + @Override + public void dispose() { + indexFolder = null; + super.dispose(); } @Override public URI getSashModelURI(URI userModelURI) { - URI uriWithoutExtension = userModelURI.trimFileExtension(); - IPath stateLocation = indexFolder.append(CDOURIUtil.extractResourcePath(uriWithoutExtension)); - return URI.createFileURI(stateLocation.toString()).appendFileExtension(SashModel.SASH_MODEL_FILE_EXTENSION); + String relativePath = CDOURIUtil.extractResourcePath(userModelURI.trimFileExtension()); + String path = new File(indexFolder, relativePath).getAbsolutePath(); + return URI.createFileURI(path).appendFileExtension(SashModel.SASH_MODEL_FILE_EXTENSION); } - } diff --git a/cdo/bundles/org.eclipse.papyrus.cdo.ui.customization.properties/src/org/eclipse/papyrus/cdo/internal/ui/customization/properties/storage/CDOContextStorageProvider.java b/cdo/bundles/org.eclipse.papyrus.cdo.ui.customization.properties/src/org/eclipse/papyrus/cdo/internal/ui/customization/properties/storage/CDOContextStorageProvider.java index 0300631d..5fb80d5c 100755 --- a/cdo/bundles/org.eclipse.papyrus.cdo.ui.customization.properties/src/org/eclipse/papyrus/cdo/internal/ui/customization/properties/storage/CDOContextStorageProvider.java +++ b/cdo/bundles/org.eclipse.papyrus.cdo.ui.customization.properties/src/org/eclipse/papyrus/cdo/internal/ui/customization/properties/storage/CDOContextStorageProvider.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.Collections; import org.eclipse.core.runtime.CoreException; +import org.eclipse.emf.cdo.common.util.CDOResourceNodeNotFoundException; import org.eclipse.emf.cdo.eresource.CDOResourceFolder; import org.eclipse.emf.cdo.eresource.CDOTextResource; import org.eclipse.emf.cdo.explorer.CDOExplorerUtil; @@ -200,7 +201,7 @@ public class CDOContextStorageProvider extends AbstractContextStorageProvider { try { folder = checkout.getView().getResourceFolder(CONTEXTS_PATH); - } catch (Exception e) { + } catch (CDOResourceNodeNotFoundException e) { // normal consequence when the folder doesn't exist } |