Package hudson.model

Class Descriptor<T extends Describable<T>>

All Implemented Interfaces:
Saveable, Loadable, OnMaster
Direct Known Subclasses:
AbstractNodeMonitorDescriptor, ArtifactManagerFactoryDescriptor, AuthorizationStrategy.Unsecured.DescriptorImpl, BuildDiscarderDescriptor, BuildStepDescriptor, BuildWrapperDescriptor, CaptchaSupportDescriptor, CloudSet.DescriptorImpl, ComputerConnectorDescriptor, ComputerSet.DescriptorImpl, ConsoleAnnotationDescriptor, Correlator, CrumbIssuerDescriptor, DefaultConsoleUrlProvider.DescriptorImpl, DelegatingComputerLauncher.DescriptorImpl, EnvVarsFilterLocalRuleDescriptor, FingerprintStorageDescriptor, FullControlOnceLoggedInAuthorizationStrategy.DescriptorImpl, GlobalBuildDiscarderStrategyDescriptor, GlobalConfiguration, GlobalSecurityConfiguration.DescriptorImpl, GlobalSettingsProviderDescriptor, HudsonPrivateSecurityRealm.DescriptorImpl, IdStrategyDescriptor, JNLPLauncher.DescriptorImpl, JobPropertyDescriptor, LabelAtomPropertyDescriptor, LegacyAuthorizationStrategy.DescriptorImpl, LegacySecurityRealm.DescriptorImpl, ListViewColumnDescriptor, MarkupFormatterDescriptor, MyViewsTabBarDescriptor, NodeDescriptor, PageDecorator, ParameterDefinition.ParameterDescriptor, ProjectNamingStrategy.ProjectNamingStrategyDescriptor, PropertyDescriptor, ProxyConfiguration.DescriptorImpl, QueueItemAuthenticatorDescriptor, RemotingWorkDirSettings.DescriptorImpl, RetentionStrategy.Always.DescriptorImpl, RetentionStrategy.Demand.DescriptorImpl, SCMCheckoutStrategyDescriptor, SCMDescriptor, SettingsProviderDescriptor, SimplePageDecorator, SimpleScheduledRetentionStrategy.DescriptorImpl, StatusFilter.StatusFilterDescriptor, ToolDescriptor, ToolInstallerDescriptor, TopLevelItemDescriptor, TriggerDescriptor, UserPropertyDescriptor, ViewDescriptor, ViewPropertyDescriptor, ViewsTabBarDescriptor

public abstract class Descriptor<T extends Describable<T>> extends Object implements Loadable, Saveable, OnMaster
Metadata about a configurable instance.

Descriptor is an object that has metadata about a Describable object, and also serves as a factory (in a way this relationship is similar to Object/Class relationship. A Descriptor/Describable combination is used throughout in Jenkins to implement a configuration/extensibility mechanism.

Take the list view support as an example, which is implemented in ListView class. Whenever a new view is created, a new ListView instance is created with the configuration information. This instance gets serialized to XML, and this instance will be called to render the view page. This is the job of Describable — each instance represents a specific configuration of a view (what projects are in it, regular expression, etc.)

For Jenkins to create such configured ListView instance, Jenkins needs another object that captures the metadata of ListView, and that is what a Descriptor is for. ListView class has a singleton descriptor, and this descriptor helps render the configuration form, remember system-wide configuration, and works as a factory.

Descriptor also usually have its associated views.


Descriptor can persist data just by storing them in fields. However, it is the responsibility of the derived type to properly invoke save() and load(). load() is automatically invoked as a JSR-250 lifecycle method if derived class do implement PersistentDescriptor.

Reflection Enhancement

Descriptor defines addition to the standard Java reflection and provides reflective information about its corresponding Describable. These are primarily used by tag libraries to keep the Jelly scripts concise.
Kohsuke Kawaguchi
See Also:
  • Field Details

    • clazz

      public final transient Class<? extends T extends Describable<T>> clazz
      The class being described by this descriptor.
  • Constructor Details

    • Descriptor

      protected Descriptor(Class<? extends T> clazz)
      clazz - Pass in self() to have the descriptor describe itself, (this hack is needed since derived types can't call "getClass()" to refer to itself.
    • Descriptor

      protected Descriptor()
      Infers the type of the corresponding Describable from the outer class. This version works when you follow the common convention, where a descriptor is written as the static nested class of the describable class.
  • Method Details

    • getDisplayName

      @NonNull public String getDisplayName()
      Human readable name of this kind of configurable object. Should be overridden for most descriptors, if the display name is visible somehow. As a fallback it uses Class.getSimpleName() on clazz, so for example MyThing from some.pkg.MyThing.DescriptorImpl. Historically some implementations returned null as a way of hiding the descriptor from the UI, but this is generally managed by an explicit method such as isEnabled or isApplicable.
    • getId

      public String getId()
      Uniquely identifies this Descriptor among all the other Descriptors.

      Historically clazz is assumed to be unique, so this method uses that as the default, but if you are adding Descriptors programmatically for the same type, you can change this to disambiguate them.

      To look up Descriptor from ID, use Jenkins.getDescriptor(String).

      Stick to valid Java identifier character, plus '.', which had to be allowed for historical reasons.
    • getT

      public Class<T> getT()
      Unlike clazz, return the parameter type 'T', which determines the DescriptorExtensionList that this goes to.

      In those situations where subtypes cannot provide the type parameter, this method can be overridden to provide it.

    • getDescriptorUrl

      public String getDescriptorUrl()
      Gets the URL that this Descriptor is bound to, relative to the nearest DescriptorByNameOwner. Since Jenkins is a DescriptorByNameOwner, there's always one such ancestor to any request.
    • getDescriptorFullUrl

      public final String getDescriptorFullUrl()
      Gets the URL that this Descriptor is bound to, relative to the context path.
    • getCurrentDescriptorByNameUrl

      public static String getCurrentDescriptorByNameUrl()
    • getCheckUrl

      @Deprecated public String getCheckUrl(String fieldName)
      since 1.528 Use getCheckMethod(String)
    • getCheckMethod

      public FormValidation.CheckMethod getCheckMethod(String fieldName)
      If the field "xyz" of a Describable has the corresponding "doCheckXyz" method, return the model of the check method.

      This method is used to hook up the form validation method to the corresponding HTML input element.

    • calcFillSettings

      public void calcFillSettings(String field, Map<String,Object> attributes)
      Computes the list of other form fields that the given field depends on, via the doFillXyzItems method, and sets that as the 'fillDependsOn' attribute. Also computes the URL of the doFillXyzItems and sets that as the 'fillUrl' attribute.
    • calcAutoCompleteSettings

      public void calcAutoCompleteSettings(String field, Map<String,Object> attributes)
      Computes the auto-completion setting
    • getPropertyType

      @CheckForNull public Descriptor.PropertyType getPropertyType(@NonNull Object instance, @NonNull String field)
      Used by Jelly to abstract away the handling of global.jelly vs config.jelly databinding difference.
    • getPropertyTypeOrDie

      @NonNull public Descriptor.PropertyType getPropertyTypeOrDie(@NonNull Object instance, @NonNull String field)
      Akin to getPropertyType(Object,String) but never returns null.
      AssertionError - in case the field cannot be found
    • getPropertyType

      public Descriptor.PropertyType getPropertyType(String field)
      Obtains the property type of the given field of clazz
    • getGlobalPropertyType

      public Descriptor.PropertyType getGlobalPropertyType(String field)
      Obtains the property type of the given field of this descriptor.
    • getJsonSafeClassName

      public final String getJsonSafeClassName()
      Gets the class name nicely escaped to be usable as a key in the structured form submission.
    • newInstance

      @Deprecated public T newInstance(org.kohsuke.stapler.StaplerRequest req) throws Descriptor.FormException
      Implement newInstance(StaplerRequest, JSONObject) method instead. Deprecated as of 1.145.
    • newInstance

      public T newInstance(@Nullable org.kohsuke.stapler.StaplerRequest req, @NonNull net.sf.json.JSONObject formData) throws Descriptor.FormException
      Creates a configured instance from the submitted form.

      Hudson only invokes this method when the user wants an instance of T. So there's no need to check that in the implementation.

      The default implementation of this method uses bindJSON(org.kohsuke.stapler.StaplerRequest, java.lang.Class<T>, net.sf.json.JSONObject) which performs the databinding on the constructor of clazz.

      For some types of Describable, such as ListViewColumn, this method can be invoked with null request object for historical reason. Such design is considered broken, but due to the compatibility reasons we cannot fix it. Because of this, the default implementation gracefully handles null request, but the contract of the method still is "request is always non-null." Extension points that need to define the "default instance" semantics should define a descriptor subtype and add the no-arg newInstance method.

      req - Always non-null (see note above.) This object includes represents the entire submission.
      formData - The JSON object that captures the configuration data for this Descriptor. See the developer documentation. Always non-null.
      Descriptor.FormException - Signals a problem in the submitted form.
    • bindJSON

      public static <T> T bindJSON(org.kohsuke.stapler.StaplerRequest req, Class<T> type, net.sf.json.JSONObject src)
      Replacement for StaplerRequest.bindJSON(Class, JSONObject) which honors newInstance(StaplerRequest, JSONObject). This is automatically used inside newInstance(StaplerRequest, JSONObject) so a direct call would only be necessary in case the top level binding might use a Descriptor which overrides newInstance(StaplerRequest, JSONObject).
    • getKlass

      public org.kohsuke.stapler.lang.Klass<?> getKlass()
      Returns the Klass object used for the purpose of loading resources from this descriptor. This hook enables other JVM languages to provide more integrated lookup.
    • getHelpFile

      public String getHelpFile()
      Returns the resource path to the help screen HTML, if any.

      Starting 1.282, this method uses "convention over configuration" — you should just put the "help.html" (and its localized versions, if any) in the same directory you put your Jelly view files, and this method will automatically does the right thing.

      This value is relative to the context root of Hudson, so normally the values are something like "/plugin/emma/help.html" to refer to static resource files in a plugin, or "/publisher/EmmaPublisher/abc" to refer to Jelly script abc.jelly or a method EmmaPublisher.doAbc().

      null to indicate that there's no help.
    • getHelpFile

      public String getHelpFile(String fieldName)
      Returns the path to the help screen HTML for the given field.

      The help files are assumed to be at "help/FIELDNAME.html" with possible locale variations.

    • getHelpFile

      public String getHelpFile(org.kohsuke.stapler.lang.Klass<?> clazz, String fieldName)
    • addHelpFileRedirect

      protected void addHelpFileRedirect(String fieldName, Class<? extends Describable> owner, String fieldNameToRedirectTo)
      Tells Jenkins that the help file for the field 'fieldName' is defined in the help file for the 'fieldNameToRedirectTo' in the 'owner' class.
    • isInstance

      public final boolean isInstance(T instance)
      Checks if the given object is created from this Descriptor.
    • isSubTypeOf

      public final boolean isSubTypeOf(Class type)
      Checks if the type represented by this descriptor is a subtype of the given type.
    • configure

      @Deprecated public boolean configure(org.kohsuke.stapler.StaplerRequest req) throws Descriptor.FormException
    • configure

      public boolean configure(org.kohsuke.stapler.StaplerRequest req, net.sf.json.JSONObject json) throws Descriptor.FormException
      Invoked when the global configuration page is submitted. Can be overridden to store descriptor-specific information.
      json - The JSON object that captures the configuration data for this Descriptor. See the developer documentation.
      false to keep the client in the same config page.
    • getConfigPage

      public String getConfigPage()
    • getGlobalConfigPage

      public String getGlobalConfigPage()
    • getCategory

      @NonNull public GlobalConfigurationCategory getCategory()
      Define the global configuration category the global config of this Descriptor is in.
      never null, always the same value for a given instance of Descriptor.
      2.0, used to be in GlobalConfiguration before that.
    • getRequiredGlobalConfigPagePermission

      @NonNull public Permission getRequiredGlobalConfigPagePermission()
      Returns the permission type needed in order to access the getGlobalConfigPage() for this descriptor. By default, requires Jenkins.ADMINISTER permission. For now this only applies to descriptors configured through the global (GlobalConfigurationCategory.Unclassified) configuration. Override to return something different if appropriate. The only currently supported alternative return value is Jenkins.MANAGE.
      Permission required to globally configure this descriptor.
    • getViewPage

      protected final String getViewPage(Class<?> clazz, String pageName)
    • getPossibleViewNames

      protected List<String> getPossibleViewNames(String baseName)
    • save

      public void save()
      Saves the configuration info to the disk.
      Specified by:
      save in interface Saveable
    • load

      public void load()
      Loads the data from the disk into this object.

      The constructor of the derived class must call this method. (If we do that in the base class, the derived class won't get a chance to set default values.)

      Specified by:
      load in interface Loadable
    • getConfigFile

      protected XmlFile getConfigFile()
    • getPlugin

      protected PluginWrapper getPlugin()
      Returns the plugin in which this descriptor is defined.
      null to indicate that this descriptor came from the core.
    • doHelp

      public void doHelp(org.kohsuke.stapler.StaplerRequest req, org.kohsuke.stapler.StaplerResponse rsp) throws IOException, javax.servlet.ServletException
      Serves help.html from the resource of clazz.
    • getStaticHelpUrl

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public static URL getStaticHelpUrl(org.kohsuke.stapler.StaplerRequest req, org.kohsuke.stapler.lang.Klass<?> c, String suffix)
    • toArray

      public static <T> T[] toArray(T... values)
    • toList

      public static <T> List<T> toList(T... values)
    • toMap

      public static <T extends Describable<T>> Map<Descriptor<T>,T> toMap(Iterable<T> describables)
    • newInstancesFromHeteroList

      public static <T extends Describable<T>> List<T> newInstancesFromHeteroList(org.kohsuke.stapler.StaplerRequest req, net.sf.json.JSONObject formData, String key, Collection<? extends Descriptor<T>> descriptors) throws Descriptor.FormException
      Used to build Describable instance list from <f:hetero-list> tag.
      req - Request that represents the form submission.
      formData - Structured form data that represents the contains data for the list of describables.
      key - The JSON property name for 'formData' that represents the data for the list of describables.
      descriptors - List of descriptors to create instances from.
      Can be empty but never null.
    • newInstancesFromHeteroList

      public static <T extends Describable<T>> List<T> newInstancesFromHeteroList(org.kohsuke.stapler.StaplerRequest req, Object formData, Collection<? extends Descriptor<T>> descriptors) throws Descriptor.FormException
    • findById

      @CheckForNull public static <T extends Descriptor> T findById(Collection<? extends T> list, String id)
      Finds a descriptor from a collection by its ID.
      id - should match getId()
    • findByDescribableClassName

      @CheckForNull public static <T extends Descriptor> T findByDescribableClassName(Collection<? extends T> list, String className)
      Finds a descriptor from a collection by the class name of the Describable it describes.
      className - should match Class.getName() of a clazz
    • find

      @Deprecated @CheckForNull public static <T extends Descriptor> T find(Collection<? extends T> list, String string)
      Finds a descriptor from a collection by its class name or ID.
    • find

      @Deprecated @CheckForNull public static Descriptor find(String className)
    • self

      protected static Class self()