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