--- a/buildframework/helium/tools/common/java/src/com/nokia/ant/Database.java Wed Oct 28 14:39:48 2009 +0000
+++ b/buildframework/helium/tools/common/java/src/com/nokia/ant/Database.java Wed Dec 23 19:29:07 2009 +0200
@@ -27,20 +27,21 @@
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
-import java.util.HashMap;
import java.util.Map;
-import java.util.regex.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.types.ResourceCollection;
-import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.types.resources.FileResource;
-
import org.dom4j.Attribute;
import org.dom4j.CDATA;
import org.dom4j.Comment;
@@ -52,10 +53,11 @@
import org.dom4j.Text;
import org.dom4j.Visitor;
import org.dom4j.VisitorSupport;
+import org.dom4j.XPath;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
-import org.dom4j.XPath;
+
/**
* Reads the current ant project and a fileset and generates a xml file with a summary of targets,
@@ -71,7 +73,7 @@
private HashMap<String, List<String>> globalSignalList = new HashMap<String, List<String>>();
private HashMap map = new HashMap();
private Document signaldoc;
-
+
public Database(Project project, ResourceCollection rc, Task task)
{
this.project = project;
@@ -83,20 +85,20 @@
public Project getProject() {
return project;
}
-
+
public void setDebug(boolean debug) {
this.debug = debug;
}
-
+
public void setHomeFilesOnly(boolean homeFilesOnly) {
this.homeFilesOnly = homeFilesOnly;
}
-
+
public void log(String msg, int level) {
if (task != null) {
task.log(msg, level);
} else if (debug) {
- System.out.println(msg);
+ project.log(msg, level);
}
}
@@ -129,9 +131,12 @@
String antFile = (String) antFilesIter.next();
parseAntFile(root, antFile);
}
+
+ buildTaskDefs( root );
+
return outDoc;
}
-
+
public void createXMLFile(File outputFile) {
try {
Document outDoc = createDOM();
@@ -142,27 +147,25 @@
XMLWriter out = new XMLWriter(outStream, OutputFormat.createPrettyPrint());
out.write(outDoc);
} catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
throw new BuildException(e.getMessage());
}
}
-
+
private void readSignals(Element root, String antFile) throws DocumentException, IOException
{
SAXReader xmlReader = new SAXReader();
Document antDoc = xmlReader.read(new File(antFile));
-
+
XPath xpath = DocumentHelper.createXPath("//hlm:signalConfig");
xpath.setNamespaceURIs(map);
-
+
List signalNodes = xpath.selectNodes(antDoc);
for (Iterator iterator = signalNodes.iterator(); iterator.hasNext();)
{
signaldoc = antDoc;
Element propertyNode = (Element) iterator.next();
String signalid = propertyNode.attributeValue("id");
-
+
String signaltarget = signalName(signalid, signaldoc);
List existinglist = globalSignalList.get(signaltarget);
String failbuild = signalType(signalid, signaldoc);
@@ -171,7 +174,7 @@
existinglist.add(signalid + "," + failbuild);
globalSignalList.put(signaltarget, existinglist);
}
-
+
xpath = DocumentHelper.createXPath("//hlm:signalListenerConfig");
xpath.setNamespaceURIs(map);
signalNodes = xpath.selectNodes(antDoc);
@@ -180,7 +183,7 @@
signaldoc = antDoc;
Element propertyNode = (Element) iterator.next();
String signalid = propertyNode.attributeValue("id");
-
+
String signaltarget = propertyNode.attributeValue("target");
List existinglist = globalSignalList.get(signaltarget);
String failbuild = signalType(signalid, signaldoc);
@@ -190,7 +193,7 @@
globalSignalList.put(signaltarget, existinglist);
}
}
-
+
private String signalName(String signalid, Document antDoc)
{
XPath xpath = DocumentHelper.createXPath("//hlm:signalConfig[@id='" + signalid + "']/hlm:targetCondition");
@@ -204,18 +207,18 @@
}
return null;
}
-
+
private String signalType(String signalid, Document antDoc)
{
XPath xpath2 = DocumentHelper.createXPath("//hlm:signalConfig[@id='" + signalid + "']/hlm:inputRef|//hlm:signalListenerConfig[@id='" + signalid + "']/signalNotifierInput/signalInput");
xpath2.setNamespaceURIs(map);
List signalNodes3 = xpath2.selectNodes(antDoc);
-
+
for (Iterator iterator3 = signalNodes3.iterator(); iterator3.hasNext();)
{
Element propertyNode3 = (Element) iterator3.next();
String signalinputid = propertyNode3.attributeValue("refid");
-
+
XPath xpath3 = DocumentHelper.createXPath("//hlm:signalInput[@id='" + signalinputid + "']");
xpath3.setNamespaceURIs(map);
List signalNodes4 = xpath3.selectNodes(antDoc);
@@ -227,7 +230,7 @@
}
return null;
}
-
+
/**
* @param root
* @param antFile
@@ -280,10 +283,10 @@
{
Element argNode = (Element) iterator.next();
String argValue = argNode.attributeValue("value");
-
+
if (argValue == null)
argValue = argNode.attributeValue("line");
-
+
if (argValue != null)
{
Pattern filePattern = Pattern.compile(".pl|.py|.bat|.xml|.txt");
@@ -324,7 +327,7 @@
{
return getAntFiles(getProject(), true);
}
-
+
public ArrayList getAntFiles(Project project)
{
return getAntFiles(project, true);
@@ -342,16 +345,16 @@
Map targets = project.getTargets();
Iterator targetsIter = targets.values().iterator();
-
+
String projectHome = null;
try {
projectHome = new File(project.getProperty("helium.dir")).getCanonicalPath();
-
+
while (targetsIter.hasNext())
{
Target target = (Target) targetsIter.next();
String projectPath = new File(target.getLocation().getFileName()).getCanonicalPath();
-
+
if (!antFiles.contains(projectPath))
{
if (homeOnly)
@@ -365,7 +368,7 @@
antFiles.add(projectPath);
}
}
-
+
if (rc != null)
{
Iterator extraFilesIter = rc.iterator();
@@ -373,7 +376,7 @@
{
FileResource f = (FileResource) extraFilesIter.next();
String extrafile = f.getFile().getCanonicalPath();
-
+
if (!antFiles.contains(f.toString()) && !f.getFile().getName().startsWith("test_"))
{
if (homeOnly)
@@ -388,13 +391,18 @@
}
}
}
-
- } catch (Exception e) { e.printStackTrace(); }
+
+ } catch (Exception e) {
+ log(e.getMessage(), Project.MSG_ERR);
+ e.printStackTrace();
+ }
return antFiles;
}
+ //--------------------------------- PRIVATE METHODS ------------------------------------------
+
private void processMacro(Element macroNode, Element outProjectNode, String antFile)
- throws IOException, DocumentException
+ throws IOException, DocumentException
{
String macroName = macroNode.attributeValue("name");
log("Processing macro: " + macroName, Project.MSG_DEBUG);
@@ -416,7 +424,7 @@
// number.
// TODO - Later we should find the line number from the XML input.
addTextElement(outmacroNode, "location", antFile + ":1:");
-
+
List<Node> statements = macroNode.selectNodes("//scriptdef[@name='" + macroName + "']/attribute | //macrodef[@name='" + macroName + "']/attribute");
String usage = "";
for (Node statement : statements)
@@ -428,7 +436,7 @@
defaultval = "<i>" + defaultval + "</i>";
usage = usage + " " + statement.valueOf("@name") + "=\"" + defaultval + "\"";
}
-
+
String macroElements = "";
statements = macroNode.selectNodes("//scriptdef[@name='" + macroName + "']/element | //macrodef[@name='" + macroName + "']/element");
for (Node statement : statements)
@@ -439,8 +447,8 @@
addTextElement(outmacroNode, "usage", "<hlm:" + macroName + " " + usage + "/>");
else
addTextElement(outmacroNode, "usage", "<hlm:" + macroName + " " + usage + ">\n" + macroElements + "</hlm:" + macroName + ">");
-
-
+
+
// Add dependencies
// Enumeration dependencies = antmacro.getDependencies();
// while (dependencies.hasMoreElements())
@@ -495,7 +503,7 @@
addTextElement(outmacroNode, "propertyDependency", property);
}
}
-
+
private void callAntTargetVisitor(Element targetNode, Element outTargetNode, Element outProjectNode)
{
// Add antcall/runtarget dependencies
@@ -511,26 +519,26 @@
Element dependencyElement = addTextElement(outTargetNode, "dependency", antcallTarget);
dependencyElement.addAttribute("type", "exec");
}
-
+
for (String log : logs)
{
addTextElement(outTargetNode, "log", log);
}
-
+
if (globalSignalList.get(targetNode.attributeValue("name")) != null)
signals.addAll(globalSignalList.get(targetNode.attributeValue("name")));
-
+
for (String signal : signals)
{
addTextElement(outTargetNode, "signal", signal);
}
-
+
for (String executable : executables)
{
addTextElement(outTargetNode, "executable", executable);
}
}
-
+
private void processTarget(Element targetNode, Element outProjectNode) throws IOException, DocumentException
{
String targetName = targetNode.attributeValue("name");
@@ -556,7 +564,7 @@
{
Comment targetComment = (Comment) child;
commentText = targetComment.getStringValue().trim();
-
+
log(targetName + " comment: " + commentText, Project.MSG_DEBUG);
}
else
@@ -566,26 +574,26 @@
Node previousNode = (Node) children.get(children.size() - 1);
}
-
+
if (!commentText.contains("Private:"))
{
Element outTargetNode = outProjectNode.addElement("target");
-
+
addTextElement(outTargetNode, "name", targetNode.attributeValue("name"));
addTextElement(outTargetNode, "ifDependency", targetNode.attributeValue("if"));
addTextElement(outTargetNode, "unlessDependency", targetNode.attributeValue("unless"));
addTextElement(outTargetNode, "description", targetNode.attributeValue("description"));
addTextElement(outTargetNode, "tasks", String.valueOf(targetNode.elements().size()));
-
+
// Add location
Project project = getProject();
Target antTarget = (Target) project.getTargets().get(targetName);
-
+
if (antTarget == null)
return;
-
+
addTextElement(outTargetNode, "location", antTarget.getLocation().toString());
-
+
// Add dependencies
Enumeration dependencies = antTarget.getDependencies();
while (dependencies.hasMoreElements())
@@ -594,12 +602,12 @@
Element dependencyElement = addTextElement(outTargetNode, "dependency", dependency);
dependencyElement.addAttribute("type", "direct");
}
-
+
callAntTargetVisitor(targetNode, outTargetNode, outProjectNode);
-
+
// Process the comment text as MediaWiki syntax and convert to HTML
insertDocumentation(outTargetNode, commentText);
-
+
// Get names of all properties used in this target
ArrayList properties = new ArrayList();
Visitor visitor = new AntPropertyVisitor(properties);
@@ -609,12 +617,12 @@
String property = (String) iterator.next();
addTextElement(outTargetNode, "propertyDependency", property);
}
-
+
// Add the raw XML content of the element
String targetXml = targetNode.asXML();
// Replace the CDATA end notation to avoid nested CDATA sections
targetXml = targetXml.replace("]]>", "] ]>");
-
+
addTextElement(outTargetNode, "source", targetXml, true);
}
}
@@ -649,11 +657,11 @@
if (commentText.startsWith("-"))
commentText = commentText.replace("-", "");
commentText = commentText.trim();
-
+
String commentTextCheck = commentText.replace("deprecated>", "").replace("tt>", "").replace("todo>", "");
if (commentTextCheck.contains(">") && !commentTextCheck.contains("</pre>"))
log("Warning: Comment code needs <pre> tags around it: " + commentText, Project.MSG_WARN);
-
+
commentText = filterTextNewlines(commentText);
commentText = wikiModel.render(commentText);
@@ -683,7 +691,7 @@
}
// Get the documentation element as a document
String documentationText = "<documentation>" + commentText +
- "</documentation>";
+ "</documentation>";
Document docDoc = DocumentHelper.parseText(documentationText);
outNode.add(docDoc.getRootElement());
log("HTML comment: " + commentText, Project.MSG_DEBUG);
@@ -727,6 +735,78 @@
return out.toString();
}
+ /**
+ * Method adds taskdef nodes to the specified project.
+ *
+ * @param outProjectNode
+ * @throws IOException
+ */
+ private void buildTaskDefs( Element root ) throws DocumentException, IOException
+ {
+ Element projectElement = root.addElement("project");
+ projectElement.addElement("name");
+ insertDocumentation(projectElement, "");
+ HashMap < String, String > tasks = getHeliumAntTasks();
+
+ for ( String taskName : tasks.keySet() ) {
+ String className = tasks.get( taskName );
+ log("Processing TaskDef: " + taskName, Project.MSG_DEBUG);
+
+ Element outTaskDefNode = projectElement.addElement("taskdef");
+ addTextElement( outTaskDefNode, "name", taskName );
+ addTextElement( outTaskDefNode, "classname", className );
+ }
+ }
+
+ /**
+ * Method returns all the helium ant tasks in the project.
+ *
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ private HashMap < String, String > getHeliumAntTasks() {
+
+ // 1. Get all the task definitions from the project
+ Hashtable <String, Class<?> > allTaskdefs = getProject().getTaskDefinitions();
+ // 2. Filter the list by applying criteria
+ return filterTasks( allTaskdefs );
+ }
+
+ /**
+ * Method is used to filter tasks.
+ *
+ * @param allTaskdefs
+ * @param criteria
+ */
+ private HashMap < String, String > filterTasks ( Hashtable<String, Class<?> > allTaskdefs ) {
+ HashMap <String, String> tasks = new HashMap <String, String>();
+
+ Enumeration <String> taskdefsenum = allTaskdefs.keys();
+ while ( taskdefsenum.hasMoreElements () ) {
+ String key = taskdefsenum.nextElement();
+ Class<?> clazz = allTaskdefs.get(key);
+ String className = clazz.getName();
+ if ( key.contains("nokia.com") && className.startsWith("com.nokia") &&
+ className.contains("ant.taskdefs") ) {
+ tasks.put( getTaskName( key ), clazz.getName() );
+ }
+ }
+ return tasks;
+ }
+
+ /**
+ * Returns the task name delimiting the helium namespace.
+ *
+ * @param text
+ * @return
+ */
+ private String getTaskName( String text ) {
+ int lastIndex = text.lastIndexOf(':');
+ return text.substring( lastIndex + 1 );
+ }
+
+ //----------------------------------- PRIVATE CLASSES -----------------------------------------
+
private class AntPropertyVisitor extends VisitorSupport
{
private List propertyList;
@@ -753,7 +833,7 @@
String text = node.getText();
extractUsedProperties(text);
}
-
+
public void visit(Element node)
{
if (node.getName().equals("property"))
@@ -762,7 +842,7 @@
if (!propertyList.contains(propertyName))
{
propertyList.add(propertyName);
- log("property matches :" + propertyName, Project.MSG_DEBUG);
+ log("property matches :" + propertyName, Project.MSG_DEBUG);
}
}
}
@@ -821,7 +901,7 @@
{
this.targetList = targetList;
}
-
+
public AntTargetVisitor(List targetList, List logList, List signalList, List executableList)
{
this.targetList = targetList;
@@ -838,7 +918,7 @@
String text = node.attributeValue("target");
extractTarget(text);
}
-
+
if (!name.equals("include") && !name.equals("exclude"))
{
String text = node.attributeValue("name");
@@ -854,12 +934,12 @@
text = node.attributeValue("file");
addLog(text);
}
-
+
if (name.equals("signal") || name.equals("execSignal"))
{
String signalid = getProject().replaceProperties(node.attributeValue("name"));
String failbuild = signalType(signalid, signaldoc);
-
+
if (signalList != null)
{
if (failbuild != null)
@@ -868,7 +948,7 @@
signalList.add(signalid);
}
}
-
+
if (name.equals("exec") || name.equals("preset.exec"))
{
String text = node.attributeValue("executable");
@@ -876,7 +956,7 @@
log("Executable: " + text, Project.MSG_DEBUG);
}
}
-
+
private void addLog(String text)
{
if (text != null && logList != null)