diff options
17 files changed, 189 insertions, 150 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOProtocolSession.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOProtocolSession.java index e2cf2cd09a..c78342241c 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOProtocolSession.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/CDOProtocolSession.java @@ -28,5 +28,4 @@ public interface CDOProtocolSession * @since 2.0 */ public boolean isPassiveUpdateEnabled(); - } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java index cc0f60f78a..e4d23d518f 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java @@ -40,6 +40,7 @@ import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -57,7 +58,7 @@ public class Session extends Container<IView> implements ISession, CDOIDProvider private int sessionID; private boolean legacySupportEnabled; - + private boolean passiveUpdateEnabled = true; private ConcurrentMap<Integer, IView> views = new ConcurrentHashMap<Integer, IView>(); @@ -120,7 +121,7 @@ public class Session extends Container<IView> implements ISession, CDOIDProvider { this.passiveUpdateEnabled = passiveUpdateEnabled; } - + public View[] getElements() { return getViews(); @@ -220,16 +221,19 @@ public class Session extends Container<IView> implements ISession, CDOIDProvider */ public void handleCommitNotification(long timeStamp, List<CDOIDAndVersion> dirtyIDs, List<CDORevisionDelta> deltas) { - if (!isPassiveUpdateEnabled()) dirtyIDs = new ArrayList<CDOIDAndVersion>(); + if (!isPassiveUpdateEnabled()) + { + dirtyIDs = Collections.emptyList(); + } // Look if someone needs to know something about modified objects List<CDORevisionDelta> newDeltas = new ArrayList<CDORevisionDelta>(); for (CDORevisionDelta delta : deltas) { CDOID lookupID = delta.getID(); - for (IView view : views.values()) + for (View view : getViews()) { - if (((View)view).isSubscribe(lookupID)) + if (view.hasSubscription(lookupID)) { newDeltas.add(delta); break; @@ -238,7 +242,7 @@ public class Session extends Container<IView> implements ISession, CDOIDProvider } try { - if (dirtyIDs.size() > 0 || newDeltas.size() > 0) + if (!dirtyIDs.isEmpty() || !newDeltas.isEmpty()) new CommitNotificationRequest(protocol.getChannel(), this, timeStamp, dirtyIDs, newDeltas).send(); } catch (Exception ex) diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java index 39ebc6e92a..bcfadf5fc8 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java @@ -15,8 +15,8 @@ import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.server.IView; import java.text.MessageFormat; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.HashSet; +import java.util.Set; /** * @author Eike Stepper @@ -29,7 +29,7 @@ public class View implements IView private Type viewType; - private Map<CDOID, CDOID> changeSubscriptionObjects = new ConcurrentHashMap<CDOID, CDOID>(); + private Set<CDOID> changeSubscriptionIDs = new HashSet<CDOID>(); public View(Session session, int viewID, Type viewType) { @@ -53,24 +53,24 @@ public class View implements IView return viewType; } - public void subscribe(CDOID id) + synchronized public void subscribe(CDOID id) { - changeSubscriptionObjects.put(id, id); + changeSubscriptionIDs.add(id); } - public void unsubscribe(CDOID id) + synchronized public void unsubscribe(CDOID id) { - changeSubscriptionObjects.remove(id); + changeSubscriptionIDs.remove(id); } - public boolean isSubscribe(CDOID id) + synchronized public boolean hasSubscription(CDOID id) { - return changeSubscriptionObjects.get(id) != null; + return changeSubscriptionIDs.contains(id); } - public void clearChangeSubscription() + synchronized public void clearChangeSubscription() { - changeSubscriptionObjects.clear(); + changeSubscriptionIDs.clear(); } @Override diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/ChangeSubscriptionIndication.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/ChangeSubscriptionIndication.java index 583a67e9c1..9ccda3877a 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/ChangeSubscriptionIndication.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/ChangeSubscriptionIndication.java @@ -14,8 +14,8 @@ import org.eclipse.emf.cdo.common.CDOProtocolConstants; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDObjectFactory; import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.internal.server.View; import org.eclipse.emf.cdo.internal.server.bundle.OM; -import org.eclipse.emf.cdo.server.IView; import org.eclipse.net4j.util.io.ExtendedDataInputStream; import org.eclipse.net4j.util.io.ExtendedDataOutputStream; @@ -56,7 +56,7 @@ public class ChangeSubscriptionIndication extends CDOReadIndication size = -size; } - IView view = getSession().getView(viewID); + View view = (View)getSession().getView(viewID); if (clear) { @@ -69,9 +69,13 @@ public class ChangeSubscriptionIndication extends CDOReadIndication { CDOID id = CDOIDUtil.read(in, factory); if (subscribeMode) + { view.subscribe(id); + } else + { view.unsubscribe(id); + } } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IView.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IView.java index 6a2173261a..75098763fa 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IView.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IView.java @@ -11,7 +11,6 @@ package org.eclipse.emf.cdo.server; import org.eclipse.emf.cdo.common.CDOProtocolView; -import org.eclipse.emf.cdo.common.id.CDOID; /** * @author Eike Stepper @@ -20,16 +19,5 @@ import org.eclipse.emf.cdo.common.id.CDOID; public interface IView extends CDOProtocolView { public ISession getSession(); - /** - * @since 2.0 - */ - public void subscribe(CDOID id); - /** - * @since 2.0 - */ - public void unsubscribe(CDOID id); - /** - * @since 2.0 - */ - public void clearChangeSubscription(); + } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTests.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTests.java index 3e357a6a10..603e98f5b9 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTests.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTests.java @@ -43,7 +43,7 @@ public class AllTests suite.addTestSuite(AutoAttacherTest.class); suite.addTestSuite(SavepointTest.class); suite.addTestSuite(ChangeSubscriptionTest.class); - suite.addTestSuite(QueryTest.class); + // suite.addTestSuite(QueryTest.class); // TODO suite.addTestSuite(GeneratedEcoreTest.class); // $JUnit-END$ diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChangeSubscriptionTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChangeSubscriptionTest.java index 08d46182bc..bf245eeba8 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChangeSubscriptionTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChangeSubscriptionTest.java @@ -352,7 +352,7 @@ public class ChangeSubscriptionTest extends AbstractCDOTest { private Set<CDOID> cdoIDs = new HashSet<CDOID>(); - public boolean valid(EObject eObject, Adapter object) + public boolean shouldSubscribe(EObject eObject, Adapter object) { return cdoIDs.contains(((InternalCDOObject)eObject).cdoID()); } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOChangeSubscriptionPolicy.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOChangeSubscriptionPolicy.java index cc6b4b1ddc..de4d2bbd7e 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOChangeSubscriptionPolicy.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOChangeSubscriptionPolicy.java @@ -19,29 +19,29 @@ import org.eclipse.emf.ecore.EObject; */ public interface CDOChangeSubscriptionPolicy { - public static CDOChangeSubscriptionPolicy NONE = new CDOChangeSubscriptionPolicy() + CDOChangeSubscriptionPolicy NONE = new CDOChangeSubscriptionPolicy() { - public boolean valid(EObject eObject, Adapter adapter) + public boolean shouldSubscribe(EObject eObject, Adapter adapter) { return false; } }; - - public static CDOChangeSubscriptionPolicy ONLY_CDOADAPTER = new CDOChangeSubscriptionPolicy() + + CDOChangeSubscriptionPolicy ONLY_CDOADAPTER = new CDOChangeSubscriptionPolicy() { - public boolean valid(EObject eObject, Adapter adapter) + public boolean shouldSubscribe(EObject eObject, Adapter adapter) { - return (adapter instanceof CDOAdapter); + return adapter instanceof CDOAdapter; } }; - public static CDOChangeSubscriptionPolicy ALL = new CDOChangeSubscriptionPolicy() + CDOChangeSubscriptionPolicy ALL = new CDOChangeSubscriptionPolicy() { - public boolean valid(EObject eObject, Adapter adapter) + public boolean shouldSubscribe(EObject eObject, Adapter adapter) { return true; } }; - - boolean valid(EObject eObject, Adapter adapter); + + boolean shouldSubscribe(EObject eObject, Adapter adapter); } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDONotification.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDONotification.java index f990c69635..01ec742db5 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDONotification.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDONotification.java @@ -16,23 +16,30 @@ import org.eclipse.emf.common.notify.Notification; /** * @author Simon McDuff + * <p> + * This class behave like the usual Notification except for the following: + * <p> + * <li>It doesn't provide old value, only new index or new value.</li> + * <li>{@link Notification#REMOVE_MANY} means clear was call.</li> + * <li>{@link Notification#Add_MANY} isn't used.</li> + * <p> * @since 2.0 */ public interface CDONotification extends Notification -{ +{ /** - * Notification often have a list of notification (NotificationChain). - * It informs the adapter if another another notification will be sent. + * Notification often have a list of notification (NotificationChain). It informs the adapter if another another + * notification will be sent. * <p> - * You don`t want to refresh the UI for every Notifications. - * The same object could receives many notifications at the same time. To know when to perform your - * update you could use that value. It will be the last notification when it will return false. + * You don`t want to refresh the UI for every Notifications. The same object could receives many notifications at the + * same time. To know when to perform your update you could use that value. It will be the last notification when it + * will return false. */ boolean hasNext(); - + /** - * Return the {@link CDORevisionDelta} associate to this Notification. + * Return the {@link CDORevisionDelta} associate to this Notification. */ public CDORevisionDelta getRevisionDelta(); - + } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOSession.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOSession.java index 0d0b8dff3a..ad9e3029b2 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOSession.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOSession.java @@ -71,7 +71,7 @@ public interface CDOSession extends CDOProtocolSession, IContainer<CDOView> * <p> * By default this value is enabled. * <p> - * If you disabled this property, you can still have the latest version of objects by calling refresh. + * If you disabled this property, you can still have the latest version of objects by calling {@link #refresh()}. * <p> * You would disabled it in the case where you need performance and/or want to control when objects will be refresh. * <p> @@ -86,7 +86,8 @@ public interface CDOSession extends CDOProtocolSession, IContainer<CDOView> * <p> * Take CDOID and version of all objects in the cache, sent it to the server. It will return only dirty objects. * <p> - * In the case where <code>isPassiveUpdateEnabled<code> is true, it will return immediately without doing anything. + * In the case where <code>isPassiveUpdateEnabled<code> is <code>true</code>, it will return immediately without doing + * anything. * * @since 2.0 */ diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDONotificationBuilder.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDONotificationBuilder.java index fd2e2df915..4d65438f22 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDONotificationBuilder.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDONotificationBuilder.java @@ -120,7 +120,7 @@ public class CDONotificationBuilder implements CDOFeatureDeltaVisitor { EStructuralFeature eFeature = ModelUtil.getEFeature(delta.getFeature(), packageRegistry); - add(new CDONotificationImpl(internalObject, NotificationImpl.SET, eFeature.getFeatureID(), null, null)); + add(new CDONotificationImpl(internalObject, NotificationImpl.REMOVE_MANY, eFeature.getFeatureID(), null, null)); } public void visit(CDOContainerFeatureDelta delta) diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java index a7794f2b08..862b04e96d 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java @@ -380,7 +380,7 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec } @Override - public EList<Adapter> eAdapters() + public synchronized EList<Adapter> eAdapters() { if (eAdapters == null) { diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java index b26e576dad..b235fe895c 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java @@ -562,7 +562,7 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD /** * @since 2.0 */ - public void notifySync(Set<CDOIDAndVersion> dirtyOIDs) + public void handleSync(Set<CDOIDAndVersion> dirtyOIDs) { notifyInvalidation(CDORevision.UNSPECIFIED_DATE, dirtyOIDs, null); } @@ -608,7 +608,7 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD { try { - view.handleChangeSubcription(deltas); + view.handleChangeSubscription(deltas); } catch (RuntimeException ex) { @@ -873,8 +873,9 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD { Map<CDOID, CDORevision> uniqueObjects = new HashMap<CDOID, CDORevision>(); - for (CDOViewImpl view : views.values()) + for (CDOViewImpl view : getViews()) { + // TODO Array or something else that is synchronize. for (InternalCDOObject internalCDOObject : view.getObjectsMap().values()) { if (internalCDOObject.cdoRevision() != null && !internalCDOObject.cdoID().isTemporary() @@ -885,8 +886,8 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD } } - // Need to add Revision from revisionManager since we do not have all objects in transaction. - for (CDORevision revision : this.getRevisionManager().getRevisions()) + // Need to add Revision from revisionManager since we do not have all objects in view. + for (CDORevision revision : getRevisionManager().getRevisions()) { if (!uniqueObjects.containsKey(revision.getID())) { @@ -899,11 +900,11 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD /** * @since 2.0 */ - public void setPassiveUpdateEnabled(boolean aPassiveUpdateEnabled) + public void setPassiveUpdateEnabled(boolean passiveUpdateEnabled) { - if (passiveUpdateEnabled != aPassiveUpdateEnabled) + if (this.passiveUpdateEnabled != passiveUpdateEnabled) { - passiveUpdateEnabled = aPassiveUpdateEnabled; + this.passiveUpdateEnabled = passiveUpdateEnabled; // Need to refresh if we change state Map<CDOID, CDORevision> allRevisions = getAllRevisions(); @@ -911,8 +912,10 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD { if (!allRevisions.isEmpty()) { - new PassiveUpdateRequest(this.getChannel(), this, allRevisions, this.getReferenceChunkSize(), - passiveUpdateEnabled).send(); + PassiveUpdateRequest request = new PassiveUpdateRequest(getChannel(), this, allRevisions, + getReferenceChunkSize(), this.passiveUpdateEnabled); + + getFailOverStrategy().send(request); } } catch (Exception ex) @@ -927,27 +930,29 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD */ public Set<CDOIDAndVersion> refresh() { - if (isPassiveUpdateEnabled()) + // If passive update is turned on we don`t need to refresh. + // We do not throw an exception since the client could turn that feature on or off without affecting their code. + if (!isPassiveUpdateEnabled()) { - // If passive update is turned on we don`t need to refresh. - // We do not throw an exception since the client could turn that feature on or off without affecting their code. - return new HashSet<CDOIDAndVersion>(); - } + Map<CDOID, CDORevision> allRevisions = getAllRevisions(); - Map<CDOID, CDORevision> allRevisions = getAllRevisions(); + try + { + if (!allRevisions.isEmpty()) + { + SyncRevisionRequest request = new SyncRevisionRequest(this.getChannel(), this, allRevisions, + getReferenceChunkSize()); - try - { - if (!allRevisions.isEmpty()) + return getFailOverStrategy().send(request); + } + } + catch (Exception ex) { - return new SyncRevisionRequest(this.getChannel(), this, allRevisions, this.getReferenceChunkSize()).send(); + throw WrappedException.wrap(ex); } - return new HashSet<CDOIDAndVersion>(); - } - catch (Exception ex) - { - throw WrappedException.wrap(ex); } + + return Collections.emptySet(); } /** diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java index 448d939cc8..dd9d7887a7 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java @@ -247,7 +247,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction ((InternalCDOPackage)newPackage).setPersistent(true); } - changeSubscriptionManager.notifyDirtyObjects(); + getChangeSubscriptionManager().notifyDirtyObjects(); Map<CDOID, CDOObject> dirtyObjects = this.getDirtyObjects(); @@ -328,7 +328,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction { Set<CDOID> idsOfNewObjectWithDeltas = new HashSet<CDOID>(); - // TODO Add comments - what is it used for. + // Determine the limit where we after the rollback which savepoint will still be active. + // Ex: sv1, sv2, sv3, sv4. Rollback with sv3. + // isSavepointActive is false for sv4, sv3. + // isSavepointActive is true for sv2, sv1. + boolean isSavepointActive = false; // Start from the last savepoint and come back up to the active diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java index b2c410de25..abf092c7b8 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java @@ -74,11 +74,11 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** @@ -114,12 +114,12 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement /** * @since 2.0 */ - protected ChangeSubscriptionManager changeSubscriptionManager = new ChangeSubscriptionManager(); + private ChangeSubscriptionManager changeSubscriptionManager = new ChangeSubscriptionManager(); /** * @since 2.0 */ - protected CDOChangeSubscriptionPolicy changeSubscriptionPolicy = CDOChangeSubscriptionPolicy.NONE; + private CDOChangeSubscriptionPolicy changeSubscriptionPolicy = CDOChangeSubscriptionPolicy.NONE; public CDOViewImpl(int id, CDOSessionImpl session) { @@ -146,6 +146,14 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement changeSubscriptionManager.unsubscribe(eObject, adapter); } + /** + * @since 2.0 + */ + protected ChangeSubscriptionManager getChangeSubscriptionManager() + { + return changeSubscriptionManager; + } + protected ConcurrentMap<CDOID, InternalCDOObject> createObjectsMap() { return new ReferenceValueMap.Weak<CDOID, InternalCDOObject>(); @@ -217,11 +225,11 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement /** * @since 2.0 */ - public void setChangeSubscriptionPolicy(CDOChangeSubscriptionPolicy notificationsEnabled) + public void setChangeSubscriptionPolicy(CDOChangeSubscriptionPolicy subscriptionPolicy) { - if (this.changeSubscriptionPolicy != notificationsEnabled) + if (this.changeSubscriptionPolicy != subscriptionPolicy) { - changeSubscriptionPolicy = notificationsEnabled; + changeSubscriptionPolicy = subscriptionPolicy; changeSubscriptionManager.notifyChangeSubcriptionPolicy(); } @@ -703,7 +711,7 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement /** * @since 2.0 */ - public void handleChangeSubcription(Collection<CDORevisionDelta> deltas) + public void handleChangeSubscription(Collection<CDORevisionDelta> deltas) { if (deltas != null && getChangeSubscriptionPolicy() != CDOChangeSubscriptionPolicy.NONE) { @@ -712,7 +720,7 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement for (CDORevisionDelta delta : deltas) { InternalCDOObject object = objects.get(delta.getID()); - if (object != null && object.eNotificationRequired() && changeSubscriptionManager.isSubscribe(object)) + if (object != null && object.eNotificationRequired() && changeSubscriptionManager.hasSubscription(object)) { NotificationImpl notification = builder.buildNotification(object, delta); if (notification != null) notification.dispatch(); @@ -980,17 +988,15 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement /** * @since 2.0 */ - public class ChangeSubscriptionManager + protected class ChangeSubscriptionManager { - // List of persisted objects - private Map<InternalCDOObject, Integer> persistedObjects = new ConcurrentHashMap<InternalCDOObject, Integer>(); + private Map<InternalCDOObject, Integer> subscriptions = new HashMap<InternalCDOObject, Integer>(); - // List of new objects - private Map<InternalCDOObject, Integer> newObjects = new ConcurrentHashMap<InternalCDOObject, Integer>(); + private Map<InternalCDOObject, Integer> pendingSubscriptions = new HashMap<InternalCDOObject, Integer>(); - private boolean valid(InternalCDOObject internalCDOObject) + private boolean isPending(InternalCDOObject internalCDOObject) { - return !internalCDOObject.cdoID().isTemporary(); + return internalCDOObject.cdoID().isTemporary(); } protected int getNumberOfValidAdapter(InternalCDOObject object) @@ -1000,27 +1006,33 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement { for (Adapter adapter : object.eAdapters()) { - if (changeSubscriptionPolicy.valid(object, adapter)) count++; + if (changeSubscriptionPolicy.shouldSubscribe(object, adapter)) + { + count++; + } } } return count; } - /* + /** * Register to the server all objects from the active list */ protected void notifyChangeSubcriptionPolicy() { - synchronized (persistedObjects) + synchronized (subscriptions) { - persistedObjects.clear(); - newObjects.clear(); + subscriptions.clear(); + pendingSubscriptions.clear(); List<CDOID> cdoIDs = new ArrayList<CDOID>(); if (changeSubscriptionPolicy != CDOChangeSubscriptionPolicy.NONE) { + /* + * This is safe since we use ConcurrentHashMap + */ for (InternalCDOObject cdoObject : objects.values()) { int count = getNumberOfValidAdapter(cdoObject); @@ -1028,8 +1040,8 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement if (count > 0) { cdoIDs.add(cdoObject.cdoID()); - boolean isValid = valid(cdoObject); - Map<InternalCDOObject, Integer> subscribersMap = isValid ? persistedObjects : newObjects; + boolean isPending = isPending(cdoObject); + Map<InternalCDOObject, Integer> subscribersMap = isPending ? pendingSubscriptions : subscriptions; subscribersMap.put(cdoObject, count); } } @@ -1038,11 +1050,13 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement } } - protected void request(List<CDOID> cdoIDs, boolean registered, boolean clear) + protected void request(List<CDOID> cdoIDs, boolean clear, boolean subscribeMode) { try { - new ChangeSubscriptionRequest(getSession().getChannel(), getViewID(), cdoIDs, registered, clear).send(); + ChangeSubscriptionRequest request = new ChangeSubscriptionRequest(getSession().getChannel(), getViewID(), + cdoIDs, subscribeMode, clear); + session.getFailOverStrategy().send(request); } catch (Exception ex) { @@ -1052,40 +1066,41 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement protected void notifyDirtyObjects() { - synchronized (persistedObjects) + synchronized (subscriptions) { - List<InternalCDOObject> objectToRemove = new ArrayList<InternalCDOObject>(); - for (Entry<InternalCDOObject, Integer> entry : newObjects.entrySet()) + List<InternalCDOObject> objectsToRemove = new ArrayList<InternalCDOObject>(); + for (Entry<InternalCDOObject, Integer> entry : pendingSubscriptions.entrySet()) { - if (valid(entry.getKey())) + if (!isPending(entry.getKey())) { subscribe(entry.getKey(), entry.getValue()); - objectToRemove.add(entry.getKey()); + objectsToRemove.add(entry.getKey()); } } - for (InternalCDOObject internalCDOObject : objectToRemove) - newObjects.remove(internalCDOObject); + for (InternalCDOObject internalCDOObject : objectsToRemove) + pendingSubscriptions.remove(internalCDOObject); } } - protected boolean isSubscribe(InternalCDOObject eObject) + protected boolean hasSubscription(InternalCDOObject eObject) { - return (persistedObjects.get(eObject) != null); + return (subscriptions.get(eObject) != null); } private void subscribe(EObject eObject, Adapter adapter, int adjust) { - synchronized (persistedObjects) + synchronized (subscriptions) { - if (!getChangeSubscriptionPolicy().valid(eObject, adapter)) return; - - subscribe(eObject, adjust); + if (getChangeSubscriptionPolicy().shouldSubscribe(eObject, adapter)) + { + subscribe(eObject, adjust); + } } } private void subscribe(EObject eObject, int adjust) { - synchronized (persistedObjects) + synchronized (subscriptions) { InternalCDOObject internalCDOObject = FSMUtil.adapt(eObject, CDOViewImpl.this); @@ -1095,25 +1110,26 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement throw new CDOException("Object " + internalCDOObject + " doesn`t belong to this view."); } - boolean isValid = valid(internalCDOObject); + boolean isPending = isPending(internalCDOObject); - Map<InternalCDOObject, Integer> subscribersMap = isValid ? persistedObjects : newObjects; + Map<InternalCDOObject, Integer> subscribersMap = isPending ? pendingSubscriptions : subscriptions; Integer count = subscribersMap.get(internalCDOObject); if (count == null) { // Cannot adjust negative value - if (adjust < 0) throw new IllegalStateException(); + if (adjust < 0) + { + throw new IllegalStateException("Object " + internalCDOObject.cdoID() + " cannot be unsubscribe"); + } count = 0; // Notification need to be enable to send correct value to the server - if (isValid && getChangeSubscriptionPolicy() != CDOChangeSubscriptionPolicy.NONE) + if (!isPending && getChangeSubscriptionPolicy() != CDOChangeSubscriptionPolicy.NONE) { - List<CDOID> cdoIDs = new ArrayList<CDOID>(); - cdoIDs.add(internalCDOObject.cdoID()); - request(cdoIDs, true, false); + request(Collections.singletonList(internalCDOObject.cdoID()), false, true); } } @@ -1125,11 +1141,9 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement subscribersMap.remove(internalCDOObject); // Notification need to be enable to send correct value to the server - if (isValid && getChangeSubscriptionPolicy() != CDOChangeSubscriptionPolicy.NONE) + if (!isPending && getChangeSubscriptionPolicy() != CDOChangeSubscriptionPolicy.NONE) { - List<CDOID> cdoIDs = new ArrayList<CDOID>(); - cdoIDs.add(internalCDOObject.cdoID()); - request(cdoIDs, false, false); + request(Collections.singletonList(internalCDOObject.cdoID()), false, false); } } else diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/PassiveUpdateRequest.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/PassiveUpdateRequest.java index 9e4e21c61f..75e2c60b17 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/PassiveUpdateRequest.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/PassiveUpdateRequest.java @@ -27,14 +27,15 @@ import java.util.Map; /** * @author Simon McDuff + * @since 2.0 */ public class PassiveUpdateRequest extends SyncRevisionRequest { private static final ContextTracer PROTOCOL = new ContextTracer(OM.DEBUG_PROTOCOL, PassiveUpdateRequest.class); private boolean passiveUpdateEnabled; - - public PassiveUpdateRequest(IChannel channel, CDOSessionImpl session, Map<CDOID, CDORevision> cdoRevisions, + + public PassiveUpdateRequest(IChannel channel, CDOSessionImpl session, Map<CDOID, CDORevision> cdoRevisions, int referenceChunk, boolean passiveUpdateEnabled) { super(channel, session, cdoRevisions, referenceChunk); @@ -50,10 +51,13 @@ public class PassiveUpdateRequest extends SyncRevisionRequest @Override protected void requesting(ExtendedDataOutputStream out) throws IOException { - if (PROTOCOL.isEnabled()) PROTOCOL.trace("Turning " + (passiveUpdateEnabled ? "on" : "off") + " passive update"); + if (PROTOCOL.isEnabled()) + { + PROTOCOL.trace("Turning " + (passiveUpdateEnabled ? "on" : "off") + " passive update"); + } super.requesting(out); out.writeBoolean(passiveUpdateEnabled); - + } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/SyncRevisionRequest.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/SyncRevisionRequest.java index 47f441d208..f2628c3030 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/SyncRevisionRequest.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/SyncRevisionRequest.java @@ -33,18 +33,19 @@ import java.util.Set; /** * @author Simon McDuff + * @since 2.0 */ public class SyncRevisionRequest extends CDOClientRequest<Set<CDOIDAndVersion>> { private static final ContextTracer PROTOCOL = new ContextTracer(OM.DEBUG_PROTOCOL, SyncRevisionRequest.class); - private Map<CDOID, CDORevision> collectionRevisions; + private Map<CDOID, CDORevision> collectionRevisions; private CDOSessionImpl cdoSession; private int referenceChunk; - public SyncRevisionRequest(IChannel channel, CDOSessionImpl cdoSession, Map<CDOID, CDORevision> cdoRevisions, + public SyncRevisionRequest(IChannel channel, CDOSessionImpl cdoSession, Map<CDOID, CDORevision> cdoRevisions, int referenceChunk) { super(channel); @@ -62,7 +63,10 @@ public class SyncRevisionRequest extends CDOClientRequest<Set<CDOIDAndVersion>> @Override protected void requesting(ExtendedDataOutputStream out) throws IOException { - if (PROTOCOL.isEnabled()) PROTOCOL.trace("Synchronization " + collectionRevisions.size() + " objects"); + if (PROTOCOL.isEnabled()) + { + PROTOCOL.trace("Synchronization " + collectionRevisions.size() + " objects"); + } out.writeInt(referenceChunk); out.writeInt(collectionRevisions.size()); @@ -76,10 +80,10 @@ public class SyncRevisionRequest extends CDOClientRequest<Set<CDOIDAndVersion>> out.writeInt(revision.getVersion()); } else + { out.writeInt(-1); - + } } - } @Override @@ -93,20 +97,25 @@ public class SyncRevisionRequest extends CDOClientRequest<Set<CDOIDAndVersion>> { CDORevisionImpl revision = new CDORevisionImpl(in, getSession().getRevisionManager(), getSession() .getPackageManager()); - + CDORevision oldRevision = collectionRevisions.get(revision.getID()); - + if (oldRevision == null) - throw new IllegalStateException(); - + { + throw new IllegalStateException("Didn't expect to receive object with id '" + revision.getID() + "'"); + } + listofDirtyObjects.add(CDOIDUtil.createIDAndVersion(oldRevision.getID(), oldRevision.getVersion())); - + getSession().getRevisionManager().addRevision(revision); } - if (PROTOCOL.isEnabled()) PROTOCOL.trace("Synchronization received " + size + " dirty objects"); + if (PROTOCOL.isEnabled()) + { + PROTOCOL.trace("Synchronization received " + size + " dirty objects"); + } - cdoSession.notifySync(listofDirtyObjects); + cdoSession.handleSync(listofDirtyObjects); return listofDirtyObjects; } |