/*
 * (C) Copyright 2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * Contributors:
 *     Nuxeo - initial API and implementation
 *
 * $Id: MethodResultTagHandler.java 19474 2007-05-27 10:18:21Z sfermigier $
 */

package org.nuxeo.ecm.platform.ui.web.tag.handler;

import java.io.IOException;

import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;

import org.nuxeo.ecm.platform.ui.web.binding.MethodValueExpression;

import com.sun.facelets.FaceletContext;
import com.sun.facelets.tag.MetaTagHandler;
import com.sun.facelets.tag.TagAttribute;
import com.sun.facelets.tag.TagConfig;

/**
 * Tag handler that exposes the result of a method binding in the variable map.
 *
 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
 *
 */
public class MethodResultTagHandler extends MetaTagHandler {

    private static final Class[] DEFAULT_PARAM_TYPES_CLASSES = new Class[0];

    private final TagAttribute name;

    private final TagAttribute value;

    private final TagAttribute immediate;

    private final TagAttribute paramTypes;

    public MethodResultTagHandler(TagConfig config) {
        super(config);
        name = getRequiredAttribute("name");
        value = getRequiredAttribute("value");
        immediate = getAttribute("immediate");
        paramTypes = getAttribute("paramTypes");
    }

    private Class[] resolveParamTypes(FaceletContext ctx) {
        // TODO: implement string parsing ?
        return DEFAULT_PARAM_TYPES_CLASSES;
    }

    public void apply(FaceletContext ctx, UIComponent parent)
            throws IOException {
        String nameStr = name.getValue(ctx);
        // resolve given value as a method binding, paramtypes ignored for now
        Class[] paramTypesClasses = resolveParamTypes(ctx);
        MethodExpression meth = value.getMethodExpression(ctx, Object.class,
                paramTypesClasses);
        ValueExpression ve = null;
        Boolean invokeNow = false;
        if (immediate != null) {
            invokeNow = immediate.getBoolean(ctx);
        }
        if (invokeNow) {
            Object res = meth.invoke(ctx, paramTypesClasses);
            ve = ctx.getExpressionFactory().createValueExpression(res,
                    Object.class);
        } else {
            ve = new MethodValueExpression(ctx, meth, paramTypesClasses);
        }
        ctx.getVariableMapper().setVariable(nameStr, ve);
        this.nextHandler.apply(ctx, parent);
    }

}

@@ -881,32 +881,64 @@
 alueExpression;%0A
+import javax.el.VariableMapper;%0A
 import javax.fac
@@ -1073,16 +1073,66 @@
 ontext;%0A
+import com.sun.facelets.el.VariableMapperWrapper;%0A
 import c
@@ -2535,43 +2535,8 @@
 s);%0A
-        ValueExpression ve = null;%0A
     
@@ -2566,16 +2566,16 @@
  false;%0A
+
         
@@ -2652,32 +2652,60 @@
 ctx);%0A        %7D%0A
+        ValueExpression ve;%0A
         if (invo
@@ -2982,23 +2982,46 @@
       %7D%0A
+%0A
        
+ VariableMapper orig =
  ctx.get
@@ -3036,16 +3036,124 @@
 Mapper()
+;%0A        VariableMapper vm = new VariableMapperWrapper(orig);%0A        ctx.setVariableMapper(vm);%0A        vm
 .setVari
@@ -3184,12 +3184,25 @@
    t
-his.
+ry %7B%0A            
 next
@@ -3229,16 +3229,87 @@
 arent);%0A
+        %7D finally %7B%0A            ctx.setVariableMapper(orig);%0A        %7D%0A
     %7D%0A%0A%7D

Clean variable mapper when using nxu:methodResult