/*
* The MIT License
*
* Copyright (c) 2009, Romain Seguy
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Tom Huybrechts
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.plugins.radbuilder;
import hudson.EnvVars;
import hudson.Extension;
import hudson.Launcher;
import hudson.Util;
import hudson.model.EnvironmentSpecific;
import hudson.model.Hudson;
import hudson.model.Node;
import hudson.model.TaskListener;
import hudson.remoting.Callable;
import hudson.slaves.NodeSpecific;
import hudson.tools.ToolDescriptor;
import hudson.tools.ToolInstallation;
import hudson.util.FormValidation;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.jvnet.localizer.ResourceBundleHolder;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
/**
* Corresponds to an IBM Rational Application Developer 7.0/7.5 or an IBM Rational
* Application Developer Build Utility 7.5 installation.
*
* <p>To use a {@link RAD} build step, it is mandatory to define a installation:
* No default installations can be assumed.</p>
*
*
* @author Romain Seguy (using {@link Ant#AntInstallation} as an input)
* @version 1.0
*/
public class RADInstallation extends ToolInstallation implements NodeSpecific<RADInstallation>, EnvironmentSpecific<RADInstallation> {
@DataBoundConstructor
public RADInstallation(String name, String home) {
super(name, removeTrailingBackslash(home), Collections.EMPTY_LIST);
}
public RADInstallation forEnvironment(EnvVars environment) {
return new RADInstallation(getName(), environment.expand(getHome()));
}
public RADInstallation forNode(Node node, TaskListener log) throws IOException, InterruptedException {
return new RADInstallation(getName(), translateFor(node, log));
}
public String getRunAntExecutable(Launcher launcher) throws IOException, InterruptedException {
return launcher.getChannel().call(new Callable<String,IOException>() {
public String call() throws IOException {
// 1st try: do we work with a RAD installation?
File runAntFile = getRunAntFile("bin");
if(runAntFile.exists()) {
return runAntFile.getPath();
}
else {
// 2nd try: do we work with a BU installation?
runAntFile = getRunAntFile("eclipse/bin");
if(runAntFile.exists()) {
return runAntFile.getPath();
}
}
return null;
}
});
}
/**
* Returns a {@link File} representing {@code runAnt.bat}/{@code runAnt.sh}.
*/
private File getRunAntFile(String binFolder) {
String runAntFileName = "runAnt.sh";
if(Hudson.isWindows()) {
runAntFileName = "runAnt.bat";
}
return new File(Util.replaceMacro(getHome(), EnvVars.masterEnvVars), binFolder + "/" + runAntFileName);
}
/**
* Removes the '\' or '/' character that may be present at the end of the
* specified string.
*/
private static String removeTrailingBackslash(String s) {
return StringUtils.removeEnd(StringUtils.removeEnd(s, "/"), "\\");
}
@Extension
public static class DescriptorImpl extends ToolDescriptor<RADInstallation> {
@Override
public String getDisplayName() {
return ResourceBundleHolder.get(RAD.class).format("DisplayName");
}
@Override
public RADInstallation[] getInstallations() {
return Hudson.getInstance().getDescriptorByType(RAD.DescriptorImpl.class).getInstallations();
}
@Override
public void setInstallations(RADInstallation... installations) {
Hudson.getInstance().getDescriptorByType(RAD.DescriptorImpl.class).setInstallations(installations);
}
@Override
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
setInstallations(
req.bindJSONToList(
RADInstallation.class,
json.get("rad")).toArray(new RADInstallation[0]));
return true;
}
/**
* Checks if the installation folder is valid.
*/
public FormValidation doCheckHome(@QueryParameter File value) {
if(!Hudson.getInstance().hasPermission(Hudson.ADMINISTER))
return FormValidation.ok();
if(value.getPath().equals("")) {
return FormValidation.error(ResourceBundleHolder.get(RADInstallation.class).format("InstallationFolderMustBeSet"));
}
if(!value.isDirectory()) {
return FormValidation.error(ResourceBundleHolder.get(RADInstallation.class).format("NotAFolder", value));
}
// let's check for the runAnt file existence
if(Hudson.isWindows()) {
boolean noRADRunAntBat = false; // RAD on Windows
boolean noBURunAntBat = false; // RAD BU on Windows
File runAntFile = new File(value, "bin/runAnt.bat");
if(!runAntFile.exists()) {
noRADRunAntBat = true;
runAntFile = new File(value, "eclipse/bin/runAnt.bat");
if(!runAntFile.exists()) {
noBURunAntBat = true;
}
}
if(noBURunAntBat || noBURunAntBat && noRADRunAntBat) {
return FormValidation.error(ResourceBundleHolder.get(RADInstallation.class).format("NotARADInstallationFolder", value));
}
}
else {
boolean noRADRunAntSh = false; // RAD in Linux
boolean noBURunAntSh = false; // RAD BU on Linux
File runAntFile = new File(value, "bin/runAnt.sh");
if(!runAntFile.exists()) {
noRADRunAntSh = true;
runAntFile = new File(value, "eclipse/bin/runAnt.sh");
if(!runAntFile.exists()) {
noBURunAntSh = true;
}
}
if(noBURunAntSh || noBURunAntSh && noRADRunAntSh) {
return FormValidation.error(ResourceBundleHolder.get(RADInstallation.class).format("NotARADInstallationFolder", value));
}
}
return FormValidation.ok();
}
}
}