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