package com.google.gwt.gwtpages.client.message; import java.util.ArrayList; import java.util.Iterator; import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.event.shared.HasHandlers; import com.google.gwt.gwtpages.client.Pages; import com.google.gwt.gwtpages.client.event.MessageChangeEvent; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; /** * Controller class for application notification messages. All messages must * implement the {@link Message} interface. In most cases, you can use * {@link SimpleMessage} as the standard implementation. * * @author Joe Hudson */ public class Messages { private static Messages instance; protected HandlerManager eventBus; public static Messages get() { if (null == instance) instance = new Messages(Pages.get()); return instance; } public Messages(Pages pages) { if (null == pages) throw new IllegalArgumentException( "The GWT Pages instance must not be null"); this.eventBus = pages.getEventBus(); if (null == instance) instance = this; } public Messages() { if (null == instance) instance = this; } /** * Clear all application messages and fire the {@link MessageChangeEvent} * event */ public void clear() { fireChangeEvent(MessageChangeEvent.ACTION_CLEAR, null, null); } /** * Clear all application messages and fire the {@link MessageChangeEvent} * event * * @param parentContainer * an optional parent container to use as a root for looking for * a message handler (and bypass firing the event if found) */ public void clear(HasWidgets parentContainer) { if (!parentContainerCheck(parentContainer, MessageChangeEvent.ACTION_CLEAR, null, null)) fireChangeEvent(MessageChangeEvent.ACTION_CLEAR, null, null); } /** * Clear all application messages associated with the provided widget and * fire the {@link MessageChangeEvent} event * * @param widget * the associated widget */ public void clearFor(Widget widget) { fireChangeEvent(MessageChangeEvent.ACTION_CLEAR, null, widget); } /** * Clear all application messages associated with the provided widget and * fire the {@link MessageChangeEvent} event * * @param widget * the associated widget * @param parentContainer * an optional parent container to use as a root for looking for * a message handler (and bypass firing the event if found) */ public void clearFor(Widget widget, HasWidgets parentContainer) { if (!parentContainerCheck(parentContainer, MessageChangeEvent.ACTION_CLEAR, null, widget)) fireChangeEvent(MessageChangeEvent.ACTION_CLEAR, null, widget); } /** * Erase any existing messages and set the new messages. Then fire the * {@link MessageChangeEvent} event * * @param parentContainer * an optional parent container to use as a root for looking for * a message handler (and bypass firing the event if found) * @param message * the messages */ public void setMessage(Message... message) { fireChangeEvent(MessageChangeEvent.ACTION_REPLACE, message, null); } /** * Erase any existing messages and set the new messages. Then fire the * {@link MessageChangeEvent} event. * * @param parentContainer * an optional parent container to use as a root for looking for * a message handler (and bypass firing the event if found) * @param message * the messages */ public void setMessage(HasWidgets parentContainer, Message... message) { if (!parentContainerCheck(parentContainer, MessageChangeEvent.ACTION_REPLACE, message, null)) fireChangeEvent(MessageChangeEvent.ACTION_REPLACE, message, null); } /** * Erase any existing messages and set the new messages. Then fire the * {@link MessageChangeEvent} event * * @param parentContainer * an optional parent container to use as a root for looking for * a message handler (and bypass firing the event if found) * @param messages * the messages */ public void setMessages(HasWidgets parentContainer, ArrayList<Message> messages) { Message[] _messages = null != messages ? messages .toArray(new Message[messages.size()]) : null; if (!parentContainerCheck(parentContainer, MessageChangeEvent.ACTION_REPLACE, _messages, null)) fireChangeEvent(MessageChangeEvent.ACTION_REPLACE, _messages, null); } /** * Do not erase any existing messages but just add the new messages. Then * fire the {@link MessageChangeEvent} event * * @param parentContainer * an optional parent container to use as a root for looking for * a message handler (and bypass firing the event if found) * @param message * the messages */ public void addMessage(Message... message) { fireChangeEvent(MessageChangeEvent.ACTION_ADD, message, null); } /** * Do not erase any existing messages but just add the new messages. Then * fire the {@link MessageChangeEvent} event. * * @param parentContainer * an optional parent container to use as a root for looking for * a message handler (and bypass firing the event if found) * @param message * the messages */ public void addMessage(HasWidgets parentContainer, Message... message) { if (!parentContainerCheck(parentContainer, MessageChangeEvent.ACTION_ADD, message, null)) fireChangeEvent(MessageChangeEvent.ACTION_ADD, message, null); } /** * Do not erase any existing messages but just add the new messages. Then * fire the {@link MessageChangeEvent} event * * @param parentContainer * an optional parent container to use as a root for looking for * a message handler (and bypass firing the event if found) * @param messages * the messages */ public void addMessages(HasWidgets parentContainer, ArrayList<Message> messages) { Message[] _messages = null != messages ? messages .toArray(new Message[messages.size()]) : null; if (!parentContainerCheck(parentContainer, MessageChangeEvent.ACTION_ADD, _messages, null)) fireChangeEvent(MessageChangeEvent.ACTION_ADD, _messages, null); } /** * Auto-set a success message. Then fire the {@link MessageChangeEvent} * event * * @param message * the message text */ public void success(String message) { setMessage(Message.success(message)); } /** * Auto-set an error message. Then fire the {@link MessageChangeEvent} event * * @param message * the message text */ public void error(String message) { setMessage(Message.error(message)); } /** * Auto-set an error message. Then fire the {@link MessageChangeEvent} event * * @param message * the message text * @param widget * the widget that is in error */ public void error(String message, HasHandlers widget) { setMessage(Message.error(message, widget)); } /** * Auto-set a warning message. Then fire the {@link MessageChangeEvent} * event * * @param message * the message text */ public void warn(String message) { setMessage(Message.warn(message)); } /** * Auto-set an info message. Then fire the {@link MessageChangeEvent} event * * @param message * the message text */ public void info(String message) { setMessage(Message.info(message)); } /** * See if a message handler is a child of the parent container and call it * directly without firing the event * * @param parentContainer * a parent container or null if N/A * @param message * the messages * @return true if the messages were handled and false if not */ private boolean parentContainerCheck(HasWidgets parentContainer, int action, Message[] messages, Widget scopedWidget) { if (null == parentContainer) return false; Iterator<Widget> i = parentContainer.iterator(); while (i.hasNext()) { Widget child = i.next(); if (child instanceof MessageChangeEvent.MessageChangeHandler) { // let the child deal with the messages MessageChangeEvent.MessageChangeHandler handler = (MessageChangeEvent.MessageChangeHandler) child; if (action == MessageChangeEvent.ACTION_REPLACE) handler.onReplaceMessages(messages, scopedWidget); else if (action == MessageChangeEvent.ACTION_ADD) handler.onAddMessages(messages); else handler.onClearMessages(scopedWidget); return true; } else if (child instanceof HasWidgets) { boolean rtn = parentContainerCheck((HasWidgets) child, action, messages, scopedWidget); if (rtn) return true; } } return false; } private void fireChangeEvent(int action, Message[] messages, Widget scopedWidget) { if (null == eventBus) eventBus = Pages.get().getEventBus(); eventBus.fireEvent(new MessageChangeEvent(messages, action, scopedWidget)); } /** * Interface defining a container for messages which can be attached to a * request seesion for example * * @author Joe Hudson */ public interface Data { public Message[] getMessages(); } }