|
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 } |