/******************************************************************************* * * Copyright (c) 2004-2010 Oracle Corporation. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * * Kohsuke Kawaguchi * * *******************************************************************************/ package hudson.model; import hudson.ExtensionPoint; import hudson.Launcher; import hudson.Plugin; import hudson.model.queue.SubTask; import hudson.tasks.BuildStep; import hudson.tasks.Builder; import hudson.tasks.Publisher; import hudson.tasks.BuildStepMonitor; import java.io.IOException; import java.util.Collection; import java.util.Collections; import org.kohsuke.stapler.export.ExportedBean; /** * Extensible property of {@link Job}. * * <p> {@link Plugin}s can extend this to define custom properties for * {@link Job}s. {@link JobProperty}s show up in the user configuration screen, * and they are persisted with the job object. * * <p> Configuration screen should be defined in <tt>config.jelly</tt>. Within * this page, the {@link JobProperty} instance is available as <tt>instance</tt> * variable (while <tt>it</tt> refers to {@link Job}. * * <p> Starting 1.150, {@link JobProperty} implements {@link BuildStep}, meaning * it gets the same hook as {@link Publisher} and {@link Builder}. The primary * intention of this mechanism is so that {@link JobProperty}s can add actions * to the new build. The * {@link #perform(AbstractBuild, Launcher, BuildListener)} and * {@link #prebuild(AbstractBuild, BuildListener)} are invoked after those of * {@link Publisher}s. * * @param <J> When you restrict your job property to be only applicable to a * certain subtype of {@link Job}, you can use this type parameter to improve * the type signature of this class. See * {@link JobPropertyDescriptor#isApplicable(Class)}. * * @author Kohsuke Kawaguchi * @see JobPropertyDescriptor * @since 1.72 */ @ExportedBean public abstract class JobProperty<J extends Job<?, ?>> implements Describable<JobProperty<?>>, BuildStep, ExtensionPoint { /** * The {@link Job} object that owns this property. This value will be set by * the Hudson code. Derived classes can expect this value to be always set. */ protected transient J owner; /** * Hook for performing post-initialization action. * * <p> This method is invoked in two cases. One is when the {@link Job} that * owns this property is loaded from disk, and the other is when a job is * re-configured and all the {@link JobProperty} instances got re-created. */ protected void setOwner(J owner) { this.owner = owner; } /** * Get the owner of this property * @since 3.2.1 * @return owner */ public J getOwner() { return owner; } /** * {@inheritDoc} */ public JobPropertyDescriptor getDescriptor() { return (JobPropertyDescriptor) Hudson.getInstance().getDescriptorOrDie(getClass()); } /** * @deprecated as of 1.341. Override {@link #getJobActions(Job)} instead. */ public Action getJobAction(J job) { return null; } /** * {@link Action}s to be displayed in the job page. * * <p> Returning actions from this method allows a job property to add them * to the left navigation bar in the job page. * * <p> {@link Action} can implement additional marker interface to integrate * with the UI in different ways. * * @param job Always the same as {@link #owner} but passed in anyway for * backward compatibility (I guess.) You really need not use this value at * all. * @return can be empty but never null. * @since 1.341 * @see ProminentProjectAction * @see PermalinkProjectAction */ public Collection<? extends Action> getJobActions(J job) { // delegate to getJobAction (singular) for backward compatible behavior Action a = getJobAction(job); if (a == null) { return Collections.emptyList(); } return Collections.singletonList(a); } // // default no-op implementation // public boolean prebuild(AbstractBuild<?, ?> build, BuildListener listener) { return true; } /** * {@inheritDoc} * * <p> Invoked after {@link Publisher}s have run. */ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { return true; } /** * Returns {@link BuildStepMonitor#NONE} by default, as {@link JobProperty}s * normally don't depend on its previous result. */ public BuildStepMonitor getRequiredMonitorService() { return BuildStepMonitor.NONE; } public final Action getProjectAction(AbstractProject<?, ?> project) { return getJobAction((J) project); } public final Collection<? extends Action> getProjectActions(AbstractProject<?, ?> project) { return getJobActions((J) project); } public Collection<?> getJobOverrides() { return Collections.emptyList(); } /** * Contributes {@link SubTask}s to {@link AbstractProject#getSubTasks()} * * @since 1.377 */ public Collection<? extends SubTask> getSubTasks() { return Collections.emptyList(); } }