org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter Maven / Gradle / Ivy
Show all versions of aspectjtools Show documentation
/* *******************************************************************
* Copyright (c) 2003 Contributors.
* 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:
* 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 Object 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()).booleanValue()
&& 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;
}
}