001: /*
002: * $Id: FeedbackPanel.java 460079 2006-03-31 01:27:29Z ehillenius $
003: * $Revision: 460079 $ $Date: 2006-03-31 03:27:29 +0200 (Fri, 31 Mar 2006) $
004: *
005: * ==============================================================================
006: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
007: * use this file except in compliance with the License. You may obtain a copy of
008: * the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015: * License for the specific language governing permissions and limitations under
016: * the License.
017: */
018: package wicket.markup.html.panel;
019:
020: import java.util.Collections;
021: import java.util.Comparator;
022: import java.util.Iterator;
023: import java.util.List;
024:
025: import wicket.AttributeModifier;
026: import wicket.Component;
027: import wicket.feedback.FeedbackMessage;
028: import wicket.feedback.FeedbackMessagesModel;
029: import wicket.feedback.IFeedback;
030: import wicket.feedback.IFeedbackMessageFilter;
031: import wicket.markup.html.WebMarkupContainer;
032: import wicket.markup.html.basic.Label;
033: import wicket.markup.html.list.ListItem;
034: import wicket.markup.html.list.ListView;
035: import wicket.model.IModel;
036: import wicket.model.Model;
037:
038: /**
039: * A panel that displays {@link wicket.feedback.FeedbackMessage}s in a list
040: * view. The maximum number of messages to show can be set with
041: * setMaxMessages().
042: *
043: * @see wicket.feedback.FeedbackMessage
044: * @see wicket.feedback.FeedbackMessages
045: * @author Jonathan Locke
046: * @author Eelco Hillenius
047: */
048: public class FeedbackPanel extends Panel implements IFeedback {
049: private static final long serialVersionUID = 1L;
050:
051: /** whether model messages should be HTML escaped. Default is true. */
052: private boolean escapeMessages = true;
053:
054: /** Message view */
055: private final MessageListView messageListView;
056:
057: /**
058: * List for messages.
059: */
060: private final class MessageListView extends ListView {
061: private static final long serialVersionUID = 1L;
062:
063: /**
064: * @see wicket.Component#Component(String)
065: */
066: public MessageListView(final String id) {
067: super (id);
068: setModel(newFeedbackMessagesModel());
069: }
070:
071: /**
072: * @see wicket.markup.html.list.ListView#populateItem(wicket.markup.html.list.ListItem)
073: */
074: protected void populateItem(final ListItem listItem) {
075: final FeedbackMessage message = (FeedbackMessage) listItem
076: .getModelObject();
077: message.markRendered();
078: final IModel replacementModel = new Model() {
079: private static final long serialVersionUID = 1L;
080:
081: /**
082: * Returns feedbackPanel + the message level, eg
083: * 'feedbackPanelERROR'. This is used as the class of the li /
084: * span elements.
085: *
086: * @see wicket.model.IModel#getObject(Component)
087: */
088: public Object getObject(final Component component) {
089: return getCSSClass(message);
090: }
091: };
092:
093: final Label label = new Label("message", message
094: .getMessage());
095: label.setEscapeModelStrings(getEscapeMessages());
096: final AttributeModifier levelModifier = new AttributeModifier(
097: "class", replacementModel);
098: label.add(levelModifier);
099: listItem.add(levelModifier);
100: listItem.add(label);
101: }
102: }
103:
104: /**
105: * @see wicket.Component#Component(String)
106: */
107: public FeedbackPanel(final String id) {
108: this (id, null);
109: }
110:
111: /**
112: * @see wicket.Component#Component(String)
113: */
114: public FeedbackPanel(final String id, IFeedbackMessageFilter filter) {
115: super (id);
116: WebMarkupContainer messagesContainer = new WebMarkupContainer(
117: "feedbackul") {
118: private static final long serialVersionUID = 1L;
119:
120: public boolean isVisible() {
121: return anyMessage();
122: }
123: };
124: add(messagesContainer);
125: this .messageListView = new MessageListView("messages");
126: messageListView.setVersioned(false);
127: messagesContainer.add(messageListView);
128:
129: if (filter != null) {
130: setFilter(filter);
131: }
132: }
133:
134: /**
135: * Gets whether model messages should be HTML escaped. Default is true.
136: *
137: * @return whether model messages should be HTML escaped
138: */
139: public final boolean getEscapeMessages() {
140: return escapeMessages;
141: }
142:
143: /**
144: * @return Model for feedback messages on which you can install filters and
145: * other properties
146: */
147: public final FeedbackMessagesModel getFeedbackMessagesModel() {
148: return (FeedbackMessagesModel) messageListView.getModel();
149: }
150:
151: /**
152: * @return The current message filter
153: */
154: public final IFeedbackMessageFilter getFilter() {
155: return getFeedbackMessagesModel().getFilter();
156: }
157:
158: /**
159: * @return The current sorting comparator
160: */
161: public final Comparator getSortingComparator() {
162: return getFeedbackMessagesModel().getSortingComparator();
163: }
164:
165: /**
166: * @see wicket.Component#isVersioned()
167: */
168: public boolean isVersioned() {
169: return false;
170: }
171:
172: /**
173: * Sets whether model messages should be HTML escaped. Default is true.
174: *
175: * @param escapeMessages
176: * whether model messages should be HTML escaped
177: */
178: public final void setEscapeMessages(boolean escapeMessages) {
179: this .escapeMessages = escapeMessages;
180: }
181:
182: /**
183: * Sets a filter to use on the feedback messages model
184: *
185: * @param filter
186: * The message filter to install on the feedback messages model
187: */
188: public final void setFilter(IFeedbackMessageFilter filter) {
189: getFeedbackMessagesModel().setFilter(filter);
190: }
191:
192: /**
193: * @param maxMessages
194: * The maximum number of feedback messages that this feedback
195: * panel should show at one time
196: */
197: public final void setMaxMessages(int maxMessages) {
198: this .messageListView.setViewSize(maxMessages);
199: }
200:
201: /**
202: * Sets the comparator used for sorting the messages.
203: *
204: * @param sortingComparator
205: * comparator used for sorting the messages.
206: */
207: public final void setSortingComparator(Comparator sortingComparator) {
208: getFeedbackMessagesModel().setSortingComparator(
209: sortingComparator);
210: }
211:
212: /**
213: * @see wicket.feedback.IFeedback#updateFeedback()
214: */
215: public void updateFeedback() {
216: // Force model to load
217: messageListView.getModelObject();
218: }
219:
220: /**
221: * Search messages that this panel will render, and see if there is any
222: * message of level ERROR or up. This is a convenience method; same as
223: * calling 'anyMessage(FeedbackMessage.ERROR)'.
224: *
225: * @return whether there is any message for this panel of level ERROR or up
226: */
227: public final boolean anyErrorMessage() {
228: return anyMessage(FeedbackMessage.ERROR);
229: }
230:
231: /**
232: * Search messages that this panel will render, and see if there is any
233: * message.
234: *
235: * @return whether there is any message for this panel
236: */
237: public final boolean anyMessage() {
238: return anyMessage(FeedbackMessage.UNDEFINED);
239: }
240:
241: /**
242: * Search messages that this panel will render, and see if there is any
243: * message of the given level.
244: *
245: * @param level
246: * the level, see FeedbackMessage
247: * @return whether there is any message for this panel of the given level
248: */
249: public final boolean anyMessage(int level) {
250: List msgs = getCurrentMessages();
251:
252: for (Iterator i = msgs.iterator(); i.hasNext();) {
253: FeedbackMessage msg = (FeedbackMessage) i.next();
254: if (msg.isLevel(level)) {
255: return true;
256: }
257: }
258:
259: return false;
260: }
261:
262: /**
263: * Gets the css class for the given message.
264: *
265: * @param message
266: * the message
267: * @return the css class; by default, this returns feedbackPanel + the
268: * message level, eg 'feedbackPanelERROR', but you can override this
269: * method to provide your own
270: */
271: protected String getCSSClass(final FeedbackMessage message) {
272: return "feedbackPanel" + message.getLevelAsString();
273: }
274:
275: /**
276: * Gets the currently collected messages for this panel.
277: *
278: * @return the currently collected messages for this panel, possibly empty
279: */
280: protected final List getCurrentMessages() {
281: final List messages = (List) messageListView.getModelObject();
282: return Collections.unmodifiableList(messages);
283: }
284:
285: /**
286: * Gets a new instance of FeedbackMessagesModel to use.
287: *
288: * @return Instance of FeedbackMessagesModel to use
289: */
290: protected FeedbackMessagesModel newFeedbackMessagesModel() {
291: return new FeedbackMessagesModel();
292: }
293:
294: }
|