crashanalysis/crashanalyser/com.nokia.s60tools.crashanalyser/src/com/nokia/s60tools/crashanalyser/files/SummaryFile.java
changeset 0 5ad7ad99af01
child 4 615035072f7e
equal deleted inserted replaced
-1:000000000000 0:5ad7ad99af01
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 package com.nokia.s60tools.crashanalyser.files;
       
    19 
       
    20 import java.util.*;
       
    21 import java.io.*;
       
    22 import javax.xml.parsers.*;
       
    23 import org.eclipse.jface.resource.ImageDescriptor;
       
    24 import org.eclipse.ui.*;
       
    25 import org.w3c.dom.*;
       
    26 import com.nokia.s60tools.crashanalyser.containers.RegisterDetails;
       
    27 import com.nokia.s60tools.crashanalyser.containers.CodeSegment;
       
    28 import com.nokia.s60tools.crashanalyser.containers.Message;
       
    29 import com.nokia.s60tools.crashanalyser.containers.EventLog;
       
    30 import com.nokia.s60tools.crashanalyser.containers.Process;
       
    31 import com.nokia.s60tools.crashanalyser.containers.RegisterSet;
       
    32 import com.nokia.s60tools.crashanalyser.containers.Register;
       
    33 import com.nokia.s60tools.crashanalyser.containers.Summary;
       
    34 import com.nokia.s60tools.crashanalyser.containers.Symbol;
       
    35 import com.nokia.s60tools.crashanalyser.containers.Thread;
       
    36 import com.nokia.s60tools.crashanalyser.containers.Stack;
       
    37 import com.nokia.s60tools.crashanalyser.data.*;
       
    38 import com.nokia.s60tools.crashanalyser.model.*;
       
    39 import com.nokia.s60tools.crashanalyser.plugin.CrashAnalyserPlugin;
       
    40 
       
    41 /**
       
    42  * A summary file is a crash file which has not been fully decoded.
       
    43  * A summary file has been decoded without symbol information and it therefore
       
    44  * does not contain stack information. A summary file is a base class for CrashFile. 
       
    45  *
       
    46  */
       
    47 public class SummaryFile extends CrashAnalyserFile implements IEditorInput {
       
    48 
       
    49 	// XML tags
       
    50 	public static final String TAG_SYMBOL_SET = "symbol_set";
       
    51 	public static final String TAG_SYMBOL = "symbol";
       
    52 	public static final String TAG_SOURCE = "source";
       
    53 	public static final String TAG_PROCESS = "process";
       
    54 	public static final String TAG_THREAD = "thread";
       
    55 	public static final String TAG_STACK = "stack";
       
    56 	public static final String TAG_SEG_STACKS = "seg_stacks";
       
    57 	public static final String TAG_ID = "id";
       
    58 	public static final String TAG_STACK_ENTRY = "stack_entry";
       
    59 	public static final String TAG_CODESEG = "codeseg";
       
    60 	public static final String TAG_REGISTER_SET = "register_set";
       
    61 	public static final String TAG_SEG_EVENT_LOG = "seg_event_log";
       
    62 	public static final String TAG_MESSAGE = "message";
       
    63 	public static final String TAG_VI_ENTRY = "vi_entry";
       
    64 	public static final String TAG_SOURCE_INFO = "source_info";
       
    65 	public static final String TAG_TYPE = "type";
       
    66 	public static final String TAG_SEGMENT = "segment";
       
    67 	public static final String TAG_MAJOR = "major";
       
    68 	public static final String TAG_MINOR = "minor";
       
    69 
       
    70 	// data from xml file
       
    71 	protected Map<Integer, Process> processes = null;
       
    72 	protected Map<Integer, Message> messages = null;
       
    73 	protected Map<Integer, Stack> stacks = null;
       
    74 	protected Map<Integer, RegisterSet> registerSets = null;
       
    75 	protected List<RegisterDetails> registerDetails = null;
       
    76 	protected EventLog eventLog = null;
       
    77 	protected Summary crashSummary = null;
       
    78 	protected String sourceFileType = "";
       
    79 	protected String sourceFileName = "";
       
    80 	protected String sourceFilePath = "";
       
    81 
       
    82 	/**
       
    83 	 * Constructor
       
    84 	 * @param filePath file path to this crash file
       
    85 	 * @param library error library
       
    86 	 */
       
    87 	protected SummaryFile(String filePath, ErrorLibrary library) {
       
    88 		super(filePath, library);
       
    89 	}
       
    90 	
       
    91 	/**
       
    92 	 * Returns the file type of this crash file.
       
    93 	 * @return "Decoded File"
       
    94 	 */
       
    95 	public String getFileType() {
       
    96 		return "Partially Decoded File";
       
    97 	}
       
    98 	
       
    99 	public String getSourceFileType() {
       
   100 		return sourceFileType;
       
   101 	}
       
   102 	
       
   103 	public String getSourceFileName() {
       
   104 		return sourceFileName;
       
   105 	}
       
   106 	
       
   107 	public String getSourceFilePath() {
       
   108 		return sourceFilePath;
       
   109 	}
       
   110 	
       
   111 	public List<Stack> getStandAloneStacks() {
       
   112 		if (stacks != null && !stacks.isEmpty()) {
       
   113 			return new ArrayList<Stack>(stacks.values());
       
   114 		}
       
   115 		
       
   116 		return null;
       
   117 	}
       
   118 	
       
   119 	public List<RegisterSet> getStandAloneRegisterSets() {
       
   120 		if (registerSets != null && !registerSets.isEmpty()) {
       
   121 			return new ArrayList<RegisterSet>(registerSets.values());
       
   122 		}
       
   123 		
       
   124 		return null;
       
   125 	}
       
   126 	
       
   127 	/**
       
   128 	 * Checks whether this file contains any error or warning messages.
       
   129 	 * @return true if file contains errors or warning, otherwise false is returned
       
   130 	 */
       
   131 	public boolean containsErrorsOrWarnings() {
       
   132 		List<Message> msgs = getMessages();
       
   133 		if (msgs != null && !msgs.isEmpty()) {
       
   134 			for (int i = 0; i < msgs.size(); i++) {
       
   135 				if (Message.MessageTypes.ERROR.equals(msgs.get(i).getMessageType()) ||
       
   136 					Message.MessageTypes.WARNING.equals(msgs.get(i).getMessageType()))
       
   137 				return true;
       
   138 			}
       
   139 		}
       
   140 		return false;
       
   141 	}
       
   142 	
       
   143 	/**
       
   144 	 * Returns all messages
       
   145 	 * @return all messages
       
   146 	 */
       
   147 	public List<Message> getMessages() {
       
   148 		List<Message> msgs = new ArrayList<Message>();
       
   149 		msgs.addAll(messages.values());
       
   150 		return msgs;
       
   151 	}
       
   152 
       
   153 	/**
       
   154 	 * Reads crash file
       
   155 	 * @param file crash file
       
   156 	 * @param library error library
       
   157 	 * @return read crash file or null
       
   158 	 */
       
   159 	public static SummaryFile read(File file, ErrorLibrary library) {
       
   160 		if (file == null || !file.exists() || !file.isFile())
       
   161 			return null;
       
   162 		
       
   163 		SummaryFile summaryFile = new SummaryFile(file.getAbsolutePath(), library);
       
   164 		summaryFile.doRead();
       
   165 		return summaryFile;
       
   166 	}
       
   167 	
       
   168 	/**
       
   169 	 * Reads crash file
       
   170 	 * @param folder where xml file is
       
   171 	 * @param library error library
       
   172 	 * @return read crash file or null
       
   173 	 */
       
   174 	public static SummaryFile read(String folder, ErrorLibrary library) {
       
   175 		String summaryFile = findFile(folder,"xml");
       
   176 		
       
   177 		// summary file doesn't exist
       
   178 		if (summaryFile == null)
       
   179 			return null;
       
   180 		
       
   181 		SummaryFile file = new SummaryFile(summaryFile, library);
       
   182 		file.doRead();
       
   183 		return file;
       
   184 	}
       
   185 
       
   186 	/**
       
   187 	 * Writes crash file into text or html file
       
   188 	 * @param filePathWithoutFileName file path where file is to be written to
       
   189 	 * @param html if false a .txt file is created. if true a .html file is created
       
   190 	 */
       
   191 	public void writeTo(String filePathWithoutFileName, boolean html) {
       
   192 		File file = new File(FileOperations.addSlashToEnd(filePathWithoutFileName) + 
       
   193 								FileOperations.getFileNameWithoutExtension(fileName) + ".txt");
       
   194 		if (html)
       
   195 			file = new File(FileOperations.addSlashToEnd(filePathWithoutFileName) + 
       
   196 								FileOperations.getFileNameWithoutExtension(fileName) + ".html");
       
   197 		writeTo(file);
       
   198 	}
       
   199 	
       
   200 	/**
       
   201 	 * Writes crash file into a file
       
   202 	 * @param file file to be written to (.xml, .crashxml, .html, . txt, etc)
       
   203 	 */
       
   204 	public void writeTo(File file) {
       
   205 		try {
       
   206 			// file is saved as .xml or .crashxml
       
   207 			if (file.getName().endsWith(CrashAnalyserFile.OUTPUT_FILE_EXTENSION) ||
       
   208 					file.getName().endsWith("."+CrashAnalyserFile.SUMMARY_FILE_EXTENSION)) {
       
   209 				FileOperations.copyFile(new File(filePath), file, true);
       
   210 			// file is saved as .txt or .html
       
   211 			} else {
       
   212 				BufferedWriter out = null;
       
   213 				try {
       
   214 					// Create file 
       
   215 					FileWriter fstream = new FileWriter(file, false);
       
   216 					out = new BufferedWriter(fstream);
       
   217 					
       
   218 					// check whether we are writing an html file
       
   219 					boolean html = false;
       
   220 					if (file.getName().toLowerCase().endsWith(".htm") ||
       
   221 							file.getName().toLowerCase().endsWith(".html"))
       
   222 						html = true;
       
   223 					
       
   224 					// if html file, write html start tags
       
   225 					if (html)
       
   226 						writeHtmlStart(out);
       
   227 
       
   228 					// write crash analyser file version data
       
   229 					writeVersion(out);
       
   230 
       
   231 					String panicDescription = "";
       
   232 
       
   233 					// write process & thread summary
       
   234 					Process process = getCrashedProcess();
       
   235 					if (process != null) {
       
   236 						writeLine(out, "Process", process.getName());
       
   237 
       
   238 						Thread thread = process.getFirstThread();
       
   239 						if (thread != null) {
       
   240 							writeLine(out, "Thread", thread.getFullName());
       
   241 							writeLine(out, "Stack Pointer", thread.getStackPointer());
       
   242 							writeLine(out, "Link Register", thread.getLinkRegister());
       
   243 							writeLine(out, "Program Counter", thread.getProgramCounter());
       
   244 							panicDescription = thread.getPanicDescription();
       
   245 						}
       
   246 					}
       
   247 					
       
   248 					// write crash summary to file
       
   249 					if (crashSummary != null) {
       
   250 						crashSummary.writeTo(out);
       
   251 						out.newLine();
       
   252 					}
       
   253 
       
   254 					if (html)
       
   255 						writeLine(out, "</pre><A HREF=\"#STACKPOINTER\">Current Stack Pointer</A><pre>");
       
   256 					
       
   257 					// write panic description if panic description exists. Panic description
       
   258 					// is written only to html file (not to .txt)
       
   259 					if (!"".equals(panicDescription) && html) {
       
   260 						writeLine(out, "</pre><h2>Panic Description</h2>");
       
   261 						writeLine(out, panicDescription);
       
   262 						writeLine(out, "<pre>");
       
   263 					}
       
   264 					
       
   265 					List<Message> msgs = getMessages();
       
   266 					// write errors and warnings to file
       
   267 					if (msgs != null && !msgs.isEmpty()) {
       
   268 						for (int i = 0; i < msgs.size(); i++) {
       
   269 							msgs.get(i).writeTo(out);
       
   270 						}
       
   271 						out.newLine();
       
   272 					}
       
   273 					
       
   274 					// write event log to file
       
   275 					if (eventLog != null)
       
   276 						eventLog.writeTo(out);					
       
   277 						
       
   278 					// write process data to file
       
   279 					if (process != null) {
       
   280 						process.writeTo(out, Process.StackItems.ALL, html);
       
   281 						out.newLine();
       
   282 					}
       
   283 
       
   284 					// if html file, write html end tags
       
   285 					if (html)
       
   286 						writeHtmlEnd(out);
       
   287 					
       
   288 				} catch (Exception e) {
       
   289 					e.printStackTrace();
       
   290 				} finally {
       
   291 					if (out != null)
       
   292 						out.close();
       
   293 				}
       
   294 			}
       
   295 		} catch (Exception e) {
       
   296 			e.printStackTrace();
       
   297 		}
       
   298 	}
       
   299 	
       
   300 	/**
       
   301 	 * Writes CrashAnalyser version information.
       
   302 	 * @param out where to write
       
   303 	 * @throws IOException
       
   304 	 */
       
   305 	void writeVersion(BufferedWriter out) throws IOException {
       
   306 		String version = (String) CrashAnalyserPlugin.getDefault().getBundle().getHeaders().get("Bundle-Version"); //$NON-NLS-1$
       
   307 		out.write("Crash Report Created with Crash Analyser Carbide Extension " + version);
       
   308 		out.newLine();
       
   309 		out.write("----------------------------------------------------------------");
       
   310 		out.newLine();
       
   311 		out.newLine();
       
   312 	}
       
   313 	
       
   314 	/**
       
   315 	 * Writes html start tags
       
   316 	 * @param out where to write
       
   317 	 * @throws IOException
       
   318 	 */
       
   319 	void writeHtmlStart(BufferedWriter out) throws IOException {
       
   320 		out.write("<html><head><title>Crash File</title></head><body><pre>");
       
   321 		out.newLine();
       
   322 	}
       
   323 	
       
   324 	/**
       
   325 	 * Writes html end tags
       
   326 	 * @param out where to write
       
   327 	 * @throws IOException
       
   328 	 */
       
   329 	void writeHtmlEnd(BufferedWriter out) throws IOException {
       
   330 		out.newLine();
       
   331 		out.write("</pre></body></html>");
       
   332 		out.newLine();
       
   333 	}
       
   334 	
       
   335 	void writeLine(BufferedWriter out, String header, String value) throws IOException {
       
   336 		if (!"".equals(value)) {
       
   337 			out.write(String.format(Summary.FORMAT, header, value));
       
   338 			out.newLine();
       
   339 		}
       
   340 	}
       
   341 
       
   342 	void writeLine(BufferedWriter out, String line) throws IOException {
       
   343 		out.write(line);
       
   344 		out.newLine();
       
   345 	}
       
   346 
       
   347 	/**
       
   348 	 * Reads the file location of the given xml file
       
   349 	 * @param xmlFilePath path to xml file
       
   350 	 * @return file location or "".
       
   351 	 */
       
   352 	public static String getSourceFilePath(String xmlFilePath) {
       
   353 
       
   354 		try {
       
   355 			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       
   356 
       
   357 			// Using factory get an instance of document builder
       
   358 			DocumentBuilder db = dbf.newDocumentBuilder();
       
   359 
       
   360 			// parse using builder to get DOM representation of the XML file
       
   361 			Document dom = db.parse(xmlFilePath);
       
   362 			 
       
   363 			// get the root element
       
   364 			Element docEle = dom.getDocumentElement();		
       
   365 			
       
   366 			// read source file name
       
   367 			NodeList nl = docEle.getElementsByTagName(TAG_SOURCE);
       
   368 			if (nl != null && nl.getLength() > 0) {
       
   369 				String sourcePath = XmlUtils.getNodeValue(nl.item(0));
       
   370 				if (sourcePath != null && !"".equals(sourcePath)) {
       
   371 					File f = new File(sourcePath);
       
   372 					if (f.exists() && f.isFile()) {
       
   373 						return sourcePath;
       
   374 					}
       
   375 				}
       
   376 			}
       
   377 		}catch(Exception e) {
       
   378 			e.printStackTrace();
       
   379 		}
       
   380 		
       
   381 		return "";
       
   382 	}
       
   383 	
       
   384 	@Override
       
   385 	protected void doRead() {
       
   386 		super.doRead();
       
   387 		
       
   388 		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       
   389 
       
   390 		try {
       
   391 
       
   392 			// Using factory get an instance of document builder
       
   393 			DocumentBuilder db = dbf.newDocumentBuilder();
       
   394 
       
   395 			// parse using builder to get DOM representation of the XML file
       
   396 			Document dom = db.parse(filePath);
       
   397 			 
       
   398 			// get the root element
       
   399 			Element docEle = dom.getDocumentElement();		
       
   400 			
       
   401 			// read source file type
       
   402 			NodeList nl = docEle.getElementsByTagName(TAG_SOURCE_INFO);
       
   403 			if (nl != null && nl.getLength() > 0) {
       
   404 				sourceFileType = XmlUtils.getTextValue((Element)nl.item(0), TAG_TYPE);
       
   405 			}
       
   406 			
       
   407 			// read source file name
       
   408 			nl = docEle.getElementsByTagName(TAG_SOURCE);
       
   409 			if (nl != null && nl.getLength() > 0) {
       
   410 				String sourcePath = XmlUtils.getNodeValue(nl.item(0));
       
   411 				if (sourcePath != null && !"".equals(sourcePath)) {
       
   412 					File f = new File(sourcePath);
       
   413 					if (f.exists() && f.isFile()) {
       
   414 						sourceFileName = f.getName();
       
   415 						sourceFilePath = sourcePath;
       
   416 					}
       
   417 				}
       
   418 			}
       
   419 			
       
   420 			messages = new HashMap<Integer, Message>();
       
   421 			
       
   422 			// check that is the xml file newer than what we support
       
   423 			nl = docEle.getElementsByTagName(TAG_SEGMENT);
       
   424 			if (nl != null && nl.getLength() > 0) {
       
   425 				for (int i = 0; i < nl.getLength(); i++) {
       
   426 					// if major number is larger than what we support, add an error to messages
       
   427 					String major = XmlUtils.getTextValue((Element)nl.item(i), TAG_MAJOR);
       
   428 					if (!"1".equals(major)) {
       
   429 						messages.put(500, Message.newMessage(500, "Version Error", "XML file is newer than what is supported by this version of Crash Analyser.", Message.MessageTypes.ERROR));
       
   430 						break;
       
   431 					}
       
   432 					// if minor number is larger than what we support, add a warning to messages
       
   433 					String minor = XmlUtils.getTextValue((Element)nl.item(i), TAG_MINOR);
       
   434 					if (!"00".equals(minor)) {
       
   435 						messages.put(500, Message.newMessage(500, "Version Problem", "XML file has some new data which is not supported by this version of Crash Analyser.", Message.MessageTypes.WARNING));
       
   436 						break;
       
   437 					}
       
   438 				}
       
   439 			}
       
   440 			
       
   441 			// read summary data
       
   442 			crashSummary = Summary.read(docEle);
       
   443 
       
   444 			// read ROM id for this file
       
   445 			if (crashSummary != null) {
       
   446 				romId = crashSummary.getRomId();
       
   447 			}
       
   448 			
       
   449 			// read event log
       
   450 			nl = docEle.getElementsByTagName(TAG_SEG_EVENT_LOG);
       
   451 			if (nl != null && nl.getLength() > 0) {
       
   452 				eventLog = EventLog.read((Element)nl.item(0));
       
   453 			}
       
   454 			
       
   455 			// read messages from xml
       
   456 			nl = docEle.getElementsByTagName(TAG_MESSAGE);
       
   457 			if (nl != null && nl.getLength() > 0) {
       
   458 				for (int i = 0; i < nl.getLength(); i++) {
       
   459 					Element el = (Element)nl.item(i);
       
   460 					Message message = Message.read(el);
       
   461 					if (message != null)
       
   462 						messages.put(message.getId(), message);
       
   463 				}
       
   464 			}			
       
   465 			
       
   466 			Map<Integer, CodeSegment> codeSegments = new HashMap<Integer, CodeSegment>();
       
   467 			
       
   468 			// read code segments
       
   469 			nl = docEle.getElementsByTagName(TAG_CODESEG);
       
   470 			if (nl != null && nl.getLength() > 0) {
       
   471 				for (int i = 0; i < nl.getLength(); i++) {
       
   472 					Element el = (Element)nl.item(i);
       
   473 					CodeSegment codeSeg = CodeSegment.read(el, messages);
       
   474 					if (codeSeg != null)
       
   475 						codeSegments.put(codeSeg.getId(), codeSeg);
       
   476 				}
       
   477 			}
       
   478 
       
   479 			Map<Integer, Symbol> symbols = new HashMap<Integer, Symbol>();
       
   480 
       
   481 			// read symbols (Summary file won't have symbols, but this same method
       
   482 			// is used by CrashFile)
       
   483 			nl = docEle.getElementsByTagName(TAG_SYMBOL_SET);
       
   484 			if(nl != null && nl.getLength() > 0) {
       
   485 				// go throug all symbol_set tags
       
   486 				for(int i = 0 ; i < nl.getLength(); i++) {
       
   487 					// get the symbol_set element
       
   488 					Element el = (Element)nl.item(i);
       
   489 					NodeList childs = el.getChildNodes();
       
   490 					// if symbol set has child nodes
       
   491 					if (childs != null && childs.getLength() > 0) {
       
   492 						String source = "";
       
   493 						// go through all symbol_set child nodes
       
   494 						for(int k = 0; k < childs.getLength(); k++) {
       
   495 							Node child = childs.item(k);
       
   496 							// if node is source node
       
   497 							if (child.getNodeName() == TAG_SOURCE) {
       
   498 								source = child.getFirstChild().getNodeValue();
       
   499 							// if node is symbol node
       
   500 							} else if (child.getNodeName() == TAG_SYMBOL) {
       
   501 								Symbol symbol = Symbol.read((Element)child, source, codeSegments);
       
   502 								if (symbol != null)
       
   503 									symbols.put(symbol.getId(), symbol);
       
   504 							}
       
   505 						}
       
   506 					}
       
   507 				}
       
   508 			}
       
   509 					
       
   510 			registerSets = new HashMap<Integer, RegisterSet>();
       
   511 			Map<Integer, Register> allRegisters = new HashMap<Integer, Register>();
       
   512 			
       
   513 			// read register sets
       
   514 			nl = docEle.getElementsByTagName(TAG_REGISTER_SET);
       
   515 			if (nl != null && nl.getLength() > 0) {
       
   516 				for (int i = 0; i < nl.getLength(); i++) {
       
   517 					Element el = (Element)nl.item(i);
       
   518 					RegisterSet registerSet = RegisterSet.read(el, symbols, messages);
       
   519 					if (registerSet != null) {
       
   520 						registerSets.put(registerSet.getId(),registerSet);
       
   521 						
       
   522 						// read all individual registers from sets
       
   523 						List<Register> registers = registerSet.getRegisters();
       
   524 						for (int j = 0; j < registers.size(); j++) {
       
   525 							Register register = registers.get(j);
       
   526 							if (!allRegisters.containsKey(register.getId())) {
       
   527 								allRegisters.put(register.getId(), register);
       
   528 							}
       
   529 						}						
       
   530 					}
       
   531 				}
       
   532 			}
       
   533 			
       
   534 			stacks = new HashMap<Integer, Stack>();
       
   535 			
       
   536 			// read stacks
       
   537 			nl = docEle.getElementsByTagName(TAG_STACK);
       
   538 			if (nl != null && nl.getLength() > 0) {
       
   539 				for (int i = 0; i < nl.getLength(); i++) {
       
   540 					Element el = (Element)nl.item(i);
       
   541 					Stack stack = Stack.read(el, registerSets, allRegisters, symbols);
       
   542 					if (stack != null)
       
   543 						stacks.put(stack.getId(), stack);
       
   544 				}
       
   545 			}
       
   546 			
       
   547 			Map<Integer, Thread> threads = new HashMap<Integer, Thread>();
       
   548 			
       
   549 			// read threads
       
   550 			nl = docEle.getElementsByTagName(TAG_THREAD);
       
   551 			if (nl != null && nl.getLength() > 0) {
       
   552 				for (int i = 0; i < nl.getLength(); i++) {
       
   553 					Element el = (Element)nl.item(i);
       
   554 					Thread thread = Thread.read(el, registerSets, symbols, stacks, errorLibrary);
       
   555 					if (thread != null) {
       
   556 						threads.put(thread.getId(), thread);
       
   557 						stacks = thread.removeOwnStacks(stacks);
       
   558 						registerSets = thread.removeOwnRegisterSets(registerSets);
       
   559 					}
       
   560 				}
       
   561 			}
       
   562 			
       
   563 			processes = new HashMap<Integer, Process>();
       
   564 			
       
   565 			// read processes
       
   566 			nl = docEle.getElementsByTagName(TAG_PROCESS);
       
   567 			if (nl != null && nl.getLength() > 0) {
       
   568 				for (int i = 0; i < nl.getLength(); i++) {
       
   569 					Element el = (Element)nl.item(i);
       
   570 					Process process = Process.read(el, threads, codeSegments);
       
   571 					if (process != null)
       
   572 						processes.put(process.getId(), process);
       
   573 				}
       
   574 			}
       
   575 			
       
   576 			registerDetails = new ArrayList<RegisterDetails>();
       
   577 			
       
   578 			// read register details
       
   579 			nl = docEle.getElementsByTagName(TAG_VI_ENTRY);
       
   580 			if (nl != null && nl.getLength() > 0) {
       
   581 				for (int i = 0; i < nl.getLength(); i++) {
       
   582 					Element el = (Element)nl.item(i);
       
   583 					RegisterDetails details = RegisterDetails.read(el);
       
   584 					if (details != null)
       
   585 						registerDetails.add(details);
       
   586 				}
       
   587 			}
       
   588 
       
   589 			// if xml contained crash date and time, parse them into this.time
       
   590 			if (!"".equals(crashSummary.getCrashDate()) && !"".equals(crashSummary.getCrashTime()))
       
   591 				time = crashSummary.getCrashDate() + " " + crashSummary.getCrashTime();
       
   592 			
       
   593 			// set panic data
       
   594 			Process process = getCrashedProcess();
       
   595 			if (process != null) {
       
   596 				Thread firstThread = process.getFirstThread();
       
   597 				if (firstThread != null) {
       
   598 					panicCategory = firstThread.getExitCategory();
       
   599 					panicCode = firstThread.getExitReason();
       
   600 					threadName = firstThread.getFullName();
       
   601 				}
       
   602 			}
       
   603 
       
   604 			formatDescription();
       
   605 		}catch(Exception e) {
       
   606 			e.printStackTrace();
       
   607 		}
       
   608 	}
       
   609 
       
   610 	/**
       
   611 	 * Formats a description for this crash. 
       
   612 	 */
       
   613 	void formatDescription() {
       
   614 		Thread thread = null;
       
   615 		
       
   616 		// get the first thread of the first process
       
   617 		if (processes != null && !processes.isEmpty()) {
       
   618 			Process[] processesArray = processes.values().toArray(new Process[processes.values().size()]);
       
   619 			Process process = processesArray[0];
       
   620 			thread = process.getFirstThread();
       
   621 		}
       
   622 		
       
   623 		description = HtmlFormatter.formatCrashFileDescription(crashSummary, getMessages(), thread);
       
   624 		shortDescription = HtmlFormatter.formatCrashFileDescription(crashSummary, null, thread);
       
   625 	}
       
   626 	
       
   627 	public Summary getSummary() {
       
   628 		return crashSummary;
       
   629 	}
       
   630 	
       
   631 	/**
       
   632 	 * Get crashed process
       
   633 	 * 
       
   634 	 * @return first process or null
       
   635 	 */
       
   636 	public Process getCrashedProcess() {
       
   637 		Process crashedProcess = null;
       
   638 		if (processes != null && !processes.isEmpty()) {
       
   639 			Process[] processesArray = processes.values().toArray(new Process[processes.values().size()]);
       
   640 			for (Process process : processesArray) {
       
   641 				for (Thread thread : process.getThreads()) {
       
   642 					String exitType = thread.getExitType();
       
   643 					if (exitType.equalsIgnoreCase("Panic") || exitType.equalsIgnoreCase("Exception")) {
       
   644 						crashedProcess = process;
       
   645 						break;
       
   646 					}					
       
   647 				}
       
   648 			}
       
   649 		}
       
   650 		return crashedProcess;
       
   651 	}
       
   652 	
       
   653 	public EventLog getEventLog() {
       
   654 		return eventLog;
       
   655 	}
       
   656 	
       
   657 	public List<RegisterDetails> getRegisterDetails() {
       
   658 		return registerDetails;
       
   659 	}
       
   660 	
       
   661 	public boolean exists() {
       
   662 		return true;
       
   663 	}
       
   664 
       
   665 	public ImageDescriptor getImageDescriptor() {
       
   666 		return null;
       
   667 	}
       
   668 
       
   669 	public String getName() {
       
   670 		return fileName;
       
   671 	}
       
   672 
       
   673 	public IPersistableElement getPersistable() {
       
   674 		return null;
       
   675 	}
       
   676 
       
   677 	public String getToolTipText() {
       
   678 		return "Partial Crash Analyser File";
       
   679 	}
       
   680 
       
   681 	@SuppressWarnings("unchecked")
       
   682 	public Object getAdapter(Class adapter) {
       
   683 		return null;
       
   684 	}	
       
   685 }