buildframework/helium/sf/java/internaldata/src/com/nokia/helium/internaldata/ant/listener/XMLRenderer.java
/*
* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "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.helium.internaldata.ant.listener;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
import org.apache.tools.ant.BuildEvent;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
/**
* This xml render object does the following -
* Generates target only for TargetNode type of node
* Creates the targets section.
* Generates task only for TargetNode type of node
* Creates the task section.
* Creates execution tree recursively, visiting the DataNodes.
* Creates the execution tree section.
* Creates the property section.
* Renders the build node into XML string.
*/
public class XMLRenderer {
// Dump of properties
private Hashtable<String, String> properties;
// the toplevel node.
private BuildNode root;
// Helium content database.
private Document database;
// Deps hashes: helper to remove duplicates.
private Vector<String> targetList = new Vector<String>();
private Vector<String> assertList = new Vector<String>();
public XMLRenderer(BuildNode root, Document database, Hashtable<String, String> properties, BuildEvent event) {
this.root = root;
this.database = database;
this.properties = properties;
}
/**
* Generating target only for TargetNode type of node
* @param node
* @param targets
*/
protected void createTarget(DataNode node, Element targets) {
if (node instanceof TargetNode) {
TargetNode targetNode = (TargetNode)node;
if (!targetList.contains(targetNode.getName() + targetNode.getFilename())) {
targetList.add(targetNode.getName() + targetNode.getFilename());
Element target = targets.addElement("target");
target.addAttribute("id", "target@" + targetList.indexOf(targetNode.getName() + targetNode.getFilename()));
target.addAttribute("name", targetNode.getName());
target.addAttribute("file", targetNode.getFilename());
target.addAttribute("line", "" + targetNode.getLine());
}
}
for (Iterator<DataNode> i = node.iterator() ; i.hasNext() ; ) {
createTarget(i.next(), targets);
}
}
/**
* Creating the targets section.
* @param statistics
*/
protected void createTargets(Element statistics) {
Element targets = statistics.addElement("targets");
if (root != null) {
createTarget(root, targets);
}
}
/**
* Creating the assert section.
* @param statistics
*/
protected void createAsserts(Element statistics) {
Element asserts = statistics.addElement("asserts");
if (root != null) {
createAssert(root, asserts);
}
}
/**
* Generating assert only for TargetNode type of node
* @param node
* @param targets
*/
protected void createAssert(DataNode node, Element targets) {
if (node instanceof AssertNode) {
AssertNode assertNode = (AssertNode)node;
if (assertNode.getAssertName() != null) {
assertList.add(assertNode.getAssertName());
Element target = targets.addElement("assert");
target.addAttribute("id", "assert@" + assertList.indexOf(assertNode.getAssertName()));
target.addAttribute("name", assertNode.getAssertName());
target.addAttribute("file", assertNode.getFilename());
target.addAttribute("line", "" + assertNode.getLine());
target.addAttribute("message", "" + assertNode.getMessage());
}
}
for (Iterator<DataNode> i = node.iterator() ; i.hasNext() ; ) {
createAssert(i.next(), targets);
}
}
/**
* Creating execution tree recursively, visiting the DataNodes.
* @param node
* @param tree
*/
protected void createTree(DataNode node, Element tree) {
Element elt = null;
if (node instanceof BuildNode) {
BuildNode buildNode = (BuildNode)node;
elt = tree.addElement("build");
elt.addAttribute("name", buildNode.getName());
elt.addAttribute("startTime", "" + buildNode.getStartTime().getTime());
elt.addAttribute("endTime", "" + buildNode.getEndTime().getTime());
elt.addAttribute("status", buildNode.getSuccessful() ? "successful" : "failed");
elt.addAttribute("thread", "" + buildNode.getThreadId());
} else if (node instanceof TargetNode) {
TargetNode targetNode = (TargetNode)node;
elt = tree.addElement("targetRef");
elt.addAttribute("reference", "target@" + targetList.indexOf(targetNode.getName() + targetNode.getFilename()));
elt.addAttribute("startTime", "" + targetNode.getStartTime().getTime());
elt.addAttribute("endTime", "" + targetNode.getEndTime().getTime());
elt.addAttribute("thread", "" + targetNode.getThreadId());
elt.addAttribute("startUsedHeap", "" + targetNode.getStartUsedHeap());
elt.addAttribute("startCommittedHeap", "" + targetNode.getStartCommittedHeap());
elt.addAttribute("endUsedHeap", "" + targetNode.getEndUsedHeap());
elt.addAttribute("endCommittedHeap", "" + targetNode.getEndCommittedHeap());
} else if (node instanceof AssertNode) {
AssertNode assertNode = (AssertNode)node;
if (assertNode.getAssertName() != null) {
elt = tree.addElement("assertRef");
elt.addAttribute("reference", "assert@" + assertList.indexOf(assertNode.getAssertName()));
elt.addAttribute("startTime", "" + assertNode.getStartTime().getTime());
elt.addAttribute("endTime", "" + assertNode.getEndTime().getTime());
elt.addAttribute("thread", "" + assertNode.getThreadId());
}
}
if (elt != null) {
for (Iterator<DataNode> i = node.iterator() ; i.hasNext() ; ) {
createTree(i.next(), elt);
}
}
}
/**
* Creating the execution tree section.
* @param statistics
*/
protected void createExecutionTree(Element statistics) {
Element executionTree = statistics.addElement("executionTree");
if (root != null) {
createTree(root, executionTree);
}
}
/**
* Creating the property section.
* @param statistics
*/
protected void createProperties(Element statistics) {
Element propertiesElt = statistics.addElement("properties");
if (properties != null) {
for (Enumeration<String> propertyEnum = properties.keys(); propertyEnum.hasMoreElements() ; ) {
String key = propertyEnum.nextElement();
Element propertyElt = propertiesElt.addElement("property");
propertyElt.addAttribute("name", key);
propertyElt.addAttribute("value", properties.get(key));
}
}
}
protected void insertDatabase(Element statistics) {
if (database != null) {
Element databaseElt = statistics.addElement("database");
databaseElt.add(database.getRootElement().detach());
}
}
/**
* Rendering the build node into XML string.
*/
public String toString() {
// Creating the XML document
Document document = DocumentHelper.createDocument();
Element statistics = document.addElement( "statistics" );
statistics.addAttribute("version", "1.1");
// Creating the document content.
insertDatabase(statistics);
createTargets(statistics);
createAsserts(statistics);
createExecutionTree(statistics);
createProperties(statistics);
try {
ByteArrayOutputStream output = new ByteArrayOutputStream();
XMLWriter out = new XMLWriter(output, OutputFormat.createPrettyPrint());
out.write(document);
return output.toString();
} catch (UnsupportedEncodingException exc) {
return document.asXML();
} catch (IOException exc) {
return document.asXML();
}
}
}