org.aspectj.tools.ant.taskdefs.Ajc2 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) 2000-2001 Xerox Corporation.
* 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:
* Xerox/PARC initial implementation
* ******************************************************************/
package org.aspectj.tools.ant.taskdefs;
import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;
import org.apache.tools.ant.taskdefs.*;
import org.apache.tools.ant.util.JavaEnvUtils;
import java.io.*;
import java.util.List;
import java.util.ArrayList;
import java.util.StringTokenizer;
/**
* Ant task for the AspectJ compiler -- AJC.
* List (.lst) files are passed in as includes.
*
* This task was developed by the AspectJ Project
*
* @author Jeffrey Palm
* @see org.aspectj.tools.ant.taskdefs.compilers.Ajc
*/
public class Ajc2 extends Javac {
/**
* The name of the adapter we use.
*/
public final static String ADAPTER_CLASS =
"org.aspectj.tools.ant.taskdefs.compilers.Ajc";
/* ----------------------------------------------------------------------
* Attribute members
* ----------------------------------------------------------------------
*/
/**
* How many concurrent threads to use for compilation,
* defaults to 0 -- multi-threading disabled.
*/
private Integer threads;
/**
* Don't generate any comments into the woven code.
*/
private boolean nocomments;
/**
* Don't generate .ajsym or .ajsline files.
*/
private boolean nosymbols;
/**
* Generate regular Java code into .
*/
private boolean preprocess;
/**
* Specify where to place intermediate .java files
* defaults to ./ajworkingdir.
*/
private File workingdir;
/**
* The file is a line-delimited list of arguments
* these arguments are inserted into the argument list
*/
private List argfiles;
/* ----------------------------------------------------------------------
* Misc. members
* ----------------------------------------------------------------------
*/
/**
* Whether we have used the excludes
attribute.
*/
private boolean haveExcludes = false;
/**
* Whether we have used the includes
attribute.
*/
private boolean haveIncludes = false;
/**
* Whether we have used the excludes
attribute.
* @return Whether we have used the excludes
attribute.
*/
protected boolean hasExcludes() {
return haveExcludes;
}
/**
* Whether we have used the includes
attribute.
* @return Whether we have used the includes
attribute.
*/
protected boolean hasIncludes() {
return haveIncludes;
}
/* ----------------------------------------------------------------------
* Attribute access methods
* ----------------------------------------------------------------------
*/
/**
* Sets the number of threads.
*
* @param threads the number of threads.
* @see Ajc2#threads
*/
public void setThreads(Integer threads) {
this.threads = threads;
}
/**
* Returns the number of threads.
*
* @return the number of threads.
* @see Ajc2#threads
*/
public Integer getThreads() {
return threads;
}
/**
* Set the -nocomments
flag.
*
* @param nocomments true turns on the flag.
* @see Ajc2#nocomments
*/
public void setNocomments(boolean nocomments) {
this.nocomments = nocomments;
}
/**
* Returns if the -nocomments
flag is turned on.
*
* @return true
if the -nocomments
flag is on.
* @see Ajc2#nocomments
*/
public boolean getNocomments() {
return nocomments;
}
/**
* Set the -nosymbols
flag.
*
* @param nosymbols true turns on the flag.
* @see Ajc2#nosymbols
*/
public void setNosymbols(boolean nosymbols) {
this.nosymbols = nosymbols;
}
/**
* Returns if the -nosymbols
flag is turned on.
*
* @return true
if the -nosymbols
flag is on.
* @see Ajc2#nosymbols
*/
public boolean getNosymbols() {
return nosymbols;
}
/**
* Set the -preprocess
flag.
*
* @param preprocess true
turns on the -preprocess
flag.
* @see Ajc2#preprocess
*/
public void setPreprocess(boolean preprocess) {
this.preprocess = preprocess;
}
/**
* Returns if the -preprocess
flag is turned on.
*
* @return true
if the -preprocess
flag is on.
* @see Ajc2#preprocess
*/
public boolean getPreprocess() {
return preprocess;
}
/**
* Sets the workingdir.
*
* @param workingdir the new workingdir.
* @see Ajc2#workingdir
*/
public void setWorkingdir(File workingdir) {
this.workingdir = workingdir;
}
/**
* Returns the current workingdir.
*
* @return the current workingdir.
* @see Ajc2#workingdir
*/
public File getWorkingdir() {
return workingdir;
}
/**
* Sets the the argument files by the comma-delimited String passed in.
*
* @param argfiles comma-delimited String contained argument files.
*/
public void setArgfiles(String argfiles) {
StringTokenizer tok = new StringTokenizer(argfiles, ",");
while (tok.hasMoreTokens()) {
File argfile = project.resolveFile(tok.nextToken());
if (argfile != null && argfile.exists() && !argfile.isDirectory()) {
createArgfile().setFile(argfile);
}
}
}
/**
* Creates a nested Argfile
, add it to the list
* argfiles
, and returns the new Argfile
* instance.
*
* @return a new Argfile
instance.
*/
public Argfile createArgfile() {
Argfile argfile = new Argfile();
if (argfiles == null) {
argfiles = new ArrayList<>();
}
argfiles.add(argfile);
return argfile;
}
/**
* Returns the java.util.List of argfiles.
* This could be null
.
*
* @return the list of argfiles.
*/
public List getArgfiles() {
return argfiles;
}
/**
* A simple class with one member -- file
-- that
* represents an argument file.
*/
public static class Argfile {
private File file;
public void setFile(File file) { this.file = file; }
public File getFile() { return file; }
public String toString() { return file.getAbsolutePath(); }
}
/* ----------------------------------------------------------------------
* Misc. methods
* ----------------------------------------------------------------------
*/
/* Leaving the includes blank in the Javac task defaults to including all.
* In Ajc, if the user specifies an argfile, but leaves the includes and
* excludes blank that person probably meant to just includes to argfile.
* So, we keep track of whether includes and/or excludes have been explicitly
* used with the have{In,Ex}cludes members, and setting these flags
* in the create... and set... methods.
*
* When constructing the compileList, if both haveIncludes and haveExcludes
* are false, but the user has specified an argfile, then we set includes
* to '!**' before adding the contents of the argfile.
*/
/**
* Override Javac.createInclude() to set haveIncludes
* to true
.
*
* @return new PatternSet.NameEntry to be added to the include list.
* @see org.apache.tools.ant.taskdefs.Javac#createInclude()
*/
public PatternSet.NameEntry createInclude() {
haveIncludes = true;
return super.createInclude();
}
/**
* Override Javac.createExclude() to set haveExcludes
* to true
.
*
* @return new PatternSet.NameEntry to be added to the exclude list.
* @see org.apache.tools.ant.taskdefs.Javac#createExclude()
*/
public PatternSet.NameEntry createExclude() {
haveExcludes = true;
return super.createExclude();
}
/**
* Override Javac.setIncludes(String) to set haveIncludes
* to true
.
*
* @param includes Comma-separated list of includes.
* @see org.apache.tools.ant.taskdefs.Javac#setIncludes(java.lang.String)
*/
public void setIncludes(String includes) {
haveIncludes = true;
super.setIncludes(includes);
}
/**
* Override Javac.setExcludes(String) to set haveExcludes
* to true
.
*
* @param excludes Comma-separated list of excludes.
* @see org.apache.tools.ant.taskdefs.Javac#setExcludes(java.lang.String)
*/
public void setExcludes(String excludes) {
haveExcludes = true;
super.setExcludes(excludes);
}
public String getAdapterClass() {
return ADAPTER_CLASS;
}
public final void execute() throws BuildException {
prepare();
executeAfterPrepare();
}
/**
* Executes by first setting the build.compiler
property
* to AjcCompiler, then invokes the super.execute() method.
*
* @throws org.apache.tools.ant.BuildException
* @see org.apache.tools.ant.taskdefs.Javac#execute()
*/
public void executeAfterPrepare() throws BuildException {
// Save the old build.compiler property
String oldBuildCompiler = project.getProperty("build.compiler");
// If oldBuildCompiler is null try to resolve it
if (oldBuildCompiler == null) {
String javaVersion = JavaEnvUtils.getJavaVersion();
if (javaVersion.equals(JavaEnvUtils.JAVA_1_0)) {
// Cannot happen
} else if (javaVersion.equals(JavaEnvUtils.JAVA_1_1)) {
oldBuildCompiler = "classic";
} else if (javaVersion.equals(JavaEnvUtils.JAVA_1_2)) {
oldBuildCompiler = "classic";
} else if (javaVersion.equals(JavaEnvUtils.JAVA_1_3)) {
oldBuildCompiler = "modern";
}
}
// Set the new adapter
project.setProperty("build.compiler", getAdapterClass());
BuildException caught = null;
try {
super.execute();
} catch (BuildException be) {
caught = be;
} finally {
// Reset to the old compiler
if (oldBuildCompiler != null) {
project.setProperty("build.compiler", oldBuildCompiler);
}
}
// If we caught an exception executing throw it
if (caught != null) {
throw caught;
}
}
/**
* Guaranteed to be called before doing real execute.
*/
public void prepare() {
if (argfiles != null && !haveIncludes &&
!haveExcludes && getSrcdir() == null) {
useDefaultSrcdir();
}
}
protected final void useDefaultSrcdir() {
setSrcdir(new Path(project, "."));
}
/**
* Overrides Javac.scanDir(..) so that it doesn't check dependencies.
*
* @see org.apache.tools.ant.taskdefs.Javac#scanDir
*/
protected void scanDir(File srcDir, File destDir, String files[]) {
List newFiles = new ArrayList<>();
// Add the files listed in the argfiles to the includes
List newIncludes = new ArrayList<>();
List newArguments = new ArrayList<>();
if (argfiles != null) {
for (Argfile o : argfiles) {
File argfile = o.getFile();
expandArgfile(argfile, newIncludes, newArguments);
}
}
// If there aren't any includes, but we've used an argfile then we should
// set the includes to be the one's found in newIncludes
// If we do this, we need to re-read files from the directory scanner
if (!haveIncludes && !haveExcludes && argfiles != null) {
log("Setting includes to '!**'", Project.MSG_VERBOSE);
setIncludes("!**");
//files = getDirectoryScanner(srcDir).getIncludedFiles();
}
// Otherwise we want to add all .java files to the compileList
else {
for (String file : files) {
File newFile = new File(srcDir, file);
if (newFile != null &&
newFile.exists() &&
newFile.getName().endsWith(".java")) {
newFiles.add(newFile);
}
}
}
// Add the new included files
for (File newInclude : newIncludes) {
newFiles.add(newInclude);
}
// This is the same behavior found in Javac
int newFileSize = newFiles.size();
if (newFileSize > 0) {
File[] newCompileList = new File[compileList.length + newFileSize];
System.arraycopy(compileList, 0, newCompileList, 0, compileList.length);
System.arraycopy(newFiles.toArray(), 0, newCompileList,
compileList.length, newFileSize);
compileList = newCompileList;
}
}
private void expandArgfile(File argfile, List includes, List arguments) {
log("argfile:" + argfile, Project.MSG_VERBOSE);
// All paths are relative to the parent
File parent = argfile.getParentFile();
// Sanity check
if (parent == null || !parent.isDirectory()) {
return;
}
// Read the file
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(argfile));
String line;
while ((line = in.readLine()) != null) {
line = line.trim();
// Skip blank lines
if ("".equals(line)) {
continue;
}
// Allow '#' and '//' line comments
int isharp = line.indexOf("#");
if (isharp != -1) {
line = line.substring(0, isharp);
}
// int istar = -1;
// Argument
if (line.startsWith("-")) {
arguments.add(line);
}
// If there are stars we'll try to resolve the file here
else if (line.contains("*")) {
log("The argfile line '" + line + "' is invalid",
Project.MSG_WARN);
}
// Another argfile
else if (line.startsWith("@")) {
String newArgfileName = line.substring(1);
File newArgfile = new File(parent, newArgfileName);
expandArgfile(newArgfile, includes, arguments);
}
// Source file
else {
File newfile = new File(line);
if (!newfile.isAbsolute()) {
newfile = new File(parent, line);
}
if (newfile != null && newfile.exists() &&
!newfile.isDirectory() &&
newfile.getName().endsWith(".java")) {
includes.add(newfile);
}
}
}
} catch (IOException ioe) {
log("trouble with argfile: " + argfile + ":" + ioe, Project.MSG_ERR);
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException ioe2) {
}
}
}
}