📄 messagetemplate.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.lang.acl;
import java.io.Writer;
import java.io.IOException;
import java.util.Date;
import jade.util.leap.Serializable;
import jade.util.leap.Iterator;
import jade.util.leap.List;
import jade.util.leap.LinkedList;
import jade.util.leap.ArrayList;
import jade.core.AID;
import jade.core.CaseInsensitiveString;
import jade.core.messaging.TopicManagementHelper;
import jade.core.messaging.TopicUtility;
/**
A pattern for matching incoming ACL messages. This class allows to
build complex slot patterns to select ACL messages. These patterns
can then be used in <code>receive()</code> operations.
This class provide one method for each attribute of an ACLMessage,
that can be combined using the logic operators to create more complex
patterns.
A user can also create an application-specific pattern.
In this case he has to implement the MatchExpression interface,
writing the application specific <code>match()</code> method.
Then an instance of that class can be used as parameter of the MessageTemplate
constructor to define the application specific MessageTemaplate.
@see jade.core.Agent#receive(MessageTemplate mt)
@author Giovanni Rimassa - Universita' di Parma
@author Tiziana Trucco - Telecom Italia Lab S.p.A.
@version $Date: 2007-11-28 13:56:10 +0100 (mer, 28 nov 2007) $ $Revision: 6012 $
*/
public class MessageTemplate implements Serializable {
// Names of the various fields of an ACL messages.
private static final int CONVERSATION_ID = 0;
private static final int ENCODING = 1;
private static final int IN_REPLY_TO = 2;
private static final int LANGUAGE = 3;
private static final int ONTOLOGY = 4;
private static final int PROTOCOL = 5;
private static final int REPLY_BY = 6;
private static final int REPLY_WITH = 7;
private static final int RECEIVER = 9;
private static final int REPLY_TO = 10;
private static final int PERFORMATIVE = 11;
private static final int CONTENT = 12;
private static final int SENDER = 13;
private static final int REPLY_BY_DATE = 14;
/**
This interface must be overriden in order to define an application
specific MessageTemplate.
In particular in the method <code> match()</code> the programmer
should realize the necessary checks on the ACLMessage in order
to return <b>true</b> if the message match with the application
specific requirements <b>false</b> otherwise.
*/
public static interface MatchExpression extends Serializable{
/**
Check whether a given ACL message matches this
template. Concrete implementations of this interface will
have this method called to accept or refuse an ACL message.
@param msg The ACL message to match against this message
template.
@return A compliant implementation will return
<code>true</code> if the parameter ACL message matches the
template, and <code>false</code> otherwise.
*/
boolean match(ACLMessage msg);
}
private static class AndExpression implements MatchExpression {
private MatchExpression op1;
private MatchExpression op2;
public AndExpression(MatchExpression e1, MatchExpression e2) {
op1 = e1;
op2 = e2;
}
public boolean match(ACLMessage msg) {
return op1.match(msg) && op2.match(msg);
}
public String toString(){
return "("+op1.toString()+ " AND " + op2.toString()+")";
}
} // End of AndExpression class
private static class OrExpression implements MatchExpression{
private MatchExpression op1;
private MatchExpression op2;
public OrExpression(MatchExpression e1, MatchExpression e2) {
op1 = e1;
op2 = e2;
}
public boolean match(ACLMessage msg) {
return op1.match(msg) || op2.match(msg);
}
//only for debug
public String toString(){
return "("+op1.toString()+ " OR " + op2.toString()+")";
}
} // End of OrExpression class
private static class NotExpression implements MatchExpression{
private MatchExpression op;
public NotExpression(MatchExpression e) {
op = e;
}
public boolean match(ACLMessage msg) {
return ! op.match(msg);
}
//only for debug
public String toString(){
return "(NOT " + op.toString()+")";
}
} // End of NotExpression class
private static class Literal implements MatchExpression{
Object matchValue;
int perfValue;
int slotName;
//Literal for all the string value to match: language, ontology,encoding...
Literal(String matchValue, int slotName) {
this.matchValue = matchValue;
this.slotName = slotName;
}
//Literal for the sender value
Literal(AID matchValue){
this.matchValue = matchValue;
this.slotName = SENDER;
}
//Literal for the receiver and replyTo slot.
Literal(AID[] matchValue, int slotName){
this.matchValue = matchValue;
this.slotName = slotName;
}
//Literal for the performative slot
Literal(int matchValue){
this.perfValue = matchValue;
this.slotName = PERFORMATIVE;
}
//literal for the reply_by_date slot.
Literal(Date matchValue){
this.matchValue=matchValue;
this.slotName = REPLY_BY_DATE;
}
public boolean match(ACLMessage msg) {
switch(slotName){
case CONVERSATION_ID:
return CaseInsensitiveString.equalsIgnoreCase((String)matchValue,msg.getConversationId());
case REPLY_WITH:
return CaseInsensitiveString.equalsIgnoreCase((String)matchValue,msg.getReplyWith());
case PERFORMATIVE:
return (perfValue == msg.getPerformative());
case LANGUAGE:
return CaseInsensitiveString.equalsIgnoreCase((String)matchValue,msg.getLanguage());
case ONTOLOGY:
return CaseInsensitiveString.equalsIgnoreCase((String)matchValue,msg.getOntology());
case PROTOCOL:
return CaseInsensitiveString.equalsIgnoreCase((String)matchValue,msg.getProtocol());
case ENCODING:
return CaseInsensitiveString.equalsIgnoreCase((String)matchValue,msg.getEncoding());
case IN_REPLY_TO:
return CaseInsensitiveString.equalsIgnoreCase((String)matchValue,msg.getInReplyTo());
// case(REPLY_BY):
// return CaseInsensitiveString.equalsIgnoreCase((String)matchValue,msg.getReplyBy());
case REPLY_BY_DATE:
return ((Date)matchValue).equals(msg.getReplyByDate());
case RECEIVER:
if(matchValue != null){
AID[] receivers = (AID[])matchValue;
for(int i =0; i<receivers.length; i++){
AID recToMatch = receivers[i];
Iterator rec = msg.getAllReceiver();
boolean found = false;
while(rec.hasNext()){
if(recToMatch.equals((AID)rec.next())){
found = true;
break; //out of the inner loop
}
}//end while
if (found == false)
return false;
}//end for
return true;
}else
return false;
case REPLY_TO:
if(matchValue != null){
AID[] receivers = (AID[])matchValue;
for(int i =0; i<receivers.length; i++){
AID recToMatch = receivers[i];
Iterator rec = msg.getAllReplyTo();
boolean found = false;
while(rec.hasNext()){
if(recToMatch.equals((AID)rec.next())){
found = true;
break; //out of the inner loop
}
}//end while
if (found == false)
return false;
}//end for
return true;
}else
return false;
case CONTENT://FIXME: verificare il caso in cui il contenuto e'in byte.
return CaseInsensitiveString.equalsIgnoreCase((String)matchValue,msg.getContent());
case SENDER:
if(matchValue != null)
return ((AID)matchValue).equals(msg.getSender());
else
return false;
default:return false;
}
}
//#MIDP_EXCLUDE_BEGIN
//only for debug purpose.
public String toString(){
switch(slotName){
case CONVERSATION_ID:
return "(ConversationId: " + (String)matchValue + ")";
case ENCODING:
return "( Encoding: " +(String)matchValue + " )";
case IN_REPLY_TO:
return "( InReplyTo: " + (String)matchValue + " )";
case LANGUAGE:
return "( Language: " + (String)matchValue + " )";
case ONTOLOGY:
return "( Ontology: " + (String)matchValue + " )";
case PROTOCOL:
return "( Protocol: " + (String)matchValue+ " )";
// case(REPLY_BY):
// return CaseInsensitiveString.equalsIgnoreCase((String)matchValue,msg.getReplyBy());
case REPLY_BY_DATE:
return "( ReplyByDate: "+ (Date)matchValue + " )";
case REPLY_WITH:
return "( ReplyWith: " + (String)matchValue + " )";
case RECEIVER:
if(matchValue != null){
AID[] receivers = (AID[])matchValue;
String output = "( Receivers: ";
for(int i =0; i<receivers.length; i++){
AID recToMatch = receivers[i];
output += recToMatch.toString();
}
return output + ")" ;}
else
return "(Receivers: null)";
case REPLY_TO: //FIXME: da finire.
if(matchValue != null){
AID[] receivers = (AID[])matchValue;
String output = "( ReplyTo: ";
for(int i =0; i<receivers.length; i++){
AID recToMatch = receivers[i];
output += recToMatch.toString();
}
return output + " )" ;
}else
return "(ReplyTo: null)" ;
case PERFORMATIVE:
return "( Perfomative: " + ACLMessage.getPerformative(perfValue) + " )" ;
case CONTENT:
return "( Content: " + (String)matchValue + ")";
case SENDER:
if(matchValue != null)
return "( Sender AID: " + ((AID)matchValue).toString()+ ")" ;
else
return "(Sender AID: null)" ;
default:return "No slot. This casa should never occur !!!" ;
}
}
//#MIDP_EXCLUDE_END
} // End of Literal class
private static class MatchAllLiteral implements MatchExpression{
//use this literal for a MessageTemplate who matches all ACLMessages
MatchAllLiteral(){
}
public boolean match(ACLMessage msg){
return true;
}
public String toString(){
return "Match ALL Template";
}
}//end class MatchAllLiteral
private static class CustomMsgLiteral implements MatchExpression{
//use this literal for a messageTemplate matching the values of a given ACLMessage.
ACLMessage messageToMatch;
boolean matchPerformative;
CustomMsgLiteral(ACLMessage msg,boolean matchPerformative){
messageToMatch = msg;
this.matchPerformative = matchPerformative;
}
public boolean match(ACLMessage msg){
if(matchPerformative && (messageToMatch.getPerformative() != msg.getPerformative()))
return false;
if(messageToMatch.hasByteSequenceContent()) {
if (!messageToMatch.getByteSequenceContent().equals(msg.getByteSequenceContent()))
return false;
else if(!match(messageToMatch.getContent(),msg.getContent()))
return false;
}
if(!match(messageToMatch.getConversationId(),msg.getConversationId()))
return false;
if(!match(messageToMatch.getEncoding(),msg.getEncoding()))
return false;
if(!match(messageToMatch.getInReplyTo(),msg.getInReplyTo()))
return false;
if(!match(messageToMatch.getLanguage(),msg.getLanguage()))
return false;
if(!match(messageToMatch.getOntology(),msg.getOntology()))
return false;
if(!match(messageToMatch.getProtocol(),msg.getProtocol()))
return false;
if(!match(messageToMatch.getReplyWith(),msg.getReplyWith()))
return false;
if(!match(messageToMatch.getReplyByDate(),msg.getReplyByDate()))
return false;
//receiver
Iterator it1 = messageToMatch.getAllReceiver();
while(it1.hasNext()){
boolean found = false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -