Showing posts with label Tutorial. Show all posts
Showing posts with label Tutorial. Show all posts

Thursday, 30 January 2014

PrimeFaces JBoss forge plugin updated

With the announcement of the new CR release of JBoss Forge 2 (now final release), I remembered that once upon a time (already 2 years ago) I wrote a plugin for PrimeFaces for this tool.
Since then, a lot happened and that version of the plugin doesn’t support PrimeFaces 4. Although it isn’t a big problem, you can manually update the version number of the artifact to 4 in the pom.xml file, I decided to spent some time again on the plugin.
Mainly because the Forge 2 version uses a different concept and now you have the notion of addons. So a rework will be needed to keep the functionality in the new release of JBoss forge.

PrimeFaces 4

The new version of the plugin supports PrimeFaces 4 directly and you can use it to configure the Client Side Validation feature of PrimeFaces.

What are the commands that you need to specify within JBoss Forge?
forge install-plugin primefaces

This command will install the PrimeFaces plugin and is only required the one time.


new-project --named demo --topLevelPackage be.rubus.forge.demo --type war

This command will create a new maven project with packaging type war.  You can choose of course the value for the –topLevelPackage attribute. The command will also ask some questions like the location where the project must be created.


faces setup

This command will add the required maven dependencies for using JavaServer Faces development.  And it will add also some resource files like web.xml, faces-config.xml and beans.xml if you want CDI (this is a question of the command)


primefaces setup

Now the PrimeFaces dependency is added to the project. The version depends on selection you made and you are ready to go with your favourite IDE.

Additional goodies


The plugin also has some additional commands which can be handy
primefaces install-example-facelet

This adds a JSF view file (index.xhtml) which uses templating and contains a Hello World type example of using PrimeFaces.  This is handy is you are not familiar with PrimeFaces and shows you how to add the PrimeFaces namespace.  It is also an example of using the JSF 2.x template feature.


primefaces set-theme

If you execute this command, you see the list of available free themes for PrimeFaces.  It adds the required maven artifact and configures the theme in the web.xml file.


primefaces install-CSV

This is a PrimeFaces 4 specific command which configures the Client Side Validation feature in the web.xml file. See the PrimeFaces users guide how you can use this feature.

JBoss Forge 2


For the new release of the tool, the plugin will be adapted and a short guide will be posted when the addon is available. But enjoy version 1.1 of the PrimeFaces plugin from today on.

Thursday, 14 February 2013

Client Behavior functionality with JSF 2.x (part 2)

Introduction

In the previous text, I described how you can create a button that ask for a confirmation.  It showed the basic functionality of creating reusable client side functionality.
The example was very simple, just requiring one javaScript command.
In this text, I'll show some more advanced usages where you need to include an external resource and have to respond on multiple events.
The example shows how you can create the hover functionality for an input field. And of course with most browsers you can specify it as a css selector
    .myHover:hover {
        background-color: red;
    }
Unfortunately, not all browsers supports this and it is a pity that IE9 fails to understand it. So lets write an universal hover functionality.

Specify the event

For the change of color when the mouse is over a field, we need to respond to 2 events.  The mouse that enters the field, mouseover event, to adjust the color and when the mouse leaves the field, mouseout event, to revert the color to his original one.
So we need a client behaviour tag, just like the confirmation tag we have created the last time, lets call it hover so that we can attach the functionality to a field.  We have 2 events but we don't need to create 2 different tags. We are able to retrieve the intended event in the getScript method.
So let start with the definition of the tag in the facelet tag library
    <tag>
        <tag-name>hover</tag-name>
        <behavior>
            <behavior-id>hover<behavior-id>
        </behavior>
    </tag>;
This is identical to the confirmation functionality.  And we can use it in the following way
        <h:inputText value="#{bean.prop}" >
            <custom:hover event="mouseover"/>
            <custom:hover event="mouseout"/>
        </h:inputText>
We now specify the events we like to intercept and based on the event name, we can code the required javaScript        
    @Override
    public String getScript(ClientBehaviorContext behaviorContext) {
        if (MOUSEOVER_EVENT.equals(behaviorContext.getEventName())) {
            return "this.className += ' hoverClass '";
        }
        if (MOUSEOUT_EVENT.equals(behaviorContext.getEventName())) {
            return "this.className = this.className.replace( /(?:^|\\s)hoverClass(?!\\S)/g , '' )";
        }
        return null;
    }
The event name is passed to the getScript method in the behaviorContext parameter. The code adds or removes a CSS class to the HTML element. So when the hoverclass is defined as a red background, the input text element becomes red when the mouse is over the field and returns to his 'normal' color when we move out of it.

A single tag

The above solution is from a developers perspective not an ideal situation. The first improvement we will make is that you only need to specify 1 tag, and not 2.
The hover tag we created earlier was explicitly linked to the client behaviour functionality.  You can also create a tag for other purposes like a converter or your new component.  But there is also the possibility to create a tag for which you must implement the functionality, like this
<tag>
        <tag-name>myHover</tag-name>
        <handler-class>be.rubus.web.jsf.tutorial.clientbehaviour.HoverHandler</handler-class>
    </tag>

Within the HoverHandler, you must program the behaviour that you want. Before you can start with it, you must know what the function of a handler class is.

This class will be used by the JSF system to convert the xhtml page to the component tree. Afterwards this component tree will be converted to the HTML which is sent to the browser in the Render Response phase of the JSF lifecycle.
With a handler class you can change the created component tree. You can manipulate the 'DOM tree' (or what will become the DOM tree) by adding, removing and rearranging nodes but also change the properties of the nodes in the component tree.
The HoverHandler looks like this
public class HoverHandler extends TagHandler {
    private HoverBehavior mouseOver = new HoverBehavior();
    private HoverBehavior mouseOut = new HoverBehavior();
    public HoverHandler(TagConfig config) {
        super(config);
    }
    @Override
    public void apply(FaceletContext ctx, UIComponent parent) throws IOException {
        if (parent instanceof ClientBehaviorHolder) {
            ClientBehaviorHolder comp = (ClientBehaviorHolder) parent;
            comp.addClientBehavior("mouseover", mouseOver);
            comp.addClientBehavior("mouseout", mouseOut);
        }
    }
}
If you want to create a tag handler class of your own, you should extend it from javax.faces.view.facelets.TagHandler and do your work in the apply method. The method has a parameter parent and it is the immediate parent of the tag. In our case, the inputText.
Since we now have a reference to the component we like to modify, we can call the addClientBehavior method twice, once for the mouseover event and once for the mouseout event.
The HoverBehaviour class we pass along with the event names, is the same class as we used in the previous section.  So it will generate the correct javaScript code for each event.
So now we have improved our hover functionality greatly from a developers standpoint.  He doesn't have to type the event names (strings where he can make mistakes) and has to type a lot less characters.

Resource dependency

The only thing that can go wrong now, is the definition of the CSS class.  If we define it in the CSS file of the application, we have it available on every page.

But what if we decide to create some kind of reusable library so that we can use it for all the applications of the company. Or what if the javaScript code is large and we have placed it in an external file?
Maybe you know already that with a JSF renderer, you can specify the external resources the renderer depends on. Resources like javascript files and CSS files, just as we also need for the client behaviour functionality.
The good news is that there exists a special renderer for client behaviour, called ClientBehaviorRenderer.  It has also a getScript method that we need to implement and we can specify the resources we need with the ResourceDependency annotation.  This is the renderer version of the hover functionality
@FacesBehaviorRenderer(rendererType="hover")
@ResourceDependency(name = "hover.css")
public class HoverBehaviorRenderer extends ClientBehaviorRenderer {
    private static final String MOUSEOVER_EVENT = "mouseover";
    private static final String MOUSEOUT_EVENT = "mouseout";
    @Override
    public String getScript(ClientBehaviorContext behaviorContext, ClientBehavior behavior) {
        if (MOUSEOVER_EVENT.equals(behaviorContext.getEventName())) {
            return "this.className += ' hoverCls '";
        }
        if (MOUSEOUT_EVENT.equals(behaviorContext.getEventName())) {
            return "this.className = this.className.replace( /(?:^|\\s)hoverCls(?!\\S)/g , '' )";
        }
        return null;
    }
}
It is a straight copy, only the base class is different and has other annotations.
The client behavior itself becomes now empty, except for the definition of the renderer that must be used.
@FacesBehavior(value = "hover")
public class HoverBehavior extends ClientBehaviorBase {
    @Override
    public String getRendererType() {
        return "hover";
    }
}

Wrap up

We now have created a custom tag which allows us to have the 'hover' functionality using javascript functionalities. We only need a single tag and due to the renderer approach, we can package it in a jar file. When the file is in the classpath and we use the template, the correct coloring is applied to the 'hovered' field.

Conclusion

With the client side behavior of JSF 2, you have the possibilities to further enhance the components in a component library with some client side features in a reusable way. JSF remains mainly a server side framework but the client side representation can now greatly enhanced by the developer.
With these possibilities available, JSF can go along with the recent HTML5 and JavaScript frameworks raise in interest in the application development business.

You can find the code for this tutorial here.




Sunday, 3 February 2013

Client Behavior functionality with JSF 2.x (part 1)

Introduction

One of the lesser know new features of JSF 2, is the ability to define some client behavior for a component in a reusable way. We all know the possibility to enhance a component with ajax, using the tag.  It is also based on the Client Behavior functionality but we can define our custom functionality.

Just as you can define a validator for an input field, you can define a behavior which results in some JavaScript code which can be executed in the browser.

These features shows that, although JSF is still mainly a server side framework, the importance and the popularity of the client side is acknowledged.

Confirm button

We start with a simple example where we like to make a button that first asks for a confirmation before it performs its action.  A classic example is the button that deletes some information but first we ask the user for a confirmation if he is sure to execute this irreversible action.

The key Java class for the Client Behavior is ClientBehaviorBase. It implements the ClientBehavior interface, common to all functionality related to client side behavior, and by implementing the getScript method, half of the work is already done.
For our confirm functionality, we have a method like this

    @Override
    public String getScript(ClientBehaviorContext behaviorContext) {
        return "return confirm('Are you sure ?');";
    }

The return string is the JavaScript we like to execute in the browser, here it is the confirm method which pops-up a javascript ‘window’ with an OK and Cancel button.

When the class is annotated with @FacesBehavior, The JSF system add our class to the list of implemented client behaviors.

@FacesBehavior(value = "confirmation")
public class ConfirmBehavior extends ClientBehaviorBase {

The content of the value member is the, unique, name we can use to refer to our custom client behavior.  This is needed when we define a tag for the behavior.

A tag is needed so that we can specify in the xhtml files which components receive our javascript. In the facelet tag library we can define it as follows.

    <namespace>http://www.rubus.be/jsf/tutorial</namespace>

    <tag>
        <tag-name>confirmation</tag-name>
        <behavior>
            <behavior-id>confirmation</behavior-id>
        </behavior>
    </tag>



The behavior-id must match the value member of the FacesBehaviour annotation.  The tag name can be freely chosen but here it happens to be the same as the behavior id.

Assigning to a commandButton is not different than using any other custom tag that you have defined in a facelet tag library.

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:r="http://www.rubus.be/jsf/tutorial"
        >
<h:head>
    ...
</h:head>
<h:body>
    ...
    <h:form>
        ...
        <h:commandButton value="with confirmation" actionListener="#{bean.performAction}">
            <r:confirmation/>
        </h:commandButton>
        ...
    >/h:form>
    ...
</h:body>
</html>

When the user clicks now on the button, a confirmation is asked with the text ‘Are you sure?’. And when he clicks on the cancel button, the action listener method isn’t performed. In the case he has pressed on the OK button, the post to the server is executed as usual.

Which components


To what components can we attach a custom client behaviour? This is determined by the ClientBehaviourHolder interface.  It has a few methods to handle the addition and retrieval of registered client behaviors and event names. More on event names in the next section.

Well almost all components implement that interface.  The most useful ones are of course all the input fields and the buttons. But also on the html body component we can attach a behaviour. More specifically, the load event can be used to attach some additional code to the page when rendered in the browser.

How to specify the event?


In our example with the confirmation question, the javascript method is attached to the onClick method of the button.  This is because the click event is the default event for the commandButton component. If we like to attach the code to some other event, then we have to specify the event name with the event attribute of the tag. We will see an example of it in the second part of this blog.

What are all the events which are supported? This differs from component to component. But the rule is that when you have the onXXX attribute on a component to attach some behaviour, the event XXX is available for creating a reusable client behaviour with the technique explained above.

Conclusion


It is very easy to specify some client behavior in a repeatable manner with JSF 2. And in the second part of this text I’ll explain some more advanced topics of the client behavior functionality.

Sunday, 6 January 2013

DeltaSpike JSF message system

Introduction

One of the main aspects of the Java EE 6 version was type safety. With the introduction of CDI, there are many tasks that can be done in a type safe way, with no needs of Strings anymore.
This improves the quality of the code since it reduces the chance of typo errors. During compilation, you can be warned of your mistake.
DeltaSpike is a CDI extension that combines all the goodies of the Apache CODI and SEAM 3 frameworks. It is a work in progress and lately the work on some JSF goodies is started.
In this text, I want to explain the message feature of DeltaSpike. And although there is still some String handling required, at least it makes it very flexible and extensible.  This is not the case with the default JSF functionality.

Getting started

The message feature is based on some advanced features of CDI where we can define our message as methods in an interface where no implementation is needed. Lets explain this based on the classic Hello world style example.
So we start with an interface that we annotate with MessageBundle

@MessageBundle
public interface ApplicationMessages
{
    String helloWorld(String name);
}
In a managed bean/controller we can inject then the message component and ask for the text linked with the message.  This is an example of a managed bean using the JsfMessage.

@Named
@RequestScoped
public class ControllerView
{
    private String name;
    @Inject
    private JsfMessage msg;
    public void doGreeting()
    {
        msg.addInfo().helloWorld(name);
    }
}

In the typical Hello world style where there is an input field on the screen linked with the name property and a button linked to the doGreeting method, the above code shows a JSF Info message on the screen.

JsfMessage is also an interface and can take only as type parameter an interface which is annotated with MessageBundle such as in our example above.
On the JsfMessage interface there are methods available to add a message to the JSF Message system with a certain severity, like info in our example, add the message for a certain component or just get the text of the message, without adding it.

The default implementation takes care of looking up the correct locale, message text and assembles the resulting String.

It isn't CDI as it wasn't customizable and extensible. But before we look at the possibilities, I have to explain first where, by default, it looks for the text definition.

In the above example, a resource bundle ApplicationMessages in the same directory as the package of the interface is interrogated for the key helloWorld.
So by default, it looks in the same directory for a key which equals the method name.
 
helloWorld=Welcome %s

Also pay attention on how you need to specify the place of the parameter in the text.  The default version uses the String#format() method which requires the %-character as placeholder indicator.  This is different from the standard JSF where we used the {0} type of placeholder.

But this can be customized by the MessageInterpolator but first try some easy configuration options.

Configuration options

In the previous section, we used the JsfMessage feature in his most basic format.  We used all the default settings and implementations.  In this section, I'll explain how you can customize the ResourceBundle and the key which will be used.

On the methods, we can place the MessageTemplate annotation.  With this annotation we can specify the key or the entire text which will be used. In case it is a key in the resource bundle, we need to wrap it inside {} characters as you can see in the example below.
The second customization is the ResourceBundle name which will be searched, in addition to the default one. It can be specified by the MessageContextConfig#messageSource member.

As you noticed in my wording, it defines additional ResourceBundles, so be careful if you define multiple candidates where the resource key can be found.

@MessageBundle
@MessageContextConfig(messageSource = {"org.apache.deltaspike.example.message.ApplicationMessages" }) 
public interface CustomizedMessages
{
    @MessageTemplate(value = "{nowMessage}")
    String getTimestampMessage(Date now);
}

When we use the above code, we look for a key nowMessage in the ApplicationMessages ResourceBundle. Without the curly brackets, the text itself would be used without looking up a ResourceBundle.

Pay attention to the typos in the messageSource member. When you specify a non existing ResourceBundle, you don’t get a warning or error and of course, the text won’t be displayed correctly.

Customizing individual MessageBundles

With the MessageContextConfig annotation, when can also customize other functionality of the Message system. In this section I'll explain how you can change the MessageInterpolator back to the standard JSF version.

The MessageFormatMessageInterpolator class uses the java.text.MessageFormat to replace the placeholders in the string with the arguments as we are used too. The class implements the interpolate method from the MessageInterpolator interface.

The Custom annotation is a CDI qualifier that I created and is required before the example can work.  I'll explain in a moment the reason for this.

@Custom
public class MessageFormatMessageInterpolator implements MessageInterpolator
{
    @Override
    public String interpolate(String messageText, Serializable[] arguments, Locale locale)
    {
        return MessageFormat.format(messageText, arguments);
    }
}

As already mentioned, with the MessageContextConfig annotation we can decide to use this MessageInterpolator on certain MessageBundles like this

@MessageBundle
@MessageContextConfig(messageInterpolator = MessageFormatMessageInterpolator.class)
public interface CustomizedMessages
{

Why do we need a CDI qualifier on our implementation?  We are not using it for injection, we refer to it by its class name!  Since the default implementation is also available in the Bean archive, the CDI container has 2 implementations available and don't know which one to choose when he needs to inject a MessageInterpolator into the default JsfMessage implementation.

So without the qualifier, our application will fail during deployment with an ambiguous dependency error.

So it is easier and probably also much more useful to replace the default implementation with your version.  This is explained in the next section.

Replace default implementation

In the previous section we changed the behavior for one MessageBundle.  But most of the time, we need to change the default implementation and don't want to specify this for each MessageBundle we create in our application.

As an example, I'll show you how you can define that the message bundle in the Faces config file is also used when a resource key is searched in the ResourceBundles.

@Specializes
public class CustomMessageResolver extends DefaultMessageResolver
{
    @Override
    public String getMessage(MessageContext messageContext, String messageTemplate, String category)
    {
        addMessageBundleFromFacesConfig(messageContext);
        return super.getMessage(messageContext, messageTemplate, category);
    }
    private void addMessageBundleFromFacesConfig(MessageContext someMessageContext)
    {
        String messageBundle = FacesContext.getCurrentInstance().getApplication().getMessageBundle();
        if (messageBundle != null && messageBundle.length() > 0)
        {
            someMessageContext.messageSource(messageBundle);
        }
    }
}

For this, we need to override the DefaultMessageResolver and intercept the call to the getMessage method.  This is the only method in the MessageResolver interface and is responsible for looking up the resource key in resource bundles.  But custom implementation can be written to look up the message text in a database system for example.

Here we use the CDI specilization functionality.  When we annotate an extended CDI bean with Specializes, CDI will use our version, the CustomMessageResolver, in all the cases where DefaultMessageResolver would be used.  Without the need of a CDI qualifier and without the issue of having an ambiguous dependency error.

In our extension of the default functionality, we look in the faces configuration to see if there is a MessageBundle defined.  If so, we add it to the list of messageSources maintained and searched to find the requested message.

The same procedure can be used to define a custom MessageInterpolator and LocaleResolver, dedicated to find the language in which the message text must be returned.

Plain message text

In the hello World example at the beginning of the text, we used the JsfMessage DeltaSpike functionality to add a JSF message.  We can also ask for the text without the need to show it as a JSF Message.
The JsfMessage interface has the get() method for this purpose.  The following snippet could be used to display the current time as text on the screen with #{bean.now}

    public String getNow()
    {
        return custom.get().getTimestampMessage(new Date());
    }

Conclusion

There is no type safety, which is popular in Java EE6, with the JsfMessage feature of DeltaSpike because you always need to specify somehow the resource key that needs to be used when the text is looked up.  But you have a flexible and extensible system that is much more readable due to the builder like pattern.
The JsfMessage feature is currently (begin January 2013) under development in the 0.4-INCUBATING version and the code can be found here.
In the JsfExample module you can find the examples described in this text.

Wednesday, 9 November 2011

Custom reference resolver tutorial : creating a grammar


Introduction

In my previous blog entry, I presented an example on the new reference resolver add-on of ExtVal. It was able to read from a property from a MBean and use that value for validation.
As it was designed as a Reference Resolver, you had to specify a parameter at the cross field validation annotation of ExtVal where you needed the resolver. This is not friendly if you have designed some kind of resolver that you would use on a lot of locations.  Therefore the add-on has foreseen the option to create a new Reference Grammar. In this text I'll explain you how you can convert a reference resolver to a reference grammar.

Coding it

Basically, there are 2 small differences between a Reference Resolver and a Reference Grammar and you can use almost the same code in both situations. You only need to structure it a bit different.  Besides the registration of your grammar with the ExtVal add-on, see further, you should extend from the AbstractReferenceGrammar class. This class has a type parameter that needs to be specified.  In our case, it is just a simple object that holds the bean and property name. If you remember from my previous text, we invented a new grammar 'mbean@property' and the object just holds the 2 parts of the grammar (before and after the @-sign).
Your grammar has to implement 4 methods, so the empty grammar looks like this

@InvocationOrder(100)
public class MBeanGrammar extends AbstractReferenceGrammar
{

    @Override
    public void initGrammar()
    {
    }

    @Override
    protected boolean targetNotCompatibleWithGrammar(String targetValue)
    {
    }

    @Override
    protected MBeanGrammarData determineReference(String targetValue, MetaDataEntry metadataEntry)
    {
    }

    @Override
    public ReferencedValue resolveReference(MBeanGrammarData targetValue, MetaDataEntry metadataEntry)
    {
    }
}

where the (MBeanGrammarData object holds the bean and property name the user specified.

The initGrammar method is called when you register the grammar with the add-on.  You can use this interception point to do any initialization required to have a proper function of the grammar.  In our case we grab a reference to the MBean server we will be using for the resolving of the value.  Important thing to remember is that this method is just executed once.
When the ExtVal add-on encounters an annotation related to the cross field validation feature, it will ask to all the grammars if it can handle the specified reference.  Our implementation should return false for the targetNotCompatibleWithGrammar method when it contains the @-sign (our grammar can handle the reference) and true when we don't know it (like some EL-reference).  The first grammar that says that it can handle, will be used by the add-on.  How is the order determined? Grammars can be annotated with @InvocationOrder and the value you specify determines the order.  The default grammars (JavaBean and EL) have values of 950 and 1000.  So when we specify a value of 100, our new grammar is the first to be contacted to resolve the reference.
If we have a reference that we should handle, the add-on calls the determineReference method next. There we have the opportunity to parse the reference according to the grammar.  In our case it is just splitting the reference around the @-sign and put it into the MBeanGrammarData instance.

As a last step, the resolveReference method is called where we get the MBeanGrammarData instance we prepared in the previous step and we need to resolve the reference.  In our case we contact the MBean server, ask for the correct bean and extract the value of the property.  That value is wrapped nicely into the ReferencedValue and returned.

So the main difference is that the reference resolver contained all the logic in the resolveReference method and in the grammar version, we have the functionality split into 4 methods. You can find the code here.

Configuration

This is an additional step we need to do to integrate our grammar in the ExtVal add-on.  With the following 2 lines, placed in a startupListener, the Reference Grammar is registered and ready to use.

 ExtValContext extValContext = ExtValContext.getContext();
        extValContext.getModuleConfiguration(AdvancedCrossValidationAddonConfiguration.class).addReferenceGrammar(new MBeanGrammar());


Testing it

This version behaves exactly the same as our previous example, so I refer to the other text on how you can test it.

Conclusion

As easy it was to create a Reference Resolver, as easy it is to create a reference Grammar.  The grammar has the advantage that you don’t have to specify a parameter at the cross field validation annotation. But on the other side, if you only using it on a few locations, the add-on will ask your code for every reference, if you understand it.  So based on the concrete situation you have to decide what you need, a resolver or a reference.

Thursday, 20 October 2011

Custom reference resolver tutorial

Introduction


In the previous blog text, I described the cross field validation feature of ExtVal. In the meantime, the reference resolver add-on is released and this text shows how you can write your custom reference resolver.
And since the usage of the add-on API is easy, we are aiming a little bit higher with our example as a simple hello world. I'll explain you how you can write a resolver that checks a value stored in an MBean object.

Coding it

The reference resolver api is described here in the project documentation. There is just one method that you need to implement, resolveReference. The first parameter contains the string defined in the value attribute of the annotation (or method is repeatedly called for each string defined in the case of multiple values)


ReferencedValue resolveReference(final String targetValue, final MetaDataEntry metadataEntry);
So, first we have to 'invent' our indication how we will describe the property of the MBean where the value is stored. A possibility is using mbean@property where mbean is just the name in a certain node of our MBean server.

Our implementation of the method needs to do 3 things

  1. Get a reference to the MBean server of our environment
  2. Split the parameter in 2 parts (around the @ sign)
  3. Lookup the MBean and retrieve the value of the specified property.
If you aren't familiar with accessing JMX beans, you can find various documents on internet which explain it in detail. For this example, you can have a look at the source code placed in an apache extra repository (link). The implementation of our resolver is in the class org.os890.extval.addon.demo.resolver.MBeanReferenceResolver.

Before we can use this new resolver, we have to define a validationParameter so that we are able to use it in the cross field annotations of ExtVal. It is described in the add-on documentation on the referenceResolver page.

In our case, it results in:

public class MBeanReferenceResolver implements ReferenceResolver
{
    public interface MBeanReferenceResolverParameter extends ValidationParameter
    {
       @ParameterKey
       public Class KEY = ReferenceResolver.class;

       @ParameterValue
        public Class referenceResolverClass = MBeanReferenceResolver.class;
    }

     @Override
      public ReferencedValue resolveReference(String targetValue, MetaDataEntry metadataEntry)
      {
         // Implementation details omitted
       }
}
Now we can use this resolver in all cross field annotations like @Equals. In the example you can find a usage in the class org.os890.extval.addon.demo.view.BackingBean.

@Equals(value = "demo@TargetValue", parameters = MBeanReferenceResolver.MBeanReferenceResolverParameter.class)
private String source;
This property is linked to an inputField on a screen in the example.

Testing it

Now we are ready to run the example. If we press the 'Submit' button, a comparison will be made between the entered value and the value which is by default set in the MBean, which is 'ExtVal'. If they don't match, you see the message that the input is different.

This default value is set by the class org.os890.extval.addon.demo.startup.MBeanResolverStartupListener which is defined as JSF PhaseListener in the faces config file.

The following steps makes this example interesting. You can start up the default JMX console of your environment (look for the JConsole program) or any other JMX console that is able to connect to your (application) server. You will find between all the other MBeans, the one created by the demo application in the org.os890.extval.reference.addon node. It is called demo. The property TargetValue can be changed to another value, let's say 'Test'. If you now go back to your browser you will see that the comparison now only succeed with the new value 'Test' that you have entered in the JMX bean.

Conclusion
 This example shows how easy it is to create a new reference resolver and integrate it in ExtVal.  With the add-on you can create any reference you like that needs to be used by the cross field validation feature of ExtVal.