Write a JSF 2 custom EL resolver
|
|
|
The following example describe the creation and the configuration of a custom variable resolver or ELResolver using JSF .� The custom resolver we will implement will not implement VariableResolver or PropertyResolver but ELResolver to give you the fexibility to reuse the same implementation for different purpose.
In this example we want to retrieve a collection of
JSF
configuration parameters using EL directly in our
JSF
page. The keyword used to access the collection will be
jsfConfigurations.
Let's define first feature description associated with our variable to resolve :
| Name | Value |
|---|---|
| NAME | jsfConfigurations |
| DISPLAY_NAME | Jsf configurations |
| DESCRIPTION | JSF configurations parameters |
| EXPORT | false |
| HIDDEN | false |
| PREFERRED | true |
| TYPE | List.class |
| RESOLVABLE_DESIGN_TIME | Boolean.false |
Let's implement ELresover interface. ELResolver enables customization of variable, property and method call resolution behavior for EL expression evaluation.
Implementation of a custom ELResolver
As properties of our EL resolver we will define the feature description for the feature descriptor. If we have multiple FeatureDescriptor we will probably not define those properties as constants.
Return the correponding value
In the implementation of the getValue() we will return the Configuration items if the property requested correponds to the NAME constants ( jsfConfigurations )
Return the corresponding value type
For a given base and property this method attempts to identify the most general acceptable type for the corresponding property. jsfConfigurations is suppose to return a list of object.
|
|
Allowing base to be null for the first part of the expression is the key enabling concept that permits the JSF 1.1 concepts of VariableResolver and PropertyResolver to be combined into the ELResolver . When the base argument is null, an ELResolver functions much like a VariableResolver. Otherwise, it functions as a PropertyResolver. |
Implement setValue() method
Attempts to set the value of the given property� object on the given base� object. jsfConfigurations is a read only variable. We return a PropertyNotWritableException if someone try to edit our variable.
Read only
Our variable is read only
Feature description
The following method return an iterator returning information about the set of variables or properties that can be resolved.
Common property type
Returns the most general type that this resolver accepts
Return the collection
The last method return the collection needed by the getValue() method. In this example we are using the static attribute defined in our ApplicationBB backing bean.
Configure our EL Resolver in the webapp
Finally declaring the custom resolver in the faces-config is needed in order to put them to the responsibility chain.
The
el-resolver
element is used to specify the fully qualified class name of a
javax.el.ELResolver
implementation class that will replace the
JSF
implementation�s default expression language resolver implementation. The expression language resolver is called each time an expression
must be resolved. The el-resolver element provides the ability to override the default
JSF
expression language resolving by plugging in a custom ELResolver.
If you are facing a
listener start error
check if you have correctly defined the class in your EL-resolver. If your
logging configuration
is not properly defined you we not be able to see the ClassNotFoundException
Display the el expression in a datatable
As a conclusion you are now able to access your newly defined variable and iterate to display it in a data table
The result shoud look like
JSF Configuration
| name | description | defaultValue |
|---|---|---|
| com.sun.faces.NUMBER_OF_VIEWS_IN_LOGICAL_VIEW_IN_SESSION | 15 | |
| com.sun.faces.NUMBER_OF_VIEWS_IN_SESSION | 15 | |
| com.sun.faces.annotationScanPackages | ||
| com.sun.faces.clientStateTimeout | ||
| com.sun.faces.clientStateWriteBufferSize | 8192 | |
| com.sun.faces.compressableMimeTypes | ||
| com.sun.faces.defaultResourceMaxAge | 604800000 | |
| com.sun.faces.disableUnicodeEscaping | auto | |
| com.sun.faces.duplicateJARPattern | ||
| com.sun.faces.expressionFactory | com.sun.el.ExpressionFactoryImpl | com.sun.el.ExpressionFactoryImpl |
| com.sun.faces.faceletCache | ||
| com.sun.faces.faceletFactory | ||
| com.sun.faces.injectionProvider | ||
| com.sun.faces.managedBeanFactoryDecoratorClass | ||
| com.sun.faces.numberOfConcerrentFlashUsers | 5000 | |
| com.sun.faces.numberOfFlashesBetweenFlashReapings | 5000 | |
| com.sun.faces.numberOfLogicalViews | 15 | |
| com.sun.faces.numberOfViewsInSession | 15 | |
| com.sun.faces.resourceBufferSize | 2048 | |
| com.sun.faces.resourceUpdateCheckPeriod | 5 | |
| com.sun.faces.responseBufferSize | 1024 | |
| com.sun.faces.serializationProvider | ||
| facelets.BUFFER_SIZE | 1024 | |
| facelets.DECORATORS | ||
| facelets.LIBRARIES | ||
| facelets.REFRESH_PERIOD | 2 | |
| facelets.RESOURCE_RESOLVER | ||
| facelets.VIEW_MAPPINGS | ||
| javax.faces.CONFIG_FILES | ||
| javax.faces.DEFAULT_SUFFIX | .xhtml | .xhtml .jsp |
| javax.faces.FACELETS_BUFFER_SIZE | 1024 | |
| javax.faces.FACELETS_DECORATORS | ||
| javax.faces.FACELETS_LIBRARIES | /WEB-INF/tags/ubiteck.taglib.xml | |
| javax.faces.FACELETS_REFRESH_PERIOD | 2 | |
| javax.faces.FACELETS_RESOURCE_RESOLVER | ||
| javax.faces.FACELETS_SUFFIX | .xhtml | |
| javax.faces.FACELETS_VIEW_MAPPINGS | ||
| javax.faces.FULL_STATE_SAVING_VIEW_IDS | ||
| javax.faces.LIFECYCLE_ID | ||
| javax.faces.PROJECT_STAGE | Development | Production |
| javax.faces.RESOURCE_EXCLUDES | .class .jsp .jspx .properties .xhtml .groovy | |
| javax.faces.STATE_SAVING_METHOD | server | |
| javax.faces.VALIDATE_EMPTY_FIELDS | auto |
Conclusion
As you have seen, the unified EL provides more features like a pluggable, extensible resolver machinery, and a way to set data and invoke methods from the page.
If you have any remark or questions feel free to put a comment.If you enjoyed this tutorial and want to promote it don't hesitate to click on