package jade.wrapper.gateway;
//#J2ME_EXCLUDE_FILE
import jade.util.leap.Iterator;
import jade.util.leap.HashMap;
import jade.core.behaviours.CyclicBehaviour;
import jade.util.Event;
import jade.util.Logger;
/**
* This is a cyclic behaviour that processes the commands received via JadeGateway.
* <code>JadeGateway</code> enables two alternative ways to implement a gateway
* that allows non-JADE code to communicate with JADE agents.
* <br> The first one is to extend the <code>GatewayAgent</code> (see its javadoc for reference).
* <br> The second one is to extend this <code>GatewayBehaviour</code> and add an instance
* of this Behaviour to your own agent that will have to function as a gateway.
* @author Fabio Bellifemine, Telecom Italia Lab
* @version $Date: $ $Revision: $
*/
public abstract class GatewayBehaviour extends CyclicBehaviour {
/**
* Queue of all pending commands that have not yet been released (see method releaseCommand)
* In this Hash, the key is the Object while the value is the Event
*/
private final HashMap commandQueue = new HashMap(2);
private final Logger myLogger = Logger.getMyLogger(this.getClass().getName());
public void action() {
Event e = (Event) myAgent.getO2AObject();
if (e == null) {
block();
return;
}
// put the event into the command Queue
commandQueue.put(e.getSource(), e);
if (myLogger.isLoggable(Logger.INFO)) {
myLogger.log(Logger.INFO, myAgent.getLocalName() + " started execution of command " + e.getSource());
}
// call the processCommand method such as the command is executed
processCommand(e.getSource());
}
/** subclasses must implement this method.
* The method is called each time a request to process a command
* is received from the JSP Gateway.
* <p> The recommended pattern is the following implementation:
<code>
if (c instanceof Command1)
execCommand1(c);
else if (c instanceof Command2)
execCommand2(c);
</code>
* </p>
* <b> REMIND THAT WHEN THE COMMAND HAS BEEN PROCESSED,
* YOU MUST CALL THE METHOD <code>releaseCommand</code>.
* Sometimes, you might prefer launching a new Behaviour that asynchronously processes
* this command and release the command just when the Behaviour terminates,
* i.e. in its <code>onEnd()</code> method.
**/
abstract protected void processCommand(Object command);
/**
* notify that the command has been processed and remove the command from the queue
* @param command is the same object that was passed in the processCommand method
**/
final public void releaseCommand(Object command) {
// remove the command from the queue
Event e = (Event) commandQueue.remove(command);
// notify that the command has been processed such as the JADEGateway is waken-up
if (e != null) {
if (myLogger.isLoggable(Logger.INFO)) {
myLogger.log(Logger.INFO, myAgent.getLocalName() + " terminated execution of command " + command);
}
e.notifyProcessed(null);
}
}
public int onEnd() {
if (myLogger.isLoggable(Logger.INFO))
myLogger.log(Logger.INFO, myAgent.getLocalName()
+ " terminated GatewayBehaviour");
for (Iterator i = commandQueue.values().iterator(); i.hasNext();)
((Event) (i.next())).notifyProcessed(null);
return super.onEnd();
}
}