Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "EL Context Framework Design"

(How EL symbols are resolved at design-time)
(How EL symbols are resolved at design-time)
Line 45: Line 45:
  
 
[[Image:ELContext class diagram.png]]
 
[[Image:ELContext class diagram.png]]
 +
 +
All of the classes in this diagram except for ''DTELResolverDescriptor'' are direct mirrors of runtime equivilents.  DTELResolver is used to resolve model objects, properties and method names as the following example:
 +
 +
<pre>#{bean.property}</pre>
 +
 +
In the first example, the symbol 'bean' would be passed to the DTELResolver to determine if it is a valid model object.  If it is, the DTELResolver would then be asked if 'property' is a valid property of that object.

Revision as of 14:28, 20 September 2006

Motivation

In EL expressions, user and system-defined symbols can be used be used to store and retrieve values as well as point to methods that can be called. For example, the following expression references a property on some object:

#{object.property}

In JSP 2.1/Faces 1.2, the job resolving 'object' and 'property' to values that can be used in evaluating the expression is delegated to an API defined in the Unified EL specification. The root of the API is an class called 'ELContext'. Each implementer of Unified EL can create and populate one or more ELContext object for use in evaluating expressions.

This document lays out the design of a 'design-time framework' to allow tooling that supports technologies that use Unified EL. The emphasis is on supporting JSF and JSP technologies. An effort is also made to remain as backward-compatible with previous tooling as possible without shackling new design.

Restatement of Requirements

ELToolingStakeholderUser.usecase.png

There are three major user-stakeholders in this framework. The first is Developer (specialized as JSFDeveloper for JSF tooling. Developer needs to be able to support EL at design-time any place they may use it at runtime. This user also needs a way to install additional support for dependent behaviour for things like third-party libraries.

The second stakeholder is LibraryDeveloper. LibraryDeveloper classifies any users who wishes to have a library that uses Unified EL to be supported by the tooling. In JSP an example of LibraryDeveloper is anyone creating JSP tag libraries; in JSF a specialized example is the JSFComponentLibraryDeveloper. This user needs to be able to add additional support for their library to default framework behaviour.

The third user-stakeholder is ToolsDeveloper. ToolsDeveloper uses the tooling to create specialized tooling that needs to support EL technologies. This user needs to be able to modify any default behaviour to suit specialization to the standard technologies being supporting by the tooling.

Within this context, framework design goals will emphasize the following requirements:

  • The framework must be flexible enough to allow each web application (as defined at design time by a dynamic web project rooted in an IProject) to have entirely different symbol resolution in different application contexts. This supports the needs of ToolsDeveloper. For example, Faces 1.2 supports two different ELResolvers depending on where an expression is being resolved.
  • The framework must allow third parties to modify the way symbols are resolved in each of the possible application contexts. This supports the needs LibraryDeveloper.
  • The framework must provide a simple but comprehensive way for JSFDeveloper to manage these new behaviors on each web application within the constraints of providing correct design time behavior. This includes managing third-party contributions and the ability to enable or disable functionality in ways that match what could happen at runtime.

Why EL symbols are resolved at design-time

The actual value of an EL symbol is normally not computable at design-time because it is often dependent on runtime state, user input and so on. However, with many of the more widely used EL symbol objects like POJO beans and resource bundles, enough information can be predicted about runtime semantics to provide useful tooling support to tooling users. In some cases like resource bundles, it is sometimes even possible to evaluate the actual value of a symbol and aid the user further.

Major users design-time resolution information include:

  • Validation: type information can be derived and checked against what is expected.
  • Content-assist: an object's possible methods and properties can be determined and presented to the user as code assist tips.
  • Refactoring: When underlying objects change, EL that was valid may become invalid. The user can be presented with automatic refactoring options when underlying dependencies change.


How EL symbols are resolved at design-time

In order to predict the runtime type and other semantics of an EL symbol, the design-time framework needs to parallel as closely as possible the way it is evaluated at runtime. In that respect, the EL Context Framework mirrors the runtime Unified EL API by creating "design-time versions" of the API. Class and interface naming generally follows the convention of taking the runtime API name and prepending "DT" to it.

The "root" of the API class hierarchy is the ELContext object. The ELContext contains resolver objects that can map EL symbols into meaningful runtime objects and values. The design time framework therefore defines a "DTELContext" object that similar contains similar design-time resolvers. The most important classes are listed below:

File:ELContext class diagram.png

All of the classes in this diagram except for DTELResolverDescriptor are direct mirrors of runtime equivilents. DTELResolver is used to resolve model objects, properties and method names as the following example:

#{bean.property}

In the first example, the symbol 'bean' would be passed to the DTELResolver to determine if it is a valid model object. If it is, the DTELResolver would then be asked if 'property' is a valid property of that object.

Back to the top