From d02065c09acb4c127d8ae60580dfd19941da74a0 Mon Sep 17 00:00:00 2001 From: kohsuke Date: Tue, 24 Feb 2009 19:44:48 +0000 Subject: [PATCH] improved parameterization of DescriptorExtensionList to better support custom Descriptor type. git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@15667 71c3de6d-444a-0410-be80-ed276b4c234a --- .../java/hudson/DescriptorExtensionList.java | 16 +++++++-- .../java/hudson/FileSystemProvisioner.java | 2 +- core/src/main/java/hudson/Functions.java | 3 +- .../java/hudson/model/AbstractProject.java | 2 +- core/src/main/java/hudson/model/Build.java | 2 +- core/src/main/java/hudson/model/Hudson.java | 6 ++-- .../hudson/model/ParameterDefinition.java | 2 +- .../java/hudson/scm/RepositoryBrowser.java | 2 +- .../main/java/hudson/scm/SubversionSCM.java | 3 +- .../security/AuthorizationStrategy.java | 2 +- .../java/hudson/slaves/NodeDescriptor.java | 2 +- .../java/hudson/slaves/RetentionStrategy.java | 2 +- .../main/java/hudson/tasks/BuildWrapper.java | 4 ++- core/src/main/java/hudson/tasks/Builder.java | 3 +- .../main/java/hudson/triggers/SCMTrigger.java | 21 +++++------ .../java/hudson/triggers/TimerTrigger.java | 8 ++--- .../main/java/hudson/triggers/Trigger.java | 35 ++++++++++++++++--- .../main/java/hudson/triggers/Triggers.java | 28 +++++++++------ .../java/hudson/views/ListViewColumn.java | 3 +- .../lib/hudson/project/config-trigger.jelly | 2 +- .../test/java/hudson/ExtensionListTest.java | 4 +-- 21 files changed, 99 insertions(+), 53 deletions(-) diff --git a/core/src/main/java/hudson/DescriptorExtensionList.java b/core/src/main/java/hudson/DescriptorExtensionList.java index 50bcd0cbe9..9968bdbdd9 100644 --- a/core/src/main/java/hudson/DescriptorExtensionList.java +++ b/core/src/main/java/hudson/DescriptorExtensionList.java @@ -26,8 +26,10 @@ package hudson; import hudson.model.Descriptor; import hudson.model.Describable; import hudson.model.Hudson; +import hudson.model.ViewDescriptor; import hudson.model.Descriptor.FormException; import hudson.util.Memoizer; +import hudson.slaves.NodeDescriptor; import java.util.List; import java.util.ArrayList; @@ -46,9 +48,17 @@ import net.sf.json.JSONObject; * * Use {@link Hudson#getDescriptorList(Class)} to obtain instances. * + * @param + * Represents the descriptor type. This is {@code Descriptor} normally but often there are subtypes + * of descriptors, like {@link ViewDescriptor}, {@link NodeDescriptor}, etc, and this parameter points + * to those for better type safety of users. + * + * The actual value of 'D' is not necessary for the operation of this code, so it's purely for convenience + * of the users of this class. + * * @since 1.286 */ -public final class DescriptorExtensionList> extends ExtensionList> { +public final class DescriptorExtensionList, D extends Descriptor> extends ExtensionList { /** * Type of the {@link Describable} that this extension list retains. */ @@ -65,7 +75,7 @@ public final class DescriptorExtensionList> extends Ext * @param fqcn * Fully qualified name of the descriptor, not the describable. */ - public Descriptor find(String fqcn) { + public D find(String fqcn) { return Descriptor.find(this,fqcn); } @@ -89,7 +99,7 @@ public final class DescriptorExtensionList> extends Ext * Loading the descriptors in this case means filtering the descriptor from the master {@link ExtensionList}. */ @Override - protected List> load() { + protected List load() { List r = new ArrayList(); for( Descriptor d : hudson.getExtensionList(Descriptor.class) ) { Type subTyping = Types.getBaseClass(d.getClass(), Descriptor.class); diff --git a/core/src/main/java/hudson/FileSystemProvisioner.java b/core/src/main/java/hudson/FileSystemProvisioner.java index f88a987b3d..b963811cf0 100644 --- a/core/src/main/java/hudson/FileSystemProvisioner.java +++ b/core/src/main/java/hudson/FileSystemProvisioner.java @@ -182,7 +182,7 @@ public abstract class FileSystemProvisioner implements ExtensionPoint, Describab /** * Returns all the registered {@link FileSystemProvisioner} descriptors. */ - public static DescriptorExtensionList all() { + public static DescriptorExtensionList all() { return Hudson.getInstance().getDescriptorList(FileSystemProvisioner.class); } diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index dd659ea239..790fdc78b8 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -41,6 +41,7 @@ import hudson.model.Project; import hudson.model.Run; import hudson.model.TopLevelItem; import hudson.model.View; +import hudson.model.ParameterDefinition.ParameterDescriptor; import hudson.search.SearchableModelObject; import hudson.security.AccessControlled; import hudson.security.AuthorizationStrategy; @@ -616,7 +617,7 @@ public class Functions { return RetentionStrategy.all(); } - public static List> getParameterDescriptors() { + public static List getParameterDescriptors() { return ParameterDefinition.all(); } diff --git a/core/src/main/java/hudson/model/AbstractProject.java b/core/src/main/java/hudson/model/AbstractProject.java index 044026a5f5..85c82732dc 100644 --- a/core/src/main/java/hudson/model/AbstractProject.java +++ b/core/src/main/java/hudson/model/AbstractProject.java @@ -1165,7 +1165,7 @@ public abstract class AbstractProject

,R extends A for (Trigger t : triggers) t.stop(); - triggers = buildDescribable(req, Triggers.getApplicableTriggers(this)); + triggers = buildDescribable(req, Trigger.for_(this)); for (Trigger t : triggers) t.start(this,true); diff --git a/core/src/main/java/hudson/model/Build.java b/core/src/main/java/hudson/model/Build.java index a53c1f151a..7349ac2255 100644 --- a/core/src/main/java/hudson/model/Build.java +++ b/core/src/main/java/hudson/model/Build.java @@ -74,7 +74,7 @@ public abstract class Build

,B extends Build> @Override protected void onStartBuilding() { super.onStartBuilding(); - SCMTrigger t = (SCMTrigger)project.getTriggers().get(SCMTrigger.DESCRIPTOR); + SCMTrigger t = (SCMTrigger)project.getTriggers().get(Hudson.getInstance().getDescriptorByType(SCMTrigger.DescriptorImpl.class)); if(t!=null) { // acquire the lock buildLock = t.getLock(); diff --git a/core/src/main/java/hudson/model/Hudson.java b/core/src/main/java/hudson/model/Hudson.java index 36a7c1f692..2efe1fb467 100644 --- a/core/src/main/java/hudson/model/Hudson.java +++ b/core/src/main/java/hudson/model/Hudson.java @@ -668,7 +668,7 @@ public final class Hudson extends Node implements ItemGroup, Stapl * Gets the trigger descriptor by name. Primarily used for making them web-visible. */ public TriggerDescriptor getTrigger(String shortClassName) { - return (TriggerDescriptor) findDescriptor(shortClassName, Triggers.TRIGGERS); + return (TriggerDescriptor) findDescriptor(shortClassName, Trigger.all()); } /** @@ -1504,7 +1504,7 @@ public final class Hudson extends Node implements ItemGroup, Stapl * Can be an empty list but never null. */ @SuppressWarnings({"unchecked"}) - public > DescriptorExtensionList getDescriptorList(Class type) { + public ,D extends Descriptor> DescriptorExtensionList getDescriptorList(Class type) { return descriptorLists.get(type); } @@ -2043,7 +2043,7 @@ public final class Hudson extends Node implements ItemGroup, Stapl for( SCMDescriptor scmd : SCMS.SCMS ) result &= configureDescriptor(req,json,scmd); - for( TriggerDescriptor d : Triggers.TRIGGERS ) + for( TriggerDescriptor d : Trigger.all() ) result &= configureDescriptor(req,json,d); for( JobPropertyDescriptor d : JobPropertyDescriptor.all() ) diff --git a/core/src/main/java/hudson/model/ParameterDefinition.java b/core/src/main/java/hudson/model/ParameterDefinition.java index 9294c11195..8637acd65f 100644 --- a/core/src/main/java/hudson/model/ParameterDefinition.java +++ b/core/src/main/java/hudson/model/ParameterDefinition.java @@ -137,7 +137,7 @@ public abstract class ParameterDefinition implements /** * Returns all the registered {@link ParameterDefinition} descriptors. */ - public static DescriptorExtensionList all() { + public static DescriptorExtensionList all() { return Hudson.getInstance().getDescriptorList(ParameterDefinition.class); } diff --git a/core/src/main/java/hudson/scm/RepositoryBrowser.java b/core/src/main/java/hudson/scm/RepositoryBrowser.java index 07b2f4f47b..1dbc57b731 100644 --- a/core/src/main/java/hudson/scm/RepositoryBrowser.java +++ b/core/src/main/java/hudson/scm/RepositoryBrowser.java @@ -101,7 +101,7 @@ public abstract class RepositoryBrowser implements /** * Returns all the registered {@link RepositoryBrowser} descriptors. */ - public static DescriptorExtensionList> all() { + public static DescriptorExtensionList,Descriptor>> all() { return (DescriptorExtensionList)Hudson.getInstance().getDescriptorList(RepositoryBrowser.class); } diff --git a/core/src/main/java/hudson/scm/SubversionSCM.java b/core/src/main/java/hudson/scm/SubversionSCM.java index 5e7511b6ab..0f392454db 100644 --- a/core/src/main/java/hudson/scm/SubversionSCM.java +++ b/core/src/main/java/hudson/scm/SubversionSCM.java @@ -44,6 +44,7 @@ import hudson.remoting.Callable; import hudson.remoting.Channel; import hudson.remoting.VirtualChannel; import hudson.triggers.SCMTrigger; +import hudson.triggers.SCMTrigger.DescriptorImpl; import hudson.util.EditDistance; import hudson.util.FormFieldValidator; import hudson.util.IOException2; @@ -516,7 +517,7 @@ public class SubversionSCM extends SCM implements Serializable { e.printStackTrace(listener.error("Failed to update "+l.remote)); // trouble-shooting probe for #591 if(e.getErrorMessage().getErrorCode()== SVNErrorCode.WC_NOT_LOCKED) { - listener.getLogger().println("Polled jobs are "+ SCMTrigger.DESCRIPTOR.getItemsBeingPolled()); + listener.getLogger().println("Polled jobs are "+ Hudson.getInstance().getDescriptorByType(SCMTrigger.DescriptorImpl.class).getItemsBeingPolled()); } return null; } diff --git a/core/src/main/java/hudson/security/AuthorizationStrategy.java b/core/src/main/java/hudson/security/AuthorizationStrategy.java index b49eba8e62..6303fc013b 100644 --- a/core/src/main/java/hudson/security/AuthorizationStrategy.java +++ b/core/src/main/java/hudson/security/AuthorizationStrategy.java @@ -182,7 +182,7 @@ public abstract class AuthorizationStrategy implements Describable all() { + public static DescriptorExtensionList> all() { return Hudson.getInstance().getDescriptorList(AuthorizationStrategy.class); } diff --git a/core/src/main/java/hudson/slaves/NodeDescriptor.java b/core/src/main/java/hudson/slaves/NodeDescriptor.java index 0d73e427ad..b5d0f356cb 100644 --- a/core/src/main/java/hudson/slaves/NodeDescriptor.java +++ b/core/src/main/java/hudson/slaves/NodeDescriptor.java @@ -63,7 +63,7 @@ public abstract class NodeDescriptor extends Descriptor { /** * Returns all the registered {@link NodeDescriptor} descriptors. */ - public static DescriptorExtensionList all() { + public static DescriptorExtensionList all() { return Hudson.getInstance().getDescriptorList(Node.class); } diff --git a/core/src/main/java/hudson/slaves/RetentionStrategy.java b/core/src/main/java/hudson/slaves/RetentionStrategy.java index 8e0c52bb31..4e60f2e0f0 100644 --- a/core/src/main/java/hudson/slaves/RetentionStrategy.java +++ b/core/src/main/java/hudson/slaves/RetentionStrategy.java @@ -90,7 +90,7 @@ public abstract class RetentionStrategy implements Describab /** * Returns all the registered {@link RetentionStrategy} descriptors. */ - public static DescriptorExtensionList> all() { + public static DescriptorExtensionList,Descriptor>> all() { return (DescriptorExtensionList)Hudson.getInstance().getDescriptorList(RetentionStrategy.class); } diff --git a/core/src/main/java/hudson/tasks/BuildWrapper.java b/core/src/main/java/hudson/tasks/BuildWrapper.java index c943be9c35..359f4e448d 100644 --- a/core/src/main/java/hudson/tasks/BuildWrapper.java +++ b/core/src/main/java/hudson/tasks/BuildWrapper.java @@ -34,6 +34,7 @@ import hudson.model.Project; import hudson.model.Action; import hudson.model.AbstractProject; import hudson.model.Hudson; +import hudson.model.Descriptor; import hudson.model.Run.RunnerAbortedException; import java.io.IOException; @@ -187,7 +188,8 @@ public abstract class BuildWrapper implements ExtensionPoint, Describable all() { + // for compatibility we can't use BuildWrapperDescriptor + public static DescriptorExtensionList> all() { // use getDescriptorList and not getExtensionList to pick up legacy instances return Hudson.getInstance().getDescriptorList(BuildWrapper.class); } diff --git a/core/src/main/java/hudson/tasks/Builder.java b/core/src/main/java/hudson/tasks/Builder.java index 03d77fd3a6..db1f8d4536 100644 --- a/core/src/main/java/hudson/tasks/Builder.java +++ b/core/src/main/java/hudson/tasks/Builder.java @@ -70,7 +70,8 @@ public abstract class Builder extends BuildStepCompatibilityLayer implements Bui /** * Returns all the registered {@link Builder} descriptors. */ - public static DescriptorExtensionList all() { + // for backward compatibility, the signature is not BuildStepDescriptor + public static DescriptorExtensionList> all() { return Hudson.getInstance().getDescriptorList(Builder.class); } diff --git a/core/src/main/java/hudson/triggers/SCMTrigger.java b/core/src/main/java/hudson/triggers/SCMTrigger.java index d138e82664..25e862deaf 100644 --- a/core/src/main/java/hudson/triggers/SCMTrigger.java +++ b/core/src/main/java/hudson/triggers/SCMTrigger.java @@ -101,7 +101,9 @@ public class SCMTrigger extends Trigger { pollingScheduled = true; LOGGER.fine("Scheduling a polling for "+job); - if (DESCRIPTOR.synchronousPolling) { + DescriptorImpl d = getDescriptor(); + + if (d.synchronousPolling) { LOGGER.fine("Running the trigger directly without threading, " + "as it's already taken care of by Trigger.Cron"); new Runner().run(); @@ -110,11 +112,15 @@ public class SCMTrigger extends Trigger { // even if we end up submitting this too many times, that's OK. // the real exclusion control happens inside Runner. LOGGER.fine("scheduling the trigger to (asynchronously) run"); - DESCRIPTOR.getExecutor().submit(new Runner()); - DESCRIPTOR.clogCheck(); + d.getExecutor().submit(new Runner()); + d.clogCheck(); } } + public DescriptorImpl getDescriptor() { + return (DescriptorImpl)super.getDescriptor(); + } + public Action getProjectAction() { return new SCMAction(); } @@ -126,12 +132,7 @@ public class SCMTrigger extends Trigger { return new File(job.getRootDir(),"scm-polling.log"); } - public DescriptorImpl getDescriptor() { - return DESCRIPTOR; - } - - public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl(); - + @Extension public static final class DescriptorImpl extends TriggerDescriptor { /** * Used to control the execution of the polling tasks. @@ -155,7 +156,7 @@ public class SCMTrigger extends Trigger { */ private int maximumThreads; - DescriptorImpl() { + public DescriptorImpl() { load(); /* * Need to resize the thread pool here in case there is no existing configuration file for SCMTrigger as diff --git a/core/src/main/java/hudson/triggers/TimerTrigger.java b/core/src/main/java/hudson/triggers/TimerTrigger.java index e52d650616..0b07f675eb 100644 --- a/core/src/main/java/hudson/triggers/TimerTrigger.java +++ b/core/src/main/java/hudson/triggers/TimerTrigger.java @@ -29,6 +29,7 @@ import hudson.model.Cause; import hudson.model.Item; import hudson.scheduler.CronTabList; import hudson.util.FormFieldValidator; +import hudson.Extension; import java.io.IOException; @@ -56,12 +57,7 @@ public class TimerTrigger extends Trigger { job.scheduleBuild(0, new TimerTriggerCause()); } - public TriggerDescriptor getDescriptor() { - return DESCRIPTOR; - } - - public static final TriggerDescriptor DESCRIPTOR = new DescriptorImpl(); - + @Extension public static class DescriptorImpl extends TriggerDescriptor { public boolean isApplicable(Item item) { return item instanceof BuildableItem; diff --git a/core/src/main/java/hudson/triggers/Trigger.java b/core/src/main/java/hudson/triggers/Trigger.java index c286e3b4ae..c139648d4a 100644 --- a/core/src/main/java/hudson/triggers/Trigger.java +++ b/core/src/main/java/hudson/triggers/Trigger.java @@ -27,6 +27,7 @@ import antlr.ANTLRException; import hudson.DependencyRunner; import hudson.DependencyRunner.ProjectRunnable; import hudson.ExtensionPoint; +import hudson.DescriptorExtensionList; import hudson.slaves.ComputerRetentionWork; import hudson.model.AbstractProject; import hudson.model.Action; @@ -50,6 +51,8 @@ import java.util.Collections; import java.util.GregorianCalendar; import java.util.Timer; import java.util.Date; +import java.util.List; +import java.util.ArrayList; import java.util.concurrent.Future; import java.util.logging.Level; import java.util.logging.Logger; @@ -59,7 +62,7 @@ import java.util.logging.Logger; * *

* To register a custom {@link Trigger} from a plugin, - * add it to {@link Triggers#TRIGGERS}. + * put {@link Extension} on your {@link TriggerDescriptor} class. * * @author Kohsuke Kawaguchi */ @@ -105,7 +108,9 @@ public abstract class Trigger implements Describable> return null; } - public abstract TriggerDescriptor getDescriptor(); + public TriggerDescriptor getDescriptor() { + return (TriggerDescriptor)Hudson.getInstance().getDescriptor(getClass()); + } @@ -181,7 +186,8 @@ public abstract class Trigger implements Describable> Hudson inst = Hudson.getInstance(); // Are we using synchronous polling? - if (SCMTrigger.DESCRIPTOR.synchronousPolling) { + SCMTrigger.DescriptorImpl scmd = inst.getDescriptorByType(SCMTrigger.DescriptorImpl.class); + if (scmd.synchronousPolling) { LOGGER.fine("using synchronous polling"); // Check that previous synchronous polling job is done to prevent piling up too many jobs @@ -190,7 +196,7 @@ public abstract class Trigger implements Describable> // ignored, only the global setting is honored. The polling job is submitted only if the previous job has // terminated. // FIXME allow to set a global crontab spec - previousSynchronousPolling = SCMTrigger.DESCRIPTOR.getExecutor().submit(new DependencyRunner(new ProjectRunnable() { + previousSynchronousPolling = scmd.getExecutor().submit(new DependencyRunner(new ProjectRunnable() { public void run(AbstractProject p) { for (Trigger t : (Collection) p.getTriggers().values()) { if (t instanceof SCMTrigger) { @@ -208,7 +214,7 @@ public abstract class Trigger implements Describable> // Process all triggers, except SCMTriggers when synchronousPolling is set for (AbstractProject p : inst.getAllItems(AbstractProject.class)) { for (Trigger t : p.getTriggers().values()) { - if (! (t instanceof SCMTrigger && SCMTrigger.DESCRIPTOR.synchronousPolling)) { + if (! (t instanceof SCMTrigger && scmd.synchronousPolling)) { LOGGER.fine("cron checking "+p.getName()); if (t.tabs.check(cal)) { @@ -251,4 +257,23 @@ public abstract class Trigger implements Describable> } }, 1000*10); } + + /** + * Returns all the registered {@link Trigger} descriptors. + */ + public static DescriptorExtensionList,TriggerDescriptor> all() { + return (DescriptorExtensionList)Hudson.getInstance().getDescriptorList(Trigger.class); + } + + /** + * Returns a subset of {@link TriggerDescriptor}s that applys to the given item. + */ + public static List for_(Item i) { + List r = new ArrayList(); + for (TriggerDescriptor t : all()) { + if(t.isApplicable(i)) + r.add(t); + } + return r; + } } diff --git a/core/src/main/java/hudson/triggers/Triggers.java b/core/src/main/java/hudson/triggers/Triggers.java index 520f9ed569..c9a97f85c9 100644 --- a/core/src/main/java/hudson/triggers/Triggers.java +++ b/core/src/main/java/hudson/triggers/Triggers.java @@ -25,6 +25,8 @@ package hudson.triggers; import hudson.model.Descriptor; import hudson.model.Item; +import hudson.util.DescriptorList; +import hudson.Extension; import java.util.List; import java.util.ArrayList; @@ -33,22 +35,28 @@ import java.util.ArrayList; * List of all installed {@link Trigger}s. * * @author Kohsuke Kawaguchi + * @deprecated as of 1.286 + * See each member for how to migrate your code. */ public class Triggers { - public static final List TRIGGERS = Descriptor.toList( - SCMTrigger.DESCRIPTOR, - TimerTrigger.DESCRIPTOR - ); + /** + * All registered {@link TriggerDescriptor} implementations. + * @deprecated as of 1.286 + * Use {@link Trigger#all()} for read access, and {@link Extension} for registration. + */ + public static final List TRIGGERS = (List)new DescriptorList>((Class)Trigger.class); +// Descriptor.toList( +// SCMTrigger.DESCRIPTOR, +// TimerTrigger.DESCRIPTOR +// ); /** * Returns a subset of {@link TriggerDescriptor}s that applys to the given item. + * + * @deprecated as of 1.286 + * Use {@link Trigger#for_(Item)}. */ public static List getApplicableTriggers(Item i) { - List r = new ArrayList(); - for (TriggerDescriptor t : TRIGGERS) { - if(t.isApplicable(i)) - r.add(t); - } - return r; + return Trigger.for_(i); } } diff --git a/core/src/main/java/hudson/views/ListViewColumn.java b/core/src/main/java/hudson/views/ListViewColumn.java index dd808f8166..e3b92eba3b 100644 --- a/core/src/main/java/hudson/views/ListViewColumn.java +++ b/core/src/main/java/hudson/views/ListViewColumn.java @@ -33,6 +33,7 @@ import hudson.model.Describable; import hudson.model.ListView; import hudson.model.Item; import hudson.model.Hudson; +import hudson.model.Descriptor; import hudson.util.DescriptorList; import org.kohsuke.stapler.export.Exported; @@ -69,7 +70,7 @@ public abstract class ListViewColumn implements ExtensionPoint, Describable all() { + public static DescriptorExtensionList> all() { return Hudson.getInstance().getDescriptorList(ListViewColumn.class); } diff --git a/core/src/main/resources/lib/hudson/project/config-trigger.jelly b/core/src/main/resources/lib/hudson/project/config-trigger.jelly index a1064906c1..285b9490fe 100644 --- a/core/src/main/resources/lib/hudson/project/config-trigger.jelly +++ b/core/src/main/resources/lib/hudson/project/config-trigger.jelly @@ -27,7 +27,7 @@ THE SOFTWARE. --> - + d = new Sishamo().getDescriptor(); - DescriptorExtensionList list = hudson.getDescriptorList(Fish.class); + DescriptorExtensionList> list = hudson.getDescriptorList(Fish.class); assertSame(d,list.get(Sishamo.DescriptorImpl.class)); assertSame(d,hudson.getDescriptor(Sishamo.class)); @@ -110,7 +110,7 @@ public class ExtensionListTest extends HudsonTestCase { // imagine that this is a static instance, like it is in many LIST static field in Hudson. DescriptorList LIST = new DescriptorList(Fish.class); - DescriptorExtensionList list = hudson.getDescriptorList(Fish.class); + DescriptorExtensionList> list = hudson.getDescriptorList(Fish.class); assertEquals(2,list.size()); assertNotNull(list.get(Tai.DescriptorImpl.class)); assertNotNull(list.get(Saba.DescriptorImpl.class)); -- GitLab