builder/com.nokia.carbide.cdt.builder/src/com/nokia/carbide/cdt/builder/builder/CarbideCommandLauncher.java
changeset 319 d5583b4233b4
parent 0 fb279309251b
child 1347 22abc3a66090
equal deleted inserted replaced
318:db1d5c584059 319:d5583b4233b4
    14 * Description: 
    14 * Description: 
    15 *
    15 *
    16 */
    16 */
    17 package com.nokia.carbide.cdt.builder.builder;
    17 package com.nokia.carbide.cdt.builder.builder;
    18 
    18 
    19 import java.io.IOException;
    19 import com.nokia.carbide.cdt.builder.CarbideBuilderPlugin;
    20 import java.util.Properties;
    20 
    21 
    21 import org.eclipse.cdt.core.*;
    22 import org.eclipse.cdt.core.CCorePlugin;
       
    23 import org.eclipse.cdt.core.CommandLauncher;
       
    24 import org.eclipse.cdt.core.ConsoleOutputStream;
       
    25 import org.eclipse.cdt.core.ErrorParserManager;
       
    26 import org.eclipse.cdt.core.IMarkerGenerator;
       
    27 import org.eclipse.cdt.core.ProblemMarkerInfo;
       
    28 import org.eclipse.cdt.core.model.ICModelMarker;
    22 import org.eclipse.cdt.core.model.ICModelMarker;
    29 import org.eclipse.cdt.core.resources.IConsole;
    23 import org.eclipse.cdt.core.resources.IConsole;
    30 import org.eclipse.cdt.ui.CUIPlugin;
    24 import org.eclipse.cdt.ui.CUIPlugin;
    31 import org.eclipse.cdt.utils.spawner.EnvironmentReader;
    25 import org.eclipse.cdt.utils.spawner.EnvironmentReader;
    32 import org.eclipse.core.resources.IMarker;
    26 import org.eclipse.core.internal.resources.MarkerInfo;
    33 import org.eclipse.core.resources.IProject;
    27 import org.eclipse.core.internal.resources.Workspace;
    34 import org.eclipse.core.resources.IResource;
    28 import org.eclipse.core.resources.*;
    35 import org.eclipse.core.runtime.CoreException;
    29 import org.eclipse.core.runtime.*;
    36 import org.eclipse.core.runtime.IPath;
    30 
    37 import org.eclipse.core.runtime.IProgressMonitor;
    31 import java.io.IOException;
    38 import org.eclipse.core.runtime.Path;
    32 import java.util.*;
    39 import org.eclipse.core.runtime.SubProgressMonitor;
       
    40 
       
    41 import com.nokia.carbide.cdt.builder.CarbideBuilderPlugin;
       
    42 
    33 
    43 /**
    34 /**
    44  * A utility class to handle windows process execution. This utility class handles all the execution, 
    35  * A utility class to handle windows process execution. This utility class handles all the execution, 
    45  * error processing, and console output.
    36  * error processing, and console output.
    46  */
    37  */
    47 public class CarbideCommandLauncher extends CommandLauncher implements IMarkerGenerator {
    38 public class CarbideCommandLauncher extends CommandLauncher implements IMarkerGenerator {
       
    39 
       
    40 	public class MarkerCacheElement {
       
    41 		private int line;
       
    42 		private int severity;
       
    43 		private String message;
       
    44 		
       
    45 		public MarkerCacheElement(IMarker marker) throws CoreException {
       
    46 			line = marker.getAttribute(IMarker.LINE_NUMBER, -1);
       
    47 			severity = ((Integer) marker.getAttribute(IMarker.SEVERITY)).intValue();
       
    48 			message = (String) marker.getAttribute(IMarker.MESSAGE);
       
    49 		}
       
    50 
       
    51 		public MarkerCacheElement(ProblemMarkerInfo problemMarkerInfo) {
       
    52 			line = problemMarkerInfo.lineNumber;
       
    53 			severity = mapMarkerSeverity(problemMarkerInfo.severity);
       
    54 			message = problemMarkerInfo.description;
       
    55 		}
       
    56 
       
    57 		@Override
       
    58 		public int hashCode() {
       
    59 			final int prime = 31; 
       
    60 			int result = 1;
       
    61 			result = prime * result + line;
       
    62 			result = prime * result + severity;
       
    63 			result = prime * result
       
    64 					+ ((message == null) ? 0 : message.hashCode());
       
    65 			return result;
       
    66 		}
       
    67 
       
    68 		@Override
       
    69 		public boolean equals(Object obj) {
       
    70 			if (!(obj instanceof MarkerCacheElement))
       
    71 				return false;
       
    72 			MarkerCacheElement other = (MarkerCacheElement) obj;
       
    73 			if (line != other.line)
       
    74 				return false;
       
    75 			if (severity != other.severity)
       
    76 				return false;
       
    77 			if (message == null) {
       
    78 				if (other.message != null)
       
    79 					return false;
       
    80 			} 
       
    81 			else if (!message.equals(other.message))
       
    82 				return false;
       
    83 			return true;
       
    84 		}
       
    85 	}
    48 
    86 
    49 	protected IProgressMonitor monitor;
    87 	protected IProgressMonitor monitor;
    50 	protected IConsole console;
    88 	protected IConsole console;
    51 	protected ErrorParserManager stdoutStream;
    89 	protected ErrorParserManager stdoutStream;
    52 	protected ErrorParserManager stderrStream;
    90 	protected ErrorParserManager stderrStream;
    54 	protected ConsoleOutputStream consoleErrorStream;
    92 	protected ConsoleOutputStream consoleErrorStream;
    55 	protected ConsoleOutputStream consoleInfoStream;
    93 	protected ConsoleOutputStream consoleInfoStream;
    56 	protected IProject project;
    94 	protected IProject project;
    57 	protected String[] errorParserIds;
    95 	protected String[] errorParserIds;
    58 	protected IMarkerGenerator markerGen;
    96 	protected IMarkerGenerator markerGen;
       
    97 	private Map<IResource, Set<MarkerCacheElement>> markerCache;
       
    98 	private long markerCreationTime;
    59 	
    99 	
    60 	/**
   100 	/**
    61 	 * Location of tool execution
   101 	 * Location of tool execution
    62 	 */
   102 	 */
    63 	IPath workingDir;
   103 	IPath workingDir;
   210 	 * @param env - Full list of environment variables
   250 	 * @param env - Full list of environment variables
   211 	 * @param workingDir - The current working directory the command is to be invoked in.
   251 	 * @param workingDir - The current working directory the command is to be invoked in.
   212 	 * @return 0 (zero) on success. returns the actual tool return status
   252 	 * @return 0 (zero) on success. returns the actual tool return status
   213 	 */
   253 	 */
   214 	public int executeCommand(IPath command, String[] args, String[] env, IPath workingDir){
   254 	public int executeCommand(IPath command, String[] args, String[] env, IPath workingDir){
       
   255 		markerCache = null;
       
   256 		markerCreationTime = System.currentTimeMillis();
   215 		int exitValue = -1;
   257 		int exitValue = -1;
   216 		String errMsg;
   258 		String errMsg;
   217 		try {
   259 		try {
   218 			
   260 			
   219 			Process proc = execute(command, args, env, workingDir);
   261 			Process proc = execute(command, args, env, workingDir);
   297     	ProblemMarkerInfo info = new ProblemMarkerInfo(file, lineNumber, errorDesc, severity, errorVar);
   339     	ProblemMarkerInfo info = new ProblemMarkerInfo(file, lineNumber, errorDesc, severity, errorVar);
   298     	addMarker(info);
   340     	addMarker(info);
   299     }
   341     }
   300 
   342 
   301 	public void addMarker(ProblemMarkerInfo problemMarkerInfo) {
   343 	public void addMarker(ProblemMarkerInfo problemMarkerInfo) {
   302 
   344 		if (markerCache == null)
       
   345 			markerCache = new HashMap<IResource, Set<MarkerCacheElement>>();
       
   346 		
   303 		try {
   347 		try {
   304 			IResource markerResource = problemMarkerInfo.file ;
   348 			IResource markerResource = problemMarkerInfo.file ;
   305 			if (markerResource == null)  {
   349 			if (markerResource == null)  {
   306 				markerResource = stdoutStream.getProject();
   350 				markerResource = stdoutStream.getProject();
   307 			}
   351 			}
   308 			IMarker[] cur = markerResource.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ONE);
   352 			
   309 
   353 			Set<MarkerCacheElement> cacheElements = markerCache.get(markerResource);
   310 			/*
   354 			if (cacheElements == null) {
   311 			 * Try to find matching markers and don't put in duplicates
   355 				cacheElements = new HashSet<MarkerCacheElement>();
   312 			 */
   356 				markerCache.put(markerResource, cacheElements);
   313 			if ((cur != null) && (cur.length > 0)) {
   357 				IMarker[] cur = markerResource.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ONE);
   314 				for (int i = 0; i < cur.length; i++) {
   358 				for (IMarker marker : cur) {
   315 					int line = cur[i].getAttribute(IMarker.LINE_NUMBER, -1);
   359 					cacheElements.add(new MarkerCacheElement(marker));
   316 					int sev = ((Integer) cur[i].getAttribute(IMarker.SEVERITY)).intValue();
       
   317 					String mesg = (String) cur[i].getAttribute(IMarker.MESSAGE);
       
   318 					if (line == problemMarkerInfo.lineNumber && sev == mapMarkerSeverity(problemMarkerInfo.severity) && mesg.equals(problemMarkerInfo.description)) {
       
   319 						return;
       
   320 					}
       
   321 				}
   360 				}
   322 			}
   361 			}
   323 
   362 			
   324 			// need to pause briefly between marker creations so the creation timestamps
   363 			if (!cacheElements.add(new MarkerCacheElement(problemMarkerInfo)))
   325 			// are unique and sorting the problems view by creation time works properly.
   364 				return;
   326 			try {
       
   327 				Thread.sleep(20);
       
   328 			} catch (InterruptedException e1) {
       
   329 				e1.printStackTrace();
       
   330 			}
       
   331 
   365 
   332 			IMarker marker = markerResource.createMarker(ICModelMarker.C_MODEL_PROBLEM_MARKER);
   366 			IMarker marker = markerResource.createMarker(ICModelMarker.C_MODEL_PROBLEM_MARKER);
   333 			marker.setAttribute(IMarker.MESSAGE, problemMarkerInfo.description);
   367 			marker.setAttribute(IMarker.MESSAGE, problemMarkerInfo.description);
   334 			marker.setAttribute(IMarker.SEVERITY, mapMarkerSeverity(problemMarkerInfo.severity));
   368 			marker.setAttribute(IMarker.SEVERITY, mapMarkerSeverity(problemMarkerInfo.severity));
   335 			marker.setAttribute(IMarker.LINE_NUMBER, problemMarkerInfo.lineNumber);
   369 			marker.setAttribute(IMarker.LINE_NUMBER, problemMarkerInfo.lineNumber);
   354 					CarbideBuilderPlugin.log(e);
   388 					CarbideBuilderPlugin.log(e);
   355 					e.printStackTrace();
   389 					e.printStackTrace();
   356 				}
   390 				}
   357 				marker.setAttribute(ICModelMarker.C_MODEL_MARKER_EXTERNAL_LOCATION, absolutePath.toOSString());
   391 				marker.setAttribute(ICModelMarker.C_MODEL_MARKER_EXTERNAL_LOCATION, absolutePath.toOSString());
   358 			}
   392 			}
       
   393 			setUniqueCreationTime(marker);
   359 		}
   394 		}
   360 		catch (CoreException e) {
   395 		catch (CoreException e) {
   361 			CCorePlugin.log(e.getStatus());
   396 			CCorePlugin.log(e.getStatus());
   362 		}
   397 		}
   363 
   398 
   364 	}
   399 	}
   365 	
   400 	
       
   401 	private void setUniqueCreationTime(IMarker marker) {
       
   402 		// This is using internal platform APIs to avoid putting a delay into every marker creation
       
   403 		// to ensure each marker gets a unique creation time (for sorting in the problems view).
       
   404 		// The total delay could be significant when there are many problem markers
       
   405 		IResource resource = marker.getResource();
       
   406 		Workspace workspace = (Workspace) resource.getWorkspace();
       
   407 		MarkerInfo markerInfo = workspace.getMarkerManager().findMarkerInfo(resource, marker.getId());
       
   408 		markerInfo.setCreationTime(markerCreationTime++);
       
   409 	}
       
   410 
   366 	int mapMarkerSeverity(int severity) {
   411 	int mapMarkerSeverity(int severity) {
   367 
   412 
   368 		switch (severity) {
   413 		switch (severity) {
   369 			case SEVERITY_ERROR_BUILD :
   414 			case SEVERITY_ERROR_BUILD :
   370 			case SEVERITY_ERROR_RESOURCE :
   415 			case SEVERITY_ERROR_RESOURCE :