PageRenderTime 36ms CodeModel.GetById 17ms app.highlight 13ms RepoModel.GetById 2ms app.codeStats 0ms

/hudson-core/src/main/java/hudson/model/ParameterDefinition.java

http://github.com/hudson/hudson
Java | 253 lines | 91 code | 27 blank | 135 comment | 9 complexity | e75021eec056b716e09817881786fa4f MD5 | raw file
  1/*
  2 * The MIT License
  3 * 
  4 * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Luca Domenico Milanesio, Tom Huybrechts
  5 * 
  6 * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 * of this software and associated documentation files (the "Software"), to deal
  8 * in the Software without restriction, including without limitation the rights
  9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10 * copies of the Software, and to permit persons to whom the Software is
 11 * furnished to do so, subject to the following conditions:
 12 * 
 13 * The above copyright notice and this permission notice shall be included in
 14 * all copies or substantial portions of the Software.
 15 * 
 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 22 * THE SOFTWARE.
 23 */
 24package hudson.model;
 25
 26import hudson.AbortException;
 27import hudson.DescriptorExtensionList;
 28import hudson.Extension;
 29import hudson.ExtensionPoint;
 30import hudson.cli.CLICommand;
 31import hudson.util.DescriptorList;
 32import java.io.IOException;
 33import java.io.Serializable;
 34import net.sf.json.JSONObject;
 35import org.apache.commons.lang3.builder.HashCodeBuilder;
 36import org.kohsuke.stapler.StaplerRequest;
 37import org.kohsuke.stapler.export.Exported;
 38import org.kohsuke.stapler.export.ExportedBean;
 39
 40/**
 41 * Defines a parameter for a build.
 42 *
 43 * <p>
 44 * In Hudson, a user can configure a job to require parameters for a build.
 45 * For example, imagine a test job that takes the bits to be tested as a parameter.
 46 *
 47 * <p>
 48 * The actual meaning and the purpose of parameters are entirely up to users, so
 49 * what the concrete parameter implmentation is pluggable. Write subclasses
 50 * in a plugin and put {@link Extension} on the descriptor to register them.
 51 *
 52 * <p>
 53 * Three classes are used to model build parameters. First is the
 54 * {@link ParameterDescriptor}, which tells Hudson what kind of implementations are
 55 * available. From {@link ParameterDescriptor#newInstance(StaplerRequest, JSONObject)},
 56 * Hudson creates {@link ParameterDefinition}s based on the job configuration.
 57 * For example, if the user defines two string parameters "database-type" and
 58 * "appserver-type", we'll get two {@link StringParameterDefinition} instances
 59 * with their respective names.
 60 *
 61 * <p>
 62 * When a job is configured with {@link ParameterDefinition} (or more precisely,
 63 * {@link ParametersDefinitionProperty}, which in turns retains {@link ParameterDefinition}s),
 64 * user would have to enter the values for the defined build parameters.
 65 * The {@link #createValue(StaplerRequest, JSONObject)} method is used to convert this
 66 * form submission into {@link ParameterValue} objects, which are then accessible
 67 * during a build.
 68 *
 69 *
 70 *
 71 * <h2>Persistence</h2>
 72 * <p>
 73 * Instances of {@link ParameterDefinition}s are persisted into job <tt>config.xml</tt>
 74 * through XStream.
 75 *
 76 *
 77 * <h2>Assocaited Views</h2>
 78 * <h4>config.jelly</h4>
 79 * <p>
 80 * {@link ParameterDefinition} class uses <tt>config.jelly</tt> to provide contribute a form
 81 * fragment in the job configuration screen. Values entered there is fed back to
 82 * {@link ParameterDescriptor#newInstance(StaplerRequest, JSONObject)} to create {@link ParameterDefinition}s.
 83 *
 84 * <h4>index.jelly</h4>
 85 * The <tt>index.jelly</tt> view contributes a form fragment in the page where the user
 86 * enters actual values of parameters for a build. The result of this form submission
 87 * is then fed to {@link ParameterDefinition#createValue(StaplerRequest, JSONObject)} to
 88 * create {@link ParameterValue}s.
 89 *
 90 * TODO: what Jelly pages does this object need for rendering UI?
 91 * TODO: {@link ParameterValue} needs to have some mechanism to expose values to the build
 92 * @see StringParameterDefinition
 93 */
 94@ExportedBean(defaultVisibility=3)
 95public abstract class ParameterDefinition implements
 96        Describable<ParameterDefinition>, ExtensionPoint, Serializable {
 97
 98    private final String name;
 99
100    private final String description;
101
102    public ParameterDefinition(String name) {
103        this(name, null);
104    }
105
106    public ParameterDefinition(String name, String description) {
107        this.name = name;
108        this.description = description;
109    }
110
111    @Exported
112    public String getType() {
113    	return this.getClass().getSimpleName();
114    }
115    
116    @Exported
117    public String getName() {
118        return name;
119    }
120
121    @Exported
122    public String getDescription() {
123        return description;
124    }
125
126    /**
127     * {@inheritDoc}
128     */
129    public ParameterDescriptor getDescriptor() {
130        return (ParameterDescriptor)Hudson.getInstance().getDescriptorOrDie(getClass());
131    }
132
133    /**
134     * Create a parameter value from a form submission.
135     *
136     * <p>
137     * This method is invoked when the user fills in the parameter values in the HTML form
138     * and submits it to the server.
139     */
140    public abstract ParameterValue createValue(StaplerRequest req, JSONObject jo);
141    
142    /**
143     * Create a parameter value from a GET with query string.
144     * If no value is available in the request, it returns a default value if possible, or null.
145     *
146     * <p>
147     * Unlike {@link #createValue(StaplerRequest, JSONObject)}, this method is intended to support
148     * the programmatic POST-ing of the build URL. This form is less expressive (as it doesn't support
149     * the tree form), but it's more scriptable.
150     *
151     * <p>
152     * If a {@link ParameterDefinition} can't really support this mode of creating a value,
153     * you may just always return null.
154     */
155    public abstract ParameterValue createValue(StaplerRequest req);
156
157
158    /**
159     * Create a parameter value from the string given in the CLI.
160     *
161     * @param command
162     *      This is the command that got the parameter. You can use its {@link CLICommand#channel}
163     *      for interacting with the CLI JVM.
164     * @throws AbortException
165     *      If the CLI processing should be aborted. Hudson will report the error message
166     *      without stack trace, and then exits this command. Useful for graceful termination.
167     * @throws Exception
168     *      All the other exceptions cause the stack trace to be dumped, and then
169     *      the command exits with an error code.
170     * @since 1.334
171     */
172    public ParameterValue createValue(CLICommand command, String value) throws IOException, InterruptedException {
173        throw new AbortException("CLI parameter submission is not supported for the "+getClass()+" type. Please file a bug report for this");
174    }
175    
176    /**
177     * Returns default parameter value for this definition.
178     * 
179     * @return default parameter value or null if no defaults are available
180     * @since 1.253
181     */
182    @Exported
183    public ParameterValue getDefaultParameterValue() {
184        return null;
185    }
186
187    /**
188     * Returns all the registered {@link ParameterDefinition} descriptors.
189     */
190    public static DescriptorExtensionList<ParameterDefinition,ParameterDescriptor> all() {
191        return Hudson.getInstance().<ParameterDefinition,ParameterDescriptor>getDescriptorList(ParameterDefinition.class);
192    }
193
194    /**
195     * A list of available parameter definition types
196     * @deprecated as of 1.286
197     *      Use {@link #all()} for read access, and {@link Extension} for registration.
198     */
199    public static final DescriptorList<ParameterDefinition> LIST = new DescriptorList<ParameterDefinition>(ParameterDefinition.class);
200
201    public abstract static class ParameterDescriptor extends
202            Descriptor<ParameterDefinition> {
203
204        protected ParameterDescriptor(Class<? extends ParameterDefinition> klazz) {
205            super(klazz);
206        }
207
208        /**
209         * Infers the type of the corresponding {@link ParameterDescriptor} from the outer class.
210         * This version works when you follow the common convention, where a descriptor
211         * is written as the static nested class of the describable class.
212         *
213         * @since 1.278
214         */
215        protected ParameterDescriptor() {
216        }
217
218        public String getValuePage() {
219            return getViewPage(clazz, "index.jelly");
220        }
221
222        @Override
223        public String getDisplayName() {
224            return "Parameter";
225        }
226    }
227
228    @Override
229    public boolean equals(Object o) {
230        if (this == o) {
231            return true;
232        }
233        if (o == null || getClass() != o.getClass()) {
234            return false;
235        }
236
237        ParameterDefinition that = (ParameterDefinition) o;
238
239        if (name != null ? !name.equals(that.name) : that.name != null) {
240            return false;
241        }
242
243        return true;
244    }
245
246    @Override
247    public int hashCode() {
248        return new HashCodeBuilder()
249            .append(getName())
250            .append(getClass())
251            .toHashCode();
252    }
253}