JSF application configuration file
A very useful facility of JSF Tools consists of an editor especially designed for managing everything that is related to the JSF main configuration file (faces-config.xml
). You can start this editor like this:
- Place the cursor in the Package Explorer view on your project node.
- Expand your JSF project node: registerJSF| WebContent|WEB-INF.
- Double-click on the faces-config.xml file.
When the editor is available, it will appear as in the screenshot shown below:
The Diagram view
From this view, you can easily manage pages and transitions between the application's pages (navigation rules). You can create, modify, or delete a page/transition in just a few seconds, and you will always have a clear image of the application flow, thanks to the graphical representation mode.
As an example, let's create two pages named register.jsp
and success.jsp
. Usually, you would have had to edit these files by hand to describe the pages flow, but using Diagram view features, we can do it visually. For this, you have to apply the following steps:
- Right-click inside the Diagram view and select the New View... option from the contextual menu:
Another way to create a new page is selecting the View Template icon (fourth from the top) from the toolbar placed in the top-left corner of the Diagram view and, following that, clicking inside the Diagram view surface.
- The above step will open the New View window (as shown in the following screenshot). In the From-View-ID field, enter the relative path and name of the new page. For example, you can type pages/register (without the
.jsp
extension). Leave everything else unchanged and click on the Finish button. - Repeat step 2, but this time type pages/success in the From-View-ID field. Note that both pages are represented on the Diagram view surface as you can see in the following screenshot. Also, they are present under the registerJSF/WebContent/pages directory in the Package Explorer view.
Now, it is time to connect the two pages by creating a transition (navigation rule) from register.jsp
to success.jsp
. To do this, follow these steps:
- Select the Create New Connection icon (third from the top) from the toolbar placed in the top-left corner of the Diagram view. This will change the cursor into an arrow cursor with a two-pronged plug at the arrow's bottom.
- Click on
register.jsp
and after that click onsuccess.jsp
. You should see something resembling that shown in the following screenshot: - Save the changes by selecting Save option from the main File menu.
The Tree view
Maybe the most important view of this editor is the Tree view, which is made of a set of nodes that put the configuration file in a graphical and easy-to-use manner. Just with a few clicks, we can create and modify the properties of the JSF components by skipping the annoying process of manually editing the configuration file. In this section you will see how to exploit this view for managing the most important components of a JSF application, such as managed beans, converters, and validators. The Tree view can be seen as shown in the following screenshot:
A very powerful facility of the Tree view is the support for managed beans. Now, we can create, modify, and delete managed beans without touching the source code. Next, you will see how to create beans properties, how to create getter and setter methods, and how to obtain the generated source code in just a few steps.
As you have seen in the introduction of this chapter, we want to develop a registration form (register.jsp
) with four fields representing name (java.lang.String
), age (int
), birth date (java.util.Date
), and phone number (register.PhoneNumber
) of the user. Each of these fields can be encapsulated as a property of a managed bean that can be developed by following these steps:
- Select the Managed Beans node from the left panel inside the Tree view.
- From the right panel (which is displaying the current managed beans status), click on the Add button. This will open the New Managed Bean window (as shown in the following screenshot):
- In this window you have to specify the scope where the managed bean is active (in our case, the request scope), the class that represents the managed bean (for example, type register.PersonBean), and a bean's alias name used as a shortcut name (for example, type personBean). Because we want to allow JSF Tools to generate the managed bean source code, we mark as selected the Generate Source Code checkbox. Note that if you click on the Class link, you can configure internal aspects of the bean class (in our example, we will use the default settings).
- Clicking the Finish button of the New Managed Bean window will generate the managed bean, and it will display as shown in the following screenshot:
Now that we have created the managed bean stub, it is time to create the bean's properties. For doing this, you can follow these steps:
- Click on the Add button in Properties panel. This will open the Add Property window (as shown in the following screenshot):
- In this window, you have to specify the new property name (for example, for mapping the username—Your Name field of our registration form—type in the Property-Name field, personName), the property type (in our example, the username is a string), the value kind, and default value (fill up the Value field only if you want to use a different default value). Note that we have marked as selected the three checkboxes for adding the new property to our bean and to generate the corresponding getter/setter methods. At the end, click on the Finish button for generating the new property. The following screenshot will appear:
- Now, if you repeat the above two steps you can map the user age (
Your Age
field), user birth date (Your Birth Date
field), and user phone number (Your Phone Number
field) in the same way. The following three screenshots represent the settings that should be made in the Add Property window for mapping these fields to bean properties:
An interesting aspect is represented by the Your Phone Number
field, because this field is mapped to another managed bean named register.PhoneNumber
. This managed bean has three properties used for extracting from the inserted phone number, the country code (countryCode
property), area code (areaCode
property), prefix number (prefixNumber
property), and a property for keeping the entire phone number (allNumber
property). These four properties are all strings (java.lang.String
). Now, use what you have learnt so far to create this managed bean with JSF Tools (for alias name, use the phoneNumber
text).
In the end, you should have the two managed beans as shown in the following three screenshots:
Finally, save the project state by selecting the Save option from the File main menu.
If you want to see the generated code source for our beans, you can double-click the Managed-Bean-Class link that appears in the right panel of the Tree view when you select a bean from the left panel of the same view (as shown in the following screenshot).
You can also open a bean from the Package Explorer view by expanding the project node and double-clicking on the bean's name.
Note
In addition, JSF Tools allows us to add existing Java Beans to the configuration file. This is a very useful facility because it allows us to import existing Java Beans so that we don't have to recreate them from the start. For this, we select the Managed Beans node (in Tree view) and click the Add button in the right panel. In the New Managed Bean wizard, we browse to the existing Java Bean, click the Next button (adding an exiting bean will deactivate the Generate Source Code checkbox and activate the Next button), select the properties to be imported (from the Managed Properties wizard), and click on the Finish button.
Creating and registering a custom converter is a very elegant method for accomplishing conversion issues that can't be resolved by JSF default converters. For example, in our registration form, we need the following conversions:
- The username (
personName
bean property) doesn't need a conversion as the name is aString
. - The user age (
personAge
bean property) needs to be converted from aString
to anInteger
. We will use a default JSF converter. - The user birth date (
personBirthDate
bean property) needs to be converted from aString
to ajava.util.Date
instance. This conversion can be accomplished by the JSFf:convertDateTime
default converter. - The user phone number (
personPhone
bean property) needs to be converted from aString
to aregister.PhoneNumber
instance. This task can be accomplished only by a custom converter because no default converter can help us obtain this conversion.
Now, creating a custom converter can be done like this:
- Click on the Converters node inside the left panel of Tree view.
- From the right panel of Tree view, click on the Add button for opening the Add Converter window (as shown in the following screenshot).
- Fill in the Converter-ID field with the converter name and the Converter-Class field with the converter class name. If you want to customize the converter class, click on the Converter-Class link (in our example, we will use the default settings).
- In the Add Converter window, click on the Finish button for generating the new converter.
Edit the converter-generated source code by clicking on the Converter-Class link that appears in the right panel of the Tree view (as shown in the following screenshot):
Note that you have to manually insert the behavior of the getAsObject
and getAsString
methods. For example, we convert the inserted phone number into a register.PhoneNumber
object by adding the following code to these methods:
import java.util.StringTokenizer; ... public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) { // TODO Auto-generated method stub System.out.println("//getAsObject method//"); StringTokenizer st = new StringTokenizer(arg2,"-"); PhoneNumber pn = new PhoneNumber(); try{ pn.setAllNumber(arg2); pn.setCountryCode(st.nextToken()); pn.setAreaCode(st.nextToken()); pn.setPrefixNumber(st.nextToken()); }catch (Exception e){ return pn; } return pn; } public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) { // TODO Auto-generated method stub System.out.println("//getAsString method//"); if(arg2 != null) { String value = ((PhoneNumber)arg2).getAllNumber(); return value; } return ""; }
Finally, save the project state by selecting the Save option from the File main menu.
When JSF default validators don't satisfy your application's needs, it is time to implement a custom validator. For example, for our registration form, we have the following situation:
- The username (
personName
bean property)—doesn't need validation. - The user age (
personAge
bean property)—needs to be a valid age. This can be accomplished with the JSFf:validateLongRange
default validator. - The user birth date (
personBirthDate
bean property)—doesn't need validation. - The user phone number (
personPhone
bean property)—needs to be validated as a string that respects the next pattern:x[x]-xxx-xxx-xxxx
. This task can be accomplished only by a custom validator because no default validator can help us.
Now, creating a custom validator can be done like this:
- Click on the Validators node inside the left panel of Tree view.
- From the right panel of Tree view, click on the Add button for opening the Add Validator window.
- Fill in the Validator-ID field with the validator name and the Validator-Class with the validator class name. If you want to customize the validator class, click on the Validator-Class link. (In our example, we will use the default settings.)
- In the Add Validator window, click on the Finish button for generating the new validator.
Edit the validator-generated source code by clicking on the Validator-Class link that appears in the right panel of the Tree view as shown in the following screenshot:
Notice that you have to manually insert the behavior of the validate
method. For example, we validate the inserted phone number by adding the following code to this method:
import javax.faces.application.FacesMessage; tree view, JSF application configuration filecustom validators, creatingimport java.util.regex.Matcher; import java.util.regex.Pattern; ... public void validate(FacesContext arg0, UIComponent arg1, Object arg2) throws ValidatorException { // TODO Auto-generated method stub System.out.println("//validate method//"); String value = ((PhoneNumber)arg2).getAllNumber(); String countryCode = "^[0-9]{1,2}"; String areaCode = "( |-|\\(){1}[0-9]{3}( |-|\\)){1}"; String prefixNumber = "( |-)?[0-9]{3}"; String number = "( |-)[0-9]{4}$"; Pattern mask = Pattern.compile(countryCode + areaCode + prefixNumber + number); Matcher matcher = mask.matcher(value); if (!matcher.find()){ FacesMessage message = new FacesMessage(); message.setDetail("Your phone number is not valid!"); message.setSummary("Your phone number is not valid!"); message.setSeverity(FacesMessage.SEVERITY_ERROR); throw new ValidatorException(message); } }
Finally, save the project state by selecting the Save option from the File main menu.
Note
In addition to this, JSF Tools allows us to create custom referenced beans (note that referenced beans are used very rarely and they basically are Java Beans available in a JSF scope—the application must create an instance of the referenced bean and place it in the desired scope). For this, select the Referenced Beans node (Tree view) and click the Add button from the right panel. In the Add Referenced Bean wizard, fill up the Referenced-Bean-Name with a name for your referenced bean and the Referenced-Bean-Class with the full name of the referenced bean class. Optionally, click on the Referenced-Bean-Class link if you want to customize the referenced bean stub class. Click Finish.
The Source view
In the Source view, you can see the source of the faces-config.xml
document. This source is synchronized with the other two views, so you will always see the reflection of your modifications. This view allows you to modify the configuration file manually or by using the Outline view that displays a tree view of it.