Without commenting one way or the other on whether the MyFaces folks
might like the proposed technology (that's up to them), I would like
to point out one important factor -- the expression language in  JSTL
(and JSF) omits method calls *deliberately*.

One of the most common negative feedbacks you will read about
JavaServer Pages as a technology is that scriptlets make it far too
easy to intermix presentation logic and business logic ... in large
part because you can call arbitrary Java methods with them.  Best
practices standards today say that such expressions should not be
used; and, in JSP 2.0, you can even ask the compiler to enforce this
restriction for you.

Introducing arbitrary parameterized method calls into the expression
language, it seems to me, would lead users into the same temptation
that we've worked so hard to eliminate.

Instead, IMHO, the expression language should encourage you to
manipulate server side model data with model tier techniques ... it
was designed to serve as a *binding* between the tiers, rather than as
a general purpose computational technology.  If we had wanted that, we
would likely have adopted essentially the entire JavaScript language
as the expression language mechanism in the first place (it was
considered and rejected during the initial deliberations in the JSTL
expert group, for the reasons outlined above).

Craig McClanahan

On 7/18/05, Aleksei Valikov <[EMAIL PROTECTED]> wrote:
> Hi.
> 
> For me, EL-like languages always missed some functionality. Calling
> methods with parameters or simply doing things "above average" were
> always a pain.
> 
> As an experiment, I've tried to replace JSF EL (like
> #{mybean.myAccessor}) with JavaScript. At least to achieve the
> possibility to perform parameterizable method calls. So far it
> succeeded. Appeared to be easier than I thought.
> 
> I basically replaced ApplicationImpl with my own implementation,
> redefining createMethodBinding method to use Rhino JS implementation.
> The core of the method is compilation of the passed reference:
> 
> String trimmedReference = reference.trim();
> if (trimmedReference.startsWith(PREFIX) &&
> trimmedReference.endsWith(SUFFIX)) {
> 
> final String scriptString = trimmedReference.substring(3,
> trimmedReference.length() - 2);
> 
> final Context context = Context.enter();
> final Script script = context.compileString(scriptString, "", 0, null);
> 
> And creation of the method binding:
> 
> 
> return new net.orless.hijack.editor.faces.binding.MethodBinding() {
> 
> //...
>          public Object invoke(FacesContext facesContext, Object[] aobj)
>              throws EvaluationException,
>              MethodNotFoundException {
> 
>            Context context = Context.enter();
>            try {
>              ScriptableObject topScope = context.initStandardObjects();
>              Scriptable s = new ScriptableFacesContext(facesContext,
> topScope);
>              final Object result = script.exec(context, s);
>              if (result instanceof Wrapper)
>                return ((Wrapper) result).unwrap();
>              else
>                return result;
>            }
>            catch (Exception ex) {
>              throw new EvaluationException(ex);
>            }
>            finally {
>              Context.exit();
>            }
>          }
> 
>        };
> 
>      }
>      else {
>        return super.createMethodBinding(reference, params);
>      }
>    }
> 
> 
> ScriptableFacesContext is trivial:
> 
> public class ScriptableFacesContext extends ScriptableObject{
> 
>    private final FacesContext facesContext;
> 
>    public ScriptableFacesContext(FacesContext facesContext, Scriptable
> scope) {
>      super(scope, null);
>      this.facesContext = facesContext;
>    }
> 
>    public String getClassName() {
>      return ScriptableFacesContext.class.getName();
>    }
> 
>    public Object get(String name, Scriptable start) {
>      return
> facesContext.getApplication().getVariableResolver().resolveVariable(facesContext,
> name);
>    }
> }
> 
> Now , #{[....]} value bindings are compiled as JavaScript and then
> evaluated within the FacesContext context, using variable resolvers and
> so on.
> 
> A small example. In the tree I have command link like:
> 
> <h:commandLink immediate="true" action="#{[node.doIt('b')]}">
> <h:outputText value="#{node.description}" styleClass="nodeFolder"/>
> </h:commandLink>
> 
> The tree node class has a method:
> 
>    public String doIt(Object node)
>    {
>      System.out.println(node);
>      return "";
>    }
> 
> When I click on the node link within the tree, the node is printed to
> the system out:
> 
> [EMAIL PROTECTED]
> 
> Is anyone interested? I could share/contribute my sources. And would
> also be greateful for an advice from someone a bit more experienced with
> Rhino than I am.
> 
> ps. What is the easiest way to switch the used "Application" class?
> Apart from implementing and registering my own application factory.
> 
> pps. JavaScript is probably also interesting for value bindings.
> 
> ppps. Bindings could be easily implemented as Serializable/StateHolders.
> For instance, transient script + script string, script string is
> re-compiled by demand (when script is null).
> 
> Bye.
> /lexi
>

Reply via email to