sysmodelmgr/com.symbian.smt.gui/src/com/symbian/smt/gui/builder/Builder.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.builder;
       
    17 
       
    18 import java.io.File;
       
    19 import java.util.ArrayList;
       
    20 import java.util.List;
       
    21 import java.util.Locale;
       
    22 import java.util.Map;
       
    23 import java.util.ResourceBundle;
       
    24 
       
    25 import org.eclipse.core.resources.IContainer;
       
    26 import org.eclipse.core.resources.IFile;
       
    27 import org.eclipse.core.resources.IFolder;
       
    28 import org.eclipse.core.resources.IMarker;
       
    29 import org.eclipse.core.resources.IProject;
       
    30 import org.eclipse.core.resources.IResource;
       
    31 import org.eclipse.core.resources.IResourceDelta;
       
    32 import org.eclipse.core.resources.IncrementalProjectBuilder;
       
    33 import org.eclipse.core.resources.ProjectScope;
       
    34 import org.eclipse.core.runtime.CoreException;
       
    35 import org.eclipse.core.runtime.IProgressMonitor;
       
    36 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
       
    37 import org.eclipse.core.runtime.preferences.IScopeContext;
       
    38 import org.eclipse.swt.widgets.Display;
       
    39 import org.eclipse.ui.IEditorPart;
       
    40 import org.eclipse.ui.IWorkbenchPage;
       
    41 import org.eclipse.ui.PartInitException;
       
    42 import org.eclipse.ui.PlatformUI;
       
    43 import org.eclipse.ui.part.FileEditorInput;
       
    44 
       
    45 import com.symbian.smt.gui.Activator;
       
    46 import com.symbian.smt.gui.ChangeManager;
       
    47 import com.symbian.smt.gui.Logger;
       
    48 import com.symbian.smt.gui.ManageResources;
       
    49 import com.symbian.smt.gui.PersistentDataStore;
       
    50 import com.symbian.smt.gui.editors.svgeditor.SVGEditor;
       
    51 import com.symbian.smt.gui.views.ConsoleOutput;
       
    52 
       
    53 public class Builder extends IncrementalProjectBuilder {
       
    54 	final static String TEMP_FOLDER = ".svg_temp"; // Folder names stating with
       
    55 	// a . will not be displayed
       
    56 	// in the project navigator
       
    57 
       
    58 	private IFolder svgTempFolder;
       
    59 	private IFile projectFile;
       
    60 
       
    61 	private List<IResource> markedResources;
       
    62 
       
    63 	private void addFileToProject() {
       
    64 		// Adds the file to the root of the project folder
       
    65 		try {
       
    66 			// Refresh the project so that it picks up the generated SVG file
       
    67 			getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
       
    68 
       
    69 			// Set the file as a derived resource (indicates was built from
       
    70 			// source and not an original file)
       
    71 			projectFile.setDerived(true);
       
    72 		} catch (CoreException e) {
       
    73 			Logger.log(e.getMessage(), e);
       
    74 		}
       
    75 	}
       
    76 
       
    77 	@SuppressWarnings("unchecked")
       
    78 	@Override
       
    79 	protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
       
    80 			throws CoreException {
       
    81 		
       
    82 		IProject project = getProject();
       
    83 
       
    84 		if (!checkSMGinstalled()) {
       
    85 			writeToConsoleOutput("ERROR: Unable to locate the System Model Generator");
       
    86 			return null;
       
    87 		}
       
    88 		
       
    89 		project.touch(null);
       
    90 
       
    91 		// First we check that project is in sync with the file system
       
    92 		findResourcesMarkedAsUrl(project);
       
    93 
       
    94 		if (markedResources.size() == 0) {
       
    95 			if (!project.isSynchronized(IResource.DEPTH_INFINITE)) {
       
    96 				writeToConsoleOutput("ERROR: The project is out of sync with the file system");
       
    97 				return null;
       
    98 			}
       
    99 		} else {
       
   100 			boolean isSynchronised = checkSyncrhonised(project);
       
   101 
       
   102 			if (!isSynchronised) {
       
   103 				writeToConsoleOutput("ERROR: The project is out of sync with the file system");
       
   104 				return null;
       
   105 			}
       
   106 		}
       
   107 
       
   108 		IResourceDelta delta = getDelta(project);
       
   109 		ChangeManager manager = new ChangeManager();
       
   110 
       
   111 		manager.handleDelta(delta, project);
       
   112 
       
   113 		if (!manager.needsBuilding(project)) {
       
   114 			return null;
       
   115 		}
       
   116 
       
   117 		manager.reset(project);
       
   118 
       
   119 		// We are not interested in different build types are we are only able
       
   120 		// to perform one type of build using the Perl SMG
       
   121 
       
   122 		svgTempFolder = project.getFolder(TEMP_FOLDER);
       
   123 
       
   124 		// Delete generated temp files
       
   125 		if (svgTempFolder.exists()) {
       
   126 			svgTempFolder.delete(true, null);
       
   127 		}
       
   128 
       
   129 		// Build
       
   130 		performBuild();
       
   131 
       
   132 		return null;
       
   133 	}
       
   134 
       
   135 	private boolean checkSyncrhonised(IResource resource) {
       
   136 		boolean result = true;
       
   137 
       
   138 		if (resource instanceof IFile) {
       
   139 			if (markedResources.contains(resource)) {
       
   140 				result = true;
       
   141 			} else {
       
   142 				result = resource.isSynchronized(IResource.DEPTH_ZERO);
       
   143 			}
       
   144 		} else if (resource instanceof IContainer) { // It is either IProject or
       
   145 														// IFolder
       
   146 			IContainer container = (IContainer) resource;
       
   147 
       
   148 			try {
       
   149 				IResource[] children = container.members();
       
   150 
       
   151 				for (IResource child : children) {
       
   152 					result = checkSyncrhonised(child);
       
   153 
       
   154 					if (!result) {
       
   155 						break;
       
   156 					}
       
   157 				}
       
   158 			} catch (CoreException e) {
       
   159 				Logger.log(e.getMessage(), e);
       
   160 				result = false;
       
   161 			}
       
   162 		}
       
   163 
       
   164 		return result;
       
   165 	}
       
   166 
       
   167 	private void findResourcesMarkedAsUrl(IProject project)
       
   168 			throws CoreException {
       
   169 		IMarker[] messageMarkers = project.findMarkers(IMarker.TASK, false,
       
   170 				IResource.DEPTH_INFINITE);
       
   171 		markedResources = new ArrayList<IResource>();
       
   172 
       
   173 		for (int i = 0; i < messageMarkers.length; i++) {
       
   174 			IMarker marker = messageMarkers[i];
       
   175 
       
   176 			if (marker.getAttribute(ManageResources.IS_URL, false)) {
       
   177 				markedResources.add(marker.getResource());
       
   178 			}
       
   179 		}
       
   180 	}
       
   181 
       
   182 	private void performBuild() {
       
   183 		// Reset the command output window
       
   184 		Display.getDefault().asyncExec(new Runnable() {
       
   185 			public void run() {
       
   186 				ConsoleOutput.reset();
       
   187 			}
       
   188 		});
       
   189 
       
   190 		// Create a processBuilder. This will run the SMT in another thread.
       
   191 		SMTCommand command = new SMTCommand(getProject());
       
   192 		List<String> generatedCommand = command.generateCommand();
       
   193 
       
   194 		if (generatedCommand == null) {
       
   195 			return;
       
   196 		}
       
   197 
       
   198 		SMTProcess process = new SMTProcess();
       
   199 
       
   200 		// Run the process
       
   201 		int exitCode = process.run(generatedCommand);
       
   202 		
       
   203 		if (exitCode == 0) {
       
   204 			IScopeContext projectScope = new ProjectScope(getProject());
       
   205 			IEclipsePreferences projectNode = projectScope
       
   206 					.getNode(Activator.PLUGIN_ID);
       
   207 			PersistentDataStore projectStore = new PersistentDataStore(
       
   208 					projectNode);
       
   209 
       
   210 			projectFile = getProject()
       
   211 					.getFile(projectStore.getOutputFilename());
       
   212 
       
   213 			// Add the SVG file to the project
       
   214 			addFileToProject();
       
   215 
       
   216 			// Inform the user that the model has been created
       
   217 			writeToConsoleOutput("Finished");
       
   218 
       
   219 			// Open the file in the editor
       
   220 			Display.getDefault().asyncExec(new Runnable() {
       
   221 				public void run() {
       
   222 					try {
       
   223 						IWorkbenchPage page = PlatformUI.getWorkbench()
       
   224 								.getActiveWorkbenchWindow().getActivePage();
       
   225 
       
   226 						IEditorPart part = page.findEditor(new FileEditorInput(
       
   227 								projectFile));
       
   228 						if (part != null && part instanceof SVGEditor) {
       
   229 							page.openEditor(new FileEditorInput(projectFile),
       
   230 									SVGEditor.ID);
       
   231 							((SVGEditor) part).refresh();
       
   232 						} else {
       
   233 							page.openEditor(new FileEditorInput(projectFile),
       
   234 									SVGEditor.ID);
       
   235 						}
       
   236 					} catch (PartInitException e) {
       
   237 						Logger.log(e.getMessage(), e);
       
   238 					}
       
   239 				}
       
   240 			});
       
   241 		} else {
       
   242 			writeToConsoleOutput("Exit Code: " + exitCode);
       
   243 
       
   244 			// Add the output to the Eclipse log
       
   245 			Display.getDefault().asyncExec(new Runnable() {
       
   246 				public void run() {
       
   247 					Exception e = new Exception(ConsoleOutput.getText());
       
   248 					Logger
       
   249 							.log(
       
   250 									"Failed to successfully generate System Model diagram",
       
   251 									e);
       
   252 				}
       
   253 			});
       
   254 
       
   255 			writeToConsoleOutput("ERROR: Failed to successfully generate System Model diagram");
       
   256 		}
       
   257 	}
       
   258 	
       
   259 	private boolean checkSMGinstalled() {
       
   260 		
       
   261 		final ResourceBundle resourceBundle = ResourceBundle.getBundle(
       
   262 				"location", Locale.getDefault(), this.getClass()
       
   263 						.getClassLoader());
       
   264 
       
   265 		String smgFolder = resourceBundle.getString("location");
       
   266 
       
   267 		File smgCommand = new File(smgFolder + File.separator + "SysModGen.pl");
       
   268 
       
   269 		return smgCommand.exists();
       
   270 	}
       
   271 
       
   272 	private void writeToConsoleOutput(final String string) {
       
   273 		// Writes a string to the console output view
       
   274 
       
   275 		Display.getDefault().asyncExec(new Runnable() {
       
   276 			public void run() {
       
   277 				ConsoleOutput.addText(string);
       
   278 			}
       
   279 		});
       
   280 	}
       
   281 	
       
   282 }