/*==========================================================================*\
| $Id: WCComponentWithErrorMessages.java,v 1.3 2012/03/28 13:48:08 stedwar2 Exp $
|*-------------------------------------------------------------------------*|
| Copyright (C) 2006-2012 Virginia Tech
|
| This file is part of Web-CAT.
|
| Web-CAT is free software; you can redistribute it and/or modify
| it under the terms of the GNU Affero General Public License as published
| by the Free Software Foundation; either version 3 of the License, or
| (at your option) any later version.
|
| Web-CAT is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU Affero General Public License
| along with Web-CAT; if not, see <http://www.gnu.org/licenses/>.
\*==========================================================================*/
package org.webcat.core;
import org.webcat.core.ErrorDictionaryPanel;
import org.webcat.core.Status;
import org.webcat.ui.generators.JavascriptGenerator;
import com.webobjects.appserver.*;
import com.webobjects.foundation.*;
//-------------------------------------------------------------------------
/**
* This class is a base for WCComponent that extracts out the error
* message handling features.
*
* @author Stephen Edwards
* @author Last changed by $Author: stedwar2 $
* @version $Revision: 1.3 $, $Date: 2012/03/28 13:48:08 $
*/
public class WCComponentWithErrorMessages
extends WOComponent
{
//~ Constructors ..........................................................
// ----------------------------------------------------------
/**
* Creates a new object.
*
* @param context The page's context
*/
public WCComponentWithErrorMessages(WOContext context)
{
super(context);
}
//~ Methods ...............................................................
// ----------------------------------------------------------
public void appendToResponse(WOResponse response, WOContext context)
{
super.appendToResponse(response, context);
clearMessages();
}
// ----------------------------------------------------------
/**
* Determines whether this page has any messages.
* @return True if any messages are present
*/
public boolean hasMessages()
{
NSDictionary<String, Object> msgs = messagesIfPresent();
return msgs != null && msgs.count() > 0;
}
// ----------------------------------------------------------
/**
* Determines whether this page has any error messages.
* TODO: refactor this method by renaming it, since it currently
* returns true if there are any messages at all, even though some may
* not be errors.
* @return True if any error messages are present
*/
public boolean hasBlockingErrors()
{
if (hasMessages())
{
for (String key : messages.keySet())
{
Object value = messages.objectForKey(key);
ErrorDictionaryPanel.ErrorMessage msg =
(value instanceof ErrorDictionaryPanel.ErrorMessage)
? (ErrorDictionaryPanel.ErrorMessage)value
: null;
if (msg == null
|| msg.category() == Status.ERROR
|| msg.category() == Status.WARNING)
{
return true;
}
}
}
return false;
}
// ----------------------------------------------------------
/**
* Record an error message for this page.
* @param message the error message
*/
public void error(String message)
{
error(message, null);
}
// ----------------------------------------------------------
/**
* Record an exception as an error message for this page.
* @param anException the exception to be posted
*/
public void error(Throwable anException)
{
message(anException, null);
}
// ----------------------------------------------------------
/**
* Record an error message for this page.
* @param message the error message
* @param id a unique id used to distinguish this message from others
*/
public void error(String message, String id)
{
message(Status.ERROR, message, false, id);
}
// ----------------------------------------------------------
/**
* Record an error message for this page.
* @param message the error message
*/
public void warning(String message)
{
message(Status.WARNING, message, false, null);
}
// ----------------------------------------------------------
/**
* Record an error message for this page.
* @param message the error message
*/
public void confirmationMessage(String message)
{
message(Status.GOOD, message, false, null);
}
// ----------------------------------------------------------
/**
* Record an error message for this page, if one is provided. If a
* null message is provided, nothing happens (no message is recorded).
* @param message the error message, or null
*/
public void possibleErrorMessage(String message)
{
if (message != null)
{
error(message);
}
}
// ----------------------------------------------------------
/**
* Record an error message for this page, encoding it in an
* {@link ErrorDictionaryPanel.ErrorMessage} object first.
* @param category The type of message--use the constants defined
* in the {@link Status} class
* @param message The content of the message
* @param sticky True if this message should persist until it
* it explicitly cleared; otherwise, it will be
* cleared automatically after it has been displayed
* @param id a unique id used to distinguish this message from others
*/
public void message(
byte category, String message, boolean sticky, String id)
{
message(
new ErrorDictionaryPanel.ErrorMessage(category, message, sticky),
id
);
}
// ----------------------------------------------------------
/**
* Record an error message for this page, without processing.
* @param message the error message
* @param id a unique id used to distinguish this message from others
*/
public void message(Object message, String id)
{
if (id == null)
{
id = message.toString();
}
messages().setObjectForKey(message, id);
}
// ----------------------------------------------------------
/**
* Remove all non-sticky messages for this page.
*/
public void clearMessages()
{
NSMutableDictionary<String, Object> dict = messagesIfPresent();
if (dict != null)
{
NSMutableDictionary<String, Object> keep =
new NSMutableDictionary<String, Object>();
for (String key : dict.keySet())
{
Object value = dict.objectForKey(key);
if ((value instanceof ErrorDictionaryPanel.ErrorMessage)
&& ((ErrorDictionaryPanel.ErrorMessage)value).sticky())
{
keep.setObjectForKey(value, key);
}
}
dict.removeAllObjects();
dict.addEntriesFromDictionary(keep);
}
}
// ----------------------------------------------------------
/**
* Remove all messages for this page, including sticky ones.
*/
public void clearAllMessages()
{
NSMutableDictionary<String, Object> dict = messagesIfPresent();
if (dict != null)
{
dict.removeAllObjects();
}
}
// ----------------------------------------------------------
/**
* Remove a specific message from this page.
* @param id the unique identifier for the message
*/
public void clearMessage(String id)
{
NSMutableDictionary<String, Object> dict = messagesIfPresent();
if (dict != null)
{
dict.removeObjectForKey(id);
}
}
// ----------------------------------------------------------
/**
* Get the current message dictionary for this page, creating one
* if necessary. If no messages have been registered yet and no
* dictionary exists, one is created first.
* @return the message dictionary
*/
public NSMutableDictionary<String, Object> messages()
{
if (messages == null)
{
messages = new NSMutableDictionary<String, Object>();
}
return messages;
}
// ----------------------------------------------------------
/**
* Access the current message dictionary for this page, if one exists.
* If no messages have been registered yet and no dictionary exists,
* null is returned.
* @return the message dictionary, or null if one has not yet been created
*/
public NSMutableDictionary<String, Object> messagesIfPresent()
{
return messages;
}
// ----------------------------------------------------------
/**
* Returns a JavascriptGenerator that refreshes the page's error panel and
* scrolls it into view. This should be called from within remote actions
* where errors might occur and you wish to draw the user's attention to
* them (since reloading the page entirely is not possible or always
* desired from a remote action).
*
* @return a JavascriptGenerator that displays the error messages
*/
public JavascriptGenerator displayMessages()
{
JavascriptGenerator js = new JavascriptGenerator();
js.refresh("error-panel");
js.smoothScroll("error-panel", null, 200).play();
return js;
}
// ----------------------------------------------------------
public void validationFailedWithException(
Throwable ex, Object value, String key)
{
message(ex, key);
}
//~ Instance/static variables .............................................
private NSMutableDictionary<String, Object> messages;
}