The Syntax of Value Expressions

Configuring Beans

This section describes how you can configure a bean in a configuration file. The details are rather technical. You may want to have a glance at this section and return to it when you need to configure beans with complex properties.

The most commonly used configuration file is WEB-INF/faces-config.xml. However, you can also place configuration information inside the following locations:

  • Files named META-INF/faces-config.xml inside any JAR files loaded by the external context's class loader. (You use this mechanism if you deliver reusable components in a JAR file.)

  • Files listed in the javax.faces.CONFIG_FILES initialization parameter inside WEB-INF/web.xml. For example,

    <web-app>    <context-param>       <param-name>javax.faces.CONFIG_FILES</param-name>       <param-value>WEB-INF/navigation.xml,WEB-INF/beans.xml</param-value>    </context-param>    ... </web-app>

    (This mechanism is attractive for builder tools because it separates navigation, beans, etc.)

For simplicity, we use WEB-INF/faces-config.xml in this chapter.

A bean is defined with a managed-bean element inside the top-level faces-config element. Minimally, you must specify the name, class, and scope of the bean.

  <faces-config>       <managed-bean>          <managed-bean-name>user</managed-bean-name>         <managed-bean-class>com.corejsf.UserBean</managed-bean-class>         <managed-bean-scope>session</managed-bean-scope>      </managed-bean>   </faces-config>

The scope can be request, session, application, or none. The none scope denotes an object that is not kept in one of the three scope maps. You use objects with scope none as building blocks when wiring up complex beans. You will see an example in the section "Chaining Bean Definitions" on page 61.

Setting Property Values

We start with a simple example. Here we customize a UserBean instance:

  <managed-bean>       <managed-bean-name>user</managed-bean-name>      <managed-bean-class>com.corejsf.UserBean</managed-bean-class>      <managed-bean-scope>session</managed-bean-scope>       <managed-property>         <property-name>name</property-name>         <value>me</value>      </managed-property>      <managed-property>         <property-name>password</property-name>         <value>secret</value>      </managed-property>   </managed-bean>

When the user bean is first looked up, it is constructed with the UserBean() default constructor. Then the setName and setPassword methods are executed.

To initialize a property with null, use a null-value element. For example,

  <managed-property>      <property-name>password</property-name>      <null-value/>   </managed-property>

Initializing Lists and Maps

A special syntax initializes values that are of type List or Map. Here is an example of a list:

  <list-entries>      <value-class>java.lang.Integer</value.class>      <value>3</value>      <value>1</value>      <value>4</value>      <value>1</value>      <value>5</value>   </list-entries>

Here we use the java.lang.Integer wrapper type since a List cannot hold values of primitive type.

The list can contain a mixture of value and null-value elements. The value-class is optional. If it is omitted, a list of java.lang.String objects is produced.

A map is more complex. You specify optional key-class and value-class elements (again, with a default of java.lang.String). Then you provide a sequence of map-entry elements, each of which has a key element, followed by a value or null-value element.

Here is an example:

  <map-entries>      <key-class>java.lang.Integer</key-class>      <map-entry>         <key>1</key>         <value>George Washington</value>      </map-entry>      <map-entry>         <key>3</key>         <value>Thomas Jefferson</value>      </map-entry>      <map-entry>         <key>16</key>         <value>Abraham Lincoln</value>      </map-entry>      <map-entry>         <key>26</key>         <value>Theodore Roosevelt</value>      </map-entry>   </map-entries>

You can use list-entries and map-entries elements to initialize either a managed-bean or a managed-property, provided that the bean or property type is a List or Map.

Figure 2-7 shows a syntax diagram for the managed-bean element and all of its child elements. Follow the arrows to see which constructs are legal inside a managed-bean element. For example, the second graph tells you that a managed-property element starts with zero or more description elements, followed by zero or more display-name elements, zero or more icons, then a mandatory property-name, an optional property-class, and exactly one of the elements value, null-value, map-entries, or list-entries.

Figure 2-7. Syntax diagram for managed-bean elements


Chaining Bean Definitions

You can achieve more complex arrangements by using value expressions inside the value element to chain beans together. Consider the quiz bean in the number-quiz application.

The quiz contains a collection of problems, represented as the write-only problems property. You can configure it with the following instructions:

  <managed-bean>      <managed-bean-name>quiz</managed-bean-name>      <managed-bean-class>com.corejsf.QuizBean</managed-bean-class>      <managed-bean-scope>session</managed-bean-scope>      <managed-property>         <property-name>problems</property-name>         <list-entries>            <value-class>com.corejsf.ProblemBean</value-class>            <value>#{problem1}</value>            <value>#{problem2}</value>            <value>#{problem3}</value>            <value>#{problem4}</value>            <value>#{problem5}</value>         </list-entries>      </managed-property>   </managed-bean>

Of course, now we must define beans with names problem1 through problem5, like this:

  <managed-bean>      <managed-bean-name>problem1</managed-bean-name>      <managed-bean-class>         com.corejsf.ProblemBean      </managed-bean-class>      <managed-bean-scope>none</managed-bean-scope>         <managed-property>            <property-name>sequence</property-name>            <list-entries>               <value-class>java.lang.Integer</value-class>               <value>3</value>               <value>1</value>               <value>4</value>               <value>1</value>               <value>5</value>            </list-entries>         </managed-property>         <managed-property>            <property-name>solution</property-name>            <value>9</value>         </managed-property>   </managed-bean>     

When the quiz bean is requested, then the creation of the beans problem1 through problem5 is triggered automatically. You need not worry about the order in which you specify managed beans.

Note that the problem beans have scope none since they are never requested from a JSF page but are instantiated when the quiz bean is requested.

When you wire beans together, make sure that their scopes are compatible. Table 2-1 lists the permissible combinations.

Table 2-1. Compatible Bean Scopes
When defining a bean of this scope ... ... you can use beans of these scopes
none none
application none, application
session none, application, session
request none, application, session, request


String Conversions

You specify property values and elements of lists or maps with a value element that contains a string. The enclosed string needs to be converted to the type of the property or element. For primitive types, this conversion is straightforward. For example, you can specify a boolean value with the string true or false.

Starting with JSF 1.2, values of enumerated types are supported as well. The conversion is performed by calling Enum.valueOf(propertyClass, valueText).

For other property types, the JSF implementation attempts to locate a matching PropertyEditor. If a property editor exists, its setAsText method is invoked to convert strings to property values. Property editors are heavily used for client-side beans, to convert between property values and a textual or graphical representation that can be displayed in a property sheet (see Figure 2-8).

Figure 2-8. A property sheet in a GUI builder


Defining a property editor is somewhat involved, and we refer the interested reader to Horstmann and Cornell, 2004, 2005. Core Java 2, vol. 2, chap. 8.

Note that the rules are fairly restrictive. For example, if you have a property of type URL, you cannot simply specify the URL as a string, even though there is a constructor URL(String). You would need to supply a property editor for the URL type or reimplement the property type as String.

Table 2-2 summarizes these conversion rules. They are identical to the rules for the jsp:setProperty action of the JSP specification.

Table 2-2. String Conversions
Target Type Conversion
int, byte, short, long, float, double, or the corresponding wrapper type The valueOf method of the wrapper type, or 0 if the string is empty.
boolean or Boolean The result of Boolean.valueOf, or false if the string is empty.
char or Character The first character of the string, or (char) 0 if the string is empty.
String or Object A copy of the string; new String("") if the string is empty.
bean property A type that calls the setAsText method of the property editor if it exists. If the property editor does not exist or it throws an exception, the property is set to null if the string is empty. Otherwise, an error occurs.




Core JavaServerT Faces
Core JavaServer(TM) Faces (2nd Edition)
ISBN: 0131738860
EAN: 2147483647
Year: 2004
Pages: 84

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net