
org.miv.mbox.MBoxBase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mbox2 Show documentation
Show all versions of mbox2 Show documentation
The message box acts as a buffer for incoming messages. Its major property is
to be usable from any thread. This allows any external source to post any
message at any time without having to wonder about synchronisation.
The newest version!
package org.miv.mbox;
import java.util.*;
/**
* MBox default implementation usable as base class.
*
*
* The goal of this implementation is to provide a base to construct other
* classes able to handle messages comming from different sources and threads.
* The presupposed in this class is that the inheriting class will check
* messages at regular time using the method {@link #processMessages()}.
*
*
* @see org.miv.mbox.MBox
* @author Antoine Dutot
* @since 20041102
*/
public abstract class
MBoxBase
implements
MBox, MBoxListener
{
// Attributes
/**
* Temporary array to store messages when sent to the listener to avoid
* blocking the Receiver that can post messages during the execution of
* messages.
*/
protected ArrayList mtmp = new ArrayList();
/**
* List of unread messages.
*/
protected ArrayList messages = new ArrayList();
// Constructors
/**
* New empty Message Box.
*/
public MBoxBase()
{
}
// Constructors
// Access
public synchronized boolean isMBoxEmpty()
{
return( messages.size() <= 0 );
}
public synchronized int getMessageCount()
{
return messages.size();
}
// Command
public synchronized void post( String from, Object... data )
{
messages.add( new Message( from, data ) );
}
/**
* Process all messages. Call this method at regular intervals to empty the
* message box. This method will call
* {@link #processMessage(String, Object[])} for each message in the box.
*/
public void processMessages()
{
int n;
// We first copy the messages in a temporary buffer in order to let
// the synchronised block be as short as possible. This avoids that
// sending threads be blocked a long time when posting to this object.
// Indeed, we do not know the time used by processMessage(), but it can
// be quite long.
synchronized( this )
{
n = messages.size();
if( n > 0 )
{
mtmp.ensureCapacity( n );
mtmp.addAll( messages );
messages.clear();
}
}
// Then we really process the messages in our own thread without
// blocking.
for( int i=0; i 0 )
mtmp.clear();
}
/**
* Like {@link #processMessages()} but instead of calling the
* {@link #processMessage(String, Object[])} method for each message, returns the list of
* pending messages. The messages are removed from the list of pending messages and therefore
* will not be processed by the next calls to {@link #processMessages()}.
* @return A list of all messages not yet processed, removed from the list of pending messages.
*/
public ArrayList popPendingMessages()
{
int n;
ArrayList m = new ArrayList();
synchronized( this )
{
n = messages.size();
if( n > 0 )
{
m.ensureCapacity( n );
m.addAll( messages );
messages.clear();
}
}
return m;
}
/**
* Method to override to process each incomming message.
* @param from The address of the sender.
* @param data The data sent by the sender.
*/
public abstract void processMessage( String from, Object[] data );
// Inner classes
/**
* Simple message container.
*/
public static class Message
{
public String from;
public Object data[];
protected Message( String from, Object data[] ) { this.from = from; this.data = data; }
public String getFrom() { return from; }
public Object[] getData() { return data; }
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy