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

[jsr372-experts] Re: [jsr372-experts mirror] Re: Re: Re: Re: Search Expression API for JSF 2.3

From: Leonardo Uribe <leonardo.uribe_at_irian.at>
Date: Thu, 1 Dec 2016 21:52:18 -0500

Hi

There is a new exception called ComponentNotFoundException and a
SearchExpressionHint to ignore id called IGNORE_NO_RESULT.

The new algorithm is based on the previous discussion about 1372, so the
expression can locate clientIds inside UIData instances (through
invokeOnComponent). In fact, we mixed the proposal in primefaces with the
recursive algorithm I designed to fix 1372.

regards,

Leonardo Uribe

2016-12-01 2:40 GMT-05:00 Bauke Scholtz <balusc_at_gmail.com>:

> Hi,
>
> Looks definitely good, but it's not clear to me how it solves 1372. Does
> it throw a clear exception when the expression does not resolve to
> anything, regardless of the context?
>
> Cheers, B
>
> On Thu, Dec 1, 2016, 08:11 Leonardo Uribe <leonardo.uribe_at_irian.at> wrote:
>
>> Hi
>>
>> Basically the syntax to be included is the same there is in Primefaces.
>>
>> AT>> I haven't studied all the technical implications of the proposal
>> yet,
>> AT>> but the functionality itself it absolutely great to have!
>>
>> I'll describe it to make it easier to understand. Sorry if it is a bit
>> repetitive, but the idea is to provide some text about it.
>>
>> In few words, the API is all about search for one or many components from
>> a
>> specified component instance and do something with it / them.
>>
>> For example in this case:
>>
>> <h:outputLabel for="@next" value="Name">
>> <h:inputText id="name" value="#{bean.name}"/>
>>
>> h:outputLabel component requires to locate another component and to get
>> the
>> clientId to generate this html markup:
>>
>> <label for="mainForm:name">Name</label>
>>
>> Sometimes is just one component, sometimes there are many components:
>>
>> <h:commandButton ...>
>> <f:ajax render="@next anotherPanel"/>
>> </h:commandButton>
>> <h:panelGroup id="detail" layout="block">
>> ...
>> </h:panelGroup>
>>
>> In this case f:ajax requires to get a list of clientIds or keywords that
>> will
>> be passed to jsf.ajax.request(...).
>>
>> In f:ajax case, there are some keywords that can be resolved on the
>> client.
>> For example, @form or @all. So, the algorithm to resolve clientIds must
>> be able
>> to resolve some clientIds and return the keywords that can be resolved in
>> the
>> client unchanged (passthrough expression). Later, jsf.ajax.request(...)
>> will
>> complete the job and retrieve the remaining clientIds inspecting the DOM
>> tree.
>>
>> f:ajax "execute"/"render" is the most important case, but it is not the
>> only one.
>> In JSF there is invokeOnComponent(...) or visitTree(...), but both lack
>> some
>> flexibility, because there is no easy way to locate a component without
>> know the
>> clientId beforehand. Sometimes what the developer has is a "clue" that
>> helps to
>> identify the component(s).
>>
>> In "vainilla" JSF there are 4 known cases where this API is useful:
>>
>>
>> - h:message "for"
>> - h:outputLabel "for"
>> - f:ajax execute and render
>> - composite component "targets"
>>
>> In third party JSF component libraries we could found more cases and
>> that's
>> where we need help. The syntax proposed should cover these cases and the
>> ones
>> in Primefaces. But we need other examples to justify the "wildcard" case
>> proposed by Bootsfaces, because what I have seen so far is @id(...)
>> without
>> wilcards is good enough. Maybe extend @id to receive multiple ids.
>>
>> To be more specific, @id uses a visitTree(...) call from the base to
>> search
>> for components that has the id passed as param. For example in this case.
>>
>> <h:form id="mainForm">
>> <h:dataTable id="table">
>> <h:column>
>> <h:inputText id="name"/>
>> </h:column>
>> </h:dataTable
>> </h:form>
>>
>> With the expression "@form:table:@id(name)", a visitTree(...) call from
>> "table" is executed and then apply the action defined to each component
>> with "name" id, which means it applies the action for every row.
>>
>> regards,
>>
>> Leonardo Uribe
>>
>>
>> 2016-11-30 9:58 GMT-05:00 Cagatay Civici <cagatay.civici_at_gmail.com>:
>>
>> I agree, PrimeFaces users have been enjoying these alternative search
>> options for a long time, glad to see it as a standard.
>>
>> Regards,
>>
>> Cagatay Civici
>> PrimeTek
>>
>> On Wednesday, 30 November 2016 at 15:53, Josh Juneau wrote:
>>
>> The search expression API would be a very welcome addition to JSF, in my
>> opinion. Using IDs in JSF has been a pain point for many, so I think this
>> will be very well received.
>>
>> Josh Juneau
>> juneau001_at_gmail.com
>> http://jj-blogger.blogspot.com
>> https://www.apress.com/index.php/author/author/view/id/1866
>>
>>
>> On Wed, Nov 30, 2016 at 3:59 AM, arjan tijms <arjan.tijms_at_gmail.com>
>> wrote:
>>
>> Hi,
>>
>> I haven't studied all the technical implications of the proposal yet, but
>> the functionality itself it absolutely great to have!
>>
>> Thanks!
>>
>> Kind regards,
>> Arjan Tijms
>>
>>
>>
>> On Tue, Nov 29, 2016 at 7:12 AM, Leonardo Uribe <leonardo.uribe_at_irian.at>
>> wrote:
>>
>> Hi Kito
>>
>> KM>> Leonardo, this looks awesome. One question, though: what about
>> wildcard
>> KM>> / partial id matching? I'm surprised that is missing.
>>
>> The current proposal does not have it.
>> Please take a look at this link:
>>
>> http://www.beyondjava.net/blog/jsf-vs-primefaces-vs-
>> bootsfaces-search-expressions/
>>
>> Primefaces implementation does not have a wildcard like this. It has
>> something
>> like @id(...) that matches the components with the id defined using a
>> visitTree
>> call.
>>
>> In the link, Bootsfaces propose some wildcards like **:id* or
>> @findIdRecursive(id),
>> With the current API proposal, you can create your own keywords. The idea
>> could
>> be create a custom keyword that allows wildcard / partial id matching or
>> extend
>> @id(...) keyword to allow complex cases.
>>
>> It is not hard to implement a wildcard system, but we need a good syntax
>> and
>> some good examples where this can be useful. Until now, I have not found
>> examples or use cases and I only have the previous link, so it could be
>> great
>> if another expert could propose a good syntax for this part.
>>
>> The code has been already committed in MyFaces:
>>
>> http://svn.apache.org/repos/asf/myfaces/current23/
>> http://svn.apache.org/repos/asf/myfaces/core/branches/2.3.x/
>>
>> and Thomas Andraschko is reviewing it to include it in Mojarra.
>>
>> Suggestions are welcome.
>>
>> regards,
>>
>> Leonardo Uribe
>>
>> 2016-11-28 7:08 GMT-05:00 Kito Mann <kito.mann_at_virtua.com>:
>>
>> Leonardo, this looks awesome. One question, though: what about wildcard /
>> partial id matching? I'm surprised that is missing.
>>
>>
>> On Wed, 16 Nov 2016 at 22:09 Leonardo Uribe <leonardo.uribe_at_irian.at>
>> wrote:
>>
>> Hi
>>
>> As some of you already know, Thomas Andraschko from PrimeFaces team and
>> I have been working in a API that allows JSF developers to search
>> components using an expression like the one proposed by PrimeFaces here:
>>
>> http://blog.primefaces.org/?p=2740
>>
>> This mail is to give the EG an idea about how this API could work and
>> check if
>> everything has been covered from spec perspective.
>>
>> The issues in the spec that this feature will fix are:
>>
>> https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1238
>> Enhance component referencing / findComponent
>> https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1200
>> Search parent naming containers for component
>>
>> Some issues that are closed by different reasons, but are related:
>>
>> https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1372
>> f:ajax doesn't validate client ID anymore - confusing to starters
>> https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-567
>> Clarify f:ajax execute/render id behavior (closed as fixed, but for me it
>> is not)
>> https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1080
>> New Component APIs to manage EL context as it applies to components.
>>
>> The list of cases where this could be useful are (changes must be done in
>> these points):
>>
>> - h:message "for"
>> - h:outputLabel "for"
>> - f:ajax execute and render
>> - converter and validator "for".
>> - composite components "for"
>>
>> There is a table comparing the search expressions available by some
>> frameworks
>> on this link:
>>
>> http://www.beyondjava.net/blog/jsf-vs-primefaces-vs-
>> bootsfaces-search-expressions/
>>
>> The intention is standarize a subset of the proposal there.
>>
>> The idea is the algorithm must comply with the following:
>>
>> - Support the following keywords by default: @child, @composite,
>> @form, @namingcontainer, @next, @none, @parent, @previous,
>> @root, @this and @id
>> - Remember @all is valid for f:ajax and it is embedded in
>> PartialViewContext implementation. So @all return the top level
>> component (UIViewRoot) in other cases.
>> - It should be possible to reference a component inside UIData
>> instances.
>>
>> The syntax to support is this:
>>
>> <clientId>
>> :<id>
>> <id>:<id>:<id>
>> @<keyword>:<id>
>> id:@<keyword>
>> @<keyword>(<param1>)
>> @<keyword>(<param1>,<param2>)
>>
>> Some examples of possible expressions:
>>
>> @this
>> @next
>> @previous
>> @form:name
>> @namingcontainer:age
>> @parent:@id(msgName)
>> mainForm:table:3:baseText
>> mainForm:table:3:nested:1:nestedText
>>
>> It is possible to create custom keywords to extend the default algorithm
>> in
>> a similar way ELResolver works using this class:
>>
>> public abstract class SearchExpressionResolver
>> {
>>
>> public abstract void resolve(SearchKeywordContext expressionContext,
>> UIComponent last,
>> String command);
>>
>> }
>>
>> The main entry point is SearchExpressionHandler and contains the
>> following methods:
>>
>> public abstract String resolveClientId(
>> SearchExpressionContext searchExpressionContext, String
>> expressions);
>>
>> public abstract List<String> resolveClientIds(
>> SearchExpressionContext searchExpressionContext, String
>> expressions);
>>
>> public abstract void resolveComponent(
>> SearchExpressionContext searchExpressionContext, String
>> expression,
>> ContextCallback callback);
>>
>> public abstract void resolveComponents(
>> SearchExpressionContext searchExpressionContext, String
>> expressions,
>> ContextCallback callback);
>>
>> public abstract String[] splitExpressions(String expressions);
>>
>> In faces-config.xml this should be possible:
>>
>> <application>
>> <search-expression-handler>my.custom.SearchExpressionHandlerImpl</
>> search-expression-handler>
>> </application>
>>
>> One new factory will be added:
>>
>> <factory>
>> <search-expression-context-factory>....</search-
>> expression-context-factory>
>> </factory>
>>
>> And that's it.
>>
>> If anyone has a suggestion for improve the syntax, or some comment
>> related to
>> this topic, it is a good time to say something. Thanks for your attention.
>>
>> regards,
>>
>> Leonardo Uribe
>>
>>
>> --
>> ___
>>
>> Kito D. Mann | @kito99 | Author, JSF in Action
>> Web Components, Polymer, JSF, PrimeFaces, Java EE, and Liferay training
>> and consulting
>> Virtua, Inc. | virtua.tech
>> JSFCentral.com | @jsfcentral | knowesis.io
>> <http://knowesis.io/web/webcomponents> - fresh Web Components info
>> +1 203-998-0403
>>
>> * See me speak this December in Orlando at Live! 360:
>> http://bit.ly/LSPK52_Home
>> * Listen to the Enterprise Java Newscast: *http://
>> <http://blogs.jsfcentral.com/JSFNewscast/>enterprisejavanews.com
>> <http://ww.enterprisejavanews.com>*
>>
>>
>>
>>
>>
>>
>>