Java EE 8 By Example
  • Introduction
  • Overview
    • Example Codes
  • JSF 2.3
    • Activating CDI in JSF 2.3
    • Run applications in JSF 2.2 compatible mode
    • CDI alignment
    • CDI compatible @ManagedProperty
    • Inject support in Converter, Validator and Behavor
    • Websocket support
    • UIData improvements
    • Class level bean validation with f:valdiateWholeBean
    • Java 8 DateTime support
    • PostRenderViewEvent: publising events after view is rendered
    • Search expression framework
  • CDI 2.0
    • Java SE support
    • Event Priority
    • Async Events
    • Register Beans dynamicially
    • Configurators and Intercept Producers
  • JPA 2.2
    • Java 8 Datetime support
    • Return Stream based result from Query
    • More CDI Alignments
  • JSON-B 1.0
  • JSON-P 1.1
  • Bean Validation 2.0
  • JAXRS 2.1
    • Async improvements
    • Server Sent Event
    • Reactive Client
  • Java EE Security API 1.0
    • HttpAuthenticationMechanism
    • IdentityStore
    • SecurityContext
  • Servlet 4.0
    • Server Push
    • Runtime Discovery of Servlet Mappings
    • Http Trailer
  • MVC 1.0
    • Getting started with MVC
    • Handling form submission
    • Exception handling and form validation
    • Processing PUT and DELETE methods
    • Page navigation
    • MVC and CDI
    • Security
    • Bean parameter conversion
    • View engine
Powered by GitBook
On this page

Was this helpful?

  1. JSF 2.3

Search expression framework

PreviousPostRenderViewEvent: publising events after view is renderedNextCDI 2.0

Last updated 4 years ago

Was this helpful?

In before JSF versions, it uses an absolute hierarchical ID, or a relative local ID to locate a component, it is useful to rerender a component in an ajax request. For more flexible to query the component, JSF added @all, @form, @this expression to search the component to be re-rendered.

JSF 2.3 extends these expression by introducing new Component search expression framework, which adds some useful and powerful keywords, and also provides APIs to define your own keywords in the expression.

The following table lists all new keywords added in JSF 2.3, it is just a copy from .

Keyword

Description

@child(n)

The nth child of the base component

@composite

The closest composite component ancestor of the base component

@id(id)

All component descendants of the base component with the specified component id

@namingcontainer

The closest NamingContainer ancestor of the base component

@next

The next component in the view after the base component

@parent

The parent of the base component

@previous

The previous component to the base component

@root

The UIViewRoot

Let's try to create a custom keyword to find the grant parent node of the certain component in the component tree.

Create a new SearchKeywordResolver.

public class GrandParentKeywordResolver extends SearchKeywordResolver {

    @Override
    public boolean isResolverForKeyword(SearchExpressionContext searchExpressionContext, String keyword) {
        return "grandParent".equals(keyword);
    }

    @Override
    public void resolve(SearchKeywordContext searchKeywordContext, UIComponent current, String keyword) {
        UIComponent parent = current.getParent();
        if (parent != null) {
            searchKeywordContext.invokeContextCallback(parent.getParent());
        } else {
            searchKeywordContext.setKeywordResolved(true);
        }
    }
}

Register it via a @WebListener class.

@WebListener
public class WebInit implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        FacesContext.getCurrentInstance()
                .getApplication()
                .addSearchKeywordResolver(new GrandParentKeywordResolver());

    }
}

A simple facelets template.

<h:panelGroup id="panelgroup">
    <h:form id="form">
        <h:button id="button" outcome="foo2">Button foo</h:button>
        <h:commandButton id="commandButton" action="#{backingBean.foo()}" value="invoke foo"/>
        <h:outputText id="body" value="body"/>
    </h:form>
</h:panelGroup>

Get the grandParent id of the certain component at runtime.

public void foo() {
    SearchExpressionContext searchContext = createSearchExpressionContext(context, context.getViewRoot());

    context.getApplication()
            .getSearchExpressionHandler()
            .resolveComponent(
                    searchContext,
                    ":form:@parent",
                    (c, target) -> out.print(":form:@parent -> "+target.getId()));

    context.getApplication()
            .getSearchExpressionHandler()
            .resolveComponent(
                    searchContext,
                    ":form:@grandParent",
                    (c, target) -> out.print(":form:@grandParent -> "+target.getId()));
}

Grab the from my GitHub account, and have a try.

Arjan Tijms' blog entry: What's new in JSF 2.3
source codes