users@jax-rs-spec.java.net

[jax-rs-spec users] Re: Different algorithms for sorting MBRs and MBWs

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Wed, 1 Apr 2015 17:17:01 +0100

Hi Santiago
On 01/04/15 14:53, Santiago Pericas-Geertsen wrote:
> Hi Sergey,
>
>>>> Why the MBR text does not refer to the Java parameter type as a primary key for sorting the providers, with the media type being the secondary keys.
>>>
>>> Of course MBRs do take into account the Java type, but there is no sorting as you point out.
>>>
>>> Suppose B extends A. If your resource parameter is of type B, there’s no point in using a MBR that can only produce A, you really need a B.
>>
>> And if an MBR B does not exist the MBR A can still return B
>
> To help the discussion, let’s say B is ColorPoint and A is Point. If you have a MBR for Point (A), then how could it return a ColorPoint (B)? It would simply not know how to read the “color”. If it knew how to do that, it would be a MBR for ColorPoint.

if (class.isAssignableFrom(ColorPoint.class)) {
} else {
     ....
}

where 'class' is a 1st parameter to readFrom()

What if we have say 30 Point subclasses :-) ? We can't have 30
providers, and the generalized example of it is a JAXB reader

>
>> (example, Object-typed JAXB or JSON readers returning Object subclasses), I'm just adding the details, as opposed to disagreeing at this stage...
>>
>>> On the other hand, if your method returns B, you may be able to use a MBW for A if one for B does not exist —it will at least serialize a part of the object.
>>>
>>> By the same token, you could argue that if C extends B, then you could use a MBR for C to produce a B. So for readers you could use subtypes instead of supertypes. I don’t know the history if this, but I suppose readers were assumed to be strict (needing to deserialize complete objects) while writers were not.
>>
>> This is fine but this rule where a B MBR is obviously better than an A MBR does not hold if A MBR has a more specific media type.
>>
>> I feel there's something that needs to be improved/clarified here.
>>
>> Consider two cases below (in both cases a resource parameter is B extending A), with a POST text/plain body.
>
> To be clear,
>
> @POST
> @Consumes(“text/plain")
> void foo(B b) { … }
>
Yes...
>>
>> Case1.
>>
>> @Consumes(*/*)
>> MBR<A>
>>
>> and
>>
>> @Consumes(*/*)
>> MBR<B>
>>
>>
>> Obviously B wins - as you said it does not make sense to choose the A MBR if the B MBR exists.
>>
>>
>> Case2.
>>
>> @Consumes(text/plain)
>> MBR<A>
>>
>> and
>>
>> @Consumes(*/*)
>> MBR<B>
>>
>>
>> Suddenly MBR A wins ?
>
> I’m not sure I follow. For MBRs we don’t sort by nearest superclass, right? Step 2 in 4.2.1 will only choose one that can produce a B. What am I missing?

Step 2 in 4.2.1 only identifies B from a Java method signature.
Step 4 should have both A and B MBRs selected as both can handle B by
returning 'true' from isReadable ?

>
> Perhaps providing a complete example may help :)

CXF has a primitive provider (Boolean, Character, Number) as
MBR<Object>, it (now) enforces a spec requirement that these primitives
are only supported by default if it is text/plain by doing an internal
check in its isReadable, it has no explicit Consumes. A custom
MBR<Boolean> is registered without Consumes. The test expects the
default primitive provider is to be selected based on the fact the spec
requires that it supports text/plain.

I think the spec does not require how its requirements that only
text/plain payloads can be mapped to Boolean/etc, but I'm wondering,
even if we had

@Consumes(text/plain)
BooleanAndNumberAndCharacterMBR<Object>

then how would it win over a custom

@Consumes(*/*)
BooleanMBR<Boolean>


Thanks, Sergey

>
> — Santiago
>