/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.wicket.feedback; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import org.apache.wicket.Component; import org.apache.wicket.util.io.IClusterable; import org.apache.wicket.util.string.StringList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Holds list of feedback messages. The list can be added to, cleared, queried and filtered. * <p> * WARNING: This class should typically NOT be used directly. * <p> * * @author Eelco Hillenius * @author Jonathan Locke */ public final class FeedbackMessages implements IClusterable, Iterable<FeedbackMessage> { /** Log. */ private static final Logger log = LoggerFactory.getLogger(FeedbackMessages.class); private static final long serialVersionUID = 1L; /** * Holds a list of {@link org.apache.wicket.feedback.FeedbackMessage}s. */ private final List<FeedbackMessage> messages; /** * Construct. */ public FeedbackMessages() { messages = new CopyOnWriteArrayList<>(); } /** * Adds a message. * * @param message * the message */ public final void add(FeedbackMessage message) { log.debug("Adding feedback message '{}'", message); synchronized (messages) { messages.add(message); } } /** * Adds a message * * @param reporter * @param message * @param level */ public final void add(Component reporter, Serializable message, int level) { add(new FeedbackMessage(reporter, message, level)); } /** * Adds a new ui message with level DEBUG to the current messages. * * @param reporter * the reporting component * @param message * the actual message */ public final void debug(Component reporter, Serializable message) { add(new FeedbackMessage(reporter, message, FeedbackMessage.DEBUG)); } /** * Adds a new ui message with level INFO to the current messages. * * @param reporter * The reporting component * @param message * The actual message */ public final void info(Component reporter, Serializable message) { add(new FeedbackMessage(reporter, message, FeedbackMessage.INFO)); } /** * Adds a new ui message with level SUCCESS to the current messages. * * @param reporter * The reporting component * @param message * The actual message */ public final void success(Component reporter, Serializable message) { add(new FeedbackMessage(reporter, message, FeedbackMessage.SUCCESS)); } /** * Adds a new ui message with level WARNING to the current messages. * * @param reporter * the reporting component * @param message * the actual message */ public final void warn(Component reporter, Serializable message) { add(new FeedbackMessage(reporter, message, FeedbackMessage.WARNING)); } /** * Adds a new ui message with level ERROR to the current messages. * * @param reporter * the reporting component * @param message * the actual message */ public final void error(Component reporter, Serializable message) { add(new FeedbackMessage(reporter, message, FeedbackMessage.ERROR)); } /** * Adds a new ui message with level FATAL to the current messages. * * @param reporter * the reporting component * @param message * the actual message */ public final void fatal(Component reporter, Serializable message) { add(new FeedbackMessage(reporter, message, FeedbackMessage.FATAL)); } /** * Clears any existing messages. * * @return The number of messages deleted */ public final int clear() { return clear(null); } /** * Clears all messages that are accepted by the filter. * * @param filter * Filter for selecting messages. If null, all messages will be returned * @return The number of messages deleted */ public final int clear(final IFeedbackMessageFilter filter) { if (messages.isEmpty()) { return 0; } List<FeedbackMessage> toDelete = messages(filter); for (FeedbackMessage message : toDelete) { message.detach(); } synchronized(messages) { int sizeBefore = messages.size(); messages.removeAll(toDelete); int sizeAfter = messages.size(); return sizeAfter - sizeBefore; } } /** * @param filter * Filter for selecting messages * @return True if one or more messages matches the filter */ public final boolean hasMessage(final IFeedbackMessageFilter filter) { for (final FeedbackMessage message : messages) { if (filter == null || filter.accept(message)) { return true; } } return false; } /** * Checks if a message of the specified {@code level} or greater was registered.<br /> * To check for a precise {@code level} use {@link #hasMessage(IFeedbackMessageFilter)} * and pass it a reference to {@link org.apache.wicket.feedback.ExactLevelFeedbackMessageFilter}. * * @param level * The level of the message * @return {@code true} if a message with the specified {@code level} or greater was registered */ public final boolean hasMessage(final int level) { for (FeedbackMessage message : messages) { if (message.isLevel(level)) { return true; } } return false; } /** * Retrieves the first message * * @return message or {@code null} if none */ public final FeedbackMessage first() { return messages.size() > 0 ? messages.get(0) : null; } /** * Retrieves the first message that level is greater than or equal to the given level * * @param level * The minimum level of the message * @return a message with the same or a higher level, or {@code null} if none */ public final FeedbackMessage first(final int level) { for (FeedbackMessage message : messages) { if (message.isLevel(level)) { return message; } } return null; } /** * Gets an iterator over stored messages * * @return iterator over stored messages */ @Override public final Iterator<FeedbackMessage> iterator() { return messages.iterator(); } /** * Gets a list of messages from the page using a filter. * * @param filter * Filter for selecting messages. If null, all messages will be returned * @return The messages or an empty list if no messages are found */ public final List<FeedbackMessage> messages(final IFeedbackMessageFilter filter) { if (messages.isEmpty()) { return Collections.emptyList(); } final List<FeedbackMessage> list = new ArrayList<FeedbackMessage>(); for (final FeedbackMessage message : messages) { if (filter == null || filter.accept(message)) { list.add(message); } } return list; } /** * Gets whether there are no messages. * * @return True when there are no messages */ public final boolean isEmpty() { return messages.isEmpty(); } /** * Gets the number of messages * * @return the number of messages */ public final int size() { return messages.size(); } /** * Gets the number of messages. * * @param filter * Filter for counting messages. If null, the count of all messages will be returned * * @return the number of messages */ public final int size(final IFeedbackMessageFilter filter) { int count = 0; for (final FeedbackMessage message : messages) { if (filter == null || filter.accept(message)) { count++; } } return count; } /** * @see java.lang.Object#toString() */ @Override public String toString() { return "[feedbackMessages = " + StringList.valueOf(messages) + ']'; } /** * Retrieves all stored messages as an unmodifiable list * * @return stored messages as unmodifiable list */ public List<FeedbackMessage> toList() { return Collections.unmodifiableList(messages); } /** * Detaches each stored message */ public void detach() { for (FeedbackMessage message : messages) { message.detach(); } } }