1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
/*****************************************************************************
* Copyright (c) 2015 Christian W. Damus 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:
* Christian W. Damus - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.infra.sync.internal;
import static org.eclipse.papyrus.infra.core.utils.TransactionHelper.isTriggerTransaction;
import java.util.concurrent.ConcurrentMap;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.transaction.ResourceSetChangeEvent;
import org.eclipse.emf.transaction.RollbackException;
import org.eclipse.emf.transaction.Transaction;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.papyrus.infra.sync.EMFListener;
import org.eclipse.papyrus.infra.sync.SyncFeature;
import org.eclipse.papyrus.infra.sync.policy.ISyncPolicyDelegate;
import com.google.common.collect.MapMaker;
/**
* Default implementation of the sync-policy delegate registry.
*/
class SyncPolicyDelegateRegistryImpl implements ISyncPolicyDelegate.Registry {
@SuppressWarnings("rawtypes")
private ConcurrentMap<Class<? extends SyncFeature>, ISyncPolicyDelegate<?, ?>> delegates = new MapMaker().weakKeys().makeMap();
private EMFListener listener;
SyncPolicyDelegateRegistryImpl(TransactionalEditingDomain domain) {
super();
this.listener = createEMFListener(domain);
}
void dispose() {
delegates.clear();
if (listener != null) {
listener.dispose();
listener = null;
}
}
EMFListener getEMFListener() {
return listener;
}
@SuppressWarnings("unchecked")
@Override
public <M, T> ISyncPolicyDelegate<M, T> get(SyncFeature<M, T, ?> syncFeature) {
return (ISyncPolicyDelegate<M, T>) delegates.get(syncFeature.getClass());
}
@Override
public void register(ISyncPolicyDelegate<?, ?> policyDelegate, Class<?> featureType) {
delegates.putIfAbsent(featureType.asSubclass(SyncFeature.class), policyDelegate);
}
@Override
public void deregister(ISyncPolicyDelegate<?, ?> policyDelegate, Class<?> featureType) {
delegates.remove(featureType.asSubclass(SyncFeature.class), policyDelegate);
}
private EMFListener createEMFListener(TransactionalEditingDomain domain) {
return new EMFListener(domain) {
@Override
public Command transactionAboutToCommit(ResourceSetChangeEvent event) throws RollbackException {
// Don't respond to changes made by triggers because these are not explicit by the
// user and they include the changes effected by synchronization in the first place.
// We only want to detect the original user-initiated changes.
// Note that initial-sync changes made in an unprotected transaction wouldn't trigger
// the listener in any case
Transaction transaction = event.getTransaction();
return (transaction != null && isTriggerTransaction(transaction))
? null
: super.transactionAboutToCommit(event);
}
};
}
}
|