001// Copyright 2011, 2012 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.mixins;
016
017import org.apache.tapestry5.BindingConstants;
018import org.apache.tapestry5.ComponentResources;
019import org.apache.tapestry5.EventConstants;
020import org.apache.tapestry5.Link;
021import org.apache.tapestry5.annotations.AfterRender;
022import org.apache.tapestry5.annotations.InjectContainer;
023import org.apache.tapestry5.annotations.Parameter;
024import org.apache.tapestry5.corelib.components.Zone;
025import org.apache.tapestry5.internal.util.CaptureResultCallback;
026import org.apache.tapestry5.ioc.annotations.Inject;
027import org.apache.tapestry5.services.javascript.JavaScriptSupport;
028
029/**
030 * <p>
031 * This mixin periodically refreshs a @{link org.apache.tapestry5.corelib.components.Zone zone}
032 * by triggering an event on the server using ajax requests.
033 * </p>
034 * <p/>
035 * <b>Note: </b> This mixin is only meant for a @{link org.apache.tapestry5.corelib.components.Zone zone}
036 *
037 * @tapestrydoc
038 */
039public class ZoneRefresh
040{
041    /**
042     * Period between two consecutive refreshes (in seconds). If a new refresh occurs before the
043     * previous refresh has completed, it will be skipped.
044     */
045    @Parameter(required = true, defaultPrefix = BindingConstants.LITERAL)
046    private int period;
047
048    /**
049     * Context passed to the event
050     */
051    @Parameter
052    private Object[] context;
053
054    @InjectContainer
055    private Zone zone;
056
057    @Inject
058    private JavaScriptSupport javaScriptSupport;
059
060    @Inject
061    private ComponentResources resources;
062
063    //For testing purpose
064    ZoneRefresh(Object[] context, ComponentResources resources, JavaScriptSupport javaScriptSupport, Zone zone)
065    {
066        this.context = context;
067        this.resources = resources;
068        this.javaScriptSupport = javaScriptSupport;
069        this.zone = zone;
070    }
071
072    @AfterRender
073    void addJavaScript()
074    {
075        Link link = resources.createEventLink("zoneRefresh", context);
076
077        javaScriptSupport.require("t5/core/zone-refresh").with(zone.getClientId(), period, link.toString());
078    }
079
080    Object onZoneRefresh()
081    {
082        CaptureResultCallback<Object> callback = new CaptureResultCallback<Object>();
083        resources.triggerEvent(EventConstants.REFRESH, context, callback);
084
085        if (callback.getResult() != null)
086        {
087            return callback.getResult();
088        }
089
090        return zone.getBody();
091    }
092
093}