/* * The MIT License * * Copyright (c) 2010, Gregory Covert Smith * * 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.staf; import hudson.CopyOnWrite; 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.tools.ToolProperty; import hudson.util.FormValidation; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jvnet.localizer.ResourceBundleHolder; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; /** * Corresponds to an STAF / STAX installation. * * <p>To use a {@link STAF} build step, it is mandatory to define a installation: * No default installations can be assumed.</p> */ public class STAFInstallation extends ToolInstallation implements NodeSpecific<STAFInstallation>, EnvironmentSpecific<STAFInstallation> { private static final long serialVersionUID = 1L; private static final String WINDOWS_JSTAF_PATH = "bin/JSTAF.jar"; private static final String UNIX_JSTAF_PATH = "lib/JSTAF.jar"; private static final String WINDOWS_STAF_EXEC = "bin/STAF.exe"; private static final String UNIX_STAF_EXEC = "bin/STAF"; // Required environment vars private static final String LD_LIBRARY_PATH_ENV = "LD_LIBRARY_PATH"; private static final String DYLD_LIBRARY_PATH_ENV = "DYLD_LIBRARY_PATH"; private static final String STAF_CONV_DIR_ENV = "STAFCONVDIR"; private static final String CLASSPATH_ENV = "CLASSPATH"; @DataBoundConstructor public STAFInstallation(String name, String home, List<? extends ToolProperty<?>> properties) { super(name, home, properties); } public STAFInstallation forEnvironment(EnvVars environment) { return new STAFInstallation(getName(), environment.expand(getHome()), getProperties().toList()); } public STAFInstallation forNode(Node node, TaskListener log) throws IOException, InterruptedException { return new STAFInstallation(getName(), translateFor(node, log), getProperties().toList()); } public String getStafExecutable(Launcher launcher) throws IOException, InterruptedException { return launcher.getChannel().call(new Callable<String,IOException>() { public String call() throws IOException { // Get where the exec should be, then make sure it exists File execFileName = getExecFile(); if(execFileName.exists()) { return execFileName.getPath(); } else { return null; } } }); } public Map<String, String> getRequiredEnvVars() { HashMap<String, String> result = new HashMap<String, String>(3); String home = Util.replaceMacro(getHome(), EnvVars.masterEnvVars); result.put(LD_LIBRARY_PATH_ENV, getLibraryDir()); result.put(DYLD_LIBRARY_PATH_ENV, getLibraryDir()); result.put(STAF_CONV_DIR_ENV, home + "/codepage"); result.put(CLASSPATH_ENV, home + "/" + getJStafJarFile()); return result; } public String getLibraryDir() { String librariesLocation; // an install on Windows puts all of the .dlls into the // bin directory. But on Mac/Linux, the .so / .jnilib files // are put in the lib directory if(Hudson.isWindows()) { librariesLocation = "\\bin"; } else { librariesLocation = "/lib"; } String home = Util.replaceMacro(getHome(), EnvVars.masterEnvVars); return home + librariesLocation; } private File getExecFile() { String execFileName; if(Hudson.isWindows()) { execFileName = WINDOWS_STAF_EXEC; } else { execFileName = UNIX_STAF_EXEC; } return new File(Util.replaceMacro(getHome(), EnvVars.masterEnvVars), execFileName); } private File getJStafJarFile() { String jarFileName; // As with the libraries, for some reason the STAF installer // puts the jars in different places between Win / Mac / Linux if(Hudson.isWindows()) { jarFileName = WINDOWS_JSTAF_PATH; } else { jarFileName = UNIX_JSTAF_PATH; } return new File(Util.replaceMacro(getHome(), EnvVars.masterEnvVars), jarFileName); } @Extension public static class DescriptorImpl extends ToolDescriptor<STAFInstallation> { @CopyOnWrite private volatile STAFInstallation[] installations = new STAFInstallation[0]; public DescriptorImpl() { load(); } @Override public String getDisplayName() { return ResourceBundleHolder.get(STAF.class).format("DisplayName"); } @Override public STAFInstallation[] getInstallations() { return installations.clone(); } @Override public void setInstallations(STAFInstallation[] installs) { installations = installs; save(); } /** * 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(STAFInstallation.class).format("InstallationFolderMustBeSet")); } if(!value.isDirectory()) { return FormValidation.error(ResourceBundleHolder.get(STAFInstallation.class).format("NotAFolder", value)); } // let's check for the STAF files // are assumption will be if the staf executable and the // JSTAF jar exists, then everything else will be OK if(Hudson.isWindows()) { File stafExe = new File(value, WINDOWS_STAF_EXEC); File jstafJar = new File(value, WINDOWS_JSTAF_PATH); if(!stafExe.exists() || !jstafJar.exists()) { return FormValidation.error(ResourceBundleHolder.get(STAFInstallation.class).format("NotASTAFInstallationFolder", value)); } } else { File stafExe = new File(value, UNIX_STAF_EXEC); File jstafJar = new File(value, UNIX_JSTAF_PATH); if(!stafExe.exists() || !jstafJar.exists()) { return FormValidation.error(ResourceBundleHolder.get(STAFInstallation.class).format("NotASTAFInstallationFolder", value)); } } return FormValidation.ok(); } } }