提交 37dfa992 编写于 作者: J Jesse Glick 提交者: Oleg Nenashev

Offering default methods on ParameterizedJob (#2864)

* Offering default methods on ParameterizedJob.

* Javadoc typo.

* Cleaner use of default methods in ParameterizedJob.

* Need to pick up https://github.com/infradna/bridge-method-injector/pull/15 to be able to build.

* Using new type bounds.

* bridge-method-injector 1.17
上级 8edf4a34
......@@ -138,7 +138,7 @@ import org.kohsuke.stapler.interceptor.RequirePOST;
* @see AbstractBuild
*/
@SuppressWarnings("rawtypes")
public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends AbstractBuild<P,R>> extends Job<P,R> implements BuildableItem, LazyBuildMixIn.LazyLoadingJob<P,R>, ParameterizedJobMixIn.ParameterizedJob {
public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends AbstractBuild<P,R>> extends Job<P,R> implements BuildableItem, LazyBuildMixIn.LazyLoadingJob<P,R>, ParameterizedJobMixIn.ParameterizedJob<P, R> {
/**
* {@link SCM} associated with the project.
......@@ -287,15 +287,6 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
return buildMixIn;
}
private ParameterizedJobMixIn<P,R> getParameterizedJobMixIn() {
return new ParameterizedJobMixIn<P,R>() {
@SuppressWarnings("unchecked") // untypable
@Override protected P asJob() {
return (P) AbstractProject.this;
}
};
}
@Override
public synchronized void save() throws IOException {
super.save();
......@@ -468,7 +459,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
*/
public String getBuildNowText() {
// For compatibility, still use the deprecated replacer if specified.
return AlternativeUiTextProvider.get(BUILD_NOW_TEXT, this, getParameterizedJobMixIn().getBuildNowText());
return AlternativeUiTextProvider.get(BUILD_NOW_TEXT, this, ParameterizedJobMixIn.ParameterizedJob.super.getBuildNowText());
}
/**
......@@ -800,39 +791,6 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
Jenkins.getInstance().rebuildDependencyGraphAsync();
}
/**
* @deprecated
* Use {@link #scheduleBuild(Cause)}. Since 1.283
*/
@Deprecated
public boolean scheduleBuild() {
return getParameterizedJobMixIn().scheduleBuild();
}
/**
* @deprecated
* Use {@link #scheduleBuild(int, Cause)}. Since 1.283
*/
@Deprecated
public boolean scheduleBuild(int quietPeriod) {
return getParameterizedJobMixIn().scheduleBuild(quietPeriod);
}
/**
* Schedules a build of this project.
*
* @return
* true if the project is added to the queue.
* false if the task was rejected from the queue (such as when the system is being shut down.)
*/
public boolean scheduleBuild(Cause c) {
return getParameterizedJobMixIn().scheduleBuild(c);
}
public boolean scheduleBuild(int quietPeriod, Cause c) {
return getParameterizedJobMixIn().scheduleBuild(quietPeriod, c);
}
/**
* Schedules a build.
*
......@@ -869,14 +827,13 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* For the convenience of the caller, this collection can contain null, and those will be silently ignored.
* @since 1.383
*/
@SuppressWarnings("unchecked")
@WithBridgeMethods(Future.class)
public QueueTaskFuture<R> scheduleBuild2(int quietPeriod, Cause c, Collection<? extends Action> actions) {
List<Action> queueActions = new ArrayList<Action>(actions);
if (c != null) {
queueActions.add(new CauseAction(c));
}
return getParameterizedJobMixIn().scheduleBuild2(quietPeriod, queueActions.toArray(new Action[queueActions.size()]));
return scheduleBuild2(quietPeriod, queueActions.toArray(new Action[queueActions.size()]));
}
/**
......@@ -902,6 +859,11 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
return scheduleBuild2(quietPeriod, c, new Action[0]);
}
@Override
public QueueTaskFuture<R> scheduleBuild2(int quietPeriod, Action... actions) {
return ParameterizedJobMixIn.ParameterizedJob.super.scheduleBuild2(quietPeriod, actions);
}
/**
* Schedules a polling of this project.
*/
......@@ -1741,21 +1703,11 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
return buildMixIn.createHistoryWidget();
}
public boolean isParameterized() {
return getParameterizedJobMixIn().isParameterized();
}
//
//
// actions
//
//
/**
* Schedules a new build command.
*/
public void doBuild( StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay ) throws IOException, ServletException {
getParameterizedJobMixIn().doBuild(req, rsp, delay);
}
/** @deprecated use {@link #doBuild(StaplerRequest, StaplerResponse, TimeDuration)} */
@Deprecated
......@@ -1784,14 +1736,6 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
}
/**
* Supports build trigger with parameters via an HTTP GET or POST.
* Currently only String parameters are supported.
*/
public void doBuildWithParameters(StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException {
getParameterizedJobMixIn().doBuildWithParameters(req, rsp, delay);
}
/** @deprecated use {@link #doBuildWithParameters(StaplerRequest, StaplerResponse, TimeDuration)} */
@Deprecated
public void doBuildWithParameters(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
......@@ -1807,14 +1751,6 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
rsp.sendRedirect(".");
}
/**
* Cancels a scheduled build.
*/
@RequirePOST
public void doCancelQueue( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
getParameterizedJobMixIn().doCancelQueue(req, rsp);
}
@Override
protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException {
super.submit(req,rsp);
......
......@@ -26,7 +26,6 @@ package hudson.model;
import hudson.Util;
import hudson.model.Descriptor.FormException;
import hudson.model.queue.QueueTaskFuture;
import hudson.scm.SCM;
import hudson.tasks.BuildStep;
import hudson.tasks.BuildWrapper;
......@@ -109,10 +108,6 @@ public abstract class Project<P extends Project<P,B>,B extends Build<P,B>>
return this;
}
@Override public QueueTaskFuture<?> scheduleBuild2(int quietPeriod, Action... actions) {
return scheduleBuild2(quietPeriod, null, actions);
}
@Override public SCMTrigger getSCMTrigger() {
return getTrigger(SCMTrigger.class);
}
......
......@@ -266,7 +266,7 @@ public abstract class Trigger<J extends Item> implements Describable<Trigger<?>>
}
// Process all triggers, except SCMTriggers when synchronousPolling is set
for (ParameterizedJobMixIn.ParameterizedJob p : inst.allItems(ParameterizedJobMixIn.ParameterizedJob.class)) {
for (ParameterizedJobMixIn.ParameterizedJob<?, ?> p : inst.allItems(ParameterizedJobMixIn.ParameterizedJob.class)) {
for (Trigger t : p.getTriggers().values()) {
if (!(t instanceof SCMTrigger && scmd.synchronousPolling)) {
if (t !=null && t.spec != null && t.tabs != null) {
......
......@@ -53,6 +53,7 @@ import javax.annotation.CheckForNull;
import javax.servlet.ServletException;
import static javax.servlet.http.HttpServletResponse.SC_CREATED;
import static javax.servlet.http.HttpServletResponse.SC_CONFLICT;
import jenkins.triggers.SCMTriggerItem;
import jenkins.util.TimeDuration;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
......@@ -65,10 +66,11 @@ import org.kohsuke.stapler.interceptor.RequirePOST;
/**
* Allows a {@link Job} to make use of {@link ParametersDefinitionProperty} and be scheduled in various ways.
* Stateless so there is no need to keep an instance of it in a field.
* Besides implementing {@link ParameterizedJob}, you should override {@link Job#makeSearchIndex} to call {@link #extendSearchIndex}.
* @since 1.556
*/
@SuppressWarnings("unchecked") // AbstractItem.getParent does not correctly override; scheduleBuild2 inherently untypable
public abstract class ParameterizedJobMixIn<JobT extends Job<JobT, RunT> & ParameterizedJobMixIn.ParameterizedJob & Queue.Task, RunT extends Run<JobT, RunT> & Queue.Executable> {
public abstract class ParameterizedJobMixIn<JobT extends Job<JobT, RunT> & ParameterizedJobMixIn.ParameterizedJob<JobT, RunT> & Queue.Task, RunT extends Run<JobT, RunT> & Queue.Executable> {
protected abstract JobT asJob();
......@@ -95,11 +97,7 @@ public abstract class ParameterizedJobMixIn<JobT extends Job<JobT, RunT> & Param
}
/**
* Provides a standard implementation of an optional method of the same name in a {@link Job} type to schedule a build with the ability to wait for its result.
* That job method is often used during functional tests ({@code JenkinsRule.assertBuildStatusSuccess}).
* @param quietPeriod seconds to wait before starting (normally 0)
* @param actions various actions to associate with the scheduling, such as {@link ParametersAction} or {@link CauseAction}
* @return a handle by which you may wait for the build to complete (or just start); or null if the build was not actually scheduled for some reason
* Standard implementation of {@link ParameterizedJob#scheduleBuild2}.
*/
public final @CheckForNull QueueTaskFuture<RunT> scheduleBuild2(int quietPeriod, Action... actions) {
Queue.Item i = scheduleBuild2(quietPeriod, Arrays.asList(actions));
......@@ -161,15 +159,14 @@ public abstract class ParameterizedJobMixIn<JobT extends Job<JobT, RunT> & Param
}
/**
* A job should define a method of the same signature for use from {@link BuildButtonColumn}.
* Standard implementation of {@link ParameterizedJob#isParameterized}.
*/
public final boolean isParameterized() {
return asJob().getProperty(ParametersDefinitionProperty.class) != null;
}
/**
* Schedules a new build command.
* Create a method on your job with the same signature and delegate to this.
* Standard implementation of {@link ParameterizedJob#doBuild}.
*/
@SuppressWarnings("deprecation")
public final void doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException {
......@@ -206,9 +203,7 @@ public abstract class ParameterizedJobMixIn<JobT extends Job<JobT, RunT> & Param
}
/**
* Supports build trigger with parameters via an HTTP GET or POST.
* Currently only String parameters are supported.
* Create a method on your job with the same signature and delegate to this.
* Standard implementation of {@link ParameterizedJob#doBuildWithParameters}.
*/
@SuppressWarnings("deprecation")
public final void doBuildWithParameters(StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException {
......@@ -226,8 +221,7 @@ public abstract class ParameterizedJobMixIn<JobT extends Job<JobT, RunT> & Param
}
/**
* Cancels a scheduled build.
* Create a method on your job marked {@link RequirePOST} but with the same signature and delegate to this.
* Standard implementation of {@link ParameterizedJob#doCancelQueue}.
*/
@RequirePOST
public final void doCancelQueue( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
......@@ -275,7 +269,6 @@ public abstract class ParameterizedJobMixIn<JobT extends Job<JobT, RunT> & Param
/**
* Suggested implementation of {@link ParameterizedJob#getBuildNowText}.
* Uses {@link #BUILD_NOW_TEXT}.
*/
public final String getBuildNowText() {
return isParameterized() ? AlternativeUiTextProvider.get(BUILD_NOW_TEXT, asJob(), Messages.ParameterizedJobMixIn_build_with_parameters())
......@@ -294,7 +287,7 @@ public abstract class ParameterizedJobMixIn<JobT extends Job<JobT, RunT> & Param
if (!(job instanceof ParameterizedJob)) {
return null;
}
for (Trigger<?> t : ((ParameterizedJob) job).getTriggers().values()) {
for (Trigger<?> t : ((ParameterizedJob<?, ?>) job).getTriggers().values()) {
if (clazz.isInstance(t)) {
return clazz.cast(t);
}
......@@ -303,16 +296,42 @@ public abstract class ParameterizedJobMixIn<JobT extends Job<JobT, RunT> & Param
}
/**
* Marker for job using this mixin.
* Marker for job using this mixin, and default implementations of many methods.
*/
public interface ParameterizedJob extends hudson.model.Queue.Task, hudson.model.Item {
public interface ParameterizedJob<JobT extends Job<JobT, RunT> & ParameterizedJobMixIn.ParameterizedJob<JobT, RunT> & Queue.Task, RunT extends Run<JobT, RunT> & Queue.Executable> extends BuildableItem {
/**
* Creates a helper object.
* (Would have been done entirely as an interface with default methods had this been designed for Java 8.)
*/
default ParameterizedJobMixIn<JobT, RunT> getParameterizedJobMixIn() {
return new ParameterizedJobMixIn<JobT, RunT>() {
@SuppressWarnings("unchecked") // untypable
@Override protected JobT asJob() {
return (JobT) ParameterizedJob.this;
}
};
}
@SuppressWarnings("deprecation")
@CheckForNull hudson.model.BuildAuthorizationToken getAuthToken();
int getQuietPeriod();
/**
* Quiet period for the job.
* @return by default, {@link Jenkins#getQuietPeriod}
*/
default int getQuietPeriod() {
return Jenkins.getInstance().getQuietPeriod();
}
String getBuildNowText();
/**
* Text to display for a build button.
* Uses {@link #BUILD_NOW_TEXT}.
* @see ParameterizedJobMixIn#getBuildNowText
*/
default String getBuildNowText() {
return getParameterizedJobMixIn().getBuildNowText();
}
/**
* Gets currently configured triggers.
......@@ -322,6 +341,80 @@ public abstract class ParameterizedJobMixIn<JobT extends Job<JobT, RunT> & Param
*/
Map<TriggerDescriptor,Trigger<?>> getTriggers();
/**
* @deprecated use {@link #scheduleBuild(Cause)}
*/
@Deprecated
@Override
default boolean scheduleBuild() {
return getParameterizedJobMixIn().scheduleBuild();
}
@Override
default boolean scheduleBuild(Cause c) {
return getParameterizedJobMixIn().scheduleBuild(c);
}
/**
* @deprecated use {@link #scheduleBuild(int, Cause)}
*/
@Deprecated
@Override
default boolean scheduleBuild(int quietPeriod) {
return getParameterizedJobMixIn().scheduleBuild(quietPeriod);
}
@Override
default boolean scheduleBuild(int quietPeriod, Cause c) {
return getParameterizedJobMixIn().scheduleBuild(quietPeriod, c);
}
/**
* Provides a standard implementation of {@link SCMTriggerItem#scheduleBuild2} to schedule a build with the ability to wait for its result.
* That job method is often used during functional tests ({@code JenkinsRule.assertBuildStatusSuccess}).
* @param quietPeriod seconds to wait before starting (normally 0)
* @param actions various actions to associate with the scheduling, such as {@link ParametersAction} or {@link CauseAction}
* @return a handle by which you may wait for the build to complete (or just start); or null if the build was not actually scheduled for some reason
*/
@CheckForNull
default QueueTaskFuture<RunT> scheduleBuild2(int quietPeriod, Action... actions) {
return getParameterizedJobMixIn().scheduleBuild2(quietPeriod, actions);
}
/**
* Schedules a new build command.
* @see ParameterizedJobMixIn#doBuild
*/
default void doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException {
getParameterizedJobMixIn().doBuild(req, rsp, delay);
}
/**
* Supports build trigger with parameters via an HTTP GET or POST.
* Currently only String parameters are supported.
* @see ParameterizedJobMixIn#doBuildWithParameters
*/
default void doBuildWithParameters(StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException {
getParameterizedJobMixIn().doBuildWithParameters(req, rsp, delay);
}
/**
* Cancels a scheduled build.
* @see ParameterizedJobMixIn#doCancelQueue
*/
@RequirePOST
default void doCancelQueue(StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
getParameterizedJobMixIn().doCancelQueue(req, rsp);
}
/**
* For use from {@link BuildButtonColumn}.
* @see ParameterizedJobMixIn#isParameterized
*/
default boolean isParameterized() {
return getParameterizedJobMixIn().isParameterized();
}
}
}
......@@ -271,10 +271,17 @@ public abstract class LazyBuildMixIn<JobT extends Job<JobT,RunT> & Queue.Task &
*/
public interface LazyLoadingJob<JobT extends Job<JobT,RunT> & Queue.Task & LazyBuildMixIn.LazyLoadingJob<JobT,RunT>, RunT extends Run<JobT,RunT> & LazyLoadingRun<JobT,RunT>> {
LazyBuildMixIn<JobT,RunT> getLazyBuildMixIn();
// not offering default implementation for _getRuns(), removeRun(R), getBuild(String), getBuildByNumber(int), getFirstBuild(), getLastBuild(), getNearestBuild(int), getNearestOldBuild(int), or createHistoryWidget() since they are defined in Job
// nor for createExecutable() since that typically calls isDisabled() first
}
/**
* Marker for a {@link Run} which uses this mixin.
*/
public interface LazyLoadingRun<JobT extends Job<JobT,RunT> & Queue.Task & LazyBuildMixIn.LazyLoadingJob<JobT,RunT>, RunT extends Run<JobT,RunT> & LazyLoadingRun<JobT,RunT>> {
RunMixIn<JobT,RunT> getRunMixIn();
// not offering default implementations for createReference() or dropLinks() since they are protected
// nor for getPreviousBuild() or getNextBuild() since they are defined in Run
}
/**
......
......@@ -57,7 +57,7 @@ public interface SCMTriggerItem {
/** @see jenkins.model.ParameterizedJobMixIn.ParameterizedJob#getQuietPeriod */
int getQuietPeriod();
/** @see ParameterizedJobMixIn#scheduleBuild2 */
/** @see jenkins.model.ParameterizedJobMixIn.ParameterizedJob#scheduleBuild2 */
@CheckForNull QueueTaskFuture<?> scheduleBuild2(int quietPeriod, Action... actions);
/**
......
......@@ -467,7 +467,7 @@ THE SOFTWARE.
<plugin>
<groupId>com.infradna.tool</groupId>
<artifactId>bridge-method-injector</artifactId>
<version>1.15</version>
<version>1.17</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册