users@jersey.java.net

Re: Summary/proposal for spring integration

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 04 Apr 2008 10:11:34 +0200

[Moving to the users list]
On Apr 4, 2008, at 9:18 AM, Martin Grotzke wrote:

> Hi Paul,
>
> On Tue, 2008-04-01 at 10:46 +0200, Paul Sandoz wrote:
>> Martin Grotzke wrote:
>>> Did you already have time to work on the @ResourceProvider
>>> functionality?
>>>
>>
>> No :-( flat out on API stuff. I proposed to create a ResourceContext
>> iface like previously discussed:
>>
>> public interface ResourceContext {
>> <T> T getResource(Class<T> c);
>> }
>>
>> Do you want to have a go at that too? I can point you to the
>> locations
>> where it would need to be integrated. Most of the functionality is in
>> place... Perhaps we could do that first in the branch then merge
>> to the
>> trunk as a sort of warming up exercise :-)
> I just committed an early and simple version
> (branches/spring-integration, r910).
>

Great!


> Do you have some pointers where to start with the ResourceContext?
>

I think ResourceContext can be implemented and kept as a private
final field on WebApplicationImpl. Notice that the method
WebApplicationContext .getResource already implements the
functionality we require (we may be able to refactor the
UriRuleContext interface afterwards).

Then you can specify the injectable behaviour by adding an injectable
for the ResourceContext field in the
WebApplicationImpl.createInjectables method.


> How could we provide injection via @Context of spring beans - this was
> case 2:
>> - Additionally an @Inject annotation should be provided, so that not
>> each resource class has to be configured in the
>> applicationContext.xml
>> but can get other spring beans injected.
>> This annotation should also be available for resource method
>> parameters.
>

The ParameterExtractorFactory creates ParameterExtractor instances
for parameters of a constructor, sub-locator or resource method. The
defers to ParameterProcessorFactory to obtain the parameter
processors that creates parameter extractors. In this class you will
notice a map of Parameter.Source.Context to a ParameterProcessor.
Notice the first one associated with Parameter.Source.CONTEXT. (The
reason why annotations are not referred to directly is that we are
using the abstract resource model that hides the details that we are
using annotations.) A constructor or method parameter associated with
Source.CONTEXT (and @Context) will use the implementation
HttpContextParameterProcessor to obtain the parameter extractor. This
is where you can put the logic to defer to the component provider if
the class of the parameter is not of a known type. (BTW in the future
i want to have replacement functionality that generates byte code to
give a performance boost).

The tricky bit is working out how HttpContextParameterProcessor has
access to the CompomentProvider. I think there are three solutions:

1) Add a method to HttpContext to get access to the ComponentProvider;

2) Change the method signature of ParameterExtractor to include a
ComponentProvider parameter; or

3) Turn ParameterProcessor implementations into components, thus the
ComponentProvider can be injected. The ParameterProcessorFactory
would be initiated by WebApplicationImpl and use the
ComponentProviderCache to create the factory instances.

I think i prefer the latter. The reason being is the use of
ComponentProvider is specialized to one particular use-case. The
first exposes ComponentProvider to the API and i don't think it
should be used directly by developers, as it is really SPI
functionality. The second modifies the method signature for all
ParameterExtractor implementations.

Hope this helps,
Paul.