Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 35937304f027887cf0c9f5462bf82d44357c6a1b (plain) (blame)
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package org.eclipse.papyrus.team.collaborative.integration.papyrus.security;

import java.util.HashSet;
import java.util.Set;
import java.util.WeakHashMap;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.transaction.NotificationFilter;
import org.eclipse.emf.transaction.ResourceSetChangeEvent;
import org.eclipse.emf.transaction.ResourceSetListenerImpl;
import org.eclipse.emf.transaction.RollbackException;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.papyrus.infra.core.resource.IModelSetSnippet;
import org.eclipse.papyrus.infra.core.resource.ModelSet;
import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModel;
import org.eclipse.papyrus.team.collaborative.ICollaborativeManager;
import org.eclipse.papyrus.team.collaborative.IExtendedURI;
import org.eclipse.papyrus.team.collaborative.integration.papyrus.ui.actions.LockAction;
import org.eclipse.papyrus.team.collaborative.integration.papyrus.utils.UIUtils;
import org.eclipse.papyrus.team.collaborative.participants.locker.ILocker;
import org.eclipse.papyrus.team.collaborative.utils.CollabFunctionsFactory;

import com.google.common.collect.Collections2;
import com.google.common.collect.Sets;


/**
 * This model snippet will register a new {@link ResourceSetListener} that will provide a new security on modifed resources.
 * Each time a resource will be set to modified this listener will check that the resources has been locked. If the resources is not lock then it will
 * try to rollback the current transaction
 * 
 * @author adaussy
 * 
 */
public class PreCommitReadOnlyHandler implements IModelSetSnippet {

	/**
	 * This {@link ResourceSetListener} will listen each time a resource is modified to check that it has been locked or will ask for lock
	 * 
	 * @author adaussy
	 * 
	 */
	private static class ResourceSetListener extends ResourceSetListenerImpl {

		@Override
		public boolean isPostcommitOnly() {
			return false;
		}

		@Override
		public boolean isPrecommitOnly() {
			return true;
		}

		@Override
		public boolean isAggregatePrecommitListener() {
			return false;
		}

		/**
		 * Filter only IS_MODIFIED notification
		 */
		private static NotificationFilter filter = NotificationFilter.createFeatureFilter(Resource.class, Resource.RESOURCE__IS_MODIFIED);

		@Override
		public NotificationFilter getFilter() {
			return filter;
		}


		@Override
		public Command transactionAboutToCommit(ResourceSetChangeEvent event) throws RollbackException {
			final Set<Resource> resourceToTest = new HashSet<Resource>();
			for(Notification n : event.getNotifications()) {
				if(n.getNewBooleanValue()) {
					Resource resource = (Resource)n.getNotifier();
					//Filtered out any DI resource. Those resource are not collaborative resources
					if(!DiModel.MODEL_FILE_EXTENSION.equals(resource.getURI().fileExtension())) {
						resourceToTest.add(resource);
					}
				}
			}
			if(!resourceToTest.isEmpty()) {
				TransactionalEditingDomain editingDomain = event.getEditingDomain();
				ResourceSet resourceSet = editingDomain.getResourceSet();
				HashSet<IExtendedURI> uriToTest = Sets.newHashSet(Collections2.transform(resourceToTest, CollabFunctionsFactory.getResourceToExtendedURIWithContainment()));
				if(ICollaborativeManager.INSTANCE.isCollab(uriToTest, resourceSet)) {
					Set<IExtendedURI> uriToLock = new HashSet<IExtendedURI>();
					ILocker locker = ICollaborativeManager.INSTANCE.getLocker(uriToTest, resourceSet);
					if(locker == null) {
						return null;
					}
					for(IExtendedURI extendURI : locker.getExtendedSet()) {
						if(!locker.isLocked(extendURI).isOK()) {
							uriToLock.add(extendURI);
						}
					}
					if(!uriToLock.isEmpty()) {
						final IStatus status = LockAction.doSafeLock(resourceSet, uriToLock, true);
						if(!status.isOK()) {
							UIUtils.errorDialog(status, "Unable to lock");
							throw new RollbackException(status);

						}
					}
				}
			}
			return null;
		}
	}

	public PreCommitReadOnlyHandler() {
	}


	private WeakHashMap<EditingDomain, ResourceSetListener> link = new WeakHashMap<EditingDomain, PreCommitReadOnlyHandler.ResourceSetListener>();

	@Override
	public void start(ModelSet modelsManager) {
		TransactionalEditingDomain transactionalEditingDomain = modelsManager.getTransactionalEditingDomain();
		ResourceSetListener listener = new ResourceSetListener();
		link.put(transactionalEditingDomain, listener);
		transactionalEditingDomain.addResourceSetListener(listener);

	}

	@Override
	public void dispose(ModelSet modelsManager) {
		TransactionalEditingDomain transactionalEditingDomain = modelsManager.getTransactionalEditingDomain();
		transactionalEditingDomain.removeResourceSetListener(link.get(transactionalEditingDomain));

	}



}

Back to the top