/*
 * Copyright (c) 2003, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package devtests.deployment.util;

import org.apache.tools.ant.Task;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;

import java.io.File;

/**
 *Custom Ant task that runs Java, just like the built-in java ant task, but stores the result of the invocation as a
 *property value, which Ant's java task does not (yet) support.
 *<p>
 *Fortunately, we only need to minimally extend the Java class in Ant, overriding the execute method (to set the result property if
 *it was specified) and adding the setResultProperty method (inspired by the method of the same name from the execute task)
 *so the user can specify a property whose value
 *should be set to the Java execution's result.  The only real difference between this method's execute
 *method and the one from the original Java task is the handling of the result property.  Even so, the code had
 *to be duplicated in order to retain the result value from running the JVM.
 *<p>
 *Note that the execute method, essentially duplicated from the java task source, refers to some private local
 *variables.  Because these are defined as private (not protected) in the java task source, this class cannot
 *refer to them directly.  So, we duplicate those private variables in this class and also duplicate the setter
 *methods for them.  Those setter methods not only set this class's private variable but also invoke the corresponding
 *method in the superclass.
 *
 * @author  tjquinn
 */
public class JavaWithResult extends org.apache.tools.ant.taskdefs.Java {

    /*
     *String holding the name of the property to be set to the result value of the Java execution.  If
     *the build.xml file does not specify the property name, then this will remain null and no property
     *value assignment will occur.
     */
    private String resultProperty = null;

    /*
     *The next two declarations were duplicated from the java task's source so the duplicated execute
     *method could be modified as little as possible.
     */
    private File dir = null;
    private boolean failOnError = false;

    /** Creates a new instance of JavaWithResult */
    public JavaWithResult() {
    }

    public void init() {
        super.init();
        /*
         *Init the resultProperty to null so we can tell if the resultproperty attribute is actually
         *specified in this use of the javaWithResult task.
         */
        resultProperty = null;
    }

    /**
     * The working directory of the process.
     *<p>
     *This method simply mirrors the superclass setDir method.  We use it to set this class's private dir
     *variable and also to set the superclass's private dir variable.
     */
    public void setDir(File d) {
        super.setDir(d);
        this.dir = d;
    }

    /**
     *Assigns the name of the property to receive the result value from the JVM execution.
     *@param resultProperty name of the property to be assigned
     */
    public void setResultProperty(String resultProperty) {
        this.resultProperty = resultProperty;
    }

    /**
     * If true, then fail if the command exits with a
     * returncode other than 0
     */
    public void setFailonerror(boolean fail) {
        super.setFailonerror(fail);
        failOnError = fail;
    }


    /**
     * Do the execution.
     *<p>
     *Almost all of this code is duplicated from the source for the build-in java ant task.  The difference is
     *the logic that checks whether the resultproperty variable has been set and, if so, assigns a value to that
     *property.
     */
    public void execute() throws BuildException {
        File savedDir = dir;

        int err = -1;
        try {
            if ((err = executeJava()) != 0) {
                if (failOnError) {
                    throw new BuildException("Java returned: " + err, location);
                } else {
                    log("Java Result: " + err, Project.MSG_ERR);
                }
            }
        } finally {
            dir = savedDir;

            /*
             *If the result property was assigned - meaning the invoking build.xml wants to know the
             *result of the JVM execution - then assign the JVM result to the specified property.  Because
             *properties are string-valued, convert the integer result from executeJava to a string first.
             */
            String res = Integer.toString(err);
            if (resultProperty != null) {
                project.setNewProperty(resultProperty, res);
            }
        }
    }

}
