/* * Copyright 2008 Wishnu Prasetya. * * This file is part of T2. * T2 is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License (GPL) as published by the * Free Software Foundation; either version 3 of the License, or any * later version. * * T2 is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * A copy of the GNU General Public License can be found in T2 distribution. * If it is missing, see http://www.gnu.org/licenses. */ package t2ext.xml; import java.io.File; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import t2ext.util.FileCopy; import com.sun.org.apache.bcel.internal.generic.Type; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; /** * Creates the Ant build.xml file. * Assumes that these files are in the same directory as the T2Extension.jar: * ant-launcher.jar * ant.jar * aspectjrt.jar * aspectjtools.jar * * Also used for building other XML files? * * @author Maaike Gerritsen */ public class XMLBuilder { private static final String Method = "method"; private static final String PathsFile = FileCopy.TEMP_DIR+"paths.xml"; private static final String Name = "name"; private static final String TargetName = "addJar"; private static final String Argument = "arg"; private static final String Value = "value"; private static final String Jar = "jar"; private static final String NewJar = "T2ECopy.jar"; private static final String ClassPath = "classpath"; private static final String Path = "pathelement"; private static final String Location = "location"; private static final String Main = "main(java.lang.String[])"; // private String _className; private String _originalClassName; private String _jarDir; private String _directoryToCopy; private String _homeDir; private Document _classInfo; private String[] _args; public XMLBuilder() { } public XMLBuilder(String className, String jarDir, String[] args) { _args = args; _originalClassName = className; // _className = className.replace(".", "/") + ".class"; setDirectoryToCopy(); _jarDir = jarDir; getDirFromJAR(); } // TODO this seems bad ... // MyClass -> MyClass.class // org.package.MyClass -> org ? private void setDirectoryToCopy() { /* if (_originalClassName.contains(".")) { String toSplit = _originalClassName.replace(".", ":"); String[] split = toSplit.split(":"); _directoryToCopy = split[0]; } else { _directoryToCopy = _originalClassName + ".class"; } */ _directoryToCopy = t2ext.util.Util.getClassLocation(_originalClassName).getAbsolutePath(); System.out.println("DEBUG dirtocopy: "+_directoryToCopy); } private void getDirFromJAR() { File file1 = new File(_jarDir); File file2 = new File(file1.getAbsolutePath()); _jarDir = file2.getAbsolutePath(); _homeDir = file2.getParent(); if(!_homeDir.endsWith("/")) _homeDir = _homeDir+"/"; } public void setClassInfoName(String name) { _classInfo = getNewDocument(); Element root = _classInfo.createElement("class"); root.setAttribute(Name, name); _classInfo.appendChild(root); } public void registerMethodsForClassInfo(String mName, Type[] arguments) { Element method = _classInfo.createElement(Method); method.setAttribute(Name, mName); for (int i = 0; i < arguments.length; i++) { Type arg = arguments[i]; String argName = arg.toString().replace("$", "."); Element child = _classInfo.createElement("argument"); child.setAttribute(Name, argName); method.appendChild(child); } _classInfo.getChildNodes().item(0).appendChild(method); } private Element getNewWeaverClass(Document doc) { Element target = doc.createElement("target"); target.setAttribute(Name, "weaver"); Element ajc = doc.createElement("iajc"); ajc.setAttribute("source", "1.5"); ajc.setAttribute("srcdir", "t2ext/weaver"); Element classPath = doc.createElement(ClassPath); classPath.appendChild(getClassPath(_homeDir + "aspectjrt.jar", doc)); //classPath.appendChild(getClassPath(_jarDir, doc)); classPath.appendChild(getClassPath(_homeDir + "T2ECopy.jar", doc)); // Also add the classpath of the call to T2 itself: System.out.println("CLASSPATH "+System.getProperty("java.class.path")); Element path = doc.createElement(Path); path.setAttribute("path", System.getProperty("java.class.path")); classPath.appendChild(path); ajc.appendChild(classPath); target.appendChild(ajc); return target; } // private XMLElement newJarTarget() { // XMLElement target = new XMLElement(); // target.setName(Jar); // target.setAttribute("destfile", NewJar); // // XMLElement zipChild = new XMLElement(); // zipChild.setName("zipfileset"); // zipChild.setAttribute("src", _jarDir); // // XMLElement excludeChild = new XMLElement(); // excludeChild.setName("exclude"); // excludeChild.setAttribute(Name, "t2ext/T2Extension.class"); // // zipChild.addChild(excludeChild); // target.addChild(zipChild); // return target; // } public void createBuildFile() { Document doc = getNewDocument(); Element root = doc.createElement("project"); root.setAttribute("basedir", "."); root.setAttribute("default", TargetName); root.setAttribute(Name, "T2Extension"); root.appendChild(getTaskDefinition(doc)); root.appendChild(execJarTarget(_directoryToCopy, TargetName, doc, true)); root.appendChild(getNewWeaverClass(doc)); root.appendChild(execJarTarget("t2ext/weaver/Weaver.class", "addWeaverToJar", doc, false)); root.appendChild(getAjcTarget(doc)); root.appendChild(execRndEngineTarget(doc)); doc.appendChild(root); writeToFile(doc, FileCopy.TEMP_DIR+"build.xml"); } public Document getNewDocument() { try { DocumentBuilderFactory factory = DocumentBuilderFactory .newInstance(); factory.setNamespaceAware(true); DocumentBuilder docbuilder = factory.newDocumentBuilder(); Document doc = docbuilder.newDocument(); return doc; } catch (ParserConfigurationException e) { e.printStackTrace(); } return null; } public void createPathFile(Hashtable>> paths, Hashtable officialNames) { Document doc = getNewDocument(); Element root = doc.createElement("methods"); Enumeration names = paths.keys(); int methodId = 0; while (names.hasMoreElements()) { String name = names.nextElement(); String official = officialNames.get(name); if (!official.contains(Main)) { Element method = doc.createElement(Method); method.setAttribute(Name, name); method.setAttribute("official", official); method.setAttribute("id", new Integer(methodId).toString()); method.setAttribute("pathtofind", ""); methodId++; List> path = paths.get(name); int id = 0; for (Iterator> iterator = path.iterator(); iterator .hasNext();) { List list = iterator.next(); method.appendChild(getSinglePath(list, id, doc)); id++; } root.appendChild(method); } } doc.appendChild(root); writeToFile(doc, PathsFile); } private Element getSinglePath(List path, Integer id, Document doc) { Element pathElement = doc.createElement("path"); pathElement.setAttribute("id", id.toString()); pathElement.setAttribute("found", "false"); String value = ""; for (int i = 0; i < path.size(); i++) { Integer node = path.get(i); value += node.toString(); if (i < path.size() - 1) value += ", "; } Element nodes = doc.createElement("nodes"); nodes.setAttribute("value", value); pathElement.appendChild(nodes); return pathElement; } private Element getTaskDefinition(Document doc) { Element taskDef = doc.createElement("taskdef"); taskDef.setAttribute("resource", "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"); Element classPath = doc.createElement(ClassPath); Element path = doc.createElement(Path); path.setAttribute(Location, _homeDir + "aspectjtools.jar"); classPath.appendChild(path); taskDef.appendChild(classPath); return taskDef; } private Element getAjcTarget(Document doc) { Element target = doc.createElement("target"); target.setAttribute(Name, "toajc"); Element ajc = doc.createElement("iajc"); ajc.setAttribute("outjar", "T2ECopy2.jar"); ajc.setAttribute("source", "1.5"); Element inpath = doc.createElement("inpath"); Element path1 = doc.createElement(Path); path1.setAttribute(Location, _homeDir + NewJar); inpath.appendChild(path1); Element cPath = doc.createElement(ClassPath); cPath.appendChild(getClassPath(_homeDir + "aspectjrt.jar",doc)); cPath.appendChild(getClassPath(_homeDir + "ant.jar",doc)); cPath.appendChild(getClassPath(_homeDir + "ant-launcher.jar",doc)); ajc.appendChild(inpath); ajc.appendChild(cPath); target.appendChild(ajc); return target; } private Element getClassPath(String location, Document doc) { Element path = doc.createElement(Path); path.setAttribute(Location, location); return path; } private Element execRndEngineTarget(Document doc) { Element target = doc.createElement("target"); target.setAttribute(Name, "rndengine"); Element java = doc.createElement("java"); java.setAttribute("classname", "t2ext.ExecuteRndEngine"); Element prop1 = doc.createElement("sysproperty"); prop1.setAttribute("key", "DEBUG"); prop1.setAttribute("value", "true"); Element prop2 = doc.createElement("sysproperty"); prop2.setAttribute("key", "VERBOSE"); prop2.setAttribute("value", "true"); java.appendChild(prop1); java.appendChild(prop2); Element args = doc.createElement(Argument); args.setAttribute(Value, _originalClassName); Element classPath = doc.createElement(ClassPath); // classPath.appendChild(getClassPath(_jarDir,doc)); classPath.appendChild(getClassPath("T2ECopy2.jar",doc)); classPath.appendChild(getClassPath(_homeDir+"aspectjrt.jar",doc)); java.appendChild(args); for (int i = 2; i < _args.length; i++) { Element arg = doc.createElement(Argument); arg.setAttribute(Value, _args[i]); java.appendChild(arg); } java.appendChild(classPath); target.appendChild(java); return target; } /** * Makes an add-jar line for all .class files in the directory of fileName. * TODO: why?? * @param fileName * @param jarName * @param doc * @param changeDir * @return */ private Element execJarTarget(String fileName, String jarName, Document doc, boolean changeDir) { Element target = doc.createElement("target"); target.setAttribute(Name, jarName); /* if (fileName.endsWith(".class")) { String completeFileName = (new File(fileName)).getAbsolutePath(); File file = new File(completeFileName); String[] children = file.getParentFile().list(); if (children != null) { for (int i = 0; i < children.length; i++) { String child = children[i]; if (child.endsWith(".class")) { Element exec = updateJarExec(child,doc); target.appendChild(exec); } } } else { Element exec = updateJarExec(fileName, doc); target.appendChild(exec); } } else { Element exec = updateJarExec(fileName, doc); target.appendChild(exec); } */ // For now: only add the CUT Element exec = updateJarExec(fileName, doc, changeDir); target.appendChild(exec); return target; } // FIXME private Element updateJarExec(String fileName, Document doc, boolean changeDir) { Element exec = doc.createElement("exec"); exec.setAttribute("executable", Jar); Element arg1 = doc.createElement(Argument); Element arg2 = doc.createElement(Argument); Element arg3 = doc.createElement(Argument); Element arg4 = doc.createElement(Argument); Element arg5 = doc.createElement(Argument); arg1.setAttribute(Value, "uf"); arg2.setAttribute(Value, _homeDir + NewJar); if(changeDir) { arg3.setAttribute(Value, "-C"); arg4.setAttribute(Value, fileName.substring(0, fileName.length()-_originalClassName.length()-6)); arg5.setAttribute(Value, _originalClassName.replace('.', '/')+".class"); } else { arg5.setAttribute(Value, fileName); } exec.appendChild(arg1); exec.appendChild(arg2); if(changeDir) { exec.appendChild(arg3); exec.appendChild(arg4); } exec.appendChild(arg5); return exec; } public void writeToFile(Document doc, String fileName) { try { Source source = new DOMSource(doc); File file = new File(fileName); System.out.println("Writing XML to "+file); Result result = new StreamResult(file); Transformer xformer = TransformerFactory.newInstance() .newTransformer(); // Pretty print xformer.setOutputProperty(OutputKeys.INDENT, "yes"); xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); xformer.transform(source, result); } catch (Exception e) { System.out.println("HELP!!!!"+e.getMessage()); e.printStackTrace(); } } public Document readXMLFile(String fileName) { try { DocumentBuilderFactory factory = DocumentBuilderFactory .newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(fileName); // XPathFactory xFactory = XPathFactory.newInstance(); // XPath xpath = xFactory.newXPath(); // XPathExpression expr = // xpath.compile("//method[@official='example.BinarySearchTree.insert(java.lang.Comparable, // example.BinarySearchTree.BinaryNode)']"); // Element elem = (Element) expr.evaluate(doc, XPathConstants.NODE); // System.out.println(elem.getChildNodes().getLength()); return doc; } catch (Exception e) { e.printStackTrace(); } return null; } // public XMLElement readXMLFile1(String fileName) { // XMLElement element = new XMLElement(); // try { // FileInputStream in = new FileInputStream(fileName); // BufferedInputStream bi = new BufferedInputStream(in); // int ch = 0; // StringBuffer buf = new StringBuffer(); // while ((ch = bi.read()) > -1) { // buf.append((char) ch); // } // if (buf.length() > 0) { // String content = buf.toString(); // element.parseString(content); // } // } catch (FileNotFoundException e) { // e.printStackTrace(); // } catch (IOException e) { // e.printStackTrace(); // } // return element; // } public NodeList getNodesFromXML(Document doc, String condition) { try { XPathFactory xFactory = XPathFactory.newInstance(); XPath xpath = xFactory.newXPath(); XPathExpression expr = xpath.compile(condition); NodeList list = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); return list; } catch (Exception e) { e.printStackTrace(); } return null; } public Element getNodeFromXML(Document doc, String condition) { try { XPathFactory xFactory = XPathFactory.newInstance(); XPath xpath = xFactory.newXPath(); XPathExpression expr = xpath.compile(condition); Element element = (Element) expr.evaluate(doc, XPathConstants.NODE); return element; } catch (Exception e) { e.printStackTrace(); } return null; } public void createClassInfoFile() { writeToFile(_classInfo, FileCopy.TEMP_DIR+"classInfo.xml"); } }