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 info(String message) 046 { 047 alert(Duration.SINGLE, Severity.INFO, message); 048 } 049 050 public void warn(String message) 051 { 052 alert(Duration.SINGLE, Severity.WARN, message); 053 } 054 055 public void error(String message) 056 { 057 alert(Duration.SINGLE, Severity.ERROR, message); 058 } 059 060 public void alert(Duration duration, Severity severity, String message) 061 { 062 final Alert alert = new Alert(duration, severity, message); 063 064 if (request.isXHR()) 065 { 066 addCallbackForAlert(alert); 067 } 068 069 // Add it to the storage; this is always done, even in an Ajax request, because we may end up 070 // redirecting to a new page, rather than doing a partial page update on the current page ... in which 071 // case we need the alerts stored persistently until we render the new page. 072 073 getAlertStorage().add(alert); 074 } 075 076 private void addCallbackForAlert(final Alert alert) 077 { 078 ajaxResponseRenderer.addCallback(new JavaScriptCallback() 079 { 080 public void run(JavaScriptSupport javascriptSupport) 081 { 082 javascriptSupport.addInitializerCall("addAlert", alert.toJSON()); 083 } 084 }); 085 086 addAlertStorageCleanupCallback(); 087 } 088 089 private void addAlertStorageCleanupCallback() 090 { 091 // Add a callback that exists just to clear the non-persistent alerts. 092 // Only one of these is needed. 093 094 if (needAlertStorageCleanup.get(true)) 095 { 096 ajaxResponseRenderer.addCallback(new JavaScriptCallback() 097 { 098 public void run(JavaScriptSupport javascriptSupport) 099 { 100 // In an Ajax request, the Alerts are added, just so that they can be removed if not persistent. 101 // Again, this is for the rare case where there's a redirect to another page. 102 103 getAlertStorage().dismissNonPersistent(); 104 } 105 }); 106 107 needAlertStorageCleanup.set(false); 108 } 109 } 110 111 private AlertStorage getAlertStorage() 112 { 113 return asm.get(AlertStorage.class); 114 } 115 116 }