All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aspectj.tools.ant.taskdefs.Ajc2 Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/* *******************************************************************
 * 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) {
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy