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 015 package org.apache.tapestry5.corelib.components; 016 017 import org.apache.tapestry5.BindingConstants; 018 import org.apache.tapestry5.ClientElement; 019 import org.apache.tapestry5.ComponentResources; 020 import org.apache.tapestry5.MarkupWriter; 021 import org.apache.tapestry5.alerts.Alert; 022 import org.apache.tapestry5.alerts.AlertStorage; 023 import org.apache.tapestry5.annotations.*; 024 import org.apache.tapestry5.ioc.annotations.Inject; 025 import org.apache.tapestry5.json.JSONObject; 026 import org.apache.tapestry5.services.javascript.InitializationPriority; 027 import org.apache.tapestry5.services.javascript.JavaScriptSupport; 028 029 /** 030 * Renders out an empty {@code <div>} element and provides JavaScript initialization to make the element 031 * the container for alerts. After rendering markup (and initialization JavaScript), it 032 * {@linkplain org.apache.tapestry5.alerts.AlertStorage#dismissNonPersistent() removes all non-persistent alerts}. 033 * 034 * @tapestrydoc 035 * @since 5.3 036 */ 037 @SupportsInformalParameters 038 public class Alerts implements ClientElement 039 { 040 041 @Parameter(value="message:dismiss-label", defaultPrefix=BindingConstants.LITERAL) 042 private String dismissText; 043 044 @Inject 045 private ComponentResources resources; 046 047 @Environmental 048 private JavaScriptSupport javaScriptSupport; 049 050 @SessionState(create = false) 051 private AlertStorage storage; 052 053 private String clientId; 054 055 public String getClientId() 056 { 057 return clientId; 058 } 059 060 boolean beginRender(MarkupWriter writer) 061 { 062 clientId = javaScriptSupport.allocateClientId(resources); 063 064 writer.element("div", "id", clientId); 065 resources.renderInformalParameters(writer); 066 writer.end(); 067 068 JSONObject spec = new JSONObject("id", clientId, 069 "dismissURL", resources.createEventLink("dismiss").toURI(), 070 "dismissText", dismissText); 071 072 javaScriptSupport.addInitializerCall(InitializationPriority.EARLY, "alertManager", spec); 073 074 if (storage != null) 075 { 076 addAlertsFromStorage(); 077 } 078 079 080 return false; 081 } 082 083 Object onDismiss(@RequestParameter(value = "id", allowBlank = true) Long alertId) 084 { 085 // If the alert was created inside an Ajax request and AlertStorage did not previously 086 // exist, it can be null when the dismiss event comes up from the client. 087 if (storage != null) 088 { 089 if (alertId != null) 090 { 091 storage.dismiss(alertId); 092 } else 093 { 094 storage.dismissAll(); 095 } 096 } 097 098 return new JSONObject(); 099 } 100 101 @HeartbeatDeferred 102 void addAlertsFromStorage() 103 { 104 for (Alert alert : storage.getAlerts()) 105 { 106 javaScriptSupport.addInitializerCall("addAlert", alert.toJSON()); 107 } 108 109 storage.dismissNonPersistent(); 110 } 111 }