Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 7739c3375854df3cb8d066362e6865a1d78faad6 (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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*****************************************************************************
 * Copyright (c) 2010, 2013 CEA LIST.
 *
 *
 * 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:
 *  Ansgar Radermacher (CEA LIST) ansgar.radermacher@cea.fr - Initial API and implementation
 *  Christian W. Damus (CEA) - manage models by URI, not IFile (CDO)
 *  Christian W. Damus (CEA) - don't rely on IMarker changes to refresh Model Explorer labels (CDO)
 *
 *****************************************************************************/

package org.eclipse.papyrus.uml.diagram.common.resourceupdate;

import static org.eclipse.papyrus.uml.diagram.common.Activator.log;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.papyrus.infra.core.editor.IMultiDiagramEditor;
import org.eclipse.papyrus.infra.core.lifecycleevents.ILifeCycleEventsProvider;
import org.eclipse.papyrus.infra.core.resource.ModelSet;
import org.eclipse.papyrus.infra.core.services.IService;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
import org.eclipse.papyrus.uml.diagram.common.Activator;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.uml2.uml.Profile;

/**
 * A listener for resource changes, used to trigger an update of models whose
 * underlying resources have been changed.
 *
 * @author Ansgar Radermacher (CEA LIST)
 *
 * @deprecated The equivalent behavior has been implemented in oep.infra.core
 */
@Deprecated
public class ResourceUpdateService implements IService, IResourceChangeListener, IResourceDeltaVisitor {

	public static final String RESOURCE_UPDATE_ID = Activator.ID + ".resourceUpdate";

	// public init (CoreMultiDiagramEditor editor, ISaveAndDirtyService
	// saveAndDirty, ModelSet modelSet) {
	@Override
	public void init(ServicesRegistry serviceRegistry) throws ServiceException {
		modelSet = serviceRegistry.getService(ModelSet.class);
		editor = serviceRegistry.getService(IMultiDiagramEditor.class);
		ILifeCycleEventsProvider lcEventsProvider = serviceRegistry.getService(ILifeCycleEventsProvider.class);
		saveListener = new SaveListener();
		lcEventsProvider.addDoSaveListener(saveListener.preSaveListener);
		lcEventsProvider.addPostDoSaveListener(saveListener.postSaveListener);

		partActivationListener = new PartActivationListener(editor);
	}

	/**
	 * The listener operation that is called by the workspace
	 */
	@Override
	public void resourceChanged(IResourceChangeEvent event) {
		switch (event.getType()) {
		case IResourceChangeEvent.PRE_CLOSE:
		case IResourceChangeEvent.PRE_BUILD:
		case IResourceChangeEvent.POST_BUILD:
		case IResourceChangeEvent.PRE_DELETE:
			// do nothing (only handle change)
			break;
		case IResourceChangeEvent.POST_CHANGE:
			try {
				// delegate to visitor (event.getResource is typically null) and
				// there
				// might be a tree of changed resources
				event.getDelta().accept(this);
			} catch (CoreException coreException) {
				log.error(coreException);
			}
			break;
		}

	}

	/**
	 * A visitor for resource changes. Detects, whether a changed resource
	 * belongs to an opened editor
	 */
	@Override
	public boolean visit(IResourceDelta delta) {
		IResource changedResource = delta.getResource();
		if (delta.getFlags() == IResourceDelta.MARKERS) {
			// only markers have been changed. The marker-listener service takes
			// care of this
			return false;
		}
		// only proceed in case of Files (not projects, folders, ...) for the
		// moment
		if (!(changedResource instanceof IFile)) {
			return true;
		}
		final String changedResourcePath = changedResource.getFullPath().toString();
		URI changedResourceURIWOExt = URI.createPlatformResourceURI(changedResource.getFullPath().toString(), true).trimFileExtension();
		URIConverter uriConverter = modelSet.getURIConverter();

		for (Resource resource : modelSet.getResources()) {
			URI uri = resource.getURI();
			URI normalizedURI = uriConverter.normalize(uri);

			// URI path is prefixed with /resource or /plugin (registered
			// model), therefore compare with
			// endsWith.
			// Comparison is done on path level since resource and
			// changedResource are never
			// identical. The latter is a generic system resource (File, ...),
			// the former a
			// model-aware representation of the resource
			if (normalizedURI.path().endsWith(changedResourcePath)) {
				if (changedResourceURIWOExt.equals(modelSet.getURIWithoutExtension())) {
					// model itself has changed.
					// mark main resource as changed. User will asked later,
					// when he activates the editor.
					if (!saveListener.isSaveActive()) {
						partActivationListener.setModificationData(changedResource.getFullPath(), delta, true, resource.isModified());
					}
				}
				// Changed resource does not belong to the model, it might however belong to a referenced model.
				// Since the referenced model may be editable (case of controlled sub-model with write access),
				// it must not be unloaded without asking the user. User will be asked when activating the editor.

				else if (resource.isLoaded()) {
					EList<EObject> contents = resource.getContents();
					if ((contents.size() > 0) && (contents.get(0) instanceof Profile)) {
						// don't touch profiles
					} else if (!saveListener.isSaveActive()) {
						partActivationListener.setModificationData(changedResource.getFullPath(), delta, false, resource.isModified());
					}
				}
			}
		}
		return true;
	}

	private IMultiDiagramEditor editor;

	private ModelSet modelSet;

	// private ILifeCycleEventsProvider lifeCycleEvents;

	/**
	 * Activate the listeners. It will listen to resource changes and to changes
	 * of the active editor
	 */
	private void activate() {
		// ... add service to the workspace
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
		IWorkbenchPage page = editor.getSite().getPage();
		page.addPartListener(partActivationListener);
	}

	/**
	 * DeActivate the listeners.
	 */
	private void deactivate() {
		// remove it from workspace
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
		IWorkbenchPage page = editor.getSite().getPage();
		page.removePartListener(partActivationListener);
	}

	@Override
	public void startService() throws ServiceException {
		activate();
	}

	@Override
	public void disposeService() throws ServiceException {
		deactivate();
		// lifeCycleEvents.removeDoSaveListener(listener);
	}

	private PartActivationListener partActivationListener;

	private SaveListener saveListener;
}

Back to the top