Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Composite Type Descriptor
Background
At runtime, the EL symbol resolution supports the ability to coerce a symbol into one or more appropriate types. For example, consider the following the expression:
#{var.property}
Furthermore, suppose that var resolves to a managed bean class defined like this:
public class MyBean implements java.util.Map { ... // has a bean property called 'property' public String getProperty() { return this.name; } .... }
With the default symbol resolution mechanisms in both JSF 1.1 and 1.2, the bean property called property will never be referenced because the class implements Map.
In the default property resolver for JSF 1.1, the resolution logic works something like this:
public Object getValue(Object obj, Object property) { if (obj instanceof java.util.Map) { return ((Map) obj).get(property); } else { return getBeanProperty(obj, property); } }
and in the case of JSF 1.2, the default ELResolver chain will produce a similar result since the MapELResolver is always added to the chain before the BeanELResolver. (Note also that the case is similar for Lists and Arrays and may also be true other custom symbol types).
In order to support fact that different objects from the same symbol source (i.e. Managed Beans) may be treated differently depending on what interfaces and other meta-information they support, the EL tooling needs the concept multiple type coercion for symbols that support runtime type modelling.
Existing Architecture
The existing JSF 1.1 tooling (in WTP 1.5.x), supports the concept the of a type descriptor on each symbol to describes emulate its runtime type behaviour:
All entities that model symbols that exist as objects at runtime (rooted at IObjectSymbol) can have an ITypeDescriptor that describes their type behaviour. The two main descriptors that currently exist are for Java types (used principally for beans) and Map types. New basic types will also be added for Lists and Arrays but that outside of the scope of this document.
To add the capability for any IObjectSymbol to have a type descriptor that resolves to more than on possible type behaviour, we add the capability to have more than one type descriptor on an object symbol and allow it to determine which one to return it based on a specific coercian request..
Multiple coercion
The new design supports multiple coercion of an object symbol:
(Note: sub-classes shown the first diagram are not shown in this diagram, but they have not been removed from the framework)
An IObjectSymbol can now have 0..n type descriptors. To select a specific type descriptor for a desired type behaviour, the client must make use of two operations: supportsCoercion and coerce.
supportsCoercion takes a fully qualified type signature (i.e. Ljava.util.Map;) and returns true if the symbol can return an ITypeDescriptor that models the runtime behaviour of that type. This is similar to an 'instanceof' call at runtime. The second operation, coerce takes the same fully qualified type signature and either returns the supporting ITypeDescriptor or throws an exception if it is not supported. It is up to the implementation of IObjectSymbol to decide how to construct its differently coerced type descriptors.