dev@jsr311.java.net

RE: JSR311: ProviderFactory API needs a bit refactoring?

From: Liu, Jervis <jliu_at_iona.com>
Date: Wed, 7 Nov 2007 02:45:37 -0500

> -----Original Message-----
> From: Marc.Hadley_at_Sun.COM [mailto:Marc.Hadley_at_Sun.COM]
> Sent: 2007?11?7? 0:41
> To: dev_at_jsr311.dev.java.net
> Subject: Re: JSR311: ProviderFactory API needs a bit refactoring?
>
>
> Another thing, I wonder if we should define a sort order such
> that an
> entity provider that specifies "text/plain" is chosen ahead of an
> entity provider for the same type that specifies "text/*". I'm not
> sure how much use it would be but I don't really like the current
> unspecified order.
>
Hasnt this been defined by spec already? Section 3.1.1:

"When choosing an EntityProvider an implementation sorts the available providers according to the
media types they declare support for. Sorting of media types follows the general rule: x/y < x/* < */*, i.e. a
provider that explicitly lists a media types is sorted before a provider that lists */*. Quality parameter values
are also used such that x/y;q=1.0 < x/y;q=0.7."


> Marc.
>
> On Nov 6, 2007, at 11:30 AM, Marc Hadley wrote:
>
> > Thanks for bringing this up, we were about to run into a similar
> > problem fixing issue 20[1] in Jersey. I've created issue 25[2] to
> > track it.
> >
> > I agree that we need to tweak the SPI to support selection
> by media
> > type and read vs write but I think there's a potential subtle
> > problem with the method signature you suggest: its possible to
> > obtain an entity provider that supports a particular media
> type for
> > read but its not clear from the API what expectation a user of the
> > entity provider should have wrt writes. E.g. if I get an entity
> > provider that reads XML, should I expect that I can use the same
> > provider instance to write XML also ? I think there are three ways
> > we could approach this:
> >
> > 1. Add warnings to the specification and Javadoc that an
> > EntityProvider might not support the same media types for read and
> > write. Pros: simple, keeps everything in one interface. Cons:
> > potentially confusing, doesn't separate reading and writing
> > concerns, people don't always read warnings.
> > 2. Require EntityProviders to support the same media types
> for read
> > and write. Pros: simple, no need for the factory method to have a
> > read/write parameter. Cons: restrictive, may not always be
> possible
> > to read everything you can write or write everything you can read.
> > 3. Split the EntityProvider SPI into two interfaces (e.g.
> > EntityReader<T> and EntityWriter<T>),and have two methods in
> > ProviderFactory (createEntityReader(Class<T>, MediaType). Pros:
> > Keeps reading and writing separate, possible to write an entity
> > provider that only does one thing, removes potential
> confusion since
> > there no way to try to reuse a writer as a reader or vice verse.
> > Cons: extra interface and methods, more complex at first glance.
> >
> > BTW, I don't think there's any need for an array of media types in
> > the createEntityProvider method: for requests the media type is
> > single valued, for responses its the responsibility of either the
> > user to specify the media type (via Response or using ProduceMime)
> > or the client of the ProviderFactory (the runtime) to select a
> > specific media type from the list of acceptable types.
> >
> > Another question is whether EntityProvider needs a
> > supports(MediaType) method similar to the existing
> supports(Class<?>
> > ? This could be used when the Produce/Consume specifies a wilcard
> > type, e.g. "text/*" or could be used to allow a provider to reject
> > types when parameter values are not supported ?
> >
> > Thoughts, opinions ?
> > Marc.
> >
> > [1] https://jersey.dev.java.net/issues/show_bug.cgi?id=20
> > [2] https://jsr311.dev.java.net/issues/show_bug.cgi?id=25
> >
> > On Nov 6, 2007, at 12:19 AM, Liu, Jervis wrote:
> >
> >> Hi, It seems to me that the javax.ws.rs.ext. ProviderFactory API
> >> needs a bit refactoring in order to accommodate a more complex
> >> EntityProvider searching algorithm. For example, what we have
> >> currently in ProviderFactory is as below:
> >>
> >> public abstract class ProviderFactory {
> >> public abstract <T> EntityProvider<T>
> >> createEntityProvider(Class<T> type);
> >> }
> >>
> >> I.e., given a Java type then ProviderFactory returns an
> instance of
> >> EntityProvider that supports this Java type. However if we look
> >> into EntityProvider API, we will find a parameter of Java
> class is
> >> not enough for ProviderFactory to identify an
> EntityProvider to use
> >> for following reasons:
> >>
> >> a). EntityProvider can be annotated with
> @ProduceMime/_at_ConsumeMime
> >> and an EntityProvider can support different mime types for
> produce
> >> and consume. In this case when we ask ProviderFactory to
> return us
> >> a most appropriate EntityProvider, we really need to tell
> >> ProviderFactory the EntityProvider being requested is used for
> >> producing or consuming.
> >>
> >> b). ProviderFactory also needs to know the mine types of the
> >> request, this has been clearly stated in the spec, section 3.1.3:
> >>
> >> "2. Select the set of EntityProvider classes that support
> the media
> >> type of the request,"
> >>
> >> Enclosed below is a ProviderFactory I wrote that can return an
> >> instance of EntityProvider based on three parameters. Let me know
> >> if this is the intended way to use ProviderFactory and
> >> EntityProvider APIs.
> >>
> >> public class ProviderFactoryImpl extends ProviderFactory {
> >> public <T> EntityProvider<T> createEntityProvider(Class<T> type,
> >> String[] requestedMineTypes,
> >> boolean
> >> isConsumeMime) {
> >>
> >> for (EntityProvider<T> ep : entityProviders) {
> >> String[] supportedMimeTypes = {"*/*"};
> >> if (isConsumeMime) {
> >> ConsumeMime c =
> >> ep.getClass().getAnnotation(ConsumeMime.class);
> >> if (c != null) {
> >> supportedMimeTypes = c.value();
> >> }
> >> } else {
> >> ProduceMime c =
> >> ep.getClass().getAnnotation(ProduceMime.class);
> >> if (c != null) {
> >> supportedMimeTypes = c.value();
> >> }
> >> }
> >>
> >> if (matchMineTypes(supportedMimeTypes,
> >> requestedMineTypes) && ep.supports(type)) {
> >> return ep;
> >> }
> >> }
> >>
> >> return null;
> >> }
> >>
> >>
> >> private boolean matchMineTypes(String[] supportedMimeTypes,
> >> String[] requestedMimeTypes) {
> >> .
> >> }
> >> }
> >>
> >> Thanks,
> >> Jervis Liu
> >>
> >> ----------------------------
> >> IONA Technologies PLC (registered in Ireland)
> >> Registered Number: 171387
> >> Registered Address: The IONA Building, Shelbourne Road, Dublin 4,
> >> Ireland
> >>
> >>
> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: dev-unsubscribe_at_jsr311.dev.java.net
> >> For additional commands, e-mail: dev-help_at_jsr311.dev.java.net
> >>
> >
> > ---
> > Marc Hadley <marc.hadley at sun.com>
> > CTO Office, Sun Microsystems.
> >
> >
>
> ---
> Marc Hadley <marc.hadley at sun.com>
> CTO Office, Sun Microsystems.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_jsr311.dev.java.net
> For additional commands, e-mail: dev-help_at_jsr311.dev.java.net
>

----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland