Logo Search packages:      
Sourcecode: aspectj version File versions

AntBuilder.java

/* *******************************************************************
 * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
 * 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: 
 *     Xerox/PARC     initial implementation 
 * ******************************************************************/
package org.aspectj.internal.tools.ant.taskdefs;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.taskdefs.Javac;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.ZipFileSet;
import org.aspectj.internal.tools.build.BuildSpec;
import org.aspectj.internal.tools.build.Builder;
import org.aspectj.internal.tools.build.Messager;
import org.aspectj.internal.tools.build.Module;
import org.aspectj.internal.tools.build.Result;
import org.aspectj.internal.tools.build.Util;

/**
 * Implement Builder in Ant.
 */
00049 public class AntBuilder extends Builder {
    private static final boolean FORCE_FORK_FOR_LIBRARIES = false;

    /**
     * Factory for a Builder.
     * @param config the String configuration, where only substrings
     *        "verbose" and "useEclipseCompiles" are significant
     * @param project the owning Project for all tasks (not null)
     * @param tempDir the File path to a temporary dir for side effects (may be null)
     * @return a Builder for this project and configuration 
     */
00060     public static Builder getBuilder(String config, Project project, File tempDir) {
        boolean useEclipseCompiles = false;
        boolean verbose = false;        
        if (null != config) {
            if (-1 != config.indexOf("useEclipseCompiles")) {
                useEclipseCompiles = true;
            }
            if (-1 != config.indexOf("verbose")) {
                verbose = true;
            }
        }
        //Messager handler = new Messager(); // debugging
        Messager handler = new ProjectMessager(project);
        Builder result = new ProductBuilder(project, tempDir, useEclipseCompiles, handler);
        if (verbose) {
            result.setVerbose(true);
        }
        return result;
    }
    
    private static String resultToTargetName(Result result) {
        return result.getName();
    }
    /** 
     * Ensure targets exist for this module and all antecedants,
     * so topoSort can work.
     */
00087     private static void makeTargetsForResult(
            final Result result, 
            final Hashtable targets) {
            final String resultTargetName = resultToTargetName(result);
            Target target = (Target) targets.get(resultTargetName);
            if (null == target) {
                // first add the target
                target = new Target();
                target.setName(resultTargetName);
                
                Result[] reqs = result.getRequired();
                StringBuffer depends = new StringBuffer();
                boolean first = true;
                for (int i = 0; i < reqs.length; i++) {
                    Result reqResult = reqs[i];
                    if (!first) {
                        depends.append(",");
                    } else {
                        first = false;
                    }
                    depends.append(resultToTargetName(reqResult));
                }
                if (0 < depends.length()) {
                    target.setDepends(depends.toString());
                }
                targets.put(resultTargetName, target);

                // then recursively add any required results
                for (int i = 0; i < reqs.length; i++) {
                    Result reqResult = reqs[i];
                    makeTargetsForResult(reqResult, targets);
                }                        
            }
        }

    private final Project project;

    protected AntBuilder(Project project, File tempDir, boolean useEclipseCompiles,
        Messager handler) {
        super(tempDir, useEclipseCompiles, handler);
        this.project = project;
        Util.iaxIfNull(project, "project");
    }
    
    /**
     * Initialize task with project and "ajbuild-" + name as name. (Using bm-
     * prefix distinguishes these tasks from tasks found in the build script.)
     * @param task the Task to initialize - not null
     * @param name the String name suffix for the task
     * @return true unless some error
     */
00138     protected boolean setupTask(Task task, String name) {
        task.setProject(project);
        task.setTaskName("ajbuild-" + name);
        return true;
    }
    
    /** 
     * Copy file, optionally filtering.
     * (Filters set in project.)
     * @param fromFile the readable File source to copy
     * @param toFile the writable File destination file
     * @param boolean filter if true, enable filtering
     * @see org.aspectj.internal.tools.build.Builder#copyFile(File, File, boolean)
     */
00152     protected boolean copyFile(File fromFile, File toFile, boolean filter) {
        Copy copy = makeCopyTask(filter);
        copy.setFile(fromFile);
        copy.setTofile(toFile);
        executeTask(copy);
        return true;
    }
    
    /**
     * (Filters set in project.)
      * @see org.aspectj.internal.tools.ant.taskdefs.Builder#copyFiles(File, File, String, String, boolean)
      */
00164     protected boolean copyFiles(
         File fromDir,
         File toDir,
         String includes,
         String excludes,
         boolean filter) {
         Copy copy = makeCopyTask(filter);
         copy.setTodir(toDir);
         FileSet fileset = new FileSet();
         fileset.setDir(fromDir);
         if (null != includes) {
             fileset.setIncludes(includes);
         }
         if (null != excludes) {
             fileset.setExcludes(excludes);
         }
         copy.addFileset(fileset);
         executeTask(copy);
        
         return false;
     }
    
    protected void copyFileset(File toDir, FileSet fileSet, boolean filter) {
        Copy copy = makeCopyTask(filter);
        copy.addFileset(fileSet);
        copy.setTodir(toDir);
        executeTask(copy);
    }
    
    /** 
     * @param filter if FILTER_ON, use filters 
     */
00196     protected Copy makeCopyTask(boolean filter) {
        Copy copy = new Copy();
        setupTask(copy, "copy");
        if (FILTER_ON == filter) {
            copy.setFiltering(true);
        }
        return copy;
    }
    protected void dumpMinFile(Result result,File classesDir, List errors) {
        String name = result.getName() + "-empty";
        File minFile = new File(classesDir, name);
        FileWriter fw = null;
        try {
            fw = new FileWriter(minFile);
            fw.write(name);
        } catch (IOException e) {
            errors.add("IOException writing " 
                + name
                + " to "
                + minFile
                + ": "
                + Util.renderException(e));
        } finally {
            Util.close(fw);
        }
        
    }
00223     protected boolean compile(
        Result result, 
        File classesDir,
        boolean useExistingClasses, 
        List errors) {
        
        if (!classesDir.exists() && !classesDir.mkdirs()) {
            errors.add("compile - unable to create " + classesDir);
            return false;
        }
        if (useExistingClasses) {
            return true;
        }
        // -- source paths
        Path path = new Path(project);
        boolean hasSourceDirectories = false;
        boolean isJava5Compile = false;
        for (Iterator iter = result.getSrcDirs().iterator(); iter.hasNext();) {
            File file = (File) iter.next();
            path.createPathElement().setLocation(file);
            if (!isJava5Compile 
                    && (Util.Constants.JAVA5_SRC.equals(file.getName())
                        || Util.Constants.JAVA5_TESTSRC.equals(file.getName()))) {
                isJava5Compile = true;
            }
            if (!hasSourceDirectories) {
                hasSourceDirectories = true;
            }
        }
        if (!hasSourceDirectories) { 
            return true; // nothing to compile - ok
        }
        // XXX  test whether build.compiler property takes effect automatically
        // I suspect it requires the proper adapter setup.
        Javac javac = new Javac(); 
        setupTask(javac, "javac");
        javac.setIncludeantruntime(false);
        javac.setDestdir(classesDir);
        javac.setSrcdir(path);
        javac.setVerbose(verbose);
        path = null;
        
        // -- classpath
        Path classpath = new Path(project);
        boolean hasLibraries = setupClasspath(result, classpath);
        if (hasLibraries && FORCE_FORK_FOR_LIBRARIES) {
            javac.setFork(true); // otherwise never releases library jars            
            // can we build under 1.4, but fork javac 1.5 compile?
        }
        // also fork if using 1.5?
        
        // -- set output directory
        classpath.createPathElement().setLocation(classesDir);
        javac.setClasspath(classpath);

        // misc
        javac.setDebug(true);
        if (!isJava5Compile) {
            javac.setTarget("1.1"); // 1.1 class files - Javac in 1.4 uses 1.4            
            javac.setSource("1.3");
        } else {
            javac.setSource("1.5");
            javac.setTarget("1.5");
        }
        // compile
        boolean passed = false;
        BuildException failure = null;
        try {
            passed = executeTask(AspectJSupport.wrapIfNeeded(result, javac));
        } catch (BuildException e) {
            failure = e;
        } catch (Error e) {
            failure = new BuildException(e);
        } catch (RuntimeException e) {
            failure = new BuildException(e);
        } finally {
            if (!passed) {
                String args = "" + Arrays.asList(javac.getCurrentCompilerArgs());
                if ("[]".equals(args)) {
                    args = "{" + result.toLongString() + "}";
                }
                String m = "BuildException compiling " + result.toLongString() + args 
                    + (null == failure? "" : ": " + Util.renderException(failure));
                //debuglog System.err.println(m);
                errors.add(m);
            }
            javac.init(); // be nice to let go of classpath libraries...
        }
        return passed;
    }
    
    public boolean setupClasspath(Result result, Path classpath) { // XXX fix test access
        boolean hasLibraries = false;
        // required libraries
        for (Iterator iter = result.getLibJars().iterator(); iter.hasNext();) {
            File file = (File) iter.next();            
            classpath.createPathElement().setLocation(file);
            if (!hasLibraries) {
                hasLibraries = true;
            }
        }
//      Westodo        Kind kind = result.getKind();
        Result[] reqs = result.getRequired();
        // required modules and their exported libraries
        for (int i = 0; i < reqs.length; i++) {
            Result requiredResult = reqs[i];
            classpath.createPathElement().setLocation(requiredResult.getOutputFile());
            if (!hasLibraries) {
                hasLibraries = true;
            }
            // also put on classpath libraries exported from required module
            // XXX exported modules not supported
            for (Iterator iterator = requiredResult.getExportedLibJars().iterator();
                iterator.hasNext();
                ) {
                classpath.createPathElement().setLocation((File) iterator.next());
            }
        }
        return hasLibraries;
    }
    
    /**
     * Merge classes directory and any merge jars into module jar
     * with any specified manifest file.  
     * META-INF directories are excluded.
     */
00349     protected boolean assemble(Result result, File classesDir, List errors) {
        if (!buildingEnabled) {
            return false;
        }
        if (!result.outOfDate()) {
            return true;
        }

        // ---- zip result up
        Zip zip = new Zip();
        setupTask(zip, "zip");
        zip.setDestFile(result.getOutputFile());
        ZipFileSet zipfileset = null;
        
        // -- merge any resources in any of the src directories
        for (Iterator iter = result.getSrcDirs().iterator(); iter.hasNext();) {
            File srcDir = (File) iter.next();
            zipfileset = new ZipFileSet();
            zipfileset.setProject(project);
            zipfileset.setDir(srcDir);
            zipfileset.setIncludes(RESOURCE_PATTERN);
            zip.addZipfileset(zipfileset);
        }
        
        final Module module = result.getModule();

        File metaInfDir = new File(classesDir, "META-INF");
        Util.deleteContents(metaInfDir);

        // -- manifest
        File manifest = new File(module.moduleDir, module.name + ".mf.txt");  // XXXFileLiteral
        if (Util.canReadFile(manifest)) {
            if (Util.canReadDir(metaInfDir) || metaInfDir.mkdirs()) {
                        // Jar spec requires a MANIFEST.MF not a manifest.mf
                        copyFile(manifest, new File(metaInfDir, "MANIFEST.MF"), FILTER_ON);  // XXXFileLiteral
            } else {
                errors.add("have manifest, but unable to create " + metaInfDir);
                return false;
            }
        }        

        zipfileset = new ZipFileSet();
        zipfileset.setProject(project);
        zipfileset.setDir(classesDir);
        zipfileset.setIncludes("**/*");
        zip.addZipfileset(zipfileset);
        File[] contents = classesDir.listFiles();
        if ((null == contents) || (0 == contents.length)) {
            // *something* to zip up
            dumpMinFile(result, classesDir,errors);
        }

        try {
            handler.log("assemble " + module  + " in " + result.getOutputFile());
            return executeTask(zip)
                // zip returns true when it doesn't create zipfile
                // because there are no entries to add, so verify done
                && Util.canReadFile(result.getOutputFile());
        } catch (BuildException e) {
            errors.add("BuildException zipping " + module + ": " + e.getMessage());
            return false;
        } finally {
            result.clearOutOfDate();
        }
    }
    /**
       * @see org.aspectj.internal.tools.build.Builder#buildAntecedants(Module)
       */
00417       protected Result[] getAntecedantResults(Result moduleResult) {
        Hashtable targets = new Hashtable();
        makeTargetsForResult(moduleResult, targets);   
        String targetName = resultToTargetName(moduleResult);
        // bug: doc says topoSort returns String, but returns Target 
        Collection result = project.topoSort(targetName, targets);
        // fyi, we don't rely on topoSort to detect cycles - see buildAll
        int size = result.size();
        if (0 == result.size()) {
            return new Result[0];
        }
        ArrayList toReturn = new ArrayList();
        for (Iterator iter = result.iterator(); iter.hasNext();) {
            Target target = (Target) iter.next();
            String name = target.getName();
            if (null == name) {
                throw new Error("null name?");
            } else {
                toReturn.add(name);
            }
        }
        // topoSort always returns target name    
        if ((1 == size) 
            && targetName.equals(toReturn.get(0))
            && !moduleResult.outOfDate()) {
            return new Result[0];
        }
        return Result.getResults((String[]) toReturn.toArray(new String[0]));
    }
        
    /**
     * Generate Module.assembledJar with merge of itself and all antecedants
     */                    
00450     protected boolean assembleAll(Result result, Messager handler) {
        if (!buildingEnabled) {
            return false;
        }
        if (!result.outOfDate()) {
            return true;
        }
        
        Util.iaxIfNull(result, "result");
        Util.iaxIfNull(handler, "handler");
        if (!result.getKind().isAssembly()) {
            throw new IllegalStateException("not assembly: " + result);
        }
        
        // ---- zip result up
        Zip zip = new Zip();
        setupTask(zip, "zip");
        zip.setDestFile(result.getOutputFile());
        ZipFileSet zipfileset = null;
        final Module module = result.getModule();
        List known = result.findJarRequirements();
        removeLibraryFilesToSkip(module, known);
        // -- merge any antecedents, less any manifest
        for (Iterator iter = known.iterator(); iter.hasNext();) {
            File jarFile = (File) iter.next();
            zipfileset = new ZipFileSet();
            zipfileset.setProject(project);
            zipfileset.setSrc(jarFile);
            zipfileset.setIncludes("**/*");
            String name = jarFile.getName();
            name = name.substring(0, name.length()-4); // ".jar".length()
            // required includes self - exclude manifest from others
            if (!module.name.equals(name)) {
                zipfileset.setExcludes("META-INF/MANIFEST.MF");  // XXXFileLiteral
                zipfileset.setExcludes("META-INF/manifest.mf");
                zipfileset.setExcludes("meta-inf/manifest.mf");
                zipfileset.setExcludes("meta-inf/MANIFEST.MF");
            }
            zip.addZipfileset(zipfileset);
        }

        try {
            handler.log("assembling all " + module
                    + " in " + result.getOutputFile());
            if (verbose) {
                  handler.log("knownAntecedants: " + known);
            }
            return executeTask(zip);
        } catch (BuildException e) {
            handler.logException("BuildException zipping " + module, e);
            return false;
        } finally {
            result.clearOutOfDate();
        }
    }

    /**
       * @see org.aspectj.internal.tools.ant.taskdefs.Builder#buildInstaller(BuildSpec, String)
       */
00509       protected boolean buildInstaller(
            BuildSpec buildSpec,
            String targDirPath) {
            return false;
      }
    
    /** task.execute() and any advice */
00516     protected boolean executeTask(Task task) {
        if (!buildingEnabled) {
            return false;
        }
        task.execute();
        return true;
    }
    /**
     * Support for compiling basic AspectJ projects.
     * Projects may only compile all (and only) their source directories;
     * aspectpath, inpath, etc. are not supported.
     * To load the compiler, this assumes the user has either defined 
     * a project property "aspectj.home" or that there exists 
     * <code>{module-dir}/lib/aspectj/lib/aspectj[tools|rt].jar</code>.
     */
00531     static class AspectJSupport {
        static final String AJCTASK = "org.aspectj.tools.ant.taskdefs.AjcTask";
        static final String ASPECTJRT_JAR_VARIABLE = "ASPECTJRT_LIB";
        static final String LIBASPECTJ_RPATH = "/lib/aspectj";
        static final Map nameToAspectjrtjar = new HashMap();
        static final String NONE = "NONE";
        
        /**
         * If this module should be compiled with AspectJ,
         * return a task to do so.
         * @param module the Module to compile
         * @param javac the Javac compile commands
         * @return javac or a Task to compile with AspectJ if needed
         */
00545         static Task wrapIfNeeded(Result result, Javac javac) {
            final Project project = javac.getProject();
            Path runtimeJar = null;
            final Module module = result.getModule();
            if (runtimeJarOnClasspath(result)) { 
                // yes aspectjrt.jar on classpath
            } else if (result.getClasspathVariables().contains(ASPECTJRT_JAR_VARIABLE)) {
                // yes, in variables - find aspectjrt.jar to add to classpath
                runtimeJar = getAspectJLib(project, module, "aspectjrt.jar");
            } else {
                // no
                //System.out.println("javac " + result + " " + javac.getClasspath()); 
                return javac;
            }
            //System.out.println("aspectj " + result + " " + javac.getClasspath()); 
            Path aspectjtoolsJar = getAspectJLib(project, module, "aspectjtools.jar");
            return aspectJTask(javac, aspectjtoolsJar, runtimeJar);
        }
        
        /** @return true if aspectjrt.jar is on classpath */
00565         private static boolean runtimeJarOnClasspath(Result result) {
            for (Iterator iter = result.getLibJars().iterator(); iter.hasNext();) {
                File file = (File) iter.next();
                if ("aspectjrt.jar".equals(file.getName())) {
                    return true;
                }
            }
            return false;
        }

        static Path getAspectJLib(Project project, Module module, String name) {
            Path result = null;
            String[] libDirNames = { "aspectj.home", "ASPECTJ_HOME", LIBASPECTJ_RPATH};
            String[] libDirs = new String[libDirNames.length];
            for (int i = 0; i < libDirNames.length; i++) {
                if (LIBASPECTJ_RPATH == libDirNames[i]) {
                    libDirs[i] = module.getFullPath(LIBASPECTJ_RPATH);
                } else {
                    libDirs[i] = project.getProperty(libDirNames[i]);
                }
                if (null != libDirs[i]) {
                    libDirs[i] = Util.path(libDirs[i], "lib");
                    result = new Path(project, Util.path(libDirs[i], name));
                    String path = result.toString();
                    if (new File(path).canRead()) {
                        return result;
                    }
                }                
            }
            String m = "unable to find " + name + " in " + Arrays.asList(libDirs);
            throw new BuildException(m);
        }
                
        
        /**
         * Wrap AspectJ compiler as Task.
         * Only works for javac-like source compilation of everything 
         * under srcDir.
         * Written reflectively to compile in the build module,
         * which can't depend on the whole tree.
         * @param javac the Javac specification
         * @param toolsJar the Path to the aspectjtools.jar 
         * @param runtimeJar the Path to the aspectjrt.jar 
         * @return javac or another Task invoking the AspectJ compiler
         */
00610         static Task aspectJTask(Javac javac, Path toolsJar, Path runtimeJar) {        
            Object task = null;
            String url = null;
            try {
                url = "file:" + toolsJar.toString().replace('\\', '/');
                URL[] cp = new URL[] {new URL(url)};
                ClassLoader parent = Task.class.getClassLoader();
                ClassLoader loader = new URLClassLoader(cp, parent);
                Class c = loader.loadClass(AJCTASK);
                task = c.newInstance();
//              Westodo                Project project = javac.getProject();
                Method m = c.getMethod("setupAjc", new Class[] {Javac.class});
                m.invoke(task, new Object[] {javac});
                m = c.getMethod("setFork", new Class[] {boolean.class});
                m.invoke(task, new Object[] {Boolean.TRUE});
                m = c.getMethod("setForkclasspath", new Class[] {Path.class});
                m.invoke(task, new Object[] {toolsJar});
                m = c.getMethod("setSourceRoots", new Class[] {Path.class});
                m.invoke(task, new Object[] {javac.getSrcdir()});
                if (null != runtimeJar) {
                    m = c.getMethod("setClasspath", new Class[] {Path.class});
                    m.invoke(task, new Object[] {runtimeJar});
                }
            } catch (BuildException e) {
                throw e;
            } catch (Throwable t) {
                StringBuffer sb = new StringBuffer();
                sb.append("classpath=");
                sb.append(url);
                throw new BuildException(sb.toString(), t);
            }
            return (Task) task;
        }
        private AspectJSupport() {throw new Error("no instances");}
    }
}

     
// finally caught by failing to comply with proper ant initialization
//  /**
//   * Build a module that has a build script.
//   * @param buildSpec the module to build
//   * @param buildScript the script file
//     * @throws BuildException if build fails
//   */
//  private void buildByScript(BuildSpec buildSpec, File buildScript) 
//        throws BuildException {
//      Ant ant = new Ant();
//        ant.setProject(getProject());
//        ant.setAntfile(buildScript.getAbsolutePath());
//        ant.setDescription("building module " + buildSpec.module);
//        ant.setDir(buildScript.getParentFile());
//        ant.setInheritAll(true);
//        ant.setInheritRefs(false);
//        ant.setLocation(getLocation());
//        ant.setOwningTarget(getOwningTarget());
//        // by convention, for build.xml, use module name to publish
//        ant.setTarget(buildSpec.module);
//        ant.setTaskName("ant");
//        loadAntProperties(ant, buildSpec);
//        ant.execute();
//     }
//     
//     /** override definitions */
//     private void loadAntProperties(Ant ant, BuildSpec buildSpec) {
//        Property property = ant.createProperty();
//        property.setName(BuildSpec.baseDir_NAME);
//        property.setFile(buildSpec.baseDir);
//        property = ant.createProperty();
//        property.setName(buildSpec.distDir_NAME);
//        property.setFile(buildSpec.distDir);
//        property = ant.createProperty();
//        property.setName(BuildSpec.tempDir_NAME);
//        property.setFile(buildSpec.tempDir);
//        property = ant.createProperty();
//        property.setName(BuildSpec.jarDir_NAME);
//        property.setFile(buildSpec.jarDir);        
//        property = ant.createProperty();
//        property.setName(BuildSpec.stagingDir_NAME);
//        property.setFile(buildSpec.stagingDir);        
//    }


/** 
 * Segregate product-building API's from module-building APIs for clarity.
 * These are called by the superclass if the BuildSpec warrants. 
 * XXX extremely brittle/arbitrary assumptions.
 * @see BuildModule for assumptions
 */
00699 class ProductBuilder extends AntBuilder {

    private static String getProductInstallResourcesSrc(BuildSpec buildSpec) {
        final String resourcesName = "installer-resources";  // XXXFileLiteral
        File dir = buildSpec.productDir.getParentFile();
        if (null == dir) {
            return Util.path(new String[] {"..", "..", resourcesName});
        } 
        dir = dir.getParentFile();
        if (null == dir) {
            return Util.path("..", resourcesName);
        } else {
            dir = new File(dir, resourcesName);
            return dir.getPath();
        }
    }

    private static String getProductInstallerFileName(BuildSpec buildSpec) {   // XXXFileLiteral
        return "aspectj-" 
            + buildSpec.productDir.getName()
            + "-"
            + Util.shortVersion(buildSpec.version)
            + ".jar"; 
    }
    
   /**
     * Calculate name of main, typically InitialCap, and hence installer class.
     * @return $$installer$$.org.aspectj." + ProductName + "Installer" 
     */
     
00729     private static String getProductInstallerMainClass(BuildSpec buildSpec) {
        String productName = buildSpec.productDir.getName();
        String initial = productName.substring(0, 1).toUpperCase();
        productName = initial + productName.substring(1);
        return "$installer$.org.aspectj." + productName + "Installer";   // XXXNameLiteral
    }
    
    /** @see Builder.getBuilder(String, Project, File) */
00737     ProductBuilder(
        Project project, 
        File tempDir, 
        boolean useEclipseCompiles,
        Messager handler) {
        super(project, tempDir, useEclipseCompiles, handler);
    }
    
    /**
     * Delegate for super.buildProduct(..) template method.
     */
00748     protected boolean copyBinaries(BuildSpec buildSpec, File distDir, File targDir, String excludes) {
        Copy copy = makeCopyTask(false);
        copy.setTodir(targDir);
        FileSet fileset = new FileSet();
        fileset.setDir(distDir);
        fileset.setIncludes(Builder.BINARY_SOURCE_PATTERN);
        if (null != excludes) {
            fileset.setExcludes(excludes);
        }
        copy.addFileset(fileset);
        return executeTask(copy);
    }

    /**
     * Delegate for super.buildProduct(..) template method.
     */
00764     protected boolean copyNonBinaries(BuildSpec buildSpec, File distDir, File targDir) {
        // filter-copy everything but the binaries
        Copy copy = makeCopyTask(true);
        copy.setTodir(targDir);
        Util.iaxIfNotCanReadDir(distDir, "product dist directory");
        FileSet fileset = new FileSet();
        fileset.setDir(distDir);
        fileset.setExcludes(Builder.BINARY_SOURCE_PATTERN);
        copy.addFileset(fileset);
        return executeTask(copy);
    }
    
00776     protected boolean buildInstaller(BuildSpec buildSpec, String targDirPath) {
        if (buildSpec.verbose) {
            handler.log("creating installer for " + buildSpec);
        }
        AJInstaller installer = new AJInstaller();
        setupTask(installer, "installer");
        installer.setBasedir(targDirPath);
        //installer.setCompress();
        File installSrcDir = new File(buildSpec.productDir, "install");   // XXXFileLiteral
        Util.iaxIfNotCanReadDir(installSrcDir, "installSrcDir");            
        installer.setHtmlSrc(installSrcDir.getPath());
        String resourcePath = getProductInstallResourcesSrc(buildSpec);
        File resourceSrcDir = new File(resourcePath);
        Util.iaxIfNotCanReadDir(resourceSrcDir, "resourceSrcDir");                        
        installer.setResourcesSrc(resourcePath);
        String name = getProductInstallerFileName(buildSpec);
        File outFile = new File(buildSpec.jarDir, name);
        installer.setZipfile(outFile.getPath());
        installer.setMainclass(getProductInstallerMainClass(buildSpec));
        installer.setInstallerclassjar(getBuildJar(buildSpec));
        return executeTask(installer);
        
        // -- test installer XXX
        // create text setup file
        // run installer with setup file
        // cleanup installed product
    }
    
    private String getBuildJar(BuildSpec buildSpec) {
        return buildSpec.baseDir.getPath() 
            + "/lib/build/build.jar" ; // XXX
    }
    
//    private Module moduleForReplaceFile(File replaceFile, Modules modules) {
//        String jarName = moduleAliasFor(replaceFile.getName().toLowerCase());
//        if (jarName.endsWith(".jar") || jarName.endsWith(".zip")) {   // XXXFileLiteral
//            jarName = jarName.substring(0, jarName.length()-4);
//        } else {
//            throw new IllegalArgumentException("can only replace .[jar|zip]");
//        }
//        boolean assembleAll = jarName.endsWith("-all");
//        String name = (!assembleAll ? jarName : jarName.substring(0, jarName.length()-4));
//        return modules.getModule(name);
//    }
//    
}


class ProjectMessager extends Messager {
    private final Project project;
    public ProjectMessager(Project project) {
        Util.iaxIfNull(project, "project");
        this.project = project;
    }
    
    public boolean log(String s) {
        project.log(s);
        return true;
    }
    public boolean error(String s) {
        project.log(s, Project.MSG_ERR);
        return true;
    }
    public boolean logException(String context, Throwable thrown) {
        project.log(context + Util.renderException(thrown), Project.MSG_ERR);
        return true;
    }

}

Generated by  Doxygen 1.6.0   Back to index