/*****************************************************************
JADE - Java Agent DEvelopment Framework is a framework to develop
multi-agent systems in compliance with the FIPA specifications.
Copyright (C) 2000 CSELT S.p.A.
GNU Lesser General Public License
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation,
version 2.1 of the License.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*****************************************************************/
package jade.tools;
//#APIDOC_EXCLUDE_FILE
import jade.core.Agent;
import jade.core.ServiceException;
import jade.core.event.ContainerAdapter;
import jade.core.event.ContainerEvent;
import jade.core.event.ContainerListener;
import jade.core.event.NotificationHelper;
import jade.core.event.NotificationService;
import jade.domain.FIPANames;
import jade.domain.FIPAAgentManagement.*;
import jade.domain.JADEAgentManagement.*;
import jade.domain.introspection.*;
import jade.lang.acl.ACLMessage;
import jade.util.Logger;
import jade.content.lang.sl.SLCodec;
/**
This abstract class is the common ancestor of all JADE tools (RMA,
Sniffer, Introspector, etc.). It provides suitable behaviours to
interact with the AMS, registering for interesting events and
requesting actions when needed.
@author Giovanni Rimassa - Universita' di Parma
@version $Date: 2009-05-18 17:12:10 +0200 (lun, 18 mag 2009) $ $Revision: 6124 $
*/
public abstract class ToolAgent extends Agent {
private ACLMessage AMSSubscription = new ACLMessage(ACLMessage.SUBSCRIBE);
private ACLMessage AMSCancellation = new ACLMessage(ACLMessage.CANCEL);
private transient ContainerListener myContainerListener = null;
protected transient Logger logger;
// This is left here for backward compatibility
public static interface EventHandler extends AMSSubscriber.EventHandler {
}
/**
This abstract behaviour is used to receive notifications from
the AMS.
*/
protected abstract class AMSListenerBehaviour extends AMSSubscriber {
// Redefine the onStart() method not to automatically subscribe.
public void onStart() {
}
} // End of AMSListenerBehaviour class
/**
* Default constructor.
*/
public ToolAgent() {
}
/**
This method is invoked just after the generic agent
setup. Subclasses must use this method the same way ordinary
agents use their <code>setup()</code> method.
*/
protected void toolSetup() {
}
/**
This method is invoked just before the generic agent
takedown. Subclasses must use this method the same way ordinary
agents use their <code>takeDown()</code> method.
*/
protected void toolTakeDown() {
}
/**
Retrieve the <code>subscribe</code> ACL message with which this
tool agent subscribed with the AMS.
@return The subscription ACL message.
*/
protected ACLMessage getSubscribe() {
return AMSSubscription;
}
/**
Retrieve the <code>cancel</code> ACL message with which this
tool agent removes its subscription with the AMS.
@return The cancellation ACL message.
*/
protected ACLMessage getCancel() {
return AMSCancellation;
}
/**
Retrieve the <code>request</code> ACL message with which this
tool agent requests the AMS tool-specific actions.
@return The request ACL message.
*/
protected ACLMessage getRequest() {
ACLMessage AMSRequest = new ACLMessage(ACLMessage.REQUEST);
AMSRequest.setSender(getAID());
AMSRequest.addReceiver(getAMS());
AMSRequest.setProtocol(FIPANames.InteractionProtocol.FIPA_REQUEST);
AMSRequest.setLanguage(FIPANames.ContentLanguage.FIPA_SL0);
return AMSRequest;
}
public final void setup() {
init();
// Fill ACL messages fields
AMSSubscription.setSender(getAID());
AMSSubscription.clearAllReceiver();
AMSSubscription.addReceiver(getAMS());
AMSSubscription.setLanguage(FIPANames.ContentLanguage.FIPA_SL0);
AMSSubscription.setOntology(IntrospectionOntology.NAME);
AMSSubscription.setReplyWith(AMSSubscriber.AMS_SUBSCRIPTION);
AMSSubscription.setConversationId(getLocalName());
AMSSubscription.setContent(AMSSubscriber.PLATFORM_EVENTS);
AMSCancellation.setSender(getAID());
AMSCancellation.clearAllReceiver();
AMSCancellation.addReceiver(getAMS());
AMSCancellation.setLanguage(FIPANames.ContentLanguage.FIPA_SL0);
AMSCancellation.setOntology(IntrospectionOntology.NAME);
AMSCancellation.setReplyWith(AMSSubscriber.AMS_CANCELLATION);
AMSCancellation.setConversationId(getLocalName());
// No content is needed (cfr. FIPA 97 Part 2 page 26)
// Call tool-specific setup
toolSetup();
}
protected final void takeDown() {
clean();
// Call tool-specific takedown
toolTakeDown();
}
protected void afterClone() {
init();
}
protected void beforeMove() {
clean();
}
protected void afterMove() {
init();
}
protected void afterLoad() {
init();
}
protected void afterThaw() {
init();
}
protected void afterReload() {
init();
}
protected void beforeSave() {
}
protected void beforeFreeze() {
clean();
}
protected void beforeReload() {
clean();
}
private void init() {
logger = Logger.getMyLogger(getName());
// Register the supported ontologies
getContentManager().registerOntology(JADEManagementOntology.getInstance());
getContentManager().registerOntology(IntrospectionOntology.getInstance());
getContentManager().registerOntology(FIPAManagementOntology.getInstance());
// Register the supported languages
SLCodec codec = new SLCodec();
getContentManager().registerLanguage(codec, FIPANames.ContentLanguage.FIPA_SL0);
getContentManager().registerLanguage(codec, FIPANames.ContentLanguage.FIPA_SL1);
getContentManager().registerLanguage(codec, FIPANames.ContentLanguage.FIPA_SL2);
getContentManager().registerLanguage(codec, FIPANames.ContentLanguage.FIPA_SL);
// Register to be notified about the REATTACHED event in order to handle Main Container faults
try {
NotificationHelper helper = (NotificationHelper) getHelper(NotificationService.NAME);
myContainerListener = new ContainerAdapter() {
public void reattached(ContainerEvent ev) {
// The Main Container lost my subscription --> Subscribe again
send(getSubscribe());
}
};
helper.registerContainerListener(myContainerListener);
}
catch (ServiceException se) {
// Just print a warning since this does not affect the normal operation of a ToolAgent
logger.log(Logger.WARNING, "NotificationService not installed. Some tool may not work properly.");
}
}
private void clean() {
if (myContainerListener != null) {
try {
NotificationHelper helper = (NotificationHelper) getHelper(NotificationService.NAME);
helper.deregisterContainerListener(myContainerListener);
}
catch (ServiceException se) {
// Just do nothing since this does not affect the normal operation of a ToolAgent
}
}
}
}