myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mike Kienenberger <mkien...@gmail.com>
Subject Re: Length of a Collection in EL?
Date Thu, 14 Jul 2005 21:43:26 GMT
On 7/14/05, Neal Haggard <Neal.Haggard@sas.com> wrote:
> 
> I need to be able to get the length of a collection in JSF EL.  Is there a way to do
it?  Looking at JSP 2.0 EL (which JSF uses) it allows for functions, specifically the pre-defined
length() function.  However, when I try using that with MyFaces I get an exception saying
functions are not allowed.  Is there a reason this was done?  It seems like an awful handy
feature of EL to throw away.  Anyone hacked MyFaces to allow functions to be used?

I took a look at this briefly and it seems to be a very hard problem.

For myfaces to determine what functions are available, it has to parse
your jsp file's namespace, and then somehow find that function in the
classpath.

An easy workaround is to "hardcode" the available functions in your
code.  Take a look at ValueBindingImpl for hints on how to do this.

I did it this way (code compressed and imports and error handling deleted):

First set up a context listener and register it in your web.xml file

public class Initializer implements ServletContextListener{
    public Initializer() {}
    public void contextDestroyed(ServletContextEvent event){}
    public void contextInitialized(ServletContextEvent event)
    {        ValueBindingImplWithFunctionSupport.doNothing();}
}

Subclass ValueBindingImpl to provide access to your functions.

public class ValueBindingImplWithFunctionSupport extends ValueBindingImpl
{
    static // initializer block
    {  s_functionMapper = new FunctionMapper()  {
            public Method resolveFunction(String prefix, String localName)  {
                if ( ("function".equals(prefix)) &&
("size".equals(localName)) )  {
                     return Functions.class.getMethod("size", new
Class[] { List.class });
                }
                else if ( ("function".equals(prefix)) &&
("length".equals(localName)) )  {
                       return Functions.class.getMethod("length", new
Class[] { Object[].class });
                }

                throw new ReferenceSyntaxException(
                    "Functions not supported in expressions. Function: " 
                    + prefix + ":" + localName);
            }
        };
    }

    /** Hook to force class to load */
    public static void doNothing(){};
}

Actual Functions class:

public class Functions {
    public static int size(List list)  {  return list.size(); }
    public static int length(Object array[])
    { return array.length; }
}

Mime
View raw message