sysperfana/analyzetoolext/com.nokia.s60tools.analyzetool/src/com/nokia/s60tools/analyzetool/engine/ParseXMLFileSAX.java
changeset 15 0367d2db2c06
parent 6 f65f740e69f9
equal deleted inserted replaced
14:bb339882c6e9 15:0367d2db2c06
    35 
    35 
    36 /**
    36 /**
    37  * Parses atool.exe generated xml file and creates memory analysis results.
    37  * Parses atool.exe generated xml file and creates memory analysis results.
    38  * Using the SAX parser to parse xml file. SAX parser fits better than DOM
    38  * Using the SAX parser to parse xml file. SAX parser fits better than DOM
    39  * parser because it is possible that AT must handle very big xml files.
    39  * parser because it is possible that AT must handle very big xml files.
    40  *
    40  * 
    41  * @author kihe
    41  * @author kihe
    42  *
    42  * 
    43  */
    43  */
    44 public class ParseXMLFileSAX implements org.xml.sax.ContentHandler {
    44 public class ParseXMLFileSAX implements org.xml.sax.ContentHandler {
    45 	/** XML constants. */
    45 	/** XML constants. */
    46 	public static final String XML_BUILD_TARGET = "build_target";
    46 	public static final String XML_BUILD_TARGET = "build_target";
    47 	public static final String XML_CALC_MEMADDR = "calc_addr";
    47 	public static final String XML_CALC_MEMADDR = "calc_addr";
    67 	public static final String XML_START_TIME = "start_time";
    67 	public static final String XML_START_TIME = "start_time";
    68 	public static final String XML_SUBTEST = "subtest";
    68 	public static final String XML_SUBTEST = "subtest";
    69 	public static final String XML_TIME = "time";
    69 	public static final String XML_TIME = "time";
    70 	public static final String XML_UNKNOWN = "???";
    70 	public static final String XML_UNKNOWN = "???";
    71 
    71 
    72 	/**Active call stack item id*/
    72 	/** Active call stack item id */
    73 	private int activeCallstackID = 1;
    73 	private int activeCallstackID = 1;
    74 
    74 
    75 	/** Active item(memory leak) information */
    75 	/** Active item(memory leak) information */
    76 	private AnalysisItem activeItem;
    76 	private AnalysisItem activeItem;
    77 
    77 
    78 	/**Active item(memory leak) id*/
    78 	/** Active item(memory leak) id */
    79 	private int activeItemID = 1;
    79 	private int activeItemID = 1;
    80 
    80 
    81 	/** Summary field active module memory leak count*/
    81 	/** Summary field active module memory leak count */
    82 	private String activeModuleCount;
    82 	private String activeModuleCount;
    83 
    83 
    84 	/** Summary field active module name*/
    84 	/** Summary field active module name */
    85 	private String activeModuleName;
    85 	private String activeModuleName;
    86 
    86 
    87 	/** Active run information */
    87 	/** Active run information */
    88 	protected RunResults activeRunResults;
    88 	protected RunResults activeRunResults;
    89 
    89 
    91 	private final AbstractList<RunResults> activeRuns;
    91 	private final AbstractList<RunResults> activeRuns;
    92 
    92 
    93 	/** Active subtest item information */
    93 	/** Active subtest item information */
    94 	private Subtest activeSubtest;
    94 	private Subtest activeSubtest;
    95 
    95 
    96 	/**Active subtest id*/
    96 	/** Active subtest id */
    97 	private int activeSubtestID = 1;
    97 	private int activeSubtestID = 1;
    98 
    98 
    99 	/** Active callstack item information */
    99 	/** Active callstack item information */
   100 	private CallstackItem callstackItem;
   100 	private CallstackItem callstackItem;
   101 
   101 
   102 	/** xml file path. */
   102 	/** xml file path. */
   103 	private final String filePath;
   103 	private final String filePath;
   104 
   104 
   105 	/** 
   105 	/**
   106 	 * Flag to demonstrate that is the memory leak summary parsing active. 
   106 	 * Flag to demonstrate that is the memory leak summary parsing active. If
   107 	 * If this flag is set to False, then information is stored to the handle leak summary object, 
   107 	 * this flag is set to False, then information is stored to the handle leak
   108 	 * otherwise information is stored to the memory leak summary object.
   108 	 * summary object, otherwise information is stored to the memory leak
       
   109 	 * summary object.
   109 	 */
   110 	 */
   110 	private boolean moduleLeakActive = true;
   111 	private boolean moduleLeakActive = true;
   111 
   112 
   112 	/** List of modules */
   113 	/** List of modules */
   113 	private final AbstractList<String> moduleList;
   114 	private final AbstractList<String> moduleList;
   114 
   115 
   115 	/** 
   116 	/**
   116 	 * Is subtest related information parsing active. 
   117 	 * Is subtest related information parsing active. If this flag is set to
   117 	 * If this flag is set to true all the information (such as 
   118 	 * true all the information (such as memory leaks etc) is stored to the
   118 	 * memory leaks etc) is stored to the subtest object.
   119 	 * subtest object.
   119 	 */
   120 	 */
   120 	private boolean parsingSubtest = false;
   121 	private boolean parsingSubtest = false;
   121 
   122 
   122 	/** Project reference */
   123 	/** Project reference */
   123 	private final IProject project;
   124 	private final IProject project;
   125 	/** Project result reference where to save results */
   126 	/** Project result reference where to save results */
   126 	private final ProjectResults results;
   127 	private final ProjectResults results;
   127 
   128 
   128 	/** Index for active items */
   129 	/** Index for active items */
   129 	private int runID = 1;
   130 	private int runID = 1;
   130 	
       
   131 
   131 
   132 	/**
   132 	/**
   133 	 * Constructor.
   133 	 * Constructor.
   134 	 *
   134 	 * 
   135 	 * @param projectRef
   135 	 * @param projectRef
   136 	 *            Project reference
   136 	 *            Project reference
   137 	 * @param newFilePath
   137 	 * @param newFilePath
   138 	 *            Used file path
   138 	 *            Used file path
   139 	 * @param projResults
   139 	 * @param projResults
   140 	 *            Project results reference
   140 	 *            Project results reference
   141 	 */
   141 	 */
   142 	public ParseXMLFileSAX(
   142 	public ParseXMLFileSAX(final IProject projectRef, final String newFilePath,
   143 			final org.eclipse.core.resources.IProject projectRef,
   143 			final ProjectResults projResults) {
   144 			final String newFilePath, final ProjectResults projResults) {
       
   145 		results = projResults;
   144 		results = projResults;
   146 		filePath = newFilePath;
   145 		filePath = newFilePath;
   147 		project = projectRef;
   146 		project = projectRef;
   148 		activeRuns = new ArrayList<RunResults>();
   147 		activeRuns = new ArrayList<RunResults>();
   149 		moduleList = new ArrayList<String>();
   148 		moduleList = new ArrayList<String>();
   150 	}
   149 	}
   151 
   150 
   152 	/**
   151 	/**
   153 	 * Adds module name to list
   152 	 * Adds module name to list
   154 	 *
   153 	 * 
   155 	 * @param moduleName
   154 	 * @param moduleName
   156 	 *            Module to add to the list
   155 	 *            Module to add to the list
   157 	 */
   156 	 */
   158 	private void addModuleNameToList(final String moduleName) {
   157 	private void addModuleNameToList(final String moduleName) {
   159 		if (moduleName == null || ("").equals(moduleName)) {
   158 		if (moduleName == null || ("").equals(moduleName)) {
   171 	}
   170 	}
   172 
   171 
   173 	/**
   172 	/**
   174 	 * When the SAX parser reach the end of the XML file this function is
   173 	 * When the SAX parser reach the end of the XML file this function is
   175 	 * called.
   174 	 * called.
   176 	 *
   175 	 * 
   177 	 * Updates results.
   176 	 * Updates results.
   178 	 */
   177 	 */
   179 	public void endDocument() throws SAXException {
   178 	public void endDocument() throws SAXException {
   180 		results.updateRunResults(project, activeRuns, filePath);
   179 		results.updateRunResults(project, activeRuns, filePath);
   181 	}
   180 	}
   182 
   181 
   183 	/**
   182 	/**
   184 	 * When the SAX parser reach the end of the xml tag this function is called.
   183 	 * When the SAX parser reach the end of the xml tag this function is called.
   185 	 *
   184 	 * 
   186 	 * Checks what tag read is finished and stores corresponding results
   185 	 * Checks what tag read is finished and stores corresponding results
   187 	 */
   186 	 */
   188 	public void endElement(String uri, String localName, String name)
   187 	public void endElement(String uri, String localName, String name)
   189 			throws SAXException {
   188 			throws SAXException {
   190 		// "results" tag => store results
   189 		// "results" tag => store results
   191 		if (name.equals(XML_RUN)) {
   190 		if (name.equals(XML_RUN)) {
   192 			activeRuns.add(activeRunResults);
   191 			activeRuns.add(activeRunResults);
   193 		} else if (name.equals(XML_LEAK)) {
   192 		} else if (name.equals(XML_LEAK)) {
   194 
   193 
   195 			//not enough information so clear the active item
   194 			// not enough information so clear the active item
   196 			if( activeItem == null || !activeItem.checkData() ) {
   195 			if (activeItem == null || !activeItem.checkData()) {
   197 				activeItem = null;
   196 				activeItem = null;
   198 			}
   197 			} else if (parsingSubtest) {
   199 			else if (parsingSubtest) {
       
   200 				activeSubtest.addAnalysisItem(activeItem);
   198 				activeSubtest.addAnalysisItem(activeItem);
   201 			} else {
   199 			} else {
   202 				activeRunResults.addAnalysisItem(activeItem);
   200 				activeRunResults.addAnalysisItem(activeItem);
   203 			}
   201 			}
   204 		} else if (name.equals(XML_ITEM)) {
   202 		} else if (name.equals(XML_ITEM)) {
   205 			if( callstackItem.isEmpty() ) {
   203 			if (callstackItem.isEmpty()) {
   206 				callstackItem = null;
   204 				callstackItem = null;
   207 			}
   205 			} else {
   208 			else {
       
   209 				activeItem.addCallstackItem(callstackItem);
   206 				activeItem.addCallstackItem(callstackItem);
   210 			}
   207 			}
   211 		} else if (name.equals(XML_SUBTEST)) {
   208 		} else if (name.equals(XML_SUBTEST)) {
   212 			activeRunResults.addSubtest(activeSubtest);
   209 			activeRunResults.addSubtest(activeSubtest);
   213 			parsingSubtest = false;
   210 			parsingSubtest = false;
   219 					moduleLeakActive = true;
   216 					moduleLeakActive = true;
   220 					return;
   217 					return;
   221 				}
   218 				}
   222 
   219 
   223 				// convert module count information to string object
   220 				// convert module count information to string object
   224 				int count = Integer.parseInt(activeModuleCount,16);
   221 				int count = Integer.parseInt(activeModuleCount, 16);
   225 
   222 
   226 				// if module leak summary is active
   223 				// if module leak summary is active
   227 				if (moduleLeakActive) {
   224 				if (moduleLeakActive) {
   228 					activeRunResults.addModuleLeak(activeModuleName, count);
   225 					activeRunResults.addModuleLeak(activeModuleName, count);
   229 				}
   226 				}
   230 				// if handle leak summary is active
   227 				// if handle leak summary is active
   231 				else {
   228 				else {
   232 					activeRunResults.addHandleLeak(activeModuleName, count);
   229 					activeRunResults.addHandleLeak(activeModuleName, count);
   233 				}
   230 				}
   234 
   231 
   235 			}catch( NumberFormatException npe ) {
   232 			} catch (NumberFormatException npe) {
   236 				npe.printStackTrace();
   233 				npe.printStackTrace();
   237 			}
   234 			}
   238 		}
   235 		}
   239 	}
   236 	}
   240 
   237 
   244 		// also this method is overloaded
   241 		// also this method is overloaded
   245 	}
   242 	}
   246 
   243 
   247 	/**
   244 	/**
   248 	 * Returns list of modules
   245 	 * Returns list of modules
   249 	 *
   246 	 * 
   250 	 * @return List of modules
   247 	 * @return List of modules
   251 	 */
   248 	 */
   252 	public AbstractList<String> getModules() {
   249 	public AbstractList<String> getModules() {
   253 		return moduleList;
   250 		return moduleList;
   254 	}
   251 	}
   259 		// information
   256 		// information
   260 		// also this method is overloaded
   257 		// also this method is overloaded
   261 	}
   258 	}
   262 
   259 
   263 	/**
   260 	/**
   264 	 * Parses xml file content.
   261 	 * Parses XML file content.
   265 	 *
   262 	 * 
   266 	 * @return True if there are no errors while parsing XML file otherwise
   263 	 * @return True if there are no errors while parsing XML file otherwise
   267 	 *         False
   264 	 *         False
   268 	 */
   265 	 */
   269 	public final boolean parse() {
   266 	public final boolean parse() {
   270 
   267 
   273 
   270 
   274 			// check that file exists
   271 			// check that file exists
   275 			File file = new File(filePath);
   272 			File file = new File(filePath);
   276 			if (file.exists()) {
   273 			if (file.exists()) {
   277 
   274 
   278 				SAXParserFactory factor = null;
   275 				SAXParserFactory factory = null;
   279 				SAXParser parser = null;
   276 				SAXParser parser = null;
   280 				XMLReader xmlReader = null;
   277 				XMLReader xmlReader = null;
   281 
   278 
   282 				// get parser factory
   279 				// get parser factory
   283 				factor = SAXParserFactory.newInstance();
   280 				factory = SAXParserFactory.newInstance();
   284 
   281 
   285 				if (factor != null) {
   282 				if (factory != null) {
   286 					// get xml parser
   283 					// get xml parser
   287 					parser = factor.newSAXParser();
   284 					parser = factory.newSAXParser();
   288 
   285 
   289 					if (parser != null) {
   286 					if (parser != null) {
   290 						// get xml reader
   287 						// get xml reader
   291 						xmlReader = parser.getXMLReader();
   288 						xmlReader = parser.getXMLReader();
   292 
   289 
   305 			// file does not exists
   302 			// file does not exists
   306 			else {
   303 			else {
   307 				ret = false;
   304 				ret = false;
   308 			}
   305 			}
   309 
   306 
   310 			//check that XML file contains data
   307 			// check that XML file contains data
   311 			//otherwise return false
   308 			// otherwise return false
   312 			if( activeRunResults == null ) {
   309 			if (activeRunResults == null) {
   313 				ret = false;
   310 				ret = false;
   314 			}
   311 			}
   315 		} catch (SAXException sae) {
   312 		} catch (SAXException sae) {
   316 			sae.printStackTrace();
   313 			sae.printStackTrace();
   317 			ret = false;
   314 			ret = false;
   352 		// also this method is overloaded
   349 		// also this method is overloaded
   353 	}
   350 	}
   354 
   351 
   355 	/**
   352 	/**
   356 	 * When the SAX parser start to read xml tag this function is called.
   353 	 * When the SAX parser start to read xml tag this function is called.
   357 	 *
   354 	 * 
   358 	 * Checks what tag read is started and initializes corresponding objects
   355 	 * Checks what tag read is started and initializes corresponding objects
   359 	 */
   356 	 */
   360 	public void startElement(String uri, String localName, String name,
   357 	public void startElement(String uri, String localName, String name,
   361 			Attributes atts) throws SAXException {
   358 			Attributes atts) throws SAXException {
   362 
   359 
   363 		//parse one run information
   360 		// parse one run information
   364 		if (name.equals(XML_RUN)) {
   361 		if (name.equals(XML_RUN)) {
   365 			activeRunResults = new RunResults(runID);
   362 			activeRunResults = new RunResults(runID);
   366 			activeRunResults.setEndTime(atts.getValue(XML_END_TIME));
   363 			activeRunResults.setEndTime(atts.getValue(XML_END_TIME));
   367 			activeRunResults.setBuildTarget(atts.getValue(XML_BUILD_TARGET));
   364 			activeRunResults.setBuildTarget(atts.getValue(XML_BUILD_TARGET));
   368 			activeRunResults.setProcessName(atts.getValue(XML_PROCESS_NAME));
   365 			activeRunResults.setProcessName(atts.getValue(XML_PROCESS_NAME));
   369 			activeRunResults.setStartTime(atts.getValue(XML_START_TIME));
   366 			activeRunResults.setStartTime(atts.getValue(XML_START_TIME));
   370 			runID++;
   367 			runID++;
   371 			activeItemID = 1;
   368 			activeItemID = 1;
   372 			activeSubtestID = 1;
   369 			activeSubtestID = 1;
   373 		}
   370 		}
   374 		//parse one memory leak information
   371 		// parse one memory leak information
   375 		else if (name.equals(XML_LEAK)) {
   372 		else if (name.equals(XML_LEAK)) {
   376 			try {
   373 			try {
   377 				activeItem = new AnalysisItem();
   374 				activeItem = new AnalysisItem();
   378 				activeItem.setID(activeItemID);
   375 				activeItem.setID(activeItemID);
   379 				activeItem.setMemoryAddress(atts.getValue(XML_MEMADDR));
   376 				activeItem.setMemoryAddress(atts.getValue(XML_MEMADDR));
   381 				String moduleName = atts.getValue(XML_MODULE);
   378 				String moduleName = atts.getValue(XML_MODULE);
   382 				addModuleNameToList(moduleName);
   379 				addModuleNameToList(moduleName);
   383 				activeItem.setModuleName(moduleName);
   380 				activeItem.setModuleName(moduleName);
   384 				String size = atts.getValue(XML_SIZE);
   381 				String size = atts.getValue(XML_SIZE);
   385 				if (size != null && !("").equals(size)) {
   382 				if (size != null && !("").equals(size)) {
   386 					activeItem.setLeakSize(Integer
   383 					activeItem.setLeakSize(Integer.parseInt(size));
   387 							.parseInt(size));
   384 				}
   388 				}
   385 
   389 
   386 			} catch (NumberFormatException npe) {
   390 			}catch(NumberFormatException npe) {
       
   391 				npe.printStackTrace();
   387 				npe.printStackTrace();
   392 			}
   388 			}
   393 			activeItemID++;
   389 			activeItemID++;
   394 			activeCallstackID = 1;
   390 			activeCallstackID = 1;
   395 		}
   391 		}
   396 		//parse call stack item information
   392 		// parse call stack item information
   397 		else if (name.equals(XML_ITEM)) {
   393 		else if (name.equals(XML_ITEM)) {
   398 			try{
   394 			try {
   399 				//create new item
   395 				// create new item
   400 				callstackItem = new CallstackItem();
   396 				callstackItem = new CallstackItem();
   401 				callstackItem.setID(activeCallstackID);
   397 				callstackItem.setID(activeCallstackID);
   402 				callstackItem.setFileName(atts.getValue(XML_FILE));
   398 				callstackItem.setFileName(atts.getValue(XML_FILE));
   403 				callstackItem.setFunctionName(atts.getValue(XML_FUNCTION));
   399 				callstackItem.setFunctionName(atts.getValue(XML_FUNCTION));
   404 				callstackItem.setMemoryAddress(atts.getValue(XML_MEMADDR));
   400 				callstackItem.setMemoryAddress(atts.getValue(XML_MEMADDR));
   405 
   401 
   406 				//get module name and add it to list
   402 				// get module name and add it to list
   407 				//module name list is used later.
   403 				// module name list is used later.
   408 				String moduleName = atts.getValue(XML_MODULE);
   404 				String moduleName = atts.getValue(XML_MODULE);
   409 				addModuleNameToList(moduleName);
   405 				addModuleNameToList(moduleName);
   410 				callstackItem.setModuleName(moduleName);
   406 				callstackItem.setModuleName(moduleName);
   411 
   407 
   412 				//if line number is added to the XML file
   408 				// if line number is added to the XML file
   413 				//this means that the results are generated to UREL
   409 				// this means that the results are generated to UREL
   414 				String lineNumber = atts.getValue(XML_LINE);
   410 				String lineNumber = atts.getValue(XML_LINE);
   415 				if (lineNumber != null && !("").equals(lineNumber) && !(XML_UNKNOWN).equals(lineNumber)) {
   411 				if (lineNumber != null && !("").equals(lineNumber)
   416 					callstackItem.setLeakLineNumber(Integer.parseInt(lineNumber));
   412 						&& !(XML_UNKNOWN).equals(lineNumber)) {
   417 				}
   413 					callstackItem.setLeakLineNumber(Integer
   418 
   414 							.parseInt(lineNumber));
   419 				//if function line is added to the XML file
   415 				}
   420 				//this means that the results are generated to UREL
   416 
       
   417 				// if function line is added to the XML file
       
   418 				// this means that the results are generated to UREL
   421 				String functionLine = atts.getValue(XML_FUNCTION_LINE);
   419 				String functionLine = atts.getValue(XML_FUNCTION_LINE);
   422 				if (functionLine != null && !("").equals(functionLine) && !(XML_UNKNOWN).equals(functionLine)) {
   420 				if (functionLine != null && !("").equals(functionLine)
   423 					callstackItem.setLeakLineNumber(Integer.parseInt(functionLine));
   421 						&& !(XML_UNKNOWN).equals(functionLine)) {
       
   422 					callstackItem.setLeakLineNumber(Integer
       
   423 							.parseInt(functionLine));
   424 					callstackItem.setUrelBuild(true);
   424 					callstackItem.setUrelBuild(true);
   425 				}
   425 				}
   426 			}catch(NumberFormatException npe) {
   426 			} catch (NumberFormatException npe) {
   427 				npe.printStackTrace();
   427 				npe.printStackTrace();
   428 			}
   428 			}
   429 			activeCallstackID++;
   429 			activeCallstackID++;
   430 
   430 
   431 		}
   431 		}
   432 		//parse subtest information
   432 		// parse subtest information
   433 		else if (name.equals(XML_SUBTEST)) {
   433 		else if (name.equals(XML_SUBTEST)) {
   434 			activeSubtest = new Subtest(activeSubtestID);
   434 			activeSubtest = new Subtest(activeSubtestID);
   435 			activeItemID = 1;
   435 			activeItemID = 1;
   436 			activeCallstackID = 1;
   436 			activeCallstackID = 1;
   437 			activeSubtest.setEndTime(atts.getValue(XML_END_TIME));
   437 			activeSubtest.setEndTime(atts.getValue(XML_END_TIME));