sysmodelmgr/com.symbian.smt.gui/src/com/symbian/smt/gui/ChangeManager.java
changeset 0 522a326673b6
equal deleted inserted replaced
-1:000000000000 0:522a326673b6
       
     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 }