001// Copyright 2011-2013 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.Link; 019import org.apache.tapestry5.MarkupWriter; 020import org.apache.tapestry5.alerts.Alert; 021import org.apache.tapestry5.alerts.AlertStorage; 022import org.apache.tapestry5.annotations.*; 023import org.apache.tapestry5.corelib.base.BaseClientElement; 024import org.apache.tapestry5.ioc.annotations.Inject; 025import org.apache.tapestry5.json.JSONObject; 026import org.apache.tapestry5.services.compatibility.DeprecationWarning; 027 028/** 029 * Renders out an empty {@code <div>} element and provides JavaScript initialization to make the element 030 * the container for alerts. After rendering markup (and initialization JavaScript), it 031 * {@linkplain org.apache.tapestry5.alerts.AlertStorage#dismissNonPersistent() removes all non-persistent alerts}. 032 * <p/> 033 * Alerts are created using the {@link org.apache.tapestry5.alerts.AlertManager} service. 034 * 035 * @tapestrydoc 036 * @since 5.3 037 */ 038@SupportsInformalParameters 039@Import(stack = "core") 040public class Alerts extends BaseClientElement 041{ 042 043 /** 044 * Allows the button used to dismiss all alerts to be customized (and localized). 045 * 046 * @deprecated Deprecated in Tapestry 5.4; override the {@code core-dismiss-label} message key in 047 * your application's message catalog. This parameter is now ignored. 048 */ 049 @Parameter(value = "message:core-dismiss-label", defaultPrefix = BindingConstants.LITERAL) 050 private String dismissText; 051 052 /** 053 * If set to true, then the "dismiss all" button will not be rendered on the client. 054 * 055 * @since 5.4 056 */ 057 @Parameter(value = "message:private-core-alerts-show-dismiss-all", defaultPrefix = BindingConstants.LITERAL) 058 private boolean showDismissAll; 059 060 @SessionState(create = false) 061 private AlertStorage storage; 062 063 @Inject 064 private DeprecationWarning deprecationWarning; 065 066 void onPageLoaded() 067 { 068 deprecationWarning.ignoredComponentParameters(resources, "dismissText"); 069 } 070 071 boolean beginRender(MarkupWriter writer) 072 { 073 Link dismissLink = resources.createEventLink("dismiss"); 074 075 storeElement(writer.element("div", 076 "data-container-type", "alerts", 077 "data-show-dismiss-all", showDismissAll, 078 "data-dismiss-url", dismissLink)); 079 080 resources.renderInformalParameters(writer); 081 writer.end(); 082 083 addAlertsFromStorage(); 084 085 return false; 086 } 087 088 Object onDismiss(@RequestParameter(value = "id", allowBlank = true) Long alertId) 089 { 090 // If the alert was created inside an Ajax request and AlertStorage did not previously 091 // exist, it can be null when the dismiss event comes up from the client. 092 if (storage != null) 093 { 094 if (alertId != null) 095 { 096 storage.dismiss(alertId); 097 } else 098 { 099 storage.dismissAll(); 100 } 101 } 102 103 return new JSONObject(); 104 } 105 106 @HeartbeatDeferred 107 void addAlertsFromStorage() 108 { 109 if (storage == null) 110 { 111 return; 112 } 113 114 for (Alert alert : storage.getAlerts()) 115 { 116 javaScriptSupport.require("t5/core/alert").with(alert.toJSON()); 117 } 118 119 storage.dismissNonPersistent(); 120 } 121}