    001// Copyright 2008-2014 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.tapestry5.corelib.base;
    016
    017import org.apache.tapestry5.BindingConstants;
    018import org.apache.tapestry5.MarkupWriter;
    019import org.apache.tapestry5.annotations.Environmental;
    020import org.apache.tapestry5.annotations.Parameter;
    021import org.apache.tapestry5.http.Link;
    022import org.apache.tapestry5.http.services.Request;
    023import org.apache.tapestry5.ioc.annotations.Inject;
    024import org.apache.tapestry5.services.javascript.JavaScriptSupport;
    025
    026/**
    027 * Base class for link-generating components that are based on a component event request. Such events have an event
    028 * context and may also update a {@link org.apache.tapestry5.corelib.components.Zone}.
    029 */
    030public abstract class AbstractComponentEventLink extends AbstractLink
    031{
    032    /**
    033     * The context for the link (optional parameter). This list of values will be converted into strings and included in
    034     * the URI. The strings will be coerced back to whatever their values are and made available to event handler
    035     * methods.
    036     */
    037    @Parameter
    038    private Object[] context;
    039
    040    /**
    041     * Binding the zone parameter turns the link into a an Ajax control that causes the related zone to be updated.
    042     */
    043    @Parameter(defaultPrefix = BindingConstants.LITERAL)
    044    private String zone;
    045
    046    /**
    047     * When true, the the link will trigger an asynchronous request (via XmlHttpRequest); the event handler method
    048     * can make use of the {@link org.apache.tapestry5.services.ajax.AjaxResponseRenderer} in order to force content
    049     * updates to the client.  This is used as an alternative to placing the link inside a {@link org.apache.tapestry5.corelib.components.Zone}
    050     * and binding the {@code zone} parameter.
    051     *
    052     * @since 5.4
    053     */
    054    @Parameter
    055    private boolean async = false;
    056
    057    @Inject
    058    private Request request;
    059
    060    @Environmental
    061    private JavaScriptSupport javaScriptSupport;
    062
    063    void beginRender(MarkupWriter writer)
    064    {
    065        if (isDisabled()) return;
    066
    067        Link link = createLink(context);
    068
    069        writeLink(writer, link);
    070
    071        writer.attributes("data-update-zone", zone);
    072
    073        if (async)
    074        {
    075            javaScriptSupport.require("t5/core/zone");
    076            writer.attributes("data-async-trigger", true);
    077        }
    078    }
    079
    080    /**
    081     * Invoked to create the Link that will become the href attribute of the output.
    082     *
    083     * @param eventContext
    084     *         the context as an object array, possibly null
    085     * @return the link, not null
    086     */
    087    protected abstract Link createLink(Object[] eventContext);
    088
    089    void afterRender(MarkupWriter writer)
    090    {
    091        if (isDisabled()) return;
    092
    093        writer.end(); // <a>
    094    }
    095}