package org.eclipse.ant.core;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */

/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Ant", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import org.apache.tools.ant.*;
import org.apache.tools.ant.taskdefs.Property;
import org.apache.tools.ant.taskdefs.Ant;
import org.apache.tools.ant.util.FileUtils;
import java.io.*;
import java.util.*;

/**
 * Call Ant in a sub-project.
 * This is a bulk copy of the original Ant task.  Unfortunately the original
 * created a new Project in which to run Ant.  This prevents people from
 * providing their own kind of Project and having that propogate into
 * the subprojects.
 * <p>
 * <b>Note:</b> This class/interface is part of an interim API that is still under 
 * development and expected to change significantly before reaching stability. 
 * It is being made available at this early stage to solicit feedback from pioneering 
 * adopters on the understanding that any code that uses this API will almost 
 * certainly be broken (repeatedly) as the API evolves.
 * </p>
 */
public class EclipseAnt extends Ant {

    /** the basedir where is executed the build file */
    private File dir = null;
    
    /** the build.xml file (can be absolute) in this case dir will be ignored */
    private String antFile = null;
    
    /** the target to call if any */
    private String target = null;
    
    /** the output */
    private String output = null;
    
    /** should we inherit properties from the parent ? */
    private boolean inheritAll = true;
    
    /** the properties to pass to the new project */
    private Vector properties = new Vector();
    
    /** the temporary project created to run the build file */
    private Project newProject;

	private final static String DEFAULT_ANTFILE = "build.xml";

/**
 * Creates and returns a new <code>Property</code> for the receiver's
 * target project.
 * 
 * @return the new property
 */
public Property createProperty() {
    if (newProject == null) {
        reinit();
    }
    Property p=(Property)newProject.createTask("property");
    p.setUserProperty(true);
    properties.addElement( p );
    return p;
}

/**
 * Performs the execution.
 * 
 * @exception BuildException thrown if an execution problem occurs
 */
public void execute() throws BuildException {
    try {
        if (newProject == null) {
            reinit();
        }
    
        if (dir == null) {
            dir = project.getBaseDir();
        }

        initializeProject();

        newProject.setBaseDir(dir);
        newProject.setUserProperty("basedir" , dir.getAbsolutePath());
        
        // Override with local-defined properties
        Enumeration e = properties.elements();
        while (e.hasMoreElements()) {
            Property p=(Property) e.nextElement();
            p.execute();
        }
        
        if (antFile == null){
            antFile = DEFAULT_ANTFILE;
        }

        File file = FileUtils.newFileUtils().resolveFile(dir, antFile);
        antFile = file.getAbsolutePath();

        newProject.setUserProperty( "ant.file" , antFile );
        ProjectHelper.configureProject(newProject, new File(antFile));
        
        if (target == null) {
            target = newProject.getDefaultTarget();
        }

        // Are we trying to call the target in which we are defined?
        if (newProject.getBaseDir().equals(project.getBaseDir()) &&
            newProject.getProperty("ant.file").equals(project.getProperty("ant.file")) &&
            getOwningTarget() != null &&
            target.equals(this.getOwningTarget().getName())) { 

            throw new BuildException(Policy.bind("exception.antTaskCallingParentTarget"));
        }

        newProject.executeTarget(target);
    } finally {
        // help the gc
        newProject = null;
    }
}

/**
 * Initializes the receiver.
 */
public void init() {
	// This method used to create a Project, not an EclipseProject.
	// It has been changed so that it is possible to use Eclipse Ant tasks (such as eclipse.refreshLocal)
	// in Ant scripts called by through an "ant" task. Indeed, only an EclipseProject knows how to find them.
	// We need to check that it doesn't introduce new bugs.
	newProject = new EclipseProject();
	newProject.setJavaVersionProperty();
	newProject.addTaskDefinition("property", 
                         (Class)project.getTaskDefinitions().get("property"));
}

/**
 * Initializes the target project.
 */
private void initializeProject() {
    Vector listeners = project.getBuildListeners();
    for (int i = 0; i < listeners.size(); i++) {
        newProject.addBuildListener((BuildListener)listeners.elementAt(i));
    }

    if (output != null) {
        try {
            PrintStream out = new PrintStream(new FileOutputStream(output));
            DefaultLogger logger = new DefaultLogger();
            logger.setMessageOutputLevel(Project.MSG_INFO);
            logger.setOutputPrintStream(out);
            logger.setErrorPrintStream(out);
            newProject.addBuildListener(logger);
        }
        catch( IOException ex ) {
            log(Policy.bind("exception.cannotSetOutput",output));
        }
    }

    Hashtable taskdefs = project.getTaskDefinitions();
    Enumeration et = taskdefs.keys();
    while (et.hasMoreElements()) {
        String taskName = (String) et.nextElement();
        Class taskClass = (Class) taskdefs.get(taskName);
        newProject.addTaskDefinition(taskName, taskClass);
    }

    Hashtable typedefs = project.getDataTypeDefinitions();
    Enumeration e = typedefs.keys();
    while (e.hasMoreElements()) {
        String typeName = (String) e.nextElement();
        Class typeClass = (Class) typedefs.get(typeName);
        newProject.addDataTypeDefinition(typeName, typeClass);
    }

    // set user-defined or all properties from calling project
    Hashtable prop1;
    if (inheritAll == true) {
       prop1 = project.getProperties();
    }
    else {
       prop1 = project.getUserProperties();

       // set Java built-in properties separately,
       // b/c we won't inherit them.
       newProject.setSystemProperties();
    }
    
    e = prop1.keys();
    while (e.hasMoreElements()) {
        String arg = (String) e.nextElement();
        String value = (String) prop1.get(arg);
        if (inheritAll == true){
           newProject.setProperty(arg, value);
        } else {
           newProject.setUserProperty(arg, value);
        }
    }
}

/**
 * Reinitializes the receiver.
 */
private void reinit() {
    init();
    for (int i=0; i<properties.size(); i++) {
        Property p = (Property) properties.elementAt(i);
        Property newP = (Property) newProject.createTask("property");
        newP.setName(p.getName());
        if (p.getValue() != null) {
            newP.setValue(p.getValue());
        }
        if (p.getFile() != null) {
            newP.setFile(p.getFile());
        } 
        if (p.getResource() != null) {
            newP.setResource(p.getResource());
        }
        properties.setElementAt(newP, i);
    }
}

/**
 * set the build file, it can be either absolute or relative.
 * If it is absolute, <tt>dir</tt> will be ignored, if it is
 * relative it will be resolved relative to <tt>dir</tt>.
 * 
 * @param s the <b>Ant</b> file location
 */
public void setAntfile(String s) {
    // @note: it is a string and not a file to handle relative/absolute
    // otherwise a relative file will be resolved based on the current
    // basedir.
    this.antFile = s;
}

/**
 * Sets the receiver's target directory.
 * 
 * @param s the target directory
 */
public void setDir(File d) {
	this.dir = d;
}

/**
 * Sets the receiver's output destination.
 * 
 * @param s the output destination
 */
public void setOutput(String s) {
	this.output = s;
}

/**
 * set the target to execute. If none is defined it will
 * execute the default target of the build file
 * 
 * @param s the <b>Ant</b> target to execute
 */
public void setTarget(String s) {
	this.target = s;
}
protected void handleErrorOutput(String line) {
    if (newProject != null) {
        newProject.demuxOutput(line, true);
    }
    else {
        super.handleErrorOutput(line);
    }
}
protected void handleOutput(String line) {
    if (newProject != null) {
        newProject.demuxOutput(line, false);
    }
    else {
        super.handleOutput(line);
    }
}
/**
 * If true, inherit all properties from parent Project
 * If false, inherit only userProperties and those defined
 * inside the ant call itself
 */
public void setInheritAll(boolean value) {
   inheritAll = value;
}
}
