| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head> |
| <title>JSF Expression Language Tooling</title> |
| |
| |
| |
| |
| |
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
| |
| |
| |
| <meta http-equiv="Content-Style-Type" content="text/css"> |
| |
| |
| |
| <meta http-equiv="Content-Script-Type" content="text/javascript"> |
| |
| |
| |
| <link rel="stylesheet" href="../../book.css" type="text/css"> |
| </head> |
| |
| <body> |
| <table summary="" cellpadding="0" cellspacing="0" width="100%"> |
| |
| |
| <tbody><tr valign="bottom"> |
| <td align="left" width="86%"> |
| <h1>JSF Expression Language Tooling</h1> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| |
| |
| <hr> |
| <h3>Overview</h3> |
| |
| |
| <p>The JSF Expression Language (JSF EL) tooling provides basic support |
| for design time evaluation of JSF 1.1 EL. It implements parts of |
| the following specifications:</p> |
| |
| |
| |
| |
| <a href="http://java.sun.com/javaee/javaserverfaces/download.html">JSF 1.1 Specification</a> -- particularly chapters 5 and 9.<br> |
| |
| |
| <p><a href="http://jcp.org/aboutJava/communityprocess/final/jsr152/">JSP 2.0 Specification</a> -- particularly chapter 2.<br> |
| </p> |
| |
| |
| In order to support design time evaluation of expressions, the tooling has the following basic capabilities:<br> |
| <br> |
| <ul> |
| <li>syntax parsing <br> |
| </li> |
| <li>design-time variable, property and method resolution</li> |
| <li>semantic type analysis</li> |
| <li>static expression evaluation</li> |
| </ul> |
| <h3>Syntax Parsing<br> |
| </h3> |
| The WTP JSP tooling provides an EL parser that the JSF EL tooling |
| leverage because of syntactic commonality between JSP and JSF EL. |
| The parser is based on JavaCC and constructs an abstract syntax tree |
| (AST) that can be further processed by the framework. The parser |
| reports syntax errors in expressions.<br> |
| <h3>Design-time variable, property and method resolution</h3> |
| JSF EL expressions may contain variable and method bindings that |
| reference external objects. At runtime, this is accomplished |
| through a several mechanisms, which can convert different types of |
| identifier symbols into objects and methods. At designtime the |
| JSF tooling tries to parallel these as closely as possible. These |
| mechanisms are:<br> |
| <br> |
| <ul> |
| <li>VariableResolver</li> |
| <li>PropertyResolver</li> |
| <li>MethodBinding</li> |
| </ul> |
| <h4>VariableResolver</h4> |
| All identifier symbol resolution in EL starts with the |
| VariableResolver. An expression like "myBean.property" is |
| resolved by first extracting the symbol "myBean" and requesting the |
| VariableResolver to return a matching runtime object. At design |
| time, we parallel this exactly but running a design time description of |
| the object rather than its actual value (since the actual value cannot |
| be fully computed until runtime in most cases). The concept of a |
| "DTVariableResolver" is introduced. A default implementation is |
| automatically provided which closely mirrors the default runtime |
| resolver. New variable resolvers can be contributed through the |
| Eclipse extension point mechanism to support custom runtime |
| counterparts.<br> |
| <h4>PropertyResolver</h4> |
| Once a variable is resolved, the next step in resolving a value binding |
| is to resolve its properties. To return to our simple example, |
| "myBean.property", the JSF runtime will pass the object returned for |
| 'myBean' to the property resolver along with the name 'property' and |
| ask it to resolve it to an object. At design time, we parallel |
| this by introducing the "DTPropertyResolver".<br> |
| <br> |
| <h4>MethodBinding</h4> |
| The method binding mechanism implemented by the JSF runtime, differs |
| from the way variables and properties are resolved. At design |
| time however, we support them in the same way by providing a |
| "DTMethodResolver". The main reason for this divergence is that |
| at runtime, the method binding need know only enough to invoke a |
| method. However at design time, we want to be able resolve a |
| method binding in such a way that we can provide the same kinds of |
| features we provide for properties such as signature validation and |
| content assist.<br> |
| <br> |
| <span style="font-weight: bold;"></span><span style="font-weight: bold;"></span> |
| <h3>Semantic type analysis</h3> |
| Type analysis of literals is performed for all expressions. |
| Analysis is done on all variables, properties and methods that can be |
| resolved. Type analysis can verify:<br> |
| <br> |
| <ul> |
| <li>that operator arguments are of a valid type or can be coerced to one.</li> |
| <li>that EL attribute values resolve to a type that is expected by its tag attribute</li> |
| <li>that the result of an EL expression supports that assignment properties expected by its tag attribute <br> |
| </li> |
| </ul> |
| <h4>Argument Coercability</h4> |
| Many EL operators expect arguments with a particular type. For |
| example, the arithmetic addition operator, '+', expects that both of |
| its operands are numeric. EL does provide for automatic type |
| coercions and conversions, however some operands cannot be coerced and |
| will cause runtime errors. The following are examples of |
| syntactically valid EL expressions that will cause type coercions |
| exceptions at runtime:<br> |
| <br> |
| <table style="width: 100%; text-align: left;" border="1" cellpadding="2" cellspacing="2"> |
| <tbody> |
| <tr> |
| <td style="vertical-align: top;">Expression<br> |
| </td> |
| <td style="vertical-align: top;">Problem<br> |
| </td> |
| </tr> |
| <tr> |
| <td style="vertical-align: top;">myBean.stringArrayProperty + myBean.booleanProperty<br> |
| </td> |
| <td style="vertical-align: top;">The first operand is an array of strings. Arrays cannot be coerced to a numeric type supported by the addition operator<br> |
| </td> |
| </tr> |
| <tr> |
| <td style="vertical-align: top;">-false<br> |
| </td> |
| <td style="vertical-align: top;">Boolean 'false' cannot be coerced to a numeric type expected by the unary minus operator.<br> |
| </td> |
| </tr> |
| <tr> |
| <td style="vertical-align: top;"> !5<br> |
| </td> |
| <td style="vertical-align: top;">The numeric value '5' cannot be |
| coerced to a boolean required by the unary not operator (Note this is |
| what the specification says; some implementation use a C-style |
| number-to-boolean coercion and flag a warning).<br> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| <br> |
| <h4>Attribute value compatability</h4> |
| For those tag attributes that are annotated with JSF tooling meta-data |
| providing type information, EL type information can be compared to what |
| is expected by the attribute. Below are some examples of |
| attribute values being assigned EL expressions that have incompatible |
| types. The tag prefixes "f" and "h" represent the built-in JSF |
| "core" and "html" tag libraries respectively.<br> |
| <br> |
| <table style="text-align: left; width: 1241px; height: 59px;" border="1" cellpadding="2" cellspacing="2"> |
| <tbody> |
| <tr> |
| <td style="vertical-align: top; text-align: center;">Example<br> |
| </td> |
| <td style="vertical-align: top; text-align: center;">Problem<br> |
| </td> |
| </tr> |
| <tr> |
| <td style="vertical-align: top;"><h:inputText rendered="#{myBean.arrayProperty}"/><br> |
| </td> |
| <td style="vertical-align: top;">The rendered attribute expects a boolean value. An array value can be coerced or converted to boolean<br> |
| </td> |
| </tr> |
| <tr> |
| <td style="vertical-align: top;">TODO: more examples<br> |
| </td> |
| <td style="vertical-align: top;"><br> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| <br> |
| <h4>Assignability analysis</h4> |
| Some JSF tag attributes support the writing back of data to an identified object, such as a bean property:<br> |
| <br> |
| e.g. <h:inputText value=#{bean.readOnlyProperty}/><br> |
| <br> |
| For tags that are annotated with JSF tooling meta-data, the framework |
| can check if the property is writable if expected. In the example |
| above, the inputText will write back the value entered by the user to |
| bean.readOnlyProperty. However, if the bean doesn't implement a |
| setter for this property, the user will be issued a warning that the |
| tag logic may not work completely as expected.<br> |
| <h3>Static Expression Evaluation</h3> |
| |
| The JSF EL validation component performs design time expression |
| evaluation on an AST provided by the parser. The expression evaluator |
| is able to do the following expression evaluations:<br> |
| |
| <br> |
| |
| <ul> |
| <li>constant expression detection</li><li>logical short-circuit analysis</li><li>possible division by zero<br> |
| </li> |
| </ul> |
| |
| <h4>Constant expression detection</h4> |
| |
| Certain types of expressions can be statically analyzed for |
| deterministic evaluation. Such deterministic evaluation may imply |
| programmer error. For example the following expressions always |
| evaluate to a constant value regardless of runtime conditions:<br> |
| |
| <br> |
| |
| <table style="width: 100%; text-align: left;" border="1" cellpadding="2" cellspacing="2"> |
| |
| <tbody> |
| <tr> |
| <td style="vertical-align: top; text-align: center;">Expression<br> |
| </td> |
| <td style="vertical-align: top; text-align: center;">Constant Evaluation<br> |
| </td> |
| <td style="vertical-align: top; text-align: center;">Reason<br> |
| </td> |
| </tr> |
| <tr> |
| <td style="vertical-align: top; text-align: center;">5+3<br> |
| </td> |
| <td style="vertical-align: top; text-align: center;">8<br> |
| </td> |
| <td style="vertical-align: top;">All values in the expression are constant at design time.<br> |
| </td> |
| </tr> |
| <tr> |
| <td style="vertical-align: top; text-align: center;">empty 'notEmpty'<br> |
| </td> |
| <td style="vertical-align: top; text-align: center;">false<br> |
| </td> |
| <td style="vertical-align: top;">Empty operator always returns false for non-null, non-empty strings<br> |
| </td> |
| </tr> |
| <tr> |
| <td style="vertical-align: top; text-align: center;">empty 5<br> |
| </td> |
| <td style="vertical-align: top; text-align: center;">false<br> |
| </td> |
| <td style="vertical-align: top;">The empty operator always returns false if the argument is not a string, collection, array or map<br> |
| </td> |
| </tr> |
| <tr> |
| <td style="vertical-align: top; text-align: center;">-null<br> |
| </td> |
| <td style="vertical-align: top; text-align: center;">0<br> |
| </td> |
| <td style="vertical-align: top;">The minus operator treats null as 0.<br> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <br> |
| |
| <h4>Logical short-circuit analysis<br> |
| </h4> |
| |
| JSF EL supports short-circuit evaluation of boolean expressions. This |
| cause entire sub-expressions to not be evaluated and those important |
| side-effects may not occur. The following are examples of EL |
| expressions that will be short-circuited:<br> |
| |
| <br> |
| |
| <table style="text-align: left; height: 80px; width: 1241px;" border="1" cellpadding="2" cellspacing="2"> |
| |
| <tbody> |
| <tr> |
| <td style="vertical-align: top;">Expression<br> |
| </td> |
| <td style="vertical-align: top;">Description<br> |
| </td> |
| </tr> |
| <tr> |
| <td style="vertical-align: top;">false && myBean.x<br> |
| </td> |
| <td style="vertical-align: top;">This logical predicate always |
| evaluates to false regardless of the value of myBean.x. Because this |
| expression "short-circuits" on the first argument, myBean.x will never |
| be evaluated meaning any expected side-effects will not occur.<br> |
| </td> |
| </tr> |
| <tr> |
| <td style="vertical-align: top;">true || myBean.x<br> |
| </td> |
| <td style="vertical-align: top;">Similar to the above, myBean.x will never be evaluated because true or'd with any value is guaranteed to be true.<br> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <br> |
| |
| <h4>Possible division by zero</h4> |
| |
| Division by zero can cause runtime exceptions in a JSF application. |
| The following are examples of EL expressions that may result in a |
| divide-by-zero error:<br> |
| |
| <br> |
| |
| 'x / 0'<br> |
| |
| 'x / (5-5)'<br> |
| <br> |
| |
| |
| |
| |
| |
| </body></html> |