jsr372-experts@javaserverfaces-spec-public.java.net

[jsr372-experts] Re: [URGENT] _at_FacesDataModel inconsistencies with the spec (Re: Get your remaining items in)

From: arjan tijms <arjan.tijms_at_gmail.com>
Date: Tue, 14 Feb 2017 20:14:19 +0100

Hi,

On Tuesday, February 14, 2017, Leonardo Uribe <leonardo.uribe_at_irian.at>
wrote:

> Hi
>
> The problem here is there are other components that does not extend from
> UIData and uses DataModel.
>

I'm absolutely aware of the necessity and the use case ;)

But in my example the component that needs the DataModel instance doesn't
have to extend from UIData. Using the trick I mentioned you can instantiate
a separate UIData instance, then do the setValue/getDataModel trick on it.


> The closest example is UIRepeat, but there are others too.
>

UIRepeat should already support it as well, but the issue is of course
components from third party libraries that don't extend from either UIData
or UIRepeat.

Those can use the trick I mentioned though. Not ideal I know, but should
work for now.



> The important thing is provide something somewhere that can be commonly
> accessed. For example, we could use a map or some generic interface stored
> in externalContext.getApplicationMap(). It that way, we can avoid add
> methods, but we provide what we need just agreeing with the name and what
> does it return. It is not perfect but it is something at least. Is this
> possible alternative feasible?
>

I personally can't authorise anything, as I'm just a regular EG member like
you are. Only Ed can possibly allow this at this point.

But I'm afraid it's, unfortunately, simply too late now.

Kind regards,
Arjan Tijms


> regards,
>
> Leonardo Uribe
>
> 2017-02-14 11:41 GMT-05:00 arjan tijms <arjan.tijms_at_gmail.com
> <javascript:_e(%7B%7D,'cvml','arjan.tijms_at_gmail.com');>>:
>
>> Hi Leo,
>>
>> On Tue, Feb 14, 2017 at 12:40 AM, Leonardo Uribe <leonardo.uribe_at_irian.at
>> <javascript:_e(%7B%7D,'cvml','leonardo.uribe_at_irian.at');>> wrote:
>>
>>> Hi
>>>
>>> And the two methods proposed in Application class?
>>>
>>> public void addDataModel(Class<?> forClass, String dataModelClass)
>>> public DataModel createDataModel(java.lang.Class<?> forClass, Object
>>> value)
>>>
>>
>> The functionality for addDataModel at least is handled by CDI. That can't
>> be done by such a method, since it has to be done in the CDI extension and
>> the JSF Application class is not necessarily available by then. The other
>> way around, when the Application class is available it's too late for CDI
>> to accept new Bean<T> registrations, let alone annotated types.
>>
>> The createDataModel method is practically there already, it's in Mojarra:
>>
>> private DataModel<?> createDataModel(final Class<?> forClass)
>>
>> I would love to have added this method somewhere publicly, but I'm afraid
>> it's now too late for that :(
>>
>> What you CAN do however, is subclass UIData, then instantiate that. Then
>> do
>>
>> myUIData.setValue(someClassInstance);
>> UIDataModel<?> myModel = myUIData.getDataModel();
>>
>> That should guaranteed give you the right DataModel instance. If it's
>> covered by an existing known type it will return the wrapper for that,
>> otherwise the CDI version will be called.
>>
>> I humbly apologise for my oversight of adding that method at a public
>> place before. This is indeed my mistake. I will update the JavaDoc as you
>> requested to clarify this usage. For the next spec cycle we could add a
>> more convenient mechanism at the earliest opportunity.
>>
>> Once again my apologies and thanks for finding this.
>>
>> Kind regards,
>> Arjan Tijms
>>
>>
>>
>>
>>
>>> I think that's the easiest way to fix it, because it standarize the way
>>> to access
>>> registered DataModel classes and encapsulate the algorithm that finds
>>> the right
>>> DataModel from a specified class.
>>>
>>> regards,
>>>
>>> Leonardo Uribe
>>>
>>> 2017-02-13 18:31 GMT-05:00 arjan tijms <arjan.tijms_at_gmail.com
>>> <javascript:_e(%7B%7D,'cvml','arjan.tijms_at_gmail.com');>>:
>>>
>>>> Hi,
>>>>
>>>> On Mon, Feb 13, 2017 at 11:35 PM, Leonardo Uribe <
>>>> leonardo.uribe_at_irian.at
>>>> <javascript:_e(%7B%7D,'cvml','leonardo.uribe_at_irian.at');>> wrote:
>>>>
>>>>> I have been checking the related documentation of @FacesDataModel and
>>>>> the
>>>>> unofficial explanation in:
>>>>>
>>>>> http://arjan-tijms.omnifaces.org/2015/07/jsf-23-new-feature-
>>>>> registrable.html
>>>>>
>>>>> The feature is ok from a functional perspective, it has sense,
>>>>>
>>>>
>>>> Good! :)
>>>>
>>>>
>>>>
>>>>> It means if UIData.getValue() has a value with type MyCollection, the
>>>>> value
>>>>> will be wrapped in a MyCollectionModel instance. This resembles
>>>>> "targetClass" for Converter instances.
>>>>>
>>>>
>>>> True, that kinda was the inspiration for the particular implementation
>>>> of this feature request.
>>>>
>>>>
>>>>
>>>>> But in JSF, there is an Aplication class where you can register
>>>>> Converter
>>>>> instances to apply for an specific "targetClass" and so on. But there
>>>>> is
>>>>> nothing for DataModel.
>>>>>
>>>>
>>>> It basically happens fully via CDI now. Either user provided with the
>>>> @FacesDataModel annotation, or programmatically by adding your own
>>>> annotated classes and/or Bean<T> instances using the CDI API (in an CDI
>>>> extension).
>>>>
>>>>
>>>>
>>>>> no new description in UIData.getDataModel(), nothing.
>>>>>
>>>>
>>>> That's a good point, I'll look at providing something of a description
>>>> there right away.
>>>>
>>>> Thanks again Leo!
>>>>
>>>> Kind regards,
>>>> Arjan Tijms
>>>>
>>>>
>>>>
>>>>
>>>
>>
>