Re: Matching algorithm for resources

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 24 Apr 2007 18:31:52 +0200

Jan Algermissen wrote:
> Paul,
> yes, all good and valids points. I have been thinking about the various
> handler classes as being less strictly related I guess.


> Question:
> How does the dispatching work anyhow? Since the URI -> class mapping is
> only prsent inside the source code, how does the container access the
> mapping for dispatching?

Note that the annotations are retained at runtime so they are available
using the Java reflection API.

> Is your idea that, after pluging the classes in, the root class(es)
> paths' are added to the containers configuration?
> Or does the initial
> request handler iterate over the available handler classes o check for a
> match?

In our prototype we use the Java annotation processor to auto-magically
obtain the set of root classes from the Java source code. Then we
generate a Java class in a user-defined package that contains this set
of root classes. When creating a web application this package name is
used to obtain the generated class and the set of root classes. (We also
support the explicit setting of set of the root classes at runtime.)

These root classes are then processed to obtain the set of regular
expressions, derived from the URI templates on those classes, that are
the root set of regular expressions to initially match the URI path

When the runtime receives an HTTP request it obtains the URI path from
the request and goes through the (ordered) list of root regular
expressions to find the first matching resource. If it finds a match it
gets the matching right-hand-side of the URI path and tries to match
that right-hand-side URI path against all the regular expressions
derived from the sub-resources of the matching resource, and so on,
until the URI path is consumed (the right-hand-side is null) at which
point the HTTP request can be dispatched to a Java method on the last
matching resource.

The runtime can generate and cache the regular expressions from the
resources at runtime because the annotations are retained at runtime.
Essentially one can statically generate and cache meta Java Class
information derived from a Java class with its runtime-stored
annotations. One can generate this meta Java Class information on the
fly, which is necessary because when using dynamic resources the
concrete Java class is not known statically to the runtime.

Sorry for being a bit long winded! I hope this helps to further explain

> -------
> This reminds me: does the API so far include a standard way to access
> container configuration (for the handler classes to access configuration
> time parameters)?

By configuration time parameters do you mean the annotations?


> Talk to you in about an hour...
> Thanks,
> Jan
> On 24.04.2007, at 14:06, Paul Sandoz wrote:
>> Jan Algermissen wrote:
>>> Hi Paul,
>>> maybe i am missing something, but I do not see how e.g. the
>>> InvoiceResource is matched on a request URI?
>> InvoicesResource refers statically to InvoiceResource using the
>> SubResource annotation:
>> @UriTemplate("/invoices")
>> @SubResources({InvoiceResource.class})
>> class InvoicesResource { ... }
>> @UriTemplate("{invoice_Id}")
>> class InvoiceResource { ... }
>> Thus the URI path to InvoiceResource is:
>> /invoices/{invoice_Id}
>> i.e. the coalescing of the templates.
>> It is presented as steps 1 and 2 in the example table. I should have
>> put the Java classes in the table as well as it might have made things
>> a little clearer.
>>> Something else:
>>> I think that the actual paths (e.g. /invoice) are a configuration
>>> time issue and that dispatching from a request URI to
>>> a handler class should be done by a seperate component; it should not
>>> be part of the handler classes' source code
>>> (even if it's just an annotation).
>> This was an explicit design decision. We did not want to separate out
>> these things and wanted to keep the object model closely related to
>> the URI path hierarchy. See stapler [1] for more rational.
>>> Suppose I hand the class files for the code below to someone else
>>> that really does not want the path to be '/invoices'; what then?
>> This is not supported. (But i suppose it is possible to support such
>> aliasing in an underlying container by mapping between URI paths.)
>> Is it not the case that the designer of the Web application usually
>> controls the URI space and the relationship between resources in that
>> URI space?
>> In your experience how common a use-case would it be that the URI
>> templates would require changing while still keeping the Web
>> application consistent for the relationships between the resources?
>> For the Web application there are relationships between resources that
>> need to be maintained: between invoices and invoice, invoice and
>> deliveries, invoice and payments etc. Thus when considered as a whole
>> thing needs to interconnect. We chose a design where this
>> interconnection is part of the resource POJOs themselves so:
>> - the relationships between POJOs are not separated out into
>> two different places, there is only one place;
>> - related application logic need not be duplicated and/or distributed;
>> - POJOs can be intuitively reused without having to do
>> any configuration in a separate location; and
>> - POJOs can be polymorphic. For, example an invoice could be
>> polymorphic and specialized without having to break the contract
>> between invoices and invoice or invoice and deliveries etc.
>> Namely we have tried to take existing and familiar Java/OO concepts so
>> that it is 'as natural as possible' to develop RESTful Web
>> applications using just plain old Java objects.
>> From our experience with stapler/hudson it is often the case that
>> application logic can be associated quite closely with a bunch of
>> resources. For example in Hudson there is the concept of a job that
>> has a list of builds so the following URI paths interrelate for job
>> and builds:
>> job/my-job/ // get all the builds
>> job/my-job/buildTimeTrend // get a build time history as an image
>> job/my-job/lastBuild // get the last successful build
>> job/my-job/{build} // get a specific build
>> Having such relationships split up in my experience can increase the
>> number of Java classes and/or make it harder to implement and maintain
>> the application logic. As a further example the Hudson root resource
>> has at least 20 different sub-resources that interrelate in
>> application logic to various degrees with the super resource. IMHO as
>> such relationships start to grow having to maintain things in separate
>> places starts to become very unwieldy.
>> Paul.
>> [1]
>> --| ? + ? = To question
>> ----------------\
>> Paul Sandoz
>> x38109
>> +33-4-76188109
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail:
>> For additional commands, e-mail:
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

| ? + ? = To question
    Paul Sandoz