Those Jenkins classes are bound to URLs by using Stapler. The singleton
Hudson instance is bound to the context root (e.g. "/") URL, and the rest of the objects are bound according to their reachability from this root object. For Stapler uses reflection to recursively determine how to process any given URL. A few examples of how the URL
/foo/bar could be processed:
getFoo(String)is defined on the
Jenkinsobject, and Stapler passes
baras a parameter. The object returned has a method called
doIndex(…)that gets called and renders the response.
doFoo()are defined. They return an object that has a
doBarmethod. The object returned from that has an associated
doFoo()are defined. The object return has a view named
A number of additional ways to handle requests exist, but these are the most common.
As a real-world example, there's the
Hudson.getJobJenkins#getJob(String) method. So the URL
/job/foo/ will be bound to the object returned by
Hudson.getJobJenkins#getJob("foo") (which would be a
Additionally, objects can implement one of two interfaces to further control how Stapler processes URLs:
StaplerProxyallows delegating the processing of a URL to another object
- . So, for
getFoo()returns an object
getTarget()method, Stapler will call
x.getTarget()and continue using that to process the rest of the URL (
bar). This has the highest priority among all possible URL processing options.
StaplerFallbackallows delegating the processing of a URL to another object, similar to
StaplerProxy, but has the lowest priority among all possible URL processing options.
Jenkins model objects have multiple "views" that are used to render HTML pages about each object. Jenkins uses Jelly as the view technology (which is somewhat similar to JSP+JSTL.) Views are really like methods, and each of them work against a particular class. So the views are organized according to classes that they belong to, just like methods are organized according to classes that they belong to. Again, see the stapler project for more about how this works.