/* * The MIT License * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Jean-Baptiste Quenot, Seiji Sogabe, 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.model; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.AbstractList; import java.util.Set; import javax.servlet.ServletException; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import hudson.Extension; /** * Keeps a list of the parameters defined for a project. * *

* This class also implements {@link Action} so that index.jelly provides * a form to enter build parameters. */ @ExportedBean(defaultVisibility=2) public class ParametersDefinitionProperty extends JobProperty> implements Action { private final List parameterDefinitions; public ParametersDefinitionProperty(List parameterDefinitions) { this.parameterDefinitions = parameterDefinitions; } public ParametersDefinitionProperty(ParameterDefinition... parameterDefinitions) { this.parameterDefinitions = Arrays.asList(parameterDefinitions); } public AbstractProject getOwner() { return owner; } @Exported public List getParameterDefinitions() { return parameterDefinitions; } /** * Gets the names of all the parameter definitions. */ public List getParameterDefinitionNames() { return new AbstractList() { public String get(int index) { return parameterDefinitions.get(index).getName(); } public int size() { return parameterDefinitions.size(); } }; } @Override public Collection getJobActions(AbstractProject job) { return Collections.singleton(this); } public AbstractProject getProject() { return (AbstractProject) owner; } /** * Interprets the form submission and schedules a build for a parameterized job. * *

* This method is supposed to be invoked from {@link AbstractProject#doBuild(StaplerRequest, StaplerResponse)}. */ public void _doBuild(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { boolean isPromptRequired = isPromptRequired(); // if this wasn't a post, and we need the user to submit a form, // then forward to the entry form if (!req.getMethod().equals("POST") && isPromptRequired) { req.getView(this, "index.jelly").forward(req, rsp); return; } List values = new ArrayList(); Set valueNamesSubmitted = new HashSet(); // we don't need to (and can't) look in the form if no submission was // made if (isPromptRequired) { JSONObject formData = req.getSubmittedForm(); JSONArray a = JSONArray.fromObject(formData.get("parameter")); for (Object o : a) { JSONObject jo = (JSONObject) o; String name = jo.getString("name"); ParameterDefinition d = getParameterDefinition(name); if (d == null) throw new IllegalArgumentException( "No such parameter definition: " + name); ParameterValue parameterValue = d.createValue(req, jo); values.add(parameterValue); valueNamesSubmitted.add(name); } } // Add the other parameter values that weren't prompted for, which might // even be all of them. for (ParameterDefinition d : getParameterDefinitions()) { String definitionName = d.getName(); if (!valueNamesSubmitted.contains(definitionName)) { ParameterValue parameterValue = d .getDefaultParameterValueForManualBuild(); values.add(parameterValue); } } Hudson.getInstance().getQueue().schedule(owner, owner.getDelay(req), new ParametersAction(values), new CauseAction(new Cause.UserCause())); // we do the forward differently if we skip the form if (isPromptRequired) { // send the user back to the job top page. rsp.sendRedirect("."); } else { // behave the way AbstractProject does rsp.forwardToPreviousPage(req); } } protected boolean isPromptRequired() { for (ParameterDefinition d : getParameterDefinitions()) { if (!d.isNeverPrompt()) { return true; } } return false; } public void buildWithParameters(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { List values = new ArrayList(); for (ParameterDefinition d: parameterDefinitions) { ParameterValue value = d.createValue(req); if (value != null) { values.add(value); } else { throw new IllegalArgumentException("Parameter " + d.getName() + " was missing."); } } Hudson.getInstance().getQueue().schedule( owner, owner.getDelay(req), new ParametersAction(values), new CauseAction(new Cause.UserCause())); // send the user back to the job top page. rsp.sendRedirect("."); } /** * Gets the {@link ParameterDefinition} of the given name, if any. */ public ParameterDefinition getParameterDefinition(String name) { for (ParameterDefinition pd : parameterDefinitions) if (pd.getName().equals(name)) return pd; return null; } @Extension public static class DescriptorImpl extends JobPropertyDescriptor { @Override public boolean isApplicable(Class jobType) { return AbstractProject.class.isAssignableFrom(jobType); } @Override public JobProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException { if (formData.isNullObject()) { return null; } JSONObject parameterized = formData.getJSONObject("parameterized"); if (parameterized.isNullObject()) { return null; } List parameterDefinitions = Descriptor.newInstancesFromHeteroList( req, parameterized, "parameter", ParameterDefinition.all()); if(parameterDefinitions.isEmpty()) return null; return new ParametersDefinitionProperty(parameterDefinitions); } @Override public String getDisplayName() { return Messages.ParametersDefinitionProperty_DisplayName(); } } public String getDisplayName() { return null; } public String getIconFileName() { return null; } public String getUrlName() { return null; } }