|
Lines 11-16
Link Here
|
| 11 |
|
11 |
|
| 12 |
package org.eclipse.ecf.internal.sync.doc.cola; |
12 |
package org.eclipse.ecf.internal.sync.doc.cola; |
| 13 |
|
13 |
|
|
|
14 |
import java.util.ArrayList; |
| 14 |
import java.util.HashMap; |
15 |
import java.util.HashMap; |
| 15 |
import java.util.Iterator; |
16 |
import java.util.Iterator; |
| 16 |
import java.util.LinkedList; |
17 |
import java.util.LinkedList; |
|
Lines 35-41
Link Here
|
| 35 |
public class ColaSynchronizationStrategy implements IModelSynchronizationStrategy { |
36 |
public class ColaSynchronizationStrategy implements IModelSynchronizationStrategy { |
| 36 |
|
37 |
|
| 37 |
// <ColaDocumentChangeMessage> |
38 |
// <ColaDocumentChangeMessage> |
| 38 |
private final LinkedList unacknowledgedLocalOperations; |
39 |
private final List unacknowledgedLocalOperations; |
| 39 |
private final boolean isInitiator; |
40 |
private final boolean isInitiator; |
| 40 |
private long localOperationsCount; |
41 |
private long localOperationsCount; |
| 41 |
private long remoteOperationsCount; |
42 |
private long remoteOperationsCount; |
|
Lines 51-60
Link Here
|
| 51 |
} |
52 |
} |
| 52 |
|
53 |
|
| 53 |
public static ColaSynchronizationStrategy getInstanceFor(ID client, boolean isInitiator) { |
54 |
public static ColaSynchronizationStrategy getInstanceFor(ID client, boolean isInitiator) { |
| 54 |
if (sessionStrategies.get(client) == null) { |
55 |
ColaSynchronizationStrategy existingStrategy = (ColaSynchronizationStrategy) sessionStrategies.get(client); |
| 55 |
sessionStrategies.put(client, new ColaSynchronizationStrategy(isInitiator)); |
56 |
if (existingStrategy != null) { |
|
|
57 |
Boolean existingStrategyIsInitiator = new Boolean(existingStrategy.isInitiator); |
| 58 |
if (existingStrategyIsInitiator.equals(new Boolean(isInitiator))) { |
| 59 |
return existingStrategy; |
| 60 |
} |
| 56 |
} |
61 |
} |
| 57 |
return (ColaSynchronizationStrategy) sessionStrategies.get(client); |
62 |
existingStrategy = new ColaSynchronizationStrategy(isInitiator); |
|
|
63 |
sessionStrategies.put(client, existingStrategy); |
| 64 |
return existingStrategy; |
| 58 |
} |
65 |
} |
| 59 |
|
66 |
|
| 60 |
public static void cleanUpFor(ID client) { |
67 |
public static void cleanUpFor(ID client) { |
|
Lines 64-81
Link Here
|
| 64 |
public static void dispose() { |
71 |
public static void dispose() { |
| 65 |
sessionStrategies.clear(); |
72 |
sessionStrategies.clear(); |
| 66 |
} |
73 |
} |
| 67 |
|
|
|
| 68 |
public DocumentChangeMessage registerOutgoingMessage(DocumentChangeMessage localMsg) { |
| 69 |
Trace.entering(Activator.PLUGIN_ID, SyncDebugOptions.METHODS_ENTERING, this.getClass(), "registerOutgoingMessage", localMsg); //$NON-NLS-1$ |
| 70 |
final ColaDocumentChangeMessage colaMsg = new ColaDocumentChangeMessage(localMsg, localOperationsCount, remoteOperationsCount); |
| 71 |
if (!colaMsg.isReplacement()) { |
| 72 |
unacknowledgedLocalOperations.add(colaMsg); |
| 73 |
localOperationsCount++; |
| 74 |
} |
| 75 |
Trace.exiting(Activator.PLUGIN_ID, SyncDebugOptions.METHODS_EXITING, this.getClass(), "registerOutgoingMessage", colaMsg); //$NON-NLS-1$ |
| 76 |
return colaMsg; |
| 77 |
} |
| 78 |
|
| 79 |
/** |
74 |
/** |
| 80 |
* Handles proper transformation of incoming <code>ColaDocumentChangeMessage</code>s. |
75 |
* Handles proper transformation of incoming <code>ColaDocumentChangeMessage</code>s. |
| 81 |
* Returned <code>DocumentChangeMessage</code>s can be applied directly to the |
76 |
* Returned <code>DocumentChangeMessage</code>s can be applied directly to the |
|
Lines 95-100
Link Here
|
| 95 |
transformedRemotes.add(transformedRemote); |
90 |
transformedRemotes.add(transformedRemote); |
| 96 |
|
91 |
|
| 97 |
remoteOperationsCount++; |
92 |
remoteOperationsCount++; |
|
|
93 |
Trace.trace(Activator.PLUGIN_ID, "unacknowledgedLocalOperations="+unacknowledgedLocalOperations); |
| 98 |
//this is where the concurrency algorithm is executed |
94 |
//this is where the concurrency algorithm is executed |
| 99 |
if (!unacknowledgedLocalOperations.isEmpty()) {//Do not remove this. It is necessary. The following iterator does not suffice. |
95 |
if (!unacknowledgedLocalOperations.isEmpty()) {//Do not remove this. It is necessary. The following iterator does not suffice. |
| 100 |
// remove operations from queue that have been implicitly |
96 |
// remove operations from queue that have been implicitly |
|
Lines 123-129
Link Here
|
| 123 |
// don't require to be transformed against |
119 |
// don't require to be transformed against |
| 124 |
|
120 |
|
| 125 |
if (!unacknowledgedLocalOperations.isEmpty()) { |
121 |
if (!unacknowledgedLocalOperations.isEmpty()) { |
| 126 |
ColaDocumentChangeMessage localOp = (ColaDocumentChangeMessage) unacknowledgedLocalOperations.getFirst(); |
122 |
ColaDocumentChangeMessage localOp = (ColaDocumentChangeMessage) unacknowledgedLocalOperations.get(0); |
| 127 |
Assert.isTrue(transformedRemote.getRemoteOperationsCount() == localOp.getLocalOperationsCount()); |
123 |
Assert.isTrue(transformedRemote.getRemoteOperationsCount() == localOp.getLocalOperationsCount()); |
| 128 |
|
124 |
|
| 129 |
for (final ListIterator unackOpsListIt = unacknowledgedLocalOperations.listIterator(); unackOpsListIt.hasNext();) { |
125 |
for (final ListIterator unackOpsListIt = unacknowledgedLocalOperations.listIterator(); unackOpsListIt.hasNext();) { |
|
Lines 196-212
Link Here
|
| 196 |
* @see org.eclipse.ecf.sync.doc.IDocumentSynchronizationStrategy#registerLocalChange(org.eclipse.ecf.sync.doc.IModelChange) |
192 |
* @see org.eclipse.ecf.sync.doc.IDocumentSynchronizationStrategy#registerLocalChange(org.eclipse.ecf.sync.doc.IModelChange) |
| 197 |
*/ |
193 |
*/ |
| 198 |
public IModelChangeMessage[] registerLocalChange(IModelChange localChange) { |
194 |
public IModelChangeMessage[] registerLocalChange(IModelChange localChange) { |
|
|
195 |
List results = new ArrayList(); |
| 199 |
Trace.entering(Activator.PLUGIN_ID, SyncDebugOptions.METHODS_ENTERING, this.getClass(), "registerLocalChange", localChange); //$NON-NLS-1$ |
196 |
Trace.entering(Activator.PLUGIN_ID, SyncDebugOptions.METHODS_ENTERING, this.getClass(), "registerLocalChange", localChange); //$NON-NLS-1$ |
| 200 |
if (localChange instanceof IDocumentChange) { |
197 |
if (localChange instanceof IDocumentChange) { |
| 201 |
final IDocumentChange docChange = (IDocumentChange) localChange; |
198 |
final IDocumentChange docChange = (IDocumentChange) localChange; |
| 202 |
final ColaDocumentChangeMessage colaMsg = new ColaDocumentChangeMessage(new DocumentChangeMessage(docChange.getOffset(), docChange.getLengthOfReplacedText(), docChange.getText()), localOperationsCount, remoteOperationsCount); |
199 |
final ColaDocumentChangeMessage colaMsg = new ColaDocumentChangeMessage(new DocumentChangeMessage(docChange.getOffset(), docChange.getLengthOfReplacedText(), docChange.getText()), localOperationsCount, remoteOperationsCount); |
|
|
200 |
// If not replacement, we simply add to unacknowledgedLocalOperations and add message |
| 201 |
// to results |
| 203 |
if (!colaMsg.isReplacement()) { |
202 |
if (!colaMsg.isReplacement()) { |
| 204 |
unacknowledgedLocalOperations.add(colaMsg); |
203 |
unacknowledgedLocalOperations.add(colaMsg); |
| 205 |
localOperationsCount++; |
204 |
localOperationsCount++; |
|
|
205 |
results.add(colaMsg); |
| 206 |
} else { |
| 207 |
// It *is a replacement message, so we add both a delete and an insert message |
| 208 |
// First create/add a delete message (text set to "")... |
| 209 |
ColaDocumentChangeMessage delMsg = new ColaDocumentChangeMessage(new DocumentChangeMessage(docChange.getOffset(),docChange.getLengthOfReplacedText(),""), localOperationsCount, remoteOperationsCount); |
| 210 |
unacknowledgedLocalOperations.add(delMsg); |
| 211 |
localOperationsCount++; |
| 212 |
results.add(delMsg); |
| 213 |
// Then create/add the insert message (length set to 0) |
| 214 |
ColaDocumentChangeMessage insMsg = new ColaDocumentChangeMessage(new DocumentChangeMessage(docChange.getOffset(),0,docChange.getText()), localOperationsCount, remoteOperationsCount); |
| 215 |
unacknowledgedLocalOperations.add(insMsg); |
| 216 |
localOperationsCount++; |
| 217 |
results.add(insMsg); |
| 206 |
} |
218 |
} |
| 207 |
Trace.exiting(Activator.PLUGIN_ID, SyncDebugOptions.METHODS_EXITING, this.getClass(), "registerLocalChange", colaMsg); //$NON-NLS-1$ |
219 |
Trace.exiting(Activator.PLUGIN_ID, SyncDebugOptions.METHODS_EXITING, this.getClass(), "registerLocalChange", colaMsg); //$NON-NLS-1$ |
| 208 |
return new IModelChangeMessage[] {colaMsg}; |
220 |
} |
| 209 |
} else return new IModelChangeMessage[0]; |
221 |
return (IModelChangeMessage[]) results.toArray(new IModelChangeMessage[] {}); |
| 210 |
} |
222 |
} |
| 211 |
|
223 |
|
| 212 |
/* (non-Javadoc) |
224 |
/* (non-Javadoc) |