org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aspectjtools Show documentation
Show all versions of aspectjtools Show documentation
Tools from the AspectJ project
/* *******************************************************************
* Copyright (c) 2003 Contributors.
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v 2.0
* which accompanies this distribution and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
*
* Contributors:
* Wes Isberg initial implementation
* ******************************************************************/
package org.aspectj.tools.ant.taskdefs;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Javac;
import org.apache.tools.ant.taskdefs.compilers.CompilerAdapter;
import org.aspectj.util.FileUtil;
import java.io.File;
//import java.io.FileFilter;
//import java.io.FileWriter;
//import java.io.IOException;
/**
* Adapt ajc to javac commands.
* Note that the srcdirs set for javac are NOT passed on to ajc;
* instead, the list of source files generated is passed to ajc.
*
* Javac usually prunes the source file list based on the timestamps
* of corresponding .class files, which is wrong for ajc which
* requires all the files every time. To work around this,
* set the global property CLEAN ("build.compiler.clean") to delete
* all .class files in the destination directory before compiling.
*
*
* Warnings:
*
* - cleaning will not work if no destination directory
* is specified in the javac task.
* (RFE: find and kill .class files in source dirs?)
* - cleaning will makes stepwise build processes fail
* if they depend on the results of the prior compilation being
* in the same directory, since this deletes all
* .class files.
* - If no files are out of date, then the adapter is never called
* and thus cannot gain control to clean out the destination dir.
*
*
*
* @author Wes Isberg
* @since AspectJ 1.1, Ant 1.5.1
*/
public class Ajc11CompilerAdapter implements CompilerAdapter {
/**
* Define this system/project property to signal that the
* destination directory should be cleaned
* and javac reinvoked
* to get the complete list of files every time.
*/
public static final String CLEAN = "build.compiler.clean";
/** track whether we re-called javac.execute()
*/
private static final ThreadLocal inSelfCall = new ThreadLocal() {
public Boolean initialValue() {
return Boolean.FALSE;
}
};
Javac javac;
public void setJavac(Javac javac) {
this.javac = javac;
javac.setTaskName(javac.getTaskName() + " - ajc");
}
public boolean execute() throws BuildException {
if (null == javac) {
throw new IllegalStateException("null javac");
}
if (!(Boolean) inSelfCall.get()
&& afterCleaningDirs()) {
// if we are not re-calling ourself and we cleaned dirs,
// then re-call javac to get the list of all source files.
inSelfCall.set(Boolean.TRUE);
javac.execute();
// javac re-invokes us after recalculating file list
} else {
try {
AjcTask ajc = new AjcTask();
String err = ajc.setupAjc(javac);
if (null != err) {
throw new BuildException(err, javac.getLocation());
}
ajc.execute();
// handles BuildException for failonerror, etc.
} finally {
inSelfCall.set(Boolean.FALSE);
}
}
return true;
}
/**
* If destDir exists and property CLEAN is set,
* this cleans out the dest dir of any .class files,
* and returns true to signal a recursive call.
* @return true if destDir was cleaned.
*/
private boolean afterCleaningDirs() {
String clean = javac.getProject().getProperty(CLEAN);
if (null == clean) {
return false;
}
File destDir = javac.getDestdir();
if (null == destDir) {
javac.log(
CLEAN + " specified, but no dest dir to clean",
Project.MSG_WARN);
return false;
}
javac.log(
CLEAN + " cleaning .class files from " + destDir,
Project.MSG_VERBOSE);
FileUtil.deleteContents(
destDir,
FileUtil.DIRS_AND_WRITABLE_CLASSES,
true);
return true;
}
}