📄 proposeinitiator.java
字号:
/*****************************************************************
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.proto;
//#CUSTOM_EXCLUDE_FILE
import jade.core.*;
import jade.core.behaviours.*;
import jade.lang.acl.*;
import jade.proto.states.MsgReceiver;
import java.util.Date;
import java.util.Vector;
import java.util.Enumeration;
import jade.util.leap.Iterator;
import jade.util.leap.Map;
import jade.util.leap.HashMap;
import jade.util.leap.List;
import jade.util.leap.ArrayList;
import jade.util.leap.Serializable;
import jade.domain.FIPANames.InteractionProtocol;
/**
* This class implements the Fipa-Propose interaction protocol
* with an API similar and homogeneous to <code>AchieveREInitiator</code>.
* <br>
* This implementation works both for 1:1 and 1:N conversation and, of course,
* implements the role of the initiator of the protocol.
* <p>
* The following is a brief description of the protocol. The programmer
* should however refer to the
* <a href=http://www.fipa.org/specs/fipa00036/SC00036H.html>FIPA Spec</a>
* for a complete description.
* <p>
* The initiator sends a <code>PROPOSE</code> message to the Participant
* indicating that it will perform some action if the Participant agrees.
* The implementation of the callback method <code>prepareInitiations</code>
* must return the vector of messages to be sent (eventually a single message
* with multiple receivers).
* <p>
* The responders can then reply by sending a <code>ACCEPT-PROPOSAL</code>
* message. Alternatively, responders may send a <code>REJECT-PROPOSAL</code>,
* to refuse the proposal or, eventually, a <code>NOT-UNDERSTOOD</code> to
* communicate communication problems.
* This category of reply messages has been here identified as a
* response and can be handled via the <code>handleAllResponses</code>
* callback method.
* Specific handle callback methods for each type of communicative act are also
* available when the programmer wishes to handle them separately:
* <code>handleRejectProposal, handleAcceptProposal, handleNotUnderstood</code>
* <p>
* If a message were received, with the same value of this
* <code>conversation-id</code>, but that does not comply with the FIPA
* protocol, than the method <code>handleOutOfSequence</code> would be called.
* <p>
* This class can be extended by the programmer by overriding all the needed
* handle methods or, in alternative, appropriate behaviours can be
* registered for each handle via the <code>registerHandle</code>-type
* of methods. This last case is more difficult to use and proper
* care must be taken to properly use the <code>DataStore</code> of the
* <code>Behaviour</code> as a shared memory mechanism with the
* registered behaviour.
* <p>
* Read carefully the section of the
* <a href="..\..\..\programmersguide.pdf"> JADE programmer's guide </a>
* that describes
* the usage of this class.
*
* @author Jerome Picault - Motorola Labs
* @version $Date: 2005-09-16 15:54:46 +0200 (ven, 16 set 2005) $ $Revision: 5780 $
* @since JADE3.1
* @see ProposeResponder
* @see AchieveREInitiator
* @see <a href=http://www.fipa.org/specs/fipa00036>FIPA Spec</a>
**/
public class ProposeInitiator extends FSMBehaviour {
// Private data store keys (can't be static since if we register another instance of this class as stare of the FSM
//using the same data store the new values overrides the old one.
/**
* key to retrieve from the DataStore of the behaviour the ACLMessage
* object passed in the constructor of the class.
**/
protected final String INITIATION_K = "__initiation" + hashCode();
/**
* key to retrieve from the DataStore of the behaviour the vector of
* PROPOSE ACLMessage objects that have to be sent.
**/
protected final String ALL_INITIATIONS_K = "__all-initiations" +hashCode();
/**
* key to retrieve from the DataStore of the behaviour the last
* ACLMessage object that has been received (null if the timeout
* expired).
**/
public final String REPLY_KEY = "__reply" + hashCode();
/**
* key to retrieve from the DataStore of the behaviour the vector of
* ACLMessage objects that have been received as responses.
**/
public final String ALL_RESPONSES_KEY = "__all-responses" + hashCode();
// FSM states names
protected static final String PREPARE_INITIATIONS = "Prepare-initiations";
protected static final String SEND_INITIATIONS = "Send-initiations";
protected static final String RECEIVE_REPLY = "Receive-reply";
protected static final String CHECK_IN_SEQ = "Check-in-seq";
protected static final String HANDLE_NOT_UNDERSTOOD = "Handle-not-understood";
protected static final String HANDLE_OUT_OF_SEQ = "Handle-out-of-seq";
protected static final String HANDLE_ALL_RESPONSES = "Handle-all-responses";
protected static final String HANDLE_REJECT_PROPOSAL = "Handle-reject-proposal";
protected static final String HANDLE_ACCEPT_PROPOSAL = "Handle-accept-proposal";
private static final String CHECK_AGAIN = "Check-again";
protected static final String CHECK_SESSIONS = "Check-sessions";
protected static final String DUMMY_FINAL = "Dummy-final";
//#APIDOC_EXCLUDE_BEGIN
// This maps the AID of each responder to a Session object
// holding the status of the protocol as far as that responder
// is concerned. Sessions are protocol-specific
protected Map sessions = new HashMap();
// The MsgReceiver behaviour used to receive replies
protected MsgReceiver replyReceiver = null;
// The MessageTemplate used by the replyReceiver
protected MessageTemplate replyTemplate = null;
//#APIDOC_EXCLUDE_END
private ACLMessage initiation;
// States exit values
private static final int ALL_RESPONSES_RECEIVED = 1;
private static final int TERMINATED = 2;
//#APIDOC_EXCLUDE_BEGIN
// These states must be reset before they are visited again.
// Note that resetting a state before visiting it again is required
// only if
// - The onStart() method is redefined
// - The state has an "internal memory"
// The states below must be reset as the user can redefine them -->
// They can fall in one of the above categories.
protected String[] toBeReset = new String[] {
HANDLE_ACCEPT_PROPOSAL,
HANDLE_REJECT_PROPOSAL,
HANDLE_NOT_UNDERSTOOD,
HANDLE_OUT_OF_SEQ
};
//#APIDOC_EXCLUDE_END
// If set to true all expected responses have been received
private boolean allResponsesReceived = false;
/**
* Construct a <code>ProposeInitiator</code> with an empty DataStore
* @see #ProposeInitiator(Agent, ACLMessage, DataStore)
**/
public ProposeInitiator(Agent a, ACLMessage msg){
this(a,msg,new DataStore());
}
/**
* Construct a <code>ProposeInitiator</code> with a given DataStore
* @param a The agent performing the protocol
* @param initiation The message that must be used to initiate the protocol.
* Notice that the default implementation of the
* <code>prepareInitiations()</code> method returns
* an array composed of only this message.
* The values of the slot
* <code>reply-with</code> is ignored and a different value is assigned
* automatically by this class for each receiver.
* @param store The <code>DataStore</code> that will be used by this
* <code>ProposeInitiator</code>
*/
public ProposeInitiator(Agent a, ACLMessage initiation, DataStore store) {
super(a);
setDataStore(store);
this.initiation = initiation;
// Register the FSM transitions
registerDefaultTransition(PREPARE_INITIATIONS, SEND_INITIATIONS);
registerTransition(SEND_INITIATIONS, DUMMY_FINAL, 0); // Exit the protocol if no initiation message is sent
registerDefaultTransition(SEND_INITIATIONS, RECEIVE_REPLY);
registerTransition(RECEIVE_REPLY, CHECK_SESSIONS, MsgReceiver.TIMEOUT_EXPIRED);
registerTransition(RECEIVE_REPLY, CHECK_SESSIONS, MsgReceiver.INTERRUPTED);
registerDefaultTransition(RECEIVE_REPLY, CHECK_IN_SEQ);
registerTransition(CHECK_IN_SEQ, HANDLE_NOT_UNDERSTOOD, ACLMessage.NOT_UNDERSTOOD);
registerTransition(CHECK_IN_SEQ, HANDLE_REJECT_PROPOSAL, ACLMessage.REJECT_PROPOSAL);
registerTransition(CHECK_IN_SEQ, HANDLE_ACCEPT_PROPOSAL, ACLMessage.ACCEPT_PROPOSAL);
registerDefaultTransition(CHECK_IN_SEQ, HANDLE_OUT_OF_SEQ);
registerDefaultTransition(HANDLE_NOT_UNDERSTOOD, CHECK_SESSIONS);
registerDefaultTransition(HANDLE_REJECT_PROPOSAL, CHECK_SESSIONS);
registerDefaultTransition(HANDLE_ACCEPT_PROPOSAL, CHECK_SESSIONS);
registerDefaultTransition(HANDLE_OUT_OF_SEQ, RECEIVE_REPLY);
registerDefaultTransition(CHECK_SESSIONS, RECEIVE_REPLY, toBeReset);
registerTransition(CHECK_SESSIONS, HANDLE_ALL_RESPONSES, ALL_RESPONSES_RECEIVED);
registerTransition(CHECK_SESSIONS, DUMMY_FINAL, TERMINATED);
registerDefaultTransition(HANDLE_ALL_RESPONSES, CHECK_AGAIN);
registerTransition(CHECK_AGAIN, DUMMY_FINAL, 0);
registerDefaultTransition(CHECK_AGAIN, RECEIVE_REPLY, toBeReset);
Behaviour b = null;
// PREPARE_INITIATIONS
b = new OneShotBehaviour(myAgent) {
private static final long serialVersionUID = 3487495895818000L;
public void action() {
DataStore ds = getDataStore();
Vector allInitiations = prepareInitiations((ACLMessage) ds.get(INITIATION_K));
getDataStore().put(ALL_INITIATIONS_K, allInitiations);
}
};
b.setDataStore(getDataStore());
registerFirstState(b, PREPARE_INITIATIONS);
// SEND_INITIATIONS
b = new OneShotBehaviour(myAgent) {
private static final long serialVersionUID = 3487495895818001L;
public void action() {
Vector allInitiations = (Vector) getDataStore().get(ALL_INITIATIONS_K);
if (allInitiations != null) {
sendInitiations(allInitiations);
}
}
public int onEnd() {
return sessions.size();
}
};
b.setDataStore(getDataStore());
registerState(b, SEND_INITIATIONS);
// RECEIVE_REPLY
replyReceiver = new MsgReceiver(myAgent, null, MsgReceiver.INFINITE, getDataStore(), REPLY_KEY);
registerState(replyReceiver, RECEIVE_REPLY);
// CHECK_IN_SEQ
b = new OneShotBehaviour(myAgent) {
int ret;
private static final long serialVersionUID = 3487495895818002L;
public void action() {
ACLMessage reply = (ACLMessage) getDataStore().get(REPLY_KEY);
if (checkInSequence(reply)) {
ret = reply.getPerformative();
}
else {
ret = -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -