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

[jsr372-experts] Search Expression API for JSF 2.3

From: Leonardo Uribe <leonardo.uribe_at_irian.at>
Date: Wed, 16 Nov 2016 22:09:33 -0500

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