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 015package org.apache.tapestry5.corelib.components; 016 017import org.apache.tapestry5.BindingConstants; 018import org.apache.tapestry5.ClientElement; 019import org.apache.tapestry5.ComponentResources; 020import org.apache.tapestry5.MarkupWriter; 021import org.apache.tapestry5.alerts.Alert; 022import org.apache.tapestry5.alerts.AlertStorage; 023import org.apache.tapestry5.annotations.*; 024import org.apache.tapestry5.ioc.annotations.Inject; 025import org.apache.tapestry5.json.JSONObject; 026import org.apache.tapestry5.services.javascript.InitializationPriority; 027import 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 038public 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}