crashanalysis/crashanalyser/com.nokia.s60tools.crashanalyser.corecomponents/src/com/nokia/s60tools/crashanalyser/corecomponents/interfaces/CommandLineManager.java
author Jussi Ryoma <ext-jussi.s.ryoma@nokia.com>
Tue, 24 Aug 2010 14:01:48 +0300
changeset 16 72f198be1c1d
parent 4 615035072f7e
permissions -rw-r--r--
Crash Analyser Carbide Extension 1.4.0

/*
 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
 *
 * Initial Contributors:
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
 *
 * Description:
 *
 */

package com.nokia.s60tools.crashanalyser.corecomponents.interfaces;

import com.nokia.s60tools.crashanalyser.corecomponents.model.*;
import com.nokia.s60tools.crashanalyser.corecomponents.model.InputXmlGenerator.XMLGeneratorAction;
import com.nokia.s60tools.crashanalyser.corecomponents.plugin.*;
import java.io.*;
import java.util.*;
import org.eclipse.core.runtime.IProgressMonitor;

/**
 * This class is used for running CrashAnalyser.exe
 * 
 */
public final class CommandLineManager {

	private static final String ACTION_START_TAG = "} START - ";

	/**
	 * Verbose output
	 */
	static final boolean verbose = false;

	/**
	 * Progress detailed output
	 */
	static final boolean progress_detailed = false;

	public static final String PARAMETERS_XML = "parameters.xml";
	static final String EXE_FOLDER = "Binaries";
	static final String COMMAND_LINE_COMMAND = "CrashAnalyserConsole.exe\" -plugin CRASH_ANALYSIS -input ";
	static final String PROGRESS_PARAMETER = " -PROGRESS";
	static final String PROGRESS_DETAILS_PARAMETER = " -PROGRESS_DETAILS";
	static final String VERBOSE_PARAMETER = " -V";

	private CommandLineManager() {
		// not meant to be implemented
	}

	/**
	 * Executes CrashAnalyser.exe with Full data (i.e. creates an XML file from
	 * e.g. MobileCrash.bin witht symbol etc. information)
	 * 
	 * @param outputFolder
	 *            where output files are created
	 * @param crashFiles
	 *            files to be decoded
	 * @param symbolFiles
	 *            paths to symbol files (or null)
	 * @param mapFilesFolder
	 *            folder which contains map files (or null)
	 * @param imageFiles
	 *            paths to image files (or null)
	 * @param fileExtension
	 *            E.g. crashxml (not .crashxml)
	 * @param failedFileExtension
	 *            extension for failed files
	 * @param selgeEventIniFile
	 *            location of selge_event.ini
	 * @param monitor
	 *            for progress bar
	 * @return true if success, false if not
	 */
	public static boolean executeFullAnalysis(String outputFolder,
			String[] crashFiles, String[] symbolFiles, String mapFilesFolder,
			String[] imageFiles, String[] traceDictionaryFiles, String fileExtension,
			String failedFileExtension, String selgeEventIniFile,
			IProgressMonitor monitor) {
		List<String> debugMetadataFiles = new ArrayList<String>();

		// collect symbol files if any provided
		if (symbolFiles != null && symbolFiles.length > 0) {
			for (int i = 0; i < symbolFiles.length; i++)
				debugMetadataFiles.add(symbolFiles[i]);
		}

		// collect image files if any provided
		if (imageFiles != null && imageFiles.length > 0) {
			for (int i = 0; i < imageFiles.length; i++)
				debugMetadataFiles.add(imageFiles[i]);
		}

		// collect trace dictionary files if any provided
		if (traceDictionaryFiles != null && traceDictionaryFiles.length > 0) {
			for (String traceDictionaryFile : traceDictionaryFiles)
				debugMetadataFiles.add(traceDictionaryFile);
		}

		String[] debugMetadata = null;
		if (!debugMetadataFiles.isEmpty())
			debugMetadata = debugMetadataFiles
					.toArray(new String[debugMetadataFiles.size()]);

		String mapFolder = mapFilesFolder;
		if (mapFilesFolder != null && "".equals(mapFilesFolder))
			mapFolder = null;

		InputXmlGenerator xml = new InputXmlGenerator(
				XMLGeneratorAction.ANALYSE_CRASH_FULL, crashFiles, null,
				debugMetadata, mapFolder, null, null, outputFolder, "."
						+ fileExtension, "." + failedFileExtension,
				selgeEventIniFile);
		return createAndExecute(xml, monitor);
	}

	/**
	 * Executes CrashAnalyser.exe with Summary data (i.e. creates quickly an XML
	 * file from e.g. MobileCrash.bin without symbol etc. information)
	 * 
	 * @param outputFolder
	 *            where output files are created
	 * @param fileOrFolder
	 *            file to be "decoded" or directory from which files are to be
	 *            decoded
	 * @param fileExtension
	 *            E.g. xml (not .xml)
	 * @param monitor
	 *            Progress monitor
	 * @return true if success, false if not
	 */
	public static boolean executeSummary(String outputFolder,
			String fileOrFolder, String fileExtension, IProgressMonitor monitor) {
		File file = new File(fileOrFolder);
		// directory was given
		if (file.isDirectory()) {
			InputXmlGenerator xml = new InputXmlGenerator(
					XMLGeneratorAction.ANALYSE_CRASH_SUMMARY, null,
					fileOrFolder, null, null, null, null, outputFolder, "."
							+ fileExtension, null, "");
			return createAndExecute(xml, monitor);
			// a single file was given
		} else if (file.isFile()) {
			InputXmlGenerator xml = new InputXmlGenerator(
					XMLGeneratorAction.ANALYSE_CRASH_SUMMARY,
					new String[] { fileOrFolder }, null, null, null, null,
					null, outputFolder, "." + fileExtension, null, "");
			return createAndExecute(xml, monitor);
		}
		return false;
	}

	/**
	 * creates an input.xml for CrashAnalyser.exe and executes CrashAnalyser.exe
	 * 
	 * @param xml
	 *            initialized xml generator
	 * @param monitor
	 *            Progress monitor
	 * @return true if success, false if not
	 */
	private static boolean createAndExecute(InputXmlGenerator xml,
			IProgressMonitor monitor) {
		String workingDirectory = getCrashAnalyserPath();
		String parameterXmlPath = xml.getXMLAnalyseDirectoryOutput();
		String fileName = parameterXmlPath + PARAMETERS_XML;
		File filename = new File(fileName);
		BufferedWriter writer = null;
		try {
			writer = new BufferedWriter(new FileWriter(filename));
			// create input.xml for CrashAnalyser.exe
			xml.GenerateXML(writer);

		} catch (IOException e) {
			e.printStackTrace();
			return false;
		} finally {
			try {
				if (writer != null) {
					writer.flush();
					writer.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}

		try {
			String commandLineCommand = "\"" + workingDirectory
					+ COMMAND_LINE_COMMAND + parameterXmlPath + PARAMETERS_XML;
			if (monitor != null)
				if (progress_detailed) {
					commandLineCommand += PROGRESS_DETAILS_PARAMETER;
				} else {
					commandLineCommand += PROGRESS_PARAMETER;
				}

			if (verbose)
				commandLineCommand += VERBOSE_PARAMETER;

			// execute CrashAnalyser.exe
			Process p = Runtime.getRuntime().exec(commandLineCommand, null,
					new File(workingDirectory));
			// Get the input stream and read from it

			FileWriter fstream = new FileWriter(workingDirectory + "log.txt");
			BufferedWriter out = new BufferedWriter(fstream);
			int c;
			String line = "";
			InputStream in = p.getInputStream();
			boolean monitorStarted = false;
			while ((c = in.read()) != -1) {
				if ((char) c == '\n' || (char) c == '\r') {
					if (line.contains(ACTION_START_TAG)) {
						int beginIndex = line.indexOf(ACTION_START_TAG)
								+ ACTION_START_TAG.length();
						String action = line.substring(beginIndex);
						if (!line.contains("/???") && !monitorStarted) {
							int beginOfIndexOfActionsNbr = line.indexOf("/") + 1;
							int endOfIndexOfActionsNbr = line.indexOf("}",
									beginOfIndexOfActionsNbr);
							Integer nbrOfActions = 0;
							try {
								nbrOfActions = Integer.valueOf((line.substring(
										beginOfIndexOfActionsNbr,
										endOfIndexOfActionsNbr)));
							} catch (NumberFormatException e) {
								nbrOfActions = -1;
							}
							if (nbrOfActions == -1) {
								monitor.beginTask(action,
										IProgressMonitor.UNKNOWN);
							} else {
								monitor.beginTask(action, nbrOfActions
										.intValue());
							}
							monitorStarted = true;
							monitor.worked(1);
						} else {
							if (monitorStarted) {
								monitor.setTaskName(action);
								monitor.worked(1);
							}
						}
					}
					line = "";
				} else {
					line += (char) c;
				}
				out.write((char) c);
			}
			in.close();
			out.close();
			monitor.done();
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}

		return true;

	}

	/**
	 * Gets the path where CrashAnalyser.exe is located
	 * 
	 * @return the path where CrashAnalyser.exe is located
	 */
	private static String getCrashAnalyserPath() {
		String crashAnalyserExePath = CrashAnalyserCoreComponentsPlugin
				.getPluginInstallPath();
		if (!crashAnalyserExePath.endsWith(File.separator))
			crashAnalyserExePath += File.separator;
		crashAnalyserExePath += EXE_FOLDER + File.separator;
		return crashAnalyserExePath;
	}
}