001    // Copyright 2008, 2009 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.tapestry5.corelib.base;
016    
017    import org.apache.tapestry5.BindingConstants;
018    import org.apache.tapestry5.Link;
019    import org.apache.tapestry5.MarkupConstants;
020    import org.apache.tapestry5.MarkupWriter;
021    import org.apache.tapestry5.annotations.Environmental;
022    import org.apache.tapestry5.annotations.Parameter;
023    import org.apache.tapestry5.ioc.annotations.Inject;
024    import org.apache.tapestry5.services.ClientBehaviorSupport;
025    import org.apache.tapestry5.services.Request;
026    
027    /**
028     * Base class for link-generating components that are based on a component event request. Such events have an event
029     * context and may also update a {@link org.apache.tapestry5.corelib.components.Zone}.
030     */
031    public abstract class AbstractComponentEventLink extends AbstractLink
032    {
033        /**
034         * The context for the link (optional parameter). This list of values will be converted into strings and included in
035         * the URI. The strings will be coerced back to whatever their values are and made available to event handler
036         * methods.
037         */
038        @Parameter
039        private Object[] context;
040    
041        /**
042         * Binding the zone parameter turns the link into a an Ajax control that causes the related zone to be updated.
043         */
044        @Parameter(defaultPrefix = BindingConstants.LITERAL)
045        private String zone;
046    
047        @Environmental
048        private ClientBehaviorSupport clientBehaviorSupport;
049    
050        @Inject
051        private Request request;
052    
053        void beginRender(MarkupWriter writer)
054        {
055            if (isDisabled()) return;
056    
057            Link link = createLink(context);
058    
059            writeLink(writer, link);
060    
061            if (zone != null)
062            {
063                if (!request.isXHR())
064                    writer.getElement().forceAttributes(MarkupConstants.ONCLICK, MarkupConstants.WAIT_FOR_PAGE);
065    
066                clientBehaviorSupport.linkZone(getClientId(), zone, link);
067            }
068        }
069    
070        /**
071         * Invoked to create the Link that will become the href attribute of the output.
072         *
073         * @param eventContext the context as an object array, possibly null
074         */
075        protected abstract Link createLink(Object[] eventContext);
076    
077        void afterRender(MarkupWriter writer)
078        {
079            if (isDisabled()) return;
080    
081            writer.end(); // <a>
082        }
083    }