/** * Copyright (C) 2006-2017 INRIA and contributors * Spoon - http://spoon.gforge.inria.fr/ * * This software is governed by the CeCILL-C License under French law and * abiding by the rules of distribution of free software. You can use, modify * and/or redistribute the software under the terms of the CeCILL-C license as * circulated by CEA, CNRS and INRIA at http://www.cecill.info. * * This program 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 CeCILL-C License for more details. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ package spoon; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.taskdefs.Java; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.Reference; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Vector; /** * This class implements an Ant task for Spoon that encapsulates * {@link spoon.Launcher}. */ public class SpoonTask extends Java { /** * Nested element to define a processor type. */ public static class ProcessorType { String type; /** * Ant-required empty constructor. */ public ProcessorType() { } /** * Constructs a new processor type. * * @param type * the type's fully qualified name */ public ProcessorType(String type) { setType(type); } /** * Gets the processor type. */ public String getType() { return type; } /** * Sets the processor's type as a string representing the Java qualified * name. */ public void setType(String type) { this.type = type; } } String classname; File input; int javaCompliance = 7; boolean nooutput = false; boolean compile = false; File output; File destination; List<ProcessorType> processorTypes = new ArrayList<>(); Vector<FileSet> sourcefilesets = new Vector<>(); boolean stats = false; File template; Vector<FileSet> templatefilesets = new Vector<>(); boolean verbose = false; boolean debug = false; boolean imports = false; boolean noclasspath = false; boolean precompile = false; boolean buildOnlyOutdatedFiles = false; String outputType; String encoding; boolean lines; /** * Constructor. */ public SpoonTask() { setClassname("spoon.Launcher"); setFailonerror(true); } /** * Adds a new processor type to be instantiated and used by Spoon when * processing the code. */ public void addProcessor(ProcessorType processorType) { processorTypes.add(processorType); } /** * Adds a source set. */ public void addSourceSet(FileSet set) { sourcefilesets.addElement(set); } /** * Adds a template source set. */ public void addTemplateSet(FileSet set) { templatefilesets.addElement(set); } /** * Executes the task. */ @Override public void execute() throws BuildException { setFork(false); // Verbose if (verbose) { createArg().setValue("-v"); } // debug if (debug) { createArg().setValue("--vvv"); } if (precompile) { createArg().setValue("--precompile"); } if (tabs) { createArg().setValue("--tabs"); } if (imports) { createArg().setValue("--with-imports"); } if (noclasspath) { createArg().setValue("--noclasspath"); } createArg().setValue("--tabsize"); createArg().setValue("" + tabSize); if (outputType != null) { createArg().setValue("--output-type"); createArg().setValue(outputType); } if (encoding != null) { createArg().setValue("--encoding"); createArg().setValue(encoding); } if (compile) { createArg().setValue("--compile"); } if (buildOnlyOutdatedFiles) { createArg().setValue("--buildOnlyOutdatedFiles"); } if (lines) { createArg().setValue("--lines"); } createArg().setValue("--compliance"); createArg().setValue("" + javaCompliance); // output directory if (output != null) { if (output.exists() && !output.isDirectory()) { throw new BuildException("Output must be a directory"); } createArg().setValue("-o"); createArg().setValue(output.getAbsolutePath()); } // destination directory if (destination != null) { if (destination.exists() && !destination.isDirectory()) { throw new BuildException("Destination must be a directory"); } createArg().setValue("-d"); createArg().setValue(destination.getAbsolutePath()); } // Input directories if ((input != null) || (sourcefilesets.size() > 0)) { createArg().setValue("-i"); String f = ""; if (input != null) { f += input.getAbsolutePath() + File.pathSeparator; } for (int i = 0; i < sourcefilesets.size(); i++) { FileSet fs = sourcefilesets.elementAt(i); File dir = fs.getDir(getProject()); f += dir.getAbsolutePath() + File.pathSeparator; } createArg().setValue(f); } // Template directories if ((template != null) || (templatefilesets.size() > 0)) { createArg().setValue("-t"); String f = ""; if (template != null) { if (!template.exists()) { throw new BuildException( "template file or directory does not exist (" + template.getAbsolutePath() + ")"); } f += template.getAbsolutePath() + File.pathSeparator; } for (int i = 0; i < templatefilesets.size(); i++) { FileSet fs = templatefilesets.elementAt(i); File dir = fs.getDir(getProject()); f += dir.getAbsolutePath() + File.pathSeparator; } createArg().setValue(f); } // processors if ((processorTypes != null) && (processorTypes.size() > 0)) { createArg().setValue("-p"); String process = ""; for (ProcessorType t : processorTypes) { process += t.type + File.pathSeparator; } createArg().setValue(process); } if (classname != null) { createArg().setValue(classname); } if (sourceClasspath != null) { createArg().setValue("--source-classpath"); createArg().setValue(sourceClasspath.toString()); } else if (getCommandLine().getClasspath() != null) { createArg().setValue("--source-classpath"); createArg().setValue(getCommandLine().getClasspath().toString()); } if (templateClasspath != null) { createArg().setValue("--template-classpath"); createArg().setValue(templateClasspath.toString()); } else if (getCommandLine().getClasspath() != null) { createArg().setValue("--template-classpath"); createArg().setValue(getCommandLine().getClasspath().toString()); } super.execute(); } /** * Sets the name of the laucher to be used. */ public void setClassName(String classname) { this.classname = classname; } /** * Sets a file or a directory to be processed (no templates, see * {@link #setTemplate(File)}). */ @Override public void setInput(File input) { this.input = input; } /** * Sets the java14 property (to be able to parse java 1.4 source files). */ public void setJavaCompliance(int javaCompliance) { this.javaCompliance = javaCompliance; } /** * Tells Spoon not to generate any source files. */ public void setNoOutput(boolean nooutput) { this.nooutput = nooutput; } /** * Tells Spoon to generate class files (bytecode). */ public void setCompile(boolean compile) { this.compile = compile; } /** * Sets the output directory for generated sources. */ @Override public void setOutput(File output) { this.output = output; } /** * Sets the destination directory for compiled classes (bytecode). */ public void setDestination(File destination) { this.destination = destination; } /** * Enables/disable printing out statistics on Spoon execution time. */ public void setStats(boolean stats) { this.stats = stats; } /** * Sets a file or a directory to be processed (only templates, see * {@link #setInput(File)}). */ public void setTemplate(File template) { this.template = template; } /** * Sets Spoon to be in verbose mode. */ public void setVerbose(boolean verbose) { this.verbose = verbose; } /** * Sets Spoon to be in debug mode. */ public void setDebug(boolean debug) { this.debug = debug; } boolean tabs = false; /** * Sets Spoon to use tabulations instead of spaces when printing source. */ public void setTabs(boolean tabs) { this.tabs = tabs; } int tabSize = 4; /** * Sets the tabulation size (default is 4 spaces). */ public void setTabSize(int tabSize) { this.tabSize = tabSize; } /** * Tells if Spoon should precompile the input files before processing. */ public void setPrecompile(boolean precompile) { this.precompile = precompile; } Path sourceClasspath; /** * Set the classpath to be used when building, processing and compiling the * sources. * * @param s * an Ant Path object containing the classpath. */ public void setSourceClasspath(Path s) { createSourceClasspath().append(s); } /** * Source classpath to use, by reference. * * @param r * a reference to an existing classpath */ public void setSourceClasspathRef(Reference r) { createSourceClasspath().setRefid(r); } private Path createSourceClasspath() { if (sourceClasspath == null) { sourceClasspath = new Path(getProject()); } return sourceClasspath; } Path templateClasspath; /** * Set the classpath to be used when building the template sources. * * @param s * an Ant Path object containing the classpath. */ public void setTemplateClasspath(Path s) { createTemplateClasspath().append(s); } /** * Template classpath to use, by reference. * * @param r * a reference to an existing classpath */ public void setTemplateClasspathRef(Reference r) { createTemplateClasspath().setRefid(r); } private Path createTemplateClasspath() { if (templateClasspath == null) { templateClasspath = new Path(getProject()); } return templateClasspath; } /** * Sets Spoon to build only the outdated source files (gives better * performances). This option will be ignored if the noouput option is on. */ public void setBuildOnlyOutdatedFiles(boolean buildOnlyOutdatedFiles) { this.buildOnlyOutdatedFiles = buildOnlyOutdatedFiles; } /** * Sets the output type (none, classes, or compilationunits). */ public void setOutputType(String ouputType) { this.outputType = ouputType; } /** * Sets the encoding to be used by the compiler. */ public void setEncoding(String encoding) { this.encoding = encoding; } /** * Sets automatic imports in generated files. */ public void setImports(boolean imports) { this.imports = imports; } /** * Does not assume a full classpath */ public void setNoClasspath(boolean noclasspath) { this.noclasspath = noclasspath; } /** * Tells if Spoon should try to preserve the original line numbers when * generating the source code (may lead to human-unfriendly formatting). */ public void setLines(boolean lines) { this.lines = lines; } }