HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"A Multi-Agent Meeting Organizer"
Vol. 2, Issue 2 P. 8

	

Listing 1

/**
 * AMEETZER main program
 */
public class Ameetzer {

	public static Config cfg;

	/* other variable definitions */
	.....

	public static void main( String[] args ) {

		/* read in configuration file */
		.....

		/* get user's identity */
		.....

		/* register with Registry */
		.....

		/* read in user's calendar and preferences */
		.....

		/* create subagent threads */
		cfg.sa_gui = new Receptionist( 
											cfg.data_path, "gui" );
		cfg.sa_sch = new Scheduler( 
											cfg.data_path, "sch" );
		cfg.sa_msg = new Messenger( 
											cfg.data_path, "msg" );
		cfg.sa_dsp = new Dispatcher( 
											cfg.data_path, "dsp" );
		cfg.channel = new Channel( 
				cfg.assigned_port, cfg.sa_dsp.mailbox );

		/* wait for subagents to join (die) */
		try {
			cfg.sa_gui.join();
			cfg.sa_sch.join();
			cfg.sa_msg.join();
			cfg.sa_dsp.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		/* save user's data */
		.....
	}
}

// Listing 2

/**
 * Subagent object defines a subagent as a thread 
 *  with name, path, filename and mailbox fields.
 */
public class Subagent extends Thread {

	protected String myName;
	protected String myPath;
	protected String filename;
	protected MessageQueue mailbox;

	public Subagent( String path, String name ) {

		myPath = path;
		myName = name;
		filename = path+name+"_mbox.dat";

		// no existing mailbox, create new one
		if (mailbox == null)
			mailbox = new MessageQueue();
	}

	/**
	 * read and enqueue messages from file (if any)
	 */
	public void read_mbox() {
		.....
	}

	/**
	 * dequeue and write messages to file
	 */
	public void write_mbox() {
		.....
	}
}

Listing 3

public class Dispatcher extends Subagent {

	public Dispatcher( String path, String name ) {
		super( path, name );
		this.start();
	}

	public void run() {

		Message msg;

		while (Ameetzer.cfg.exit_status != true) {

			// get a message from mailbox
			msg = (Message)mailbox.get();

			// dispatch message according to intention 
			//  and content
			if (msg.intention.compareTo("ask-one") == 0
					&& ((String)msg.content[0]).compareTo(
					"schedule") == 0 || ..... ) {

				// dispatch to Receptionist subagent
				try { 
					Ameetzer.cfg.sa_gui.mailbox.put( msg );
				} catch (QueueException e) {
					return;
				}

			} else if ( ..... ) {

				// dispatch to Scheduler subagent
				.....

			} // end of message-matching
		} // while (true)
	} // run
}

Listing 4

/**
 * Message object defines a agent communication 
 *  message
 */
public class Message extends Object {

	protected String intention;

	protected String sender;

	protected String receiver[];

	protected Object content[];

	public Message() {
		// super();
	}
}

Listing 5

/**
 * MessageQueue object provides messaging via
 *  mailbox
 */
public class MessageQueue extends Queue {

	// synchronization primitives
	private Semaphore empty, full;

	/**
	 * create queue and semaphores
	 */
	public MessageQueue() {
		empty = new Semaphore( super.qsize );
		full  = new Semaphore( 0 );
	}

	/**
	 * create queue and semaphores
	 */
	public MessageQueue( int size ) {
		super( size );
		empty = new Semaphore( super.qsize );
		full  = new Semaphore( 0 );
	}

	/**
	 * remove message from queue 
	 */
	public Message get() {

		full.down();
		Message msg = (Message)super.remove();
		empty.up();
		return( msg );
	}

	/**
	 * append message to queue
	 */
	public void put( Message new_msg ) 
		throws QueueException {

		empty.down();
		super.append( new_msg );
		full.up();
	}
}

// Listing 6

/**
 * Semaphore object for synchronization
 */
public class Semaphore {

	// semaphore value
	private int count;

	/**
	 * initialize semaphore value
	 */
	public Semaphore(int value) {
		count = value;
	}

	/**
	 * V() operation
	 */
	public synchronized void up() {
		count++;
		if (count <= 0) 
			notify();
	}

	/**
	 * P() operation
	 */
	public synchronized void down() {
		count--;
		if (count < 0) {
			try {
				wait();
			} catch (InterruptedException e) {}
		}
	}
} 

Listing 7

Message query_msg = new Message();
query_msg.intention = "ask-one";
query_msg.sender = Ameetzer.cfg.userid;
query_msg.content = new Object[3];
query_msg.content[0] = "schedule";
query_msg.content[1] = mtg_id;
query_msg.content[2] = meeting;

Message fw_msg = new Message();
fw_msg.intention = "forward";
fw_msg.sender = myName;
fw_msg.receiver = new String[meeting.attendees.
															length];
for (int i = 0; i < meeting.attendees.length; 
			i++) {
	fw_msg.receiver[i] = meeting.attendees[i].name;
}
fw_msg.content = new Object[2];
fw_msg.content[0] = query_msg;
fw_msg.content[1] = mtg_id;
try {
	Ameetzer.cfg.sa_msg.mailbox.put( fw_msg );
} catch (QueueException e) {
	e.printStackTrace();
}

Listing 8

marten% java Ameetzer .        
Configuring myself ..... done.
Registering myself ..... done.
Hmm ... looking for your data ..... done.
Now ... sharpening my senses for you ..... done.
[email protected] started.
[email protected] started.
[email protected] started.
[email protected] started.

[email protected] exits now.
[email protected] exits now.
[email protected] exits now.
[email protected] exits now.
Ameetzer exits.
marten%

Listing 9

/**
 * Registry: registration and name services 
 */
public class Registry {

	public final static int WELL_KNOWN_PORT = 9999;
	public final static int AMZ_INIT_PORT = 9988;

	/* other variable definitions */
	.....

	public static void main( String[] args ) {

		Message msg;
		MessageQueue mailbox = new MessageQueue();
		Channel channel = new Channel( 
										WELL_KNOWN_PORT, mailbox );

		// map: userid --> hostname
		Hashtable uid_host_map = new Hashtable();

		// map: userid+hostname --> port number
		Hashtable ses_port_map = new Hashtable();

		System.out.println("## Registry started.");

		while (true) {

			// get a message from mailbox
			msg = (Message)mailbox.get();

			// provide service based on message 
			//  intention

			// registration
			if (msg.intention.compareTo("register")
					== 0) {

				String userid = msg.sender;
				String hostname = 
						(String)uid_host_map.get( userid );

				if (hostname != null) {
					// user's AMEETZER already active

					// reply with [sorry] message
					.....

				} else { // user's AMEETZER is new

					// create new entry and reply with
					//  allocated port numbers
					.....

				}

			// unregistration
			} else if
				(msg.intention.compareTo("unregister")
					== 0) {

				// remove entry from look-up tables
				.....

			// query
			} else if
				(msg.intention.compareTo("ask-all")
					== 0) {

				// look up the hostnames and port numbers
				//  and reply
				.....

			}
		} // while (true)
	} // run
}
 

 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.