001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.feedback;
018
019import java.io.Serializable;
020import java.util.HashMap;
021import java.util.Map;
022
023import org.apache.wicket.Component;
024import org.apache.wicket.core.util.string.CssUtils;
025import org.apache.wicket.model.IDetachable;
026
027
028/**
029 * Represents a generic message meant for the end-user/ pages.
030 * 
031 * @author Eelco Hillenius
032 * @author Jonathan Locke
033 */
034public class FeedbackMessage implements IDetachable
035{
036        private static final long serialVersionUID = 1L;
037
038        public static final String UNDEFINED_CSS_CLASS_KEY = CssUtils.key(FeedbackMessage.class,
039                        "undefined");
040
041        public static final String DEBUG_CSS_CLASS_KEY = CssUtils.key(FeedbackMessage.class, "debug");
042
043        public static final String INFO_CSS_CLASS_KEY = CssUtils.key(FeedbackMessage.class, "info");
044
045        public static final String SUCCESS_CSS_CLASS_KEY = CssUtils.key(FeedbackMessage.class,
046                        "success");
047
048        public static final String WARNING_CSS_CLASS_KEY = CssUtils.key(FeedbackMessage.class,
049                        "warning");
050
051        public static final String ERROR_CSS_CLASS_KEY = CssUtils.key(FeedbackMessage.class, "error");
052
053        public static final String FATAL_CSS_CLASS_KEY = CssUtils.key(FeedbackMessage.class, "fatal");
054
055        /**
056         * Constant for an undefined level; note that components might decide not to render anything
057         * when this level is used.
058         */
059        public static final int UNDEFINED = 0;
060
061        /** Constant for debug level. */
062        public static final int DEBUG = 100;
063
064        /** Constant for info level. */
065        public static final int INFO = 200;
066
067        /** Constant for success level (it indicates the outcome of an operation) */
068        public static final int SUCCESS = 250;
069
070        /** Constant for warning level. */
071        public static final int WARNING = 300;
072
073        /** Constant for error level. */
074        public static final int ERROR = 400;
075
076        /** Constant for fatal level. */
077        public static final int FATAL = 500;
078
079        /** Levels as strings for debugging. */
080        private static final Map<Integer, String> levelStrings = new HashMap<>();
081
082        static
083        {
084                levelStrings.put(UNDEFINED, "UNDEFINED");
085                levelStrings.put(DEBUG, "DEBUG");
086                levelStrings.put(INFO, "INFO");
087                levelStrings.put(SUCCESS, "SUCCESS");
088                levelStrings.put(WARNING, "WARNING");
089                levelStrings.put(ERROR, "ERROR");
090                levelStrings.put(FATAL, "FATAL");
091        }
092
093        /**
094         * The message level; can be used by rendering components. Note that what actually happens with
095         * the level indication is totally up to the components that render messages like these. The
096         * default level is UNDEFINED.
097         */
098        private final int level;
099
100        /** The actual message. */
101        private final Serializable message;
102
103        /** The reporting component. */
104        private Component reporter;
105
106        /** Whether or not this message has been rendered */
107        private boolean rendered = false;
108
109        /**
110         * Construct using fields.
111         * 
112         * @param reporter
113         *            The message reporter
114         * @param message
115         *            The actual message. Must not be <code>null</code>.
116         * @param level
117         *            The level of the message
118         */
119        public FeedbackMessage(final Component reporter, final Serializable message, final int level)
120        {
121                if (message == null)
122                {
123                        throw new IllegalArgumentException("Parameter message can't be null");
124                }
125                this.reporter = reporter;
126                this.message = message;
127                this.level = level;
128        }
129
130        /**
131         * Gets whether or not this message has been rendered
132         * 
133         * @return true if this message has been rendered, false otherwise
134         */
135        public final boolean isRendered()
136        {
137                return rendered;
138        }
139
140        /**
141         * Marks this message as rendered.
142         */
143        public final void markRendered()
144        {
145                rendered = true;
146        }
147
148        /**
149         * Gets the message level; can be used by rendering components. Note that what actually happens
150         * with the level indication is totally up to the components that render feedback messages.
151         * 
152         * @return The message level indicator.
153         */
154        public final int getLevel()
155        {
156                return level;
157        }
158
159        /**
160         * Gets the current level as a String
161         * 
162         * @return The current level as a String
163         */
164        public String getLevelAsString()
165        {
166                return levelStrings.get(getLevel());
167        }
168
169        /**
170         * Gets the actual message.
171         * 
172         * @return the message.
173         */
174        public final Serializable getMessage()
175        {
176                return message;
177        }
178
179        /**
180         * Gets the reporting component.
181         * 
182         * @return the reporting component.
183         */
184        public final Component getReporter()
185        {
186                return reporter;
187        }
188
189        /**
190         * Gets whether the current level is DEBUG or up.
191         * 
192         * @return whether the current level is DEBUG or up.
193         */
194        public final boolean isDebug()
195        {
196                return isLevel(DEBUG);
197        }
198
199        /**
200         * Gets whether the current level is INFO or up.
201         * 
202         * @return whether the current level is INFO or up.
203         */
204        public final boolean isInfo()
205        {
206                return isLevel(INFO);
207        }
208
209        /**
210         * Gets whether the current level is SUCCESS or up.
211         * 
212         * @return whether the current level is SUCCESS or up.
213         */
214        public final boolean isSuccess()
215        {
216                return isLevel(SUCCESS);
217        }
218
219        /**
220         * Gets whether the current level is WARNING or up.
221         * 
222         * @return whether the current level is WARNING or up.
223         */
224        public final boolean isWarning()
225        {
226                return isLevel(WARNING);
227        }
228
229        /**
230         * Gets whether the current level is ERROR or up.
231         * 
232         * @return whether the current level is ERROR or up.
233         */
234        public final boolean isError()
235        {
236                return isLevel(ERROR);
237        }
238
239        /**
240         * Gets whether the current level is FATAL or up.
241         * 
242         * @return whether the current level is FATAL or up.
243         */
244        public final boolean isFatal()
245        {
246                return isLevel(FATAL);
247        }
248
249        /**
250         * Returns whether this level is greater than or equal to the given level.
251         * 
252         * @param level
253         *            the level
254         * @return whether this level is greater than or equal to the given level
255         */
256        public final boolean isLevel(int level)
257        {
258                return (getLevel() >= level);
259        }
260
261        /**
262         * Gets whether the current level is UNDEFINED.
263         * 
264         * @return whether the current level is UNDEFINED.
265         */
266        public final boolean isUndefined()
267        {
268                return (getLevel() == UNDEFINED);
269        }
270
271        @Override
272        public String toString()
273        {
274                return "[FeedbackMessage message = \"" + getMessage() + "\", reporter = " +
275                        ((getReporter() == null) ? "null" : getReporter().getId()) + ", level = " +
276                        getLevelAsString() + ']';
277        }
278
279        @Override
280        public void detach()
281        {
282                // no-op
283        }
284}