On 4/26/07, Marc Hadley <Marc.Hadley_at_sun.com> wrote:
>
> On Apr 21, 2007, at 12:44 PM, Marc Hadley wrote:
> >
> >> I would favor the registry of externalizers discussed in another
> >> thread (registration with annotations), something like:
> >>
>
This would allow
> us to drop the ServiceFinder, ServiceConfiguration,
> TypeStreamingFactory and HeaderFactory classes from the API.
Big ++.
> @UriTemplate("/things/{thing_id}")
> public class ThingResource {
>
> public Thing(@UriParam("thing_id") String id) {...}
>
> @HttpMethod
> Thing get() {...}
> }
Off-topic, I would like to see @HttpMethod(GET) rather than a magic
method-name.
and a TypeStreamingProvider for Thing
>
> @Externalizer(classes={Thing.class}, type="application/thing")
> public class ThingExternalizer implements
> TypeStreamingProvider<Thing.class> {
Is there a case for multiple mediatypes too? for example:
@Externalizer(entity = Thing.class, mediaType = { "text/html", "text/xhtml"
})
I can see this being quite useful.
(note that you dont need braces {} when referring to a single element, it is
autoboxed into an array)
Thing readFrom(Class<Thing> type, MediaType mediaType,
> MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
> throws IOException {
> ...
> }
>
> void writeTo(Thing t, MediaType mediaType, MultivaluedMap<String,
> String> httpHeaders, OutputStream entityStream) throws IOException {
> ...
> }
> }
Just a lateral suggestion, but I'd like to use java "over-the-wire"
terminology for the aforementioned methods:
- marshall/unmarshall
- serialize/deserialize
- readExternal/writeExternal
The
> advantage is that the specification wouldn't need to tie down the
> method used as is currently the case with ServiceFinder.
+1. I think service location patterns belong with the dodo (and I don't mean
here in Australia =)
One downside I see is that this approach splits the metadata between
> two classes - you can't tell just by looking at the ThingResource
> class what media types are supported since that information is
> contained in the set of TypeStreamingProviders.
Yea I did think about this quite a bit before posting the @Externalizer
suggestion. There are a few solutions:
- Expose registered externalizers via a global injectable registry
(@Externalizers Map<Class<?>, Class<? extends TypeStreamingProvider>)
- Force annotation of the resource type with an @Externalizer (explicit
hook). This has the advantage of being able to override default
externalizers on a per-URI or per-method basis. And the disadv of being
un-enforceable and possibly violating Least Surprise (if the annotation is
unintentionally omitted).
- Don't worry about it--they are disparate concerns
However it does
> separate the two concerns nicely so you could add support for an
> additional format just by dropping in a new TypeStreamingProvider.
We would have to be *very* careful about implicit overrides, registration
order on overlapping keys, dual registrations to the same keys, etc.
> The specification would define a set of externalizers that an impl
> would be required to implement so an application only needs to add
> externalizers for custom types.
Good call. It might be worthwhile to start another thread listing what
externalizers we should require out of the box.
Dhanji.