    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
    015package org.apache.tapestry5.internal.alerts;
    016
    017import org.apache.tapestry5.alerts.*;
    018import org.apache.tapestry5.ioc.services.PerThreadValue;
    019import org.apache.tapestry5.ioc.services.PerthreadManager;
    020import org.apache.tapestry5.services.ApplicationStateManager;
    021import org.apache.tapestry5.services.Request;
    022import org.apache.tapestry5.services.ajax.AjaxResponseRenderer;
    023import org.apache.tapestry5.services.ajax.JavaScriptCallback;
    024import org.apache.tapestry5.services.javascript.JavaScriptSupport;
    025
    026public class AlertManagerImpl implements AlertManager
    027{
    028    private final ApplicationStateManager asm;
    029
    030    private final Request request;
    031
    032    private final AjaxResponseRenderer ajaxResponseRenderer;
    033
    034    private final PerThreadValue<Boolean> needAlertStorageCleanup;
    035
    036    public AlertManagerImpl(ApplicationStateManager asm, Request request, AjaxResponseRenderer ajaxResponseRenderer, PerthreadManager perThreadManager)
    037    {
    038        this.asm = asm;
    039        this.request = request;
    040        this.ajaxResponseRenderer = ajaxResponseRenderer;
    041
    042        needAlertStorageCleanup = perThreadManager.createValue();
    043    }
    044
    045    public void success(String message)
    046    {
    047        alert(Duration.SINGLE, Severity.SUCCESS, message);
    048    }
    049
    050    public void info(String message)
    051    {
    052        alert(Duration.SINGLE, Severity.INFO, message);
    053    }
    054
    055    public void warn(String message)
    056    {
    057        alert(Duration.SINGLE, Severity.WARN, message);
    058    }
    059
    060    public void error(String message)
    061    {
    062        alert(Duration.SINGLE, Severity.ERROR, message);
    063    }
    064
    065    public void alert(Duration duration, Severity severity, String message)
    066    {
    067        alert(duration, severity, message, false);
    068    }
    069
    070    public void alert(Duration duration, Severity severity, String message, boolean markup)
    071    {
    072        final Alert alert = new Alert(duration, severity, message, markup);
    073
    074        if (request.isXHR())
    075        {
    076            addCallbackForAlert(alert);
    077        }
    078
    079        // Add it to the storage; this is always done, even in an Ajax request, because we may end up
    080        // redirecting to a new page, rather than doing a partial page update on the current page ... in which
    081        // case we need the alerts stored persistently until we render the new page.
    082
    083        getAlertStorage().add(alert);
    084    }
    085
    086    private void addCallbackForAlert(final Alert alert)
    087    {
    088        ajaxResponseRenderer.addCallback(new JavaScriptCallback()
    089        {
    090            public void run(JavaScriptSupport javascriptSupport)
    091            {
    092                javascriptSupport.require("t5/core/alert").with(alert.toJSON());
    093            }
    094        });
    095
    096        addAlertStorageCleanupCallback();
    097    }
    098
    099    private void addAlertStorageCleanupCallback()
    100    {
    101        // Add a callback that exists just to clear the non-persistent alerts.
    102        // Only one of these is needed.
    103
    104        if (needAlertStorageCleanup.get(true))
    105        {
    106            ajaxResponseRenderer.addCallback(new JavaScriptCallback()
    107            {
    108                public void run(JavaScriptSupport javascriptSupport)
    109                {
    110                    // In an Ajax request, the Alerts are added, just so that they can be removed if not persistent.
    111                    // Again, this is for the rare case where there's a redirect to another page.
    112
    113                    getAlertStorage().dismissNonPersistent();
    114                }
    115            });
    116
    117            needAlertStorageCleanup.set(false);
    118        }
    119    }
    120
    121    private AlertStorage getAlertStorage()
    122    {
    123        return asm.get(AlertStorage.class);
    124    }
    125
    126}