BenhurCD
BenhurCD

Reputation: 81

Passing variable arguments to custom EL function possible?

I wanted support for a custom function call with parameters in JSF-1.2 and came across this doc http://docs.oracle.com/javaee/5/tutorial/doc/bnahq.html#bnaio.

But is it possible to use variable arguments to that function?

I tried by using arrays in Tag Library but looks like JSF doesnt recognize the function in that case.

Upvotes: 1

Views: 1603

Answers (2)

BalusC
BalusC

Reputation: 1109072

No, EL method expressions do not support varargs. Not in the current EL 2.2 version, also not in the future EL 3.0 version.

You need to look for an alternative approach. As the concrete functional requirement is unclear, I can't recommend any one.


Update: the functional requirement is thus:

I have to use parameterized messages from the Message Bundle in the JavaScript involved in my page. Something like an Error or Alert message on trying to delete a file that has the filename parameterized in the message bundle.

Well, there are no smart workarounds to go around that. You have 2 options:

  1. Create a bunch of EL functions taking a different amount of arguments.

    #{my:format1(...)}
    #{my:format2(...)}
    #{my:format3(...)}
    ...
    
  2. Extend <h:outputFormat> to store the result in a request scoped variable instead of printing it.

    <my:outputFormat ... var="foo">
        <f:param ... />
        <f:param ... />
        <f:param ... />
        ...
    </my:outputFormat>
    
    ...
    #{foo}
    

The OmniFaces JSF utility library for JSF2 has both solutions in flavor of <o:outputFormat> component and several of:formatX() functions. It's not useable on JSF 1.x, but it's open source and should provide some insight.

Upvotes: 4

McDowell
McDowell

Reputation: 108929

You could pass a list or array to the custom function.

Warning: this code is untested and might make you feel dirty - it is a complete hack.

We need two artefacts registered as managed beans.

1) A subverted Map type:

/** Important: must be none-scoped */
public class ArrayBuilder extends AbstractMap<Object, Object> {

  private List<Object> list = new ArrayList<Object>();

  @Override public Object get(Object entry) {
    if(entry instanceof MakeArray) {
      return list.toArray();
    } else {
      list.add(entry);
      return this;
    }
  }

  @Override public Set<Entry<Object, Object>> entrySet() {
    return Collections.emptySet();
  }
}

A poison pill to trigger array creation:

/** should be application scoped bean */
public final class MakeArray {
}

The EL expression:

#{fn:foo(arrayBuilder['one']['two']['three'][makeArray])}

The intent of the code is to pass an Object array containing three strings to the function foo.

I have no idea if this actually works.

Upvotes: 0

Related Questions