    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.internal.alerts;
    016
    017    import org.apache.tapestry5.alerts.*;
    018    import org.apache.tapestry5.ioc.services.PerThreadValue;
    019    import org.apache.tapestry5.ioc.services.PerthreadManager;
    020    import org.apache.tapestry5.services.ApplicationStateManager;
    021    import org.apache.tapestry5.services.Request;
    022    import org.apache.tapestry5.services.ajax.AjaxResponseRenderer;
    023    import org.apache.tapestry5.services.ajax.JavaScriptCallback;
    024    import org.apache.tapestry5.services.javascript.JavaScriptSupport;
    025
    026    public 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            final Alert alert = new Alert(duration, severity, message);
    068
    069            if (request.isXHR())
    070            {
    071                addCallbackForAlert(alert);
    072            }
    073
    074            // Add it to the storage; this is always done, even in an Ajax request, because we may end up
    075            // redirecting to a new page, rather than doing a partial page update on the current page ... in which
    076            // case we need the alerts stored persistently until we render the new page.
    077
    078            getAlertStorage().add(alert);
    079        }
    080
    081        private void addCallbackForAlert(final Alert alert)
    082        {
    083            ajaxResponseRenderer.addCallback(new JavaScriptCallback()
    084            {
    085                public void run(JavaScriptSupport javascriptSupport)
    086                {
    087                    javascriptSupport.addInitializerCall("addAlert", alert.toJSON());
    088                }
    089            });
    090
    091            addAlertStorageCleanupCallback();
    092        }
    093
    094        private void addAlertStorageCleanupCallback()
    095        {
    096            // Add a callback that exists just to clear the non-persistent alerts.
    097            // Only one of these is needed.
    098
    099            if (needAlertStorageCleanup.get(true))
    100            {
    101                ajaxResponseRenderer.addCallback(new JavaScriptCallback()
    102                {
    103                    public void run(JavaScriptSupport javascriptSupport)
    104                    {
    105                        // In an Ajax request, the Alerts are added, just so that they can be removed if not persistent.
    106                        // Again, this is for the rare case where there's a redirect to another page.
    107
    108                        getAlertStorage().dismissNonPersistent();
    109                    }
    110                });
    111
    112                needAlertStorageCleanup.set(false);
    113            }
    114        }
    115
    116        private AlertStorage getAlertStorage()
    117        {
    118            return asm.get(AlertStorage.class);
    119        }
    120
    121    }