dev@jsr311.java.net

Re: Matching algorithm for resources

From: Jan Algermissen <algermissen1971_at_mac.com>
Date: Tue, 24 Apr 2007 18:46:49 +0200

On 24.04.2007, at 18:31, Paul Sandoz wrote:
>
>> 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.
>
Ah yes, ok.

>
>> 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.)

Ok. So the handlers are plaugable at runtime, good.

>
> 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 against.
>
> 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 things.

Thanks, sounds reasonable.

Is there also a way to use the same class twice, just hooked to
different root paths? E.g. can I write a generic RDBMS wraper class
and have the container dispatch to multiple configurations of it (at
different root paths)?

>
>
>> -------
>> 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?

No, I mean for example database connection parameters that I pass in
via the configuration (this is surely not compile time information).

Jan


>
> Paul.
>
>> 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] https://stapler.dev.java.net/what-is.html
>>>
>>> --| ? + ? = To question
>>> ----------------\
>>> Paul Sandoz
>>> x38109
>>> +33-4-76188109
>>>
>>> --------------------------------------------------------------------
>>> -
>>> To unsubscribe, e-mail: dev-unsubscribe_at_jsr311.dev.java.net
>>> For additional commands, e-mail: dev-help_at_jsr311.dev.java.net
>>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe_at_jsr311.dev.java.net
>> For additional commands, e-mail: dev-help_at_jsr311.dev.java.net
>
> --
> | ? + ? = To question
> ----------------\
> Paul Sandoz
> x38109
> +33-4-76188109
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_jsr311.dev.java.net
> For additional commands, e-mail: dev-help_at_jsr311.dev.java.net
>