001// Copyright 2004, 2005 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007//     http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.tapestry.link;
016
017import java.util.List;
018
019import org.apache.tapestry.IActionListener;
020import org.apache.tapestry.IDirect;
021import org.apache.tapestry.IRequestCycle;
022import org.apache.tapestry.Tapestry;
023import org.apache.tapestry.engine.DirectServiceParameter;
024import org.apache.tapestry.engine.ILink;
025import org.apache.tapestry.listener.ListenerInvoker;
026
027/**
028 * A component for creating a link using the direct service; used for actions that are not dependant
029 * on dynamic page state. [ <a href="../../../../../ComponentReference/DirectLink.html">Component
030 * Reference </a>]
031 * 
032 * @author Howard Lewis Ship
033 */
034
035public abstract class DirectLink extends AbstractLinkComponent implements IDirect
036{
037    public abstract IActionListener getListener();
038
039    /**
040     * Returns true if the stateful parameter is bound to a true value. If stateful is not bound,
041     * also returns the default, true.
042     */
043
044    public abstract boolean isStateful();
045
046    public ILink getLink(IRequestCycle cycle)
047    {
048        Object[] serviceParameters = constructServiceParameters(getParameters());
049
050        DirectServiceParameter dsp = new DirectServiceParameter(this, serviceParameters);
051
052        return getLink(cycle, Tapestry.DIRECT_SERVICE, dsp);
053    }
054
055    /**
056     * Converts a service parameters value to an array of objects. This is used by the
057     * {@link DirectLink},{@link ServiceLink}and {@link ExternalLink}components.
058     * 
059     * @param parameterValue
060     *            the input value which may be
061     *            <ul>
062     *            <li>null (returns null)
063     *            <li>An array of Object (returns the array)
064     *            <li>A {@link List}(returns an array of the values in the List})
065     *            <li>A single object (returns the object as a single-element array)
066     *            </ul>
067     * @return An array representation of the input object.
068     * @since 2.2
069     */
070
071    public static Object[] constructServiceParameters(Object parameterValue)
072    {
073        if (parameterValue == null)
074            return null;
075
076        if (parameterValue instanceof Object[])
077            return (Object[]) parameterValue;
078
079        if (parameterValue instanceof List)
080        {
081            List list = (List) parameterValue;
082
083            return list.toArray();
084        }
085
086        return new Object[]
087        { parameterValue };
088    }
089
090    /**
091     * Invoked by the direct service to trigger the application-specific action by notifying the
092     * {@link IActionListener listener}.
093     * 
094     * @throws org.apache.tapestry.StaleSessionException
095     *             if the component is stateful, and the session is new.
096     */
097
098    public void trigger(IRequestCycle cycle)
099    {
100        IActionListener listener = getListener();
101
102        if (listener == null)
103            throw Tapestry.createRequiredParameterException(this, "listener");
104
105        getListenerInvoker().invokeListener(listener, this, cycle);
106    }
107
108    /** @since 2.2 * */
109
110    public abstract Object getParameters();
111
112    /**
113     * Injected.
114     * 
115     * @since 4.0
116     */
117
118    public abstract ListenerInvoker getListenerInvoker();
119}