0
|
1 |
// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
2 |
// All rights reserved.
|
|
3 |
// This component and the accompanying materials are made available
|
|
4 |
// under the terms of "Eclipse Public License v1.0"
|
|
5 |
// which accompanies this distribution, and is available
|
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
7 |
//
|
|
8 |
// Initial Contributors:
|
|
9 |
// Nokia Corporation - initial contribution.
|
|
10 |
//
|
|
11 |
// Contributors:
|
|
12 |
//
|
|
13 |
// Description:
|
|
14 |
//
|
|
15 |
|
|
16 |
package com.symbian.smt.gui;
|
|
17 |
|
|
18 |
import java.io.File;
|
|
19 |
import java.util.HashMap;
|
|
20 |
|
|
21 |
import org.eclipse.core.resources.IFile;
|
|
22 |
import org.eclipse.core.resources.IFolder;
|
|
23 |
import org.eclipse.core.resources.IMarker;
|
|
24 |
import org.eclipse.core.resources.IProject;
|
|
25 |
import org.eclipse.core.resources.IResource;
|
|
26 |
import org.eclipse.core.resources.IResourceDelta;
|
|
27 |
import org.eclipse.core.resources.ProjectScope;
|
|
28 |
import org.eclipse.core.resources.WorkspaceJob;
|
|
29 |
import org.eclipse.core.runtime.CoreException;
|
|
30 |
import org.eclipse.core.runtime.IPath;
|
|
31 |
import org.eclipse.core.runtime.IProgressMonitor;
|
|
32 |
import org.eclipse.core.runtime.IStatus;
|
|
33 |
import org.eclipse.core.runtime.NullProgressMonitor;
|
|
34 |
import org.eclipse.core.runtime.Path;
|
|
35 |
import org.eclipse.core.runtime.Status;
|
|
36 |
import org.eclipse.core.runtime.preferences.IScopeContext;
|
|
37 |
import org.eclipse.swt.widgets.Display;
|
|
38 |
import org.eclipse.ui.IEditorPart;
|
|
39 |
import org.eclipse.ui.IWorkbenchPage;
|
|
40 |
import org.eclipse.ui.PartInitException;
|
|
41 |
import org.eclipse.ui.PlatformUI;
|
|
42 |
import org.eclipse.ui.part.FileEditorInput;
|
|
43 |
|
|
44 |
import com.symbian.smt.gui.editors.svgeditor.SVGEditor;
|
|
45 |
|
|
46 |
public class ChangeManager {
|
|
47 |
static HashMap<String, Boolean> dirtyProjects = new HashMap<String, Boolean>();
|
|
48 |
|
|
49 |
private String checkModelNameExtension(final IProject project,
|
|
50 |
final IResource addedFile, String newOutputName) {
|
|
51 |
if (!newOutputName.endsWith(".svg")) {
|
|
52 |
final StringBuilder fullName = new StringBuilder();
|
|
53 |
fullName.append(newOutputName);
|
|
54 |
fullName.append(".svg");
|
|
55 |
|
|
56 |
newOutputName = fullName.toString();
|
|
57 |
final String outputName = fullName.toString();
|
|
58 |
|
|
59 |
// The file has the extension added and is moved to the new filename
|
|
60 |
WorkspaceJob wj = new WorkspaceJob("auto-rename") {
|
|
61 |
@Override
|
|
62 |
public IStatus runInWorkspace(IProgressMonitor monitor)
|
|
63 |
throws CoreException {
|
|
64 |
IPath newLocation = addedFile.getFullPath()
|
|
65 |
.addFileExtension("svg");
|
|
66 |
addedFile
|
|
67 |
.move(newLocation, true, new NullProgressMonitor());
|
|
68 |
|
|
69 |
project.getFile(outputName).setDerived(true);
|
|
70 |
|
|
71 |
return new Status(IStatus.OK, Activator.PLUGIN_ID,
|
|
72 |
IStatus.OK, "auto-rename succeeded", null);
|
|
73 |
}
|
|
74 |
};
|
|
75 |
wj.schedule();
|
|
76 |
}
|
|
77 |
|
|
78 |
return newOutputName;
|
|
79 |
}
|
|
80 |
|
|
81 |
private void checkPropertyChangeMarkers(final IProject project) {
|
|
82 |
try {
|
|
83 |
IMarker[] mMarkers = project.findMarkers(IMarker.MESSAGE, false, 0);
|
|
84 |
|
|
85 |
for (final IMarker aMarker : mMarkers) {
|
|
86 |
if (aMarker.getAttribute(IMarker.MESSAGE) != null) {
|
|
87 |
if (aMarker.getAttribute(IMarker.MESSAGE).equals(
|
|
88 |
"properties changed")) {
|
|
89 |
dirtyProjects.put(project.getName(), true);
|
|
90 |
|
|
91 |
try {
|
|
92 |
aMarker.delete();
|
|
93 |
} catch (CoreException e) {
|
|
94 |
// Do nothing, the markers are a bit unstable, an
|
|
95 |
// exception will only occur if the marker has
|
|
96 |
// already been deleted.
|
|
97 |
}
|
|
98 |
}
|
|
99 |
}
|
|
100 |
}
|
|
101 |
} catch (CoreException e) {
|
|
102 |
Logger.log(e.getMessage(), e);
|
|
103 |
}
|
|
104 |
}
|
|
105 |
|
|
106 |
public void closeEditor(final IFile oldProjectFile) {
|
|
107 |
Display.getDefault().asyncExec(new Runnable() {
|
|
108 |
public void run() {
|
|
109 |
IWorkbenchPage page = PlatformUI.getWorkbench()
|
|
110 |
.getActiveWorkbenchWindow().getActivePage();
|
|
111 |
IEditorPart oldEditor = page.findEditor(new FileEditorInput(
|
|
112 |
oldProjectFile));
|
|
113 |
page.closeEditor(oldEditor, false);
|
|
114 |
}
|
|
115 |
});
|
|
116 |
}
|
|
117 |
|
|
118 |
private IResourceDelta[] getAddedItems(IResourceDelta delta,
|
|
119 |
IProject project) {
|
|
120 |
IResourceDelta[] added = null;
|
|
121 |
|
|
122 |
if (delta.getFullPath().equals(Path.ROOT)) {
|
|
123 |
IResourceDelta[] children = delta
|
|
124 |
.getAffectedChildren(IResourceDelta.CHANGED);
|
|
125 |
for (IResourceDelta child : children) {
|
|
126 |
added = child.getAffectedChildren(IResourceDelta.ADDED);
|
|
127 |
break;
|
|
128 |
}
|
|
129 |
} else if (project.getFullPath().equals(delta.getFullPath())) {
|
|
130 |
added = delta.getAffectedChildren(IResourceDelta.ADDED);
|
|
131 |
}
|
|
132 |
|
|
133 |
return added;
|
|
134 |
}
|
|
135 |
|
|
136 |
private IResourceDelta[] getDeletedItems(IResourceDelta delta,
|
|
137 |
IProject project) {
|
|
138 |
IResourceDelta[] deleted = null;
|
|
139 |
|
|
140 |
if (delta.getFullPath().equals(Path.ROOT)) {
|
|
141 |
IResourceDelta[] children = delta
|
|
142 |
.getAffectedChildren(IResourceDelta.CHANGED);
|
|
143 |
for (IResourceDelta child : children) {
|
|
144 |
deleted = child.getAffectedChildren(IResourceDelta.REMOVED);
|
|
145 |
break;
|
|
146 |
}
|
|
147 |
} else if (project.getFullPath().equals(delta.getFullPath())) {
|
|
148 |
deleted = delta.getAffectedChildren(IResourceDelta.REMOVED);
|
|
149 |
}
|
|
150 |
|
|
151 |
return deleted;
|
|
152 |
}
|
|
153 |
|
|
154 |
private IPath getDeltaPath(IResourceDelta delta, IProject project) {
|
|
155 |
IPath deltaPath = null;
|
|
156 |
|
|
157 |
if (delta.getFullPath().equals(Path.ROOT)) {
|
|
158 |
IResourceDelta[] children = delta
|
|
159 |
.getAffectedChildren(IResourceDelta.CHANGED);
|
|
160 |
for (IResourceDelta child : children) {
|
|
161 |
deltaPath = child.getFullPath();
|
|
162 |
break;
|
|
163 |
}
|
|
164 |
} else if (project.getFullPath().equals(delta.getFullPath())) {
|
|
165 |
deltaPath = delta.getFullPath();
|
|
166 |
}
|
|
167 |
|
|
168 |
return deltaPath;
|
|
169 |
}
|
|
170 |
|
|
171 |
public void handleDelta(IResourceDelta delta, final IProject project) {
|
|
172 |
checkPropertyChangeMarkers(project);
|
|
173 |
|
|
174 |
if (delta != null) {
|
|
175 |
IScopeContext projectScope = new ProjectScope(project);
|
|
176 |
PersistentDataStore store = new PersistentDataStore(projectScope
|
|
177 |
.getNode(Activator.PLUGIN_ID));
|
|
178 |
|
|
179 |
// Check to see if the System Model diagram name has changed
|
|
180 |
checkPropertyChangeMarkers(project); // True means that name has
|
|
181 |
// changed
|
|
182 |
|
|
183 |
// Get the added and deleted items, we use these to work out what
|
|
184 |
// has happened
|
|
185 |
IResourceDelta[] deletedItems = getDeletedItems(delta, project);
|
|
186 |
IResourceDelta[] addedItems = getAddedItems(delta, project);
|
|
187 |
|
|
188 |
// If the diagram has been deleted but a new one hasn't been added
|
|
189 |
// then close the editor
|
|
190 |
if (addedItems != null & deletedItems != null
|
|
191 |
&& deletedItems.length == 1 && addedItems.length == 0) {
|
|
192 |
final String deletedfile = deletedItems[0].getFullPath()
|
|
193 |
.toString();
|
|
194 |
String outputName = store.getOutputFilename();
|
|
195 |
String resourceName = getDeltaPath(delta, project).append(
|
|
196 |
outputName).toString();
|
|
197 |
|
|
198 |
// Check that it was the system model diagram what was deleted,
|
|
199 |
// we are not interested in any other files
|
|
200 |
if (deletedfile.equals(resourceName)) {
|
|
201 |
IFile oldProjectFile = project.getFile(store
|
|
202 |
.getOutputFilename());
|
|
203 |
closeEditor(oldProjectFile);
|
|
204 |
dirtyProjects.put(project.getName(), true);
|
|
205 |
}
|
|
206 |
}
|
|
207 |
|
|
208 |
// Otherwise if the diagram has been deleted and a new one added
|
|
209 |
// then the diagram has been renamed
|
|
210 |
else if (addedItems != null & deletedItems != null
|
|
211 |
&& deletedItems.length == 1 && addedItems.length == 1) {
|
|
212 |
String outputName = store.getOutputFilename();
|
|
213 |
|
|
214 |
if (outputName == null) {
|
|
215 |
return;
|
|
216 |
}
|
|
217 |
|
|
218 |
final String deletedfile = deletedItems[0].getFullPath()
|
|
219 |
.toString();
|
|
220 |
final String addedfile = addedItems[0].getFullPath().toString();
|
|
221 |
|
|
222 |
String resourceName = getDeltaPath(delta, project).append(
|
|
223 |
outputName).toString();
|
|
224 |
|
|
225 |
if (addedfile.equals(resourceName)
|
|
226 |
|| deletedfile.equals(resourceName)) {
|
|
227 |
final String oldOutputName = new File(deletedfile)
|
|
228 |
.getName();
|
|
229 |
|
|
230 |
// Will add the .svg extension if required and also rename
|
|
231 |
// the file
|
|
232 |
final String newOutputName = checkModelNameExtension(
|
|
233 |
project, addedItems[0].getResource(), new File(
|
|
234 |
addedfile).getName());
|
|
235 |
|
|
236 |
// Update the project properties with the new model name
|
|
237 |
updatePropertiesWithModelName(store, resourceName,
|
|
238 |
deletedfile, newOutputName);
|
|
239 |
|
|
240 |
final IFile newProjectFile = project.getFile(newOutputName);
|
|
241 |
|
|
242 |
Boolean isDirty = false;
|
|
243 |
|
|
244 |
if (dirtyProjects.containsKey(project.getName())) {
|
|
245 |
isDirty = dirtyProjects.get(project.getName());
|
|
246 |
}
|
|
247 |
|
|
248 |
if (delta.getAffectedChildren(IResourceDelta.CHANGED).length <= 1
|
|
249 |
&& !isDirty) {
|
|
250 |
Display.getDefault().asyncExec(new Runnable() {
|
|
251 |
|
|
252 |
public void run() {
|
|
253 |
if (newProjectFile.exists()
|
|
254 |
&& !newProjectFile.isPhantom()) {
|
|
255 |
try {
|
|
256 |
IWorkbenchPage page = PlatformUI
|
|
257 |
.getWorkbench()
|
|
258 |
.getActiveWorkbenchWindow()
|
|
259 |
.getActivePage();
|
|
260 |
FileEditorInput editorInput = new FileEditorInput(
|
|
261 |
newProjectFile);
|
|
262 |
|
|
263 |
IEditorPart oldEditor = page
|
|
264 |
.findEditor(new FileEditorInput(
|
|
265 |
project
|
|
266 |
.getFile(oldOutputName)));
|
|
267 |
page.closeEditor(oldEditor, false);
|
|
268 |
|
|
269 |
page.openEditor(editorInput,
|
|
270 |
SVGEditor.ID);
|
|
271 |
|
|
272 |
} catch (PartInitException e) {
|
|
273 |
Logger.log(e.getMessage(), e);
|
|
274 |
}
|
|
275 |
}
|
|
276 |
}
|
|
277 |
});
|
|
278 |
}
|
|
279 |
}
|
|
280 |
} else { // Nothing has been deleted and nothing has been added - A
|
|
281 |
// file has been amended.
|
|
282 |
IResourceDelta[] children = delta
|
|
283 |
.getAffectedChildren(IResourceDelta.CHANGED);
|
|
284 |
|
|
285 |
for (IResourceDelta child : children) {
|
|
286 |
if (child.getResource() instanceof IFile) {
|
|
287 |
if (child.getResource().getFileExtension()
|
|
288 |
.equalsIgnoreCase("xml")) {
|
|
289 |
dirtyProjects.put(project.getName(), true);
|
|
290 |
}
|
|
291 |
} else if (child.getResource() instanceof IProject) {
|
|
292 |
if (child.getFlags() == IResourceDelta.OPEN) {
|
|
293 |
dirtyProjects.put(child.getResource().getName(),
|
|
294 |
true);
|
|
295 |
}
|
|
296 |
} else if (child.getResource() instanceof IFolder) {
|
|
297 |
IResourceDelta[] moreChildren = child
|
|
298 |
.getAffectedChildren(IResourceDelta.CHANGED);
|
|
299 |
for (IResourceDelta littlerChild : moreChildren) {
|
|
300 |
if (littlerChild.getResource().getFileExtension()
|
|
301 |
.equalsIgnoreCase("xml")) {
|
|
302 |
dirtyProjects.put(project.getName(), true);
|
|
303 |
}
|
|
304 |
}
|
|
305 |
}
|
|
306 |
}
|
|
307 |
}
|
|
308 |
}
|
|
309 |
}
|
|
310 |
|
|
311 |
public void remove(IProject project) {
|
|
312 |
if (dirtyProjects.containsKey(project.getName())) {
|
|
313 |
dirtyProjects.remove(project.getName());
|
|
314 |
}
|
|
315 |
}
|
|
316 |
|
|
317 |
public boolean needsBuilding(IProject project) {
|
|
318 |
if (dirtyProjects.containsKey(project.getName())) {
|
|
319 |
return dirtyProjects.get(project.getName());
|
|
320 |
}
|
|
321 |
|
|
322 |
IScopeContext projectScope = new ProjectScope(project);
|
|
323 |
PersistentDataStore store = new PersistentDataStore(projectScope
|
|
324 |
.getNode(Activator.PLUGIN_ID));
|
|
325 |
|
|
326 |
if (!project.getFile(store.getOutputFilename()).exists()) {
|
|
327 |
return true;
|
|
328 |
}
|
|
329 |
|
|
330 |
return false;
|
|
331 |
}
|
|
332 |
|
|
333 |
public void reset(IProject project) {
|
|
334 |
dirtyProjects.put(project.getName(), false);
|
|
335 |
}
|
|
336 |
|
|
337 |
private void updatePropertiesWithModelName(final PersistentDataStore store,
|
|
338 |
final String resourceName, final String deletedfile,
|
|
339 |
final String outName) {
|
|
340 |
WorkspaceJob wj = new WorkspaceJob("updating properties") {
|
|
341 |
@Override
|
|
342 |
public IStatus runInWorkspace(IProgressMonitor monitor)
|
|
343 |
throws CoreException {
|
|
344 |
if (deletedfile.equals(resourceName)) {
|
|
345 |
store.setOutputFilename(outName);
|
|
346 |
}
|
|
347 |
return new Status(IStatus.OK, Activator.PLUGIN_ID, IStatus.OK,
|
|
348 |
"updating properties succeeded", null);
|
|
349 |
}
|
|
350 |
};
|
|
351 |
wj.schedule();
|
|
352 |
}
|
|
353 |
}
|