ca.coglinc.gradle.plugins.javacc.AbstractJavaccTask Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javacc-gradle-plugin Show documentation
Show all versions of javacc-gradle-plugin Show documentation
Provides the ability to use JavaCC with Gradle. Compiles JavaCC files to Java.
package ca.coglinc.gradle.plugins.javacc;
import java.io.File;
import java.util.LinkedHashMap;
import java.util.Map;
import org.gradle.api.file.FileTree;
import org.gradle.api.file.FileVisitor;
import org.gradle.api.file.RelativePath;
import org.gradle.api.specs.Spec;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.SourceTask;
import org.gradle.api.tasks.TaskCollection;
import org.gradle.api.tasks.compile.JavaCompile;
import ca.coglinc.gradle.plugins.javacc.compilationresults.CompiledJavaccFile;
import ca.coglinc.gradle.plugins.javacc.compilationresults.CompiledJavaccFilesDirectory;
import ca.coglinc.gradle.plugins.javacc.compilationresults.CompiledJavaccFilesDirectoryFactory;
public abstract class AbstractJavaccTask extends SourceTask {
protected Map programArguments;
private File inputDirectory;
private File outputDirectory;
private CompiledJavaccFilesDirectoryFactory compiledJavaccFilesDirectoryFactory = new CompiledJavaccFilesDirectoryFactory();
protected AbstractJavaccTask(String inputDirectory, String outputDirectory, String filter) {
setInputDirectory(inputDirectory);
setOutputDirectory(outputDirectory);
include(filter);
}
protected void compile(File inputDirectory, RelativePath inputRelativePath) {
getLogger().debug("Compiling {} file [{}] from [{}] into [{}]", getProgramName(), inputRelativePath, inputDirectory, getOutputDirectory());
String[] arguments = buildProgramArguments(inputDirectory, inputRelativePath);
getLogger().debug("Invoking {} with arguments [{}]", getProgramName(), arguments);
try {
invokeCompiler(arguments);
} catch (Exception exception) {
final String errorMessage = String.format("Unable to compile '%s' from '%s' into '%s'", inputRelativePath, inputDirectory, getOutputDirectory());
throw new JavaccTaskException(errorMessage, exception);
}
}
protected abstract void invokeCompiler(String[] arguments) throws Exception;
protected void copyNonJavaccFilesToOutputDirectory() {
getSource().visit(getNonJavaccSourceFileVisitor());
}
protected File getTempOutputDirectory() {
return new File(getOutputDirectory(), "tmp");
}
protected void compileSourceFilesToTempOutputDirectory() {
getSource().visit(getJavaccSourceFileVisitor());
}
protected void copyCompiledFilesFromTempOutputDirectoryToOutputDirectory() {
CompiledJavaccFilesDirectory compiledJavaccFilesDirectory
= compiledJavaccFilesDirectoryFactory.getCompiledJavaccFilesDirectory(getTempOutputDirectory(), getCompleteSourceTree(), getOutputDirectory(), getLogger());
for (CompiledJavaccFile compiledJavaccFile : compiledJavaccFilesDirectory.listFiles()) {
FileTree javaSourceTree = getJavaSourceTree();
if (compiledJavaccFile.customAstClassExists(javaSourceTree)) {
compiledJavaccFile.ignoreCompiledFileAndUseCustomAstClassFromJavaSourceTree(javaSourceTree);
} else if (compiledJavaccFile.customAstClassExists()) {
compiledJavaccFile.copyCustomAstClassToTargetDirectory(getCompleteSourceTree());
} else {
compiledJavaccFile.copyCompiledFileToTargetDirectory();
}
}
}
private FileTree getCompleteSourceTree() {
FileTree javaccTaskSourceTree = getSource();
FileTree javaTasksSourceTree = getJavaSourceTree();
FileTree completeSourceTree = null;
if (javaTasksSourceTree == null) {
completeSourceTree = javaccTaskSourceTree;
} else {
completeSourceTree = javaccTaskSourceTree.plus(javaTasksSourceTree);
}
return excludeOutputDirectory(completeSourceTree);
}
private FileTree excludeOutputDirectory(FileTree sourceTree) {
if (sourceTree == null) {
return null;
}
Spec outputDirectoryFilter = new Spec() {
@Override
public boolean isSatisfiedBy(File file) {
return file.getAbsolutePath().contains(getOutputDirectory().getAbsolutePath());
}
};
sourceTree = sourceTree.minus(sourceTree.filter(outputDirectoryFilter)).getAsFileTree();
return sourceTree;
}
private FileTree getJavaSourceTree() {
FileTree javaSourceTree = null;
TaskCollection javaCompileTasks = this.getProject().getTasks().withType(JavaCompile.class);
for (JavaCompile task : javaCompileTasks) {
if (javaSourceTree == null) {
javaSourceTree = task.getSource();
} else {
javaSourceTree = javaSourceTree.plus(task.getSource());
}
}
return excludeOutputDirectory(javaSourceTree);
}
protected abstract FileVisitor getJavaccSourceFileVisitor();
protected FileVisitor getNonJavaccSourceFileVisitor() {
return new NonJavaccSourceFileVisitor(this);
}
public Map getArguments() {
return programArguments;
}
public AbstractJavaccTask setArguments(Map arguments) {
this.programArguments = arguments;
return this;
}
public File getInputDirectory() {
return inputDirectory;
}
@OutputDirectory
public File getOutputDirectory() {
return outputDirectory;
}
public AbstractJavaccTask setInputDirectory(String inputDirectory) {
return setInputDirectory(new File(getProject().getProjectDir(), inputDirectory));
}
public AbstractJavaccTask setInputDirectory(File inputDirectory) {
getLogger().debug("Changing input directory to [{}]", inputDirectory);
this.inputDirectory = inputDirectory;
setSource(inputDirectory);
return this;
}
public AbstractJavaccTask setOutputDirectory(String outputDirectory) {
return setOutputDirectory(new File(getProject().getBuildDir(), outputDirectory));
}
public AbstractJavaccTask setOutputDirectory(File outputDirectory) {
getLogger().debug("Changing output directory to [{}]", outputDirectory);
this.outputDirectory = outputDirectory;
return this;
}
String[] buildProgramArguments(File inputDirectory, RelativePath inputRelativePath) {
Map arguments = new LinkedHashMap();
if (programArguments != null) {
arguments.putAll(programArguments);
}
augmentArguments(inputDirectory, inputRelativePath, arguments);
int index = 0;
String[] commandLineArguments = new String[arguments.size() + 1];
// Add normal arguments
for (Map.Entry entry : arguments.entrySet()) {
commandLineArguments[index++] = String.format("-%1$s=%2$s", entry.getKey(), entry.getValue());
}
// Add file to compile as last command line argument
commandLineArguments[commandLineArguments.length - 1] = inputRelativePath.getFile(inputDirectory).getAbsolutePath();
return commandLineArguments;
}
/**
* Gives a chance to sub-classes to add some required arguments for example, the output directory.
*
* @param inputDirectory
* The input directory from which input relative path is derived.
* @param inputRelativePath
* The input path relative to the input directory. This is the file that will be "compiled".
* @param arguments
* The map to add new arguments to.
*/
protected abstract void augmentArguments(File inputDirectory, RelativePath inputRelativePath, Map arguments);
protected abstract String getProgramName();
protected abstract String supportedSuffix();
}