blob: a0616dd34c895c70671b0c7f32c0bb1be44f8914 [file] [log] [blame]
/*
* 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);
}
}
}
}