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