diff options
author | Eike Stepper | 2011-08-23 16:47:33 +0000 |
---|---|---|
committer | Eike Stepper | 2011-08-23 16:47:33 +0000 |
commit | d7db03e03e68812d6502d914610cf1ab84f3fa85 (patch) | |
tree | 7d4a261a78b5bbcf29a920badc3733affb1d6111 | |
parent | 763bd76462dfc27b1ed0d26d5765487eddddc3d9 (diff) | |
download | cdo-d7db03e03e68812d6502d914610cf1ab84f3fa85.tar.gz cdo-d7db03e03e68812d6502d914610cf1ab84f3fa85.tar.xz cdo-d7db03e03e68812d6502d914610cf1ab84f3fa85.zip |
[355537] Add isDirty() and DirtyStateChangedEvents to CDOWorkspace
https://bugs.eclipse.org/bugs/show_bug.cgi?id=355537
8 files changed, 312 insertions, 30 deletions
diff --git a/plugins/org.eclipse.emf.cdo.workspace/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.workspace/META-INF/MANIFEST.MF index 557cc9b243..ec86021070 100644 --- a/plugins/org.eclipse.emf.cdo.workspace/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.workspace/META-INF/MANIFEST.MF @@ -8,11 +8,12 @@ Bundle-Localization: plugin Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)";resolution:=optional, + org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)";resolution:=optional, org.eclipse.emf.cdo.server;bundle-version="[4.0.0,5.0.0)";visibility:=reexport, org.eclipse.emf.cdo.server.net4j;bundle-version="[4.0.0,5.0.0)", org.eclipse.emf.cdo.net4j;bundle-version="[4.0.0,5.0.0)", org.eclipse.net4j.jvm;bundle-version="[4.0.0,5.0.0)" -Export-Package: org.eclipse.emf.cdo.internal.workspace;version="4.1.0";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db", +Export-Package: org.eclipse.emf.cdo.internal.workspace;version="4.1.0";x-friends:="org.eclipse.emf.cdo.tests,org.eclipse.emf.cdo.tests.db,org.eclipse.emf.cdo.ui.workspace", org.eclipse.emf.cdo.internal.workspace.bundle;version="4.1.0";x-internal:=true, org.eclipse.emf.cdo.spi.workspace;version="4.1.0", org.eclipse.emf.cdo.workspace;version="4.1.0" diff --git a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/AbstractCDOWorkspaceBase.java b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/AbstractCDOWorkspaceBase.java index 6d2d06fdb3..696ed156ba 100644 --- a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/AbstractCDOWorkspaceBase.java +++ b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/AbstractCDOWorkspaceBase.java @@ -26,6 +26,7 @@ import org.eclipse.emf.cdo.spi.server.InternalStore; import org.eclipse.emf.cdo.spi.workspace.InternalCDOWorkspace; import org.eclipse.emf.cdo.spi.workspace.InternalCDOWorkspaceBase; import org.eclipse.emf.cdo.transaction.CDOTransaction; +import org.eclipse.emf.cdo.workspace.CDOWorkspaceBase2; import org.eclipse.net4j.util.io.ExtendedDataInputStream; import org.eclipse.net4j.util.io.ExtendedDataOutputStream; @@ -38,7 +39,7 @@ import java.util.Set; /** * @author Eike Stepper */ -public abstract class AbstractCDOWorkspaceBase implements InternalCDOWorkspaceBase +public abstract class AbstractCDOWorkspaceBase implements InternalCDOWorkspaceBase, CDOWorkspaceBase2 { private InternalCDOWorkspace workspace; @@ -48,6 +49,8 @@ public abstract class AbstractCDOWorkspaceBase implements InternalCDOWorkspaceBa private InternalCDOBranchManager branchManager; + private Set<CDOID> ids; + protected AbstractCDOWorkspaceBase() { } @@ -61,12 +64,22 @@ public abstract class AbstractCDOWorkspaceBase implements InternalCDOWorkspaceBa branchManager = localRepository.getBranchManager(); } - public InternalCDOWorkspace getWorkspace() + public final InternalCDOWorkspace getWorkspace() { return workspace; } - public void updateAfterCommit(CDOTransaction transaction) + public final synchronized Set<CDOID> getIDs() + { + if (ids == null) + { + ids = doGetIDs(); + } + + return ids; + } + + public final synchronized void updateAfterCommit(CDOTransaction transaction) { InternalCDOTransaction tx = (InternalCDOTransaction)transaction; Set<CDOID> dirtyObjects = tx.getDirtyObjects().keySet(); @@ -78,10 +91,16 @@ public abstract class AbstractCDOWorkspaceBase implements InternalCDOWorkspaceBa { if (isAddedObject(id)) { + if (ids != null) + { + ids.remove(id); + } + deregisterObject(id); } else { + getIDs().add(id); registerChangedOrDetachedObject(revision); } } @@ -90,10 +109,28 @@ public abstract class AbstractCDOWorkspaceBase implements InternalCDOWorkspaceBa // Don't use keySet() because only the values() are ID-mapped! for (CDOObject object : tx.getNewObjects().values()) { - registerAddedObject(object.cdoID()); + CDOID id = object.cdoID(); + getIDs().add(id); + registerAddedObject(id); } } + public final synchronized void clear() + { + ids = null; + doClear(); + } + + public final synchronized boolean isEmpty() + { + return ids == null || ids.isEmpty(); + } + + public final synchronized boolean containsID(CDOID id) + { + return getIDs().contains(id); + } + protected boolean isAddedObject(CDOID id) { // throw new RuntimeException("Check whether CDOID.isLocal() is still valid with UUIDs"); @@ -114,6 +151,10 @@ public abstract class AbstractCDOWorkspaceBase implements InternalCDOWorkspaceBa return CDOCommonUtil.createCDODataOutput(edos, packageRegistry, idProvider); } + protected abstract void doClear(); + + protected abstract Set<CDOID> doGetIDs(); + protected abstract void registerChangedOrDetachedObject(InternalCDORevision revision); protected abstract void registerAddedObject(CDOID id); diff --git a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/CDOWorkspaceImpl.java b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/CDOWorkspaceImpl.java index d80ab02ae1..aea0f1b6c6 100644 --- a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/CDOWorkspaceImpl.java +++ b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/CDOWorkspaceImpl.java @@ -60,6 +60,8 @@ import org.eclipse.emf.cdo.transaction.CDOTransactionFinishedEvent; import org.eclipse.emf.cdo.util.CommitException; import org.eclipse.emf.cdo.util.ReadOnlyException; import org.eclipse.emf.cdo.view.CDOView; +import org.eclipse.emf.cdo.workspace.CDOWorkspace; +import org.eclipse.emf.cdo.workspace.CDOWorkspaceUtil; import org.eclipse.net4j.Net4jUtil; import org.eclipse.net4j.jvm.IJVMAcceptor; @@ -69,8 +71,10 @@ import org.eclipse.net4j.signal.ISignalProtocol; import org.eclipse.net4j.util.StringUtil; import org.eclipse.net4j.util.container.ContainerUtil; import org.eclipse.net4j.util.container.IManagedContainer; +import org.eclipse.net4j.util.event.Event; import org.eclipse.net4j.util.event.IEvent; import org.eclipse.net4j.util.event.IListener; +import org.eclipse.net4j.util.event.Notifier; import org.eclipse.net4j.util.lifecycle.ILifecycle; import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter; import org.eclipse.net4j.util.lifecycle.LifecycleUtil; @@ -96,7 +100,7 @@ import java.util.Set; /** * @author Eike Stepper */ -public class CDOWorkspaceImpl implements InternalCDOWorkspace +public class CDOWorkspaceImpl extends Notifier implements InternalCDOWorkspace { private static final String PROP_BRANCH_PATH = "org.eclipse.emf.cdo.workspace.branchPath"; //$NON-NLS-1$ @@ -124,6 +128,8 @@ public class CDOWorkspaceImpl implements InternalCDOWorkspace private boolean fixed; + private boolean dirty; + private CDOSessionConfigurationFactory remoteSessionConfigurationFactory; private Set<InternalCDOView> views = new HashSet<InternalCDOView>(); @@ -162,6 +168,12 @@ public class CDOWorkspaceImpl implements InternalCDOWorkspace this.base = base; this.base.init(this); + setDirtyFromBase(); + } + + private void setDirtyFromBase() + { + setDirty(!CDOWorkspaceUtil.getWorkspaceBase2(base).isEmpty()); } protected void checkout() @@ -231,6 +243,31 @@ public class CDOWorkspaceImpl implements InternalCDOWorkspace return fixed; } + public boolean isDirty() + { + return dirty; + } + + protected void setDirty(boolean dirty) + { + if (this.dirty != dirty) + { + this.dirty = dirty; + fireEvent(new DirtyStateChangedEventImpl(this, dirty)); + } + } + + protected void clearBase() + { + base.clear(); + setDirty(false); + } + + public IDGenerationLocation getIDGenerationLocation() + { + return idGenerationLocation; + } + public CDOIDGenerator getIDGenerator() { return idGenerator; @@ -306,7 +343,7 @@ public class CDOWorkspaceImpl implements InternalCDOWorkspace @Override public void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext) { - base.clear(); + clearBase(); } }); @@ -378,7 +415,8 @@ public class CDOWorkspaceImpl implements InternalCDOWorkspace // adjustLocalIDs(idMapper, result.getAdjustedObjects()); // } - base.clear(); + clearBase(); + timeStamp = info.getTimeStamp(); saveProperties(); @@ -547,6 +585,11 @@ public class CDOWorkspaceImpl implements InternalCDOWorkspace return CDORevisionUtil.createChangeSetData(ids, base, this); } + public CDOSessionConfigurationFactory getRemoteSessionConfigurationFactory() + { + return remoteSessionConfigurationFactory; + } + protected IManagedContainer createContainer(IStore local) { IManagedContainer container = ContainerUtil.createContainer(); @@ -660,17 +703,7 @@ public class CDOWorkspaceImpl implements InternalCDOWorkspace views.add((InternalCDOView)view); } - view.addListener(new LifecycleEventAdapter() - { - @Override - protected void onDeactivated(ILifecycle view) - { - synchronized (views) - { - views.remove(view); - } - } - }); + view.addListener(new ViewAdapter()); if (view instanceof CDOTransaction) { @@ -706,11 +739,7 @@ public class CDOWorkspaceImpl implements InternalCDOWorkspace protected void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext) { base.updateAfterCommit(transaction); - } - - protected CDOSessionConfigurationFactory getRemoteSessionConfigurationFactory() - { - return remoteSessionConfigurationFactory; + setDirtyFromBase(); } protected InternalCDOSession openRemoteSession() @@ -752,4 +781,49 @@ public class CDOWorkspaceImpl implements InternalCDOWorkspace timeStamp = Long.parseLong(props.get(PROP_TIME_STAMP)); fixed = Boolean.parseBoolean(props.get(PROP_FIXED)); } + + /** + * @author Eike Stepper + */ + public final class ViewAdapter extends LifecycleEventAdapter + { + public ViewAdapter() + { + } + + public CDOWorkspace getWorkspace() + { + return CDOWorkspaceImpl.this; + } + + @Override + protected void onDeactivated(ILifecycle view) + { + synchronized (views) + { + views.remove(view); + } + } + } + + /** + * @author Eike Stepper + */ + private static final class DirtyStateChangedEventImpl extends Event implements DirtyStateChangedEvent + { + private static final long serialVersionUID = 1L; + + private boolean dirty; + + public DirtyStateChangedEventImpl(CDOWorkspace workspace, boolean dirty) + { + super(workspace); + this.dirty = dirty; + } + + public boolean isDirty() + { + return dirty; + } + } } diff --git a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/FolderCDOWorkspaceBase.java b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/FolderCDOWorkspaceBase.java index 0db8d6ce77..d8d0395222 100644 --- a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/FolderCDOWorkspaceBase.java +++ b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/internal/workspace/FolderCDOWorkspaceBase.java @@ -48,14 +48,22 @@ public class FolderCDOWorkspaceBase extends AbstractCDOWorkspaceBase return folder; } - public void clear() + @Override + public String toString() + { + return "FolderBase[" + folder.getAbsolutePath() + "]"; + } + + @Override + protected void doClear() { IOUtil.delete(folder); checkExists(folder, false); createFolder(); } - public Set<CDOID> getIDs() + @Override + protected Set<CDOID> doGetIDs() { Set<CDOID> ids = new HashSet<CDOID>(); for (String key : folder.list()) @@ -67,7 +75,7 @@ public class FolderCDOWorkspaceBase extends AbstractCDOWorkspaceBase return ids; } - public CDORevision getRevision(CDOID id) + public final synchronized CDORevision getRevision(CDOID id) { File file = getFile(id); if (!file.exists() || file.length() == 0) diff --git a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/spi/workspace/InternalCDOWorkspace.java b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/spi/workspace/InternalCDOWorkspace.java index 3f90cf59c3..fc5df3e991 100644 --- a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/spi/workspace/InternalCDOWorkspace.java +++ b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/spi/workspace/InternalCDOWorkspace.java @@ -10,6 +10,8 @@ */ package org.eclipse.emf.cdo.spi.workspace; +import org.eclipse.emf.cdo.common.CDOCommonRepository.IDGenerationLocation; +import org.eclipse.emf.cdo.session.CDOSessionConfigurationFactory; import org.eclipse.emf.cdo.spi.server.InternalRepository; import org.eclipse.emf.cdo.workspace.CDOWorkspace; @@ -22,9 +24,19 @@ import org.eclipse.emf.spi.cdo.InternalCDOSession; */ public interface InternalCDOWorkspace extends CDOWorkspace { + /** + * @since 4.1 + */ + public IDGenerationLocation getIDGenerationLocation(); + public InternalCDOWorkspaceBase getBase(); public InternalRepository getLocalRepository(); public InternalCDOSession getLocalSession(); + + /** + * @since 4.1 + */ + public CDOSessionConfigurationFactory getRemoteSessionConfigurationFactory(); } diff --git a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/workspace/CDOWorkspace.java b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/workspace/CDOWorkspace.java index 4604bfd62c..e59a9503f0 100644 --- a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/workspace/CDOWorkspace.java +++ b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/workspace/CDOWorkspace.java @@ -19,6 +19,8 @@ import org.eclipse.emf.cdo.util.CommitException; import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.net4j.util.collection.Closeable; +import org.eclipse.net4j.util.event.IEvent; +import org.eclipse.net4j.util.event.INotifier; import org.eclipse.emf.ecore.resource.ResourceSet; @@ -29,7 +31,7 @@ import org.eclipse.emf.ecore.resource.ResourceSet; * @noextend This interface is not intended to be extended by clients. * @noimplement This interface is not intended to be implemented by clients. */ -public interface CDOWorkspace extends CDORevisionProvider, Closeable +public interface CDOWorkspace extends CDORevisionProvider, Closeable, INotifier { public String getBranchPath(); @@ -66,4 +68,18 @@ public interface CDOWorkspace extends CDORevisionProvider, Closeable public void replace(String branchPath, long timeStamp); public void revert(); + + /** + * @since 4.1 + */ + public boolean isDirty(); + + /** + * @author Eike Stepper + * @since 4.1 + */ + public interface DirtyStateChangedEvent extends IEvent + { + public boolean isDirty(); + } } diff --git a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/workspace/CDOWorkspaceBase2.java b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/workspace/CDOWorkspaceBase2.java new file mode 100644 index 0000000000..a5165bbebc --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/workspace/CDOWorkspaceBase2.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2004 - 2011 Eike Stepper (Berlin, Germany) and others. + * 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: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.emf.cdo.workspace; + +import org.eclipse.emf.cdo.common.id.CDOID; + +/** + * Adds {@link #isEmpty()} and {@link #containsID(CDOID)} methods. + * + * @author Eike Stepper + * @since 4.1 + */ +public interface CDOWorkspaceBase2 extends CDOWorkspaceBase +{ + public boolean isEmpty(); + + public boolean containsID(CDOID id); +} diff --git a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/workspace/CDOWorkspaceUtil.java b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/workspace/CDOWorkspaceUtil.java index 7552646962..b0bbe66f93 100644 --- a/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/workspace/CDOWorkspaceUtil.java +++ b/plugins/org.eclipse.emf.cdo.workspace/src/org/eclipse/emf/cdo/workspace/CDOWorkspaceUtil.java @@ -10,13 +10,22 @@ */ package org.eclipse.emf.cdo.workspace; +import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; -import org.eclipse.emf.cdo.internal.workspace.CDOWorkspaceConfigurationImpl; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.internal.workspace.FolderCDOWorkspaceBase; import org.eclipse.emf.cdo.server.IStore; import org.eclipse.emf.cdo.session.CDOSessionConfigurationFactory; +import org.eclipse.emf.cdo.util.CDOUtil; +import org.eclipse.emf.cdo.view.CDOView; + +import org.eclipse.net4j.util.event.IListener; + +import org.eclipse.emf.ecore.EObject; import java.io.File; +import java.util.Set; /** * Various static helper methods for dealing with {@link CDOWorkspace workspaces}. @@ -29,6 +38,63 @@ public final class CDOWorkspaceUtil { } + /** + * @since 4.1 + */ + public static CDOWorkspace getWorkspace(EObject object) + { + CDOView view = CDOUtil.getCDOObject(object).cdoView(); + if (view == null || view.isClosed()) + { + return null; + } + + IListener[] listeners = view.getListeners(); + if (listeners != null) + { + for (int i = 0; i < listeners.length; i++) + { + IListener listener = listeners[i]; + if (listener instanceof org.eclipse.emf.cdo.internal.workspace.CDOWorkspaceImpl.ViewAdapter) + { + org.eclipse.emf.cdo.internal.workspace.CDOWorkspaceImpl.ViewAdapter adapter = (org.eclipse.emf.cdo.internal.workspace.CDOWorkspaceImpl.ViewAdapter)listener; + return adapter.getWorkspace(); + } + } + } + + return null; + } + + /** + * @since 4.1 + */ + public static boolean isDirty(EObject object) + { + CDOObject cdoObject = CDOUtil.getCDOObject(object); + if (object == null) + { + return false; + } + + CDOWorkspace workspace = getWorkspace(cdoObject); + CDOWorkspaceBase2 base = getWorkspaceBase2(workspace.getBase()); + return base.containsID(cdoObject.cdoID()); + } + + /** + * @since 4.1 + */ + public static CDOWorkspaceBase2 getWorkspaceBase2(final CDOWorkspaceBase base) + { + if (base instanceof CDOWorkspaceBase2) + { + return (CDOWorkspaceBase2)base; + } + + return new DelegatingWorkspaceBase2(base); + } + public static CDOWorkspaceBase createFolderWorkspaceBase(File folder) { return new FolderCDOWorkspaceBase(folder); @@ -39,7 +105,7 @@ public final class CDOWorkspaceUtil */ public static CDOWorkspaceConfiguration createWorkspaceConfiguration() { - return new CDOWorkspaceConfigurationImpl(); + return new org.eclipse.emf.cdo.internal.workspace.CDOWorkspaceConfigurationImpl(); } /** @@ -99,4 +165,42 @@ public final class CDOWorkspaceUtil config.setTimeStamp(timeStamp); return config.checkout(); } + + /** + * @author Eike Stepper + */ + private static final class DelegatingWorkspaceBase2 implements CDOWorkspaceBase2 + { + private final CDOWorkspaceBase delegate; + + private DelegatingWorkspaceBase2(CDOWorkspaceBase base) + { + delegate = base; + } + + public CDOWorkspace getWorkspace() + { + return delegate.getWorkspace(); + } + + public Set<CDOID> getIDs() + { + return delegate.getIDs(); + } + + public CDORevision getRevision(CDOID id) + { + return delegate.getRevision(id); + } + + public boolean isEmpty() + { + return getIDs().isEmpty(); + } + + public boolean containsID(CDOID id) + { + return getIDs().contains(id); + } + } } |