    001// Licensed under the Apache License, Version 2.0 (the "License");
    002// you may not use this file except in compliance with the License.
    003// You may obtain a copy of the License at
    004//
    005//     http://www.apache.org/licenses/LICENSE-2.0
    006//
    007// Unless required by applicable law or agreed to in writing, software
    008// distributed under the License is distributed on an "AS IS" BASIS,
    009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    010// See the License for the specific language governing permissions and
    011// limitations under the License.
    012
    013package org.apache.tapestry5.corelib.components;
    014
    015import org.apache.tapestry5.BindingConstants;
    016import org.apache.tapestry5.Link;
    017import org.apache.tapestry5.MarkupWriter;
    018import org.apache.tapestry5.alerts.Alert;
    019import org.apache.tapestry5.alerts.AlertStorage;
    020import org.apache.tapestry5.annotations.*;
    021import org.apache.tapestry5.corelib.base.BaseClientElement;
    022import org.apache.tapestry5.ioc.annotations.Inject;
    023import org.apache.tapestry5.json.JSONObject;
    024import org.apache.tapestry5.services.Request;
    025import org.apache.tapestry5.services.compatibility.DeprecationWarning;
    026
    027/**
    028 * Renders out an empty {@code <div>} element and provides JavaScript initialization to make the element
    029 * the container for alerts. After rendering markup (and initialization JavaScript), it
    030 * {@linkplain org.apache.tapestry5.alerts.AlertStorage#dismissNonPersistent() removes all non-persistent alerts}.
    031 *
    032 * Alerts are created using the {@link org.apache.tapestry5.alerts.AlertManager} service.
    033 *
    034 * @tapestrydoc
    035 * @since 5.3
    036 */
    037@SupportsInformalParameters
    038public class Alerts extends BaseClientElement
    039{
    040
    041    /**
    042     * Allows the button used to dismiss all alerts to be customized (and localized).
    043     *
    044     * @deprecated Deprecated in Tapestry 5.4; override the {@code core-dismiss-label} message key in
    045     * your application's message catalog. This parameter is now ignored.
    046     */
    047    @Parameter(value = "message:core-dismiss-label", defaultPrefix = BindingConstants.LITERAL)
    048    private String dismissText;
    049
    050    /**
    051     * If set to true, then the "dismiss all" button will not be rendered on the client.
    052     *
    053     * @since 5.4
    054     */
    055    @Parameter(value = "message:private-core-alerts-show-dismiss-all", defaultPrefix = BindingConstants.LITERAL)
    056    private boolean showDismissAll;
    057
    058    @SessionState(create = false)
    059    private AlertStorage storage;
    060
    061    @Inject
    062    private DeprecationWarning deprecationWarning;
    063
    064    @Inject
    065    private Request request;
    066
    067    void onPageLoaded()
    068    {
    069        deprecationWarning.ignoredComponentParameters(resources, "dismissText");
    070    }
    071
    072    boolean beginRender(MarkupWriter writer)
    073    {
    074        Link dismissLink = resources.createEventLink("dismiss");
    075
    076        storeElement(writer.element("div",
    077                "data-container-type", "alerts",
    078                "data-show-dismiss-all", showDismissAll,
    079                "data-dismiss-url", dismissLink));
    080
    081        resources.renderInformalParameters(writer);
    082        writer.end();
    083
    084        addAlertsFromStorage();
    085
    086        return false;
    087    }
    088
    089    Object onDismiss(@RequestParameter(value = "id", allowBlank = true) Long alertId)
    090    {
    091        // If the alert was created inside an Ajax request and AlertStorage did not previously
    092        // exist, it can be null when the dismiss event comes up from the client.
    093        if (storage != null)
    094        {
    095            if (alertId != null)
    096            {
    097                storage.dismiss(alertId);
    098            } else
    099            {
    100                storage.dismissAll();
    101            }
    102        }
    103
    104        // See TAP5-1941
    105        if (!request.isXHR())
    106        {
    107            return true;
    108        }
    109
    110        return new JSONObject();
    111    }
    112
    113    @HeartbeatDeferred
    114    void addAlertsFromStorage()
    115    {
    116        if (storage == null)
    117        {
    118            return;
    119        }
    120
    121        for (Alert alert : storage.getAlerts())
    122        {
    123            javaScriptSupport.require("t5/core/alert").with(alert.toJSON());
    124        }
    125
    126        storage.dismissNonPersistent();
    127    }
    128}