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    
015    package org.apache.tapestry.link;
016    
017    import java.util.List;
018    
019    import org.apache.tapestry.IActionListener;
020    import org.apache.tapestry.IDirect;
021    import org.apache.tapestry.IRequestCycle;
022    import org.apache.tapestry.Tapestry;
023    import org.apache.tapestry.engine.DirectServiceParameter;
024    import org.apache.tapestry.engine.IEngineService;
025    import org.apache.tapestry.engine.ILink;
026    import org.apache.tapestry.listener.ListenerInvoker;
027    
028    /**
029     * A component for creating a link using the direct service; used for actions that are not dependant
030     * on dynamic page state. [ <a href="../../../../../ComponentReference/DirectLink.html">Component
031     * Reference </a>]
032     * 
033     * @author Howard Lewis Ship
034     */
035    
036    public abstract class DirectLink extends AbstractLinkComponent implements IDirect
037    {
038        public abstract IActionListener getListener();
039    
040        /**
041         * Returns true if the stateful parameter is bound to a true value. If stateful is not bound,
042         * also returns the default, true.
043         */
044    
045        public abstract boolean isStateful();
046    
047        public ILink getLink(IRequestCycle cycle)
048        {
049            Object[] serviceParameters = constructServiceParameters(getParameters());
050            
051            DirectServiceParameter dsp = new DirectServiceParameter(this, serviceParameters);
052            
053            return getEngine().getLink(isStateful(), dsp);
054        }
055    
056        /**
057         * Converts a service parameters value to an array of objects. This is used by the
058         * {@link DirectLink},{@link ServiceLink}and {@link ExternalLink}components.
059         * 
060         * @param parameterValue
061         *            the input value which may be
062         *            <ul>
063         *            <li>null (returns null)
064         *            <li>An array of Object (returns the array)
065         *            <li>A {@link List}(returns an array of the values in the List})
066         *            <li>A single object (returns the object as a single-element array)
067         *            </ul>
068         * @return An array representation of the input object.
069         * @since 2.2
070         */
071    
072        public static Object[] constructServiceParameters(Object parameterValue)
073        {
074            if (parameterValue == null)
075                return null;
076    
077            if (parameterValue instanceof Object[])
078                return (Object[]) parameterValue;
079    
080            if (parameterValue instanceof List)
081            {
082                List list = (List) parameterValue;
083    
084                return list.toArray();
085            }
086    
087            return new Object[]
088            { parameterValue };
089        }
090    
091        /**
092         * Invoked by the direct service to trigger the application-specific action by notifying the
093         * {@link IActionListener listener}.
094         * 
095         * @throws org.apache.tapestry.StaleSessionException
096         *             if the component is stateful, and the session is new.
097         */
098    
099        public void trigger(IRequestCycle cycle)
100        {
101            IActionListener listener = getListener();
102    
103            if (listener == null)
104                throw Tapestry.createRequiredParameterException(this, "listener");
105    
106            getListenerInvoker().invokeListener(listener, this, cycle);
107        }
108    
109        /** @since 2.2 * */
110    
111        public abstract Object getParameters();
112    
113        /**
114         * Injected.
115         * 
116         * @since 4.0
117         */
118    
119        public abstract ListenerInvoker getListenerInvoker();
120        
121        /**
122         * Injected.
123         * 
124         * @since 4.1
125         */
126        public abstract IEngineService getEngine();
127    }