/******************************************************************************* * Copyright (c) 2012-2015 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.ide.ant.tools.buildfile; import org.eclipse.che.api.core.ServerException; import org.w3c.dom.Comment; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; 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.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.StringWriter; import java.util.Map; import java.util.TreeMap; /** * Creates build.xml file. That need for Ant automation build tool to be able to build simple project using Ant. * Idea based on eclipse Ant build file creator from eclipse sources (org.eclipse.ant.internal.ui.datatransfer.BuildFileCreator). * * @author Vladyslav Zhukovskii */ public class BuildFileGenerator { /** Name of the project, which used in build file generation. */ private String projectName; /** * Create instance of {@link BuildFileGenerator}. * * @param projectName * name of the generated project. */ public BuildFileGenerator(String projectName) { this.projectName = projectName; } /** Root container of the document tree. */ private Document doc; /** Element which represent document tree. */ private Element root; /** * Build simple Ant build file (build.xml) content based on project name. * * @return string representation of auto generated build file */ public String getBuildFileContent() throws ServerException { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { this.doc = dbf.newDocumentBuilder().newDocument(); createRoot(); createProperty(); // createClassPath(); createBuild(); createClean(); return documentToString(doc); } catch (ParserConfigurationException | TransformerException e) { throw new ServerException(e.getMessage(), e); } } /** * Create project tag. * <project name="project_name" default="build" basedir="."> */ private void createRoot() { root = doc.createElement("project"); root.setAttribute("name", projectName); root.setAttribute("default", "build"); root.setAttribute("basedir", "."); doc.appendChild(root); } /** * Create property tag. * <property name="value" {location,value}="value"/> */ private void createProperty() { Map<String, String> locationProperties = new TreeMap<>(); locationProperties.put("build", "${basedir}/build"); locationProperties.put("build.classes", "${build}/classes"); locationProperties.put("src.dir", "${basedir}/src"); Element nameProperty = doc.createElement("property"); nameProperty.setAttribute("name", "name"); nameProperty.setAttribute("value", projectName); Node node = root.getFirstChild(); node = root.insertBefore(nameProperty, node); for (Map.Entry<String, String> locationProperty : locationProperties.entrySet()) { Element locationElement = doc.createElement("property"); locationElement.setAttribute("name", locationProperty.getKey()); locationElement.setAttribute("location", locationProperty.getValue()); node = node.getNextSibling(); node = root.insertBefore(locationElement, node); } } // /** // * Create classpath tag. // * <path id="libs.dir"> // * <fileset dir="lib" includes="**\/*\.jar"/> // * </path> // */ // private void createClassPath() { // Element path = doc.createElement("path"); // path.setAttribute("id", "libs.dir"); // // Element fieldSet = doc.createElement("fileset"); // fieldSet.setAttribute("dir", "lib"); // fieldSet.setAttribute("includes", "**/*.jar"); // // path.appendChild(fieldSet); // // root.appendChild(path); // } /** * Create build target tag. * <target depends="clean" description="Builds the application" name="build"> * ... * </target> */ private void createBuild() { //Insert comment Comment buildComment = doc.createComment("Application build"); root.appendChild(buildComment); //Create main target tag Element target = doc.createElement("target"); target.setAttribute("name", "build"); target.setAttribute("depends", "clean"); target.setAttribute("description", "Builds the application"); //Insert comment Comment createDirectoryComment = doc.createComment("Create directory"); target.appendChild(createDirectoryComment); //Create mkdir tag inside target Element mkdir = doc.createElement("mkdir"); mkdir.setAttribute("dir", "${build.classes}"); target.appendChild(mkdir); //Insert comment Comment compileSourcesComment = doc.createComment("Compile source code"); target.appendChild(compileSourcesComment); //Create javac tag inside target Element javac = doc.createElement("javac"); javac.setAttribute("srcdir", "${src.dir}"); javac.setAttribute("destdir", "${build.classes}"); javac.setAttribute("debug", "false"); javac.setAttribute("deprecation", "true"); javac.setAttribute("optimize", "true"); javac.setAttribute("includeantruntime", "true"); // //Create classpath tag inside javac // Element classpath = doc.createElement("classpath"); // classpath.setAttribute("refid", "libs.dir"); // javac.appendChild(classpath); target.appendChild(javac); //Insert comment Comment copyNecessaryFiles = doc.createComment("Copy necessary files"); target.appendChild(copyNecessaryFiles); //Create copy tag inside target Element copy = doc.createElement("copy"); copy.setAttribute("todir", "${build.classes}"); //Create fileset tag inside copy Element copyFileset = doc.createElement("fileset"); copyFileset.setAttribute("dir", "${src.dir}"); copyFileset.setAttribute("includes", "**/*.*"); copyFileset.setAttribute("excludes", "**/*.java"); copy.appendChild(copyFileset); target.appendChild(copy); //Insert comment Comment createJarComment = doc.createComment("Create JAR-file"); target.appendChild(createJarComment); //Create jar tag inside target Element jar = doc.createElement("jar"); jar.setAttribute("jarfile", "${build}/${name}.jar"); //Create fileset tag inside jar Element jarFileset = doc.createElement("fileset"); jarFileset.setAttribute("dir", "${build.classes}"); jar.appendChild(jarFileset); target.appendChild(jar); root.appendChild(target); } /** * Create clean target tag. * <target description="Remove all temporary files" name="clean"> * ... * </target> */ private void createClean() { //Insert comment Comment cleanUpComment = doc.createComment("Clean up"); root.appendChild(cleanUpComment); //Create main target tag Element target = doc.createElement("target"); target.setAttribute("name", "clean"); target.setAttribute("description", "Remove all temporary files"); //Insert comment Comment deleteFileComment = doc.createComment("Delete files"); target.appendChild(deleteFileComment); //Create delete tag inside target tag Element delete = doc.createElement("delete"); delete.setAttribute("dir", "${build.classes}"); target.appendChild(delete); root.appendChild(target); } /** Convert document to formatted XML string. */ private String documentToString(Document doc) throws TransformerException { StringWriter writer = new StringWriter(); Source source = new DOMSource(doc); Result result = new StreamResult(writer); TransformerFactory factory = TransformerFactory.newInstance(); factory.setAttribute("indent-number", "4"); Transformer transformer = factory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.transform(source, result); return writer.toString(); } }