package hudson.plugins.tfs.util; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; import hudson.Launcher; import hudson.Util; import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.model.Computer; import hudson.model.Job; import hudson.model.TaskListener; import hudson.util.VariableResolver; /** * A {@link VariableResolver} that resolves certain Build variables. * <p> * The build variable resolver will resolve the following: * <ul> * <li> JOB_NAME - The name of the job</li> * <li> USER_NAME - The system property "user.name" on the Node that the Launcher * is being executed on (slave or master)</li> * <li> NODE_NAME - The name of the node that the Launcher is being executed on</li> * <li> Any environment variable that is set on the Node that the Launcher is * being executed on (slave or master)</li> * </ul> * * @author Erik Ramfelt */ public class BuildVariableResolver implements VariableResolver<String> { private Map<String,LazyResolver> lazyResolvers = new HashMap<String, LazyResolver>(); private List<VariableResolver<String>> otherResolvers = new ArrayList<VariableResolver<String>>(); private final Computer computer; private static final Logger LOGGER = Logger.getLogger(BuildVariableResolver.class.getName()); public BuildVariableResolver(final Job<?, ?> job) { computer = null; lazyResolvers.put("JOB_NAME", new LazyResolver() { public String getValue() { return job.getName(); } }); } public BuildVariableResolver(final AbstractProject<?, ?> project, final Computer computer) { this.computer = computer; lazyResolvers.put("JOB_NAME", new LazyResolver() { public String getValue() { return project.getName(); } }); lazyResolvers.put("NODE_NAME", new LazyComputerResolver() { public String getValue(Computer computer) { return (Util.fixEmpty(computer.getName()) == null ? "MASTER" : computer.getName()); } }); lazyResolvers.put("USER_NAME", new LazyComputerResolver() { public String getValue(Computer computer) throws IOException, InterruptedException { return (String) computer.getSystemProperties().get("user.name"); } }); } /** * Constructor that can be used with a {@linkplain AbstractBuild} instance. * <p> * This constructor should not be called in a method that may be called by * {@link AbstractBuild#getEnvVars()}. * @param build used to get the project and the build env vars */ public BuildVariableResolver(final AbstractBuild<?, ?> build, final Computer computer) throws IOException, InterruptedException { this(build.getProject(), computer); final Map<String, String> envVars = build.getEnvironment(TaskListener.NULL); if (envVars != null) { otherResolvers.add(new VariableResolver.ByMap<String>(envVars)); } } public String resolve(String variable) { try { if (lazyResolvers.containsKey(variable)) { return lazyResolvers.get(variable).getValue(); } else { if (computer != null) { otherResolvers.add(new VariableResolver.ByMap<String>(computer.getEnvironment())); } return new VariableResolver.Union<String>(otherResolvers).resolve(variable); } } catch (Exception e) { LOGGER.warning("Variable name '" + variable + "' look up failed because of " + e); } return null; } /** * Simple lazy variable resolver */ private interface LazyResolver { String getValue() throws IOException, InterruptedException; } /** * Class to handle cases when a Launcher was not created from a computer. * @see Launcher#getComputer() */ private abstract class LazyComputerResolver implements LazyResolver { protected abstract String getValue(Computer computer) throws IOException, InterruptedException; public String getValue() throws IOException, InterruptedException { return getValue(computer); } } }