myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Simon Kitching <simon.kitch...@rhe.co.nz>
Subject Re: AW: Accessing constants in EL expressions
Date Wed, 07 Feb 2007 20:45:12 GMT
The EL language is defined to provide access to Java Bean Properties, 
and only Java Bean Properties. Static fields are not regarded as Java 
Bean Properties by the java.beans.Introspector class, hence are not 
accessable.

Yes, it sucks but this is the JSF spec. Well, actually the JSF spec says:
<quote>
The syntax of a value binding expression is identical to the syntax of 
an expression language expression defined in the JavaServer Pages 
Specification (version 2.0), sections 2.3 through 2.9, with the 
following exceptions ...
</quote>
where the exceptions are not relevant in this case. And the JSP spec 
says that a.b and a[b] are:
<quote>
used to access maps, lists, arrays of objects and properties of a Java-
Beans object
</quote>

See:
    http://java.sun.com/javaee/javaserverfaces/download.html
    http://java.sun.com/products/jsp/reference/api/index.html
    http://java.sun.com/products/jsp/syntax/2.0/syntaxref207.html#1010522

Therefore to get access to static constants working, what is needed is 
to ensure that the data you want *is* a Java Bean Property (read-only in 
the case of constants). The ways to do this are:
1. add a getter method, getCONSTANT
2. add a getter method for a Map which provides access to the constants
3. play clever tricks with a BeanInfo class.

Option 1. is obvious, but clumsy as you say.

Option 2. is to do something like this:
   public Map getConstants() {
     ...
   }
where the object returned is either a Map with all the constants added 
to it (simple), or a custom Map subclass that uses reflection to map its 
key parameter to the appropriate field. The EL expression can then look 
like:
   #{ACL.constants.GRANT}
or
   #{ACL.constants['GRANT']}

Option 3. uses the fact that java.beans.Introspector will first look for 
a class ACLBeanInfo, and if that is present then it uses methods on that 
class to determine what Java Bean Properties are available on class ACL, 
rather than performing reflection on ACL directly. The BeanInfo class 
could return a PropertyDescriptor for each constant, thus making them 
read-only properties that are directly accessable via #{ACL.GRANT} and 
similar. It's a little tricky but possible.

Note that the same problem occurs when accessing static getter/setter 
methods on a class; static methods are not regarded by the 
java.beans.Introspector class as defining a Property, but a BeanInfo 
class can force them to be made available as a Property and therefore 
accessable via EL expressions.


Regards,

Simon

Ingo Düppe wrote:
> Oh, thats obvious - but I didn't saw it :-)
> 
> so you would define:
> 
> public class ACL ... {
>    public final static int GRANT = 1;
>      public ACL() {};
> 
>    public int getGRANT() { return GRANT};
> }
> 
> and
> 
>    <managed-bean>
>        <managed-bean-name>ACL</managed-bean-name>
>        
> <managed-bean-class>org.openuss.security.acl.ACL</managed-bean-class>
>        <managed-bean-scope>application</managed-bean-scope>
>    </managed-bean>
> 
> Looks a bit ugly to me, why cannot the el access public static fields 
> directly. I mean it is common in java to define constants as static 
> public fields.
> 
> Regards
> Ingo
> 
> Worm, Danny schrieb:
>> Hi,
>>
>> No problem, just write a getter for your final constants. So the EL get
>> access to it.
>>
>> kind regards
>> DaWorm
>>
>>
>>
>>   
> 


Mime
View raw message