On 7/14/05, Neal Haggard <[EMAIL PROTECTED]> 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; }
}

Reply via email to