001/*
002 * (C) Copyright 2006-2010 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.platform.ui.web.tag.handler;
021
022import java.io.IOException;
023
024import javax.el.ELException;
025import javax.faces.FacesException;
026import javax.faces.component.ActionSource;
027import javax.faces.component.UIComponent;
028import javax.faces.event.ActionEvent;
029import javax.faces.event.ActionListener;
030import javax.faces.event.MethodExpressionActionListener;
031import javax.faces.view.facelets.FaceletContext;
032import javax.faces.view.facelets.FaceletException;
033import javax.faces.view.facelets.TagAttribute;
034import javax.faces.view.facelets.TagConfig;
035import javax.faces.view.facelets.TagException;
036import javax.faces.view.facelets.TagHandler;
037
038import org.nuxeo.ecm.platform.ui.web.binding.MetaMethodExpression;
039
040/**
041 * Action listener method handler: makes it possible to add an action listener method to any action source component
042 * parent.
043 * <p>
044 * This is useful when declaring several action listeners on the same parent component, and when the order of calls
045 * needs to be respected: the action listener method declared on a component is the first one called. So this method
046 * makes it possible to add other action listeners before it, without having to declare a class (when using the
047 * f:actionListener tag).
048 *
049 * @author Anahide Tchertchian
050 */
051public class ActionListenerMethodTagHandler extends TagHandler {
052
053    protected final TagAttribute value;
054
055    @SuppressWarnings("rawtypes")
056    public static final Class[] ACTION_LISTENER_SIG = { ActionEvent.class };
057
058    public ActionListenerMethodTagHandler(TagConfig config) {
059        super(config);
060        value = getRequiredAttribute("value");
061    }
062
063    @Override
064    public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException,
065            ELException {
066        if (parent instanceof ActionSource) {
067            // only process if parent was just created
068            if (parent.getParent() == null) {
069                ActionSource src = (ActionSource) parent;
070                ActionListener listener = new MethodExpressionActionListener(new MetaMethodExpression(
071                        value.getMethodExpression(ctx, null, ACTION_LISTENER_SIG)));
072                src.addActionListener(listener);
073            }
074        } else {
075            throw new TagException(tag, "Parent is not of type ActionSource, type is: " + parent);
076        }
077    }
078
079}