fipa_acl  1.4
acl_message.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <vector>
3 #include <algorithm>
4 #include <string>
5 #include "acl_message.h"
6 #include <boost/assign/list_of.hpp>
7 #include <boost/date_time.hpp>
8 #include <boost/foreach.hpp>
9 #include <stdexcept>
10 
11 namespace fipa {
12 
13 namespace acl {
14 
15 std::map<ACLMessage::Performative, std::string> PerformativeTxt = boost::assign::map_list_of
16  (ACLMessage::ACCEPT_PROPOSAL, "accept-proposal")
17  (ACLMessage::AGREE, "agree")
18  (ACLMessage::CANCEL, "cancel")
20  (ACLMessage::CONFIRM, "confirm")
21  (ACLMessage::DISCONFIRM, "disconfirm")
22  (ACLMessage::FAILURE, "failure")
23  (ACLMessage::INFORM, "inform")
24  (ACLMessage::INFORM_IF, "inform-if")
25  (ACLMessage::INFORM_REF, "inform-ref")
26  (ACLMessage::NOT_UNDERSTOOD, "not-understood")
27  (ACLMessage::PROPAGATE, "propagate")
28  (ACLMessage::PROPOSE, "propose")
29  (ACLMessage::PROXY, "proxy")
30  (ACLMessage::QUERY_IF, "query-if")
31  (ACLMessage::QUERY_REF, "query-ref")
32  (ACLMessage::REFUSE, "refuse")
33  (ACLMessage::REJECT_PROPOSAL, "reject-proposal")
34  (ACLMessage::REQUEST, "request")
35  (ACLMessage::REQUEST_WHEN, "request-when")
36  (ACLMessage::REQUEST_WHENEVER, "request-whenever")
37  (ACLMessage::SUBSCRIBE, "subscribe");
38 
39 const std::string illegalWordChars = std::string("() ") + char(0x00);
40 const std::string illegalWordStart = std::string("@#-0123456789");
41 
43 {
44  std::map<ACLMessage::Performative, std::string>::const_iterator it = PerformativeTxt.begin();
45  for(; it != PerformativeTxt.end(); ++it)
46  {
47  if(it->second == performative)
48  {
49  return it->first;
50  }
51  }
52  std::string msg = "String '" + performative + "' does not match any existing performative definition";
53  throw std::runtime_error(msg);
54 }
55 
57 {
58  mPerformative = PerformativeTxt[INFORM];
59 }
60 
62 {
63  mPerformative = PerformativeTxt[performative];
64 }
65 
66 ACLMessage::ACLMessage(const std::string& perf)
67 {
68  if ( (perf.find_first_of(illegalWordChars) != std::string::npos) || (illegalWordStart.find_first_of(perf.c_str()[0]) != std::string::npos) )
69  {
70  char buffer[512];
71  snprintf(buffer, 512,"Illegal characters in given performative: %s", perf.c_str());
72  throw std::runtime_error(buffer);
73  } else {
74  mPerformative = perf;
75  }
76 }
77 
78 //ACLMessage& ACLMessage::operator=(const ACLMessage& mes)
79 //{
80 // // checking against message1 = message1 case
81 // if (this == &mes)
82 // return *this;
83 //
84 // //freeing any previously filled in values for the userdefined parameters, reply_to, receivers and sender fields
85 // if (!mParameters.empty())
86 // {
87 // mParameters.clear();
88 // }
89 //
90 // if (!mReplyTo.empty())
91 // {
92 // mReplyTo.clear();
93 // }
94 //
95 // if (!mReceivers.empty())
96 // {
97 // mReceivers.clear();
98 // }
99 //
100 // //building the copied message
101 // mPerformative = mes.mPerformative;
102 // mLanguage = mes.mLanguage;
103 // mEncoding = mes.mEncoding;
104 // mOntology = mes.mOntology;
105 // mProtocol = mes.mProtocol;
106 // mConversationId = mes.mConversationId;
107 // mReplyWith = mes.mReplyWith;
108 // mInReplyTo = mes.mInReplyTo;
109 // mReplyBy1 = mes.mReplyBy1;
110 // mContent = mes.mContent;
111 // mSender = mes.mSender;
112 //
113 // mReceivers.insert(mReceivers.begin(), mes.mReceivers.begin(), mes.mReceivers.end());
114 // mReplyTo.insert(mReplyTo.begin(), mes.mReplyTo.begin(), mes.mReplyTo.end());
115 // mParameters.insert(mParameters.begin(), mes.mParameters.begin(), mes.mParameters.end());
116 //
117 // return *this;
118 //}
119 
120 
122 {
123  std::map<Performative, std::string>::iterator it;
124  it = PerformativeTxt.find(perf);
125  if(it == PerformativeTxt.end())
126  {
127  throw std::runtime_error("Cannot set performative. Performative unknown");
128  }
129 
130  mPerformative = it->second;
131 }
132 
133 void ACLMessage::setPerformative(const std::string& str)
134 {
135  if ( (str.find_first_of(illegalWordChars) != std::string::npos) || (illegalWordStart.find_first_of(str.c_str()[0]) != std::string::npos) )
136  {
137 
138  char buffer[512];
139  snprintf(buffer, 512,"Illegal characters in given performative: %s", str.c_str());
140  throw std::runtime_error(buffer);
141  }
142 
143  mPerformative = str;
144 }
145 
147 {
148  // prevent entering duplicates
149  // NOTE: this function searches for and uses the overloaded == op not the resDepthEq()
150  if ( find(mReceivers.begin(), mReceivers.end(),aid) == mReceivers.end() )
151  {
152  mReceivers.insert(mReceivers.begin(),aid);
153  }
154 }
155 
157 {
158  // prevent entering duplicates
159  // NOTE: this function searches for and uses the overloaded == op not the resDepthEq()
160  std::vector<AgentID>::iterator it = find(mReceivers.begin(), mReceivers.end(),aid);
161  if ( it != mReceivers.end())
162  {
163  mReceivers.erase(it);
164  }
165 }
166 
168 {
169  mReceivers.clear();
170 }
171 
173 {
174  // prevent entering duplicates
175  // NOTE: this function searches for and uses the overloaded == op not the resDepthEq()
176  if ( find(mReplyTo.begin(), mReplyTo.end(),aid) == mReplyTo.end() )
177  {
178  mReplyTo.insert(mReplyTo.begin(),aid);
179  }
180 }
181 
183 {
184  // prevent entering duplicates
185  // NOTE: this function searches for and uses the overloaded == op not the resDepthEq()
186  std::vector<AgentID>::iterator it = find(mReplyTo.begin(), mReplyTo.end(),aid);
187  if (it != mReplyTo.end() )
188  {
189  mReplyTo.erase(it);
190  }
191 }
192 
194 {
195  mReplyTo.clear();
196 }
197 
198 void ACLMessage::setProtocol(const std::string& str)
199 {
200  if ( (str.find_first_of(illegalWordChars) != std::string::npos) || (illegalWordStart.find_first_of(str.c_str()[0]) != std::string::npos) )
201  {
202  char buffer[512];
203  snprintf(buffer, 512, "Protocol name contains illegal characters: %s", str.c_str());
204  throw std::runtime_error(buffer);
205  }
206 
207  mProtocol = str;
208 }
209 
211 {
212  // Check on the existance of 0x00 in the content
213  return ( strlen(mContent.c_str()) != mContent.size() );
214 }
215 
217 {
218  if (find (mParameters.begin(),mParameters.end(),p) == mParameters.end() )
219  {
220  mParameters.insert(mParameters.begin(),p);
221  }
222 }
223 
224 void ACLMessage::setUserdefParams(const std::vector<UserdefParam>& p)
225 {
226  mParameters.clear();
227  mParameters.insert(mParameters.begin(),p.begin(),p.end());
228 }
229 
230 bool ACLMessage::operator==(const ACLMessage& other) const
231 {
232  if (getPerformative().compare(other.getPerformative()))
233  return false;
234  if (getContent().compare(other.getContent()))
235  return false;
236  if (getLanguage().compare(other.getLanguage()))
237  return false;
238  if (getEncoding().compare(other.getEncoding()))
239  return false;
240  if (getOntology().compare(other.getOntology()))
241  return false;
242  if (getProtocol().compare(other.getProtocol()))
243  return false;
244  if (getConversationID().compare(other.getConversationID()))
245  return false;
246  if (getReplyWith().compare(other.getReplyWith()))
247  return false;
248  if (getInReplyTo().compare(other.getInReplyTo()))
249  return false;
250  if (getReplyBy() != other.getReplyBy())
251  return false;
252  if (!(getSender() == other.getSender()) )
253  return false;
254 
255  // checking if receivers sets of the message are the same
256  AgentIDList agentsA = getAllReceivers();
257  AgentIDList agentsB = other.getAllReceivers();
258  AgentIDList::iterator ait = agentsA.begin();
259  AgentIDList::iterator bit = agentsB.begin();
260 
261  int found_one = 0; // flag variable to control flow through inner loops
262 
263  while (ait != agentsA.end())
264  {
265  found_one = 0;
266  bit = agentsB.begin();
267  while (bit != agentsB.end())
268  {
270  {
271  agentsA.erase(ait);
272  ait = agentsA.begin();
273  agentsB.erase(bit);
274  bit = agentsB.end();
275  found_one = 1;
276 
277  } else {
278  ++bit;
279  }
280  }
281 
282  if (!found_one)
283  {
284  ++ait;
285  }
286  }
287 
288  if (!agentsA.empty() || !agentsB.empty())
289  return false;
290 
291  //checking if reply_to sets of the message are the same
292  agentsA = getAllReplyTo();
293  agentsB = other.getAllReplyTo();
294  ait = agentsA.begin();
295  bit = agentsB.begin();
296  while (ait != agentsA.end())
297  {
298  found_one = 0;
299  bit = agentsB.begin();
300  while (bit != agentsB.end())
301  {
303  {
304  agentsA.erase(ait);
305  ait = agentsA.begin();
306  agentsB.erase(bit);
307  bit = agentsB.end();
308  found_one = 1;
309 
310  } else {
311  ++bit;
312  }
313 
314  }
315  if (!found_one)
316  ++ait;
317 
318  }
319 
320  if (!agentsA.empty())
321  { return false; }
322  if (!agentsB.empty())
323  { return false; }
324 
325 
326  std::vector<UserdefParam> paramsA = getUserdefParams();
327  std::vector<UserdefParam> paramsB = other.getUserdefParams();
328  std::vector<UserdefParam>::iterator pita = paramsA.begin();
329  std::vector<UserdefParam>::iterator pitb = paramsB.begin();
330 
331  while (pita != paramsA.end())
332  {
333  found_one = 0;
334  pitb = paramsB.begin();
335  while (pitb != paramsB.end())
336  {
337  if (*pita == *pitb)
338  {
339  paramsA.erase(pita);
340  pita = paramsA.begin();
341  paramsB.erase(pitb);
342  pitb = paramsB.end();
343  found_one = 1;
344 
345  } else {
346  pitb++;
347  }
348  }
349 
350  if (!found_one)
351  pita++;
352  }
353 
354  if (!paramsA.empty())
355  return false;
356 
357  if (!paramsB.empty())
358  return false;
359 
360  return true;
361 }
362 
363 std::string ACLMessage::toString() const
364 {
365  std::stringstream ss;
366  ss << "(";
367  ss << mPerformative << std::endl;
368  ss << ":sender (agent-identifier :name " << mSender.getName() << " )" << std::endl;
369 
370  if(!mReceivers.empty())
371  {
372  ss << ":receiver (set "<< std::endl;
373  BOOST_FOREACH(const AgentID& agent, mReceivers)
374  {
375  ss << "\t(agent-identifier ";
376  ss << ":name " << agent.getName();
377  ss << ") " << std::endl;
378  }
379  ss << ")" << std::endl;
380  }
381 
382  if(!mLanguage.empty())
383  {
384  ss << ":language " << mLanguage << std::endl;
385  }
386 
387  if(!mEncoding.empty())
388  {
389  ss << ":encoding " << mEncoding << std::endl;
390  }
391 
392  if(!mOntology.empty())
393  {
394  ss << ":ontology " << mOntology << std::endl;
395  }
396 
397  if(!mProtocol.empty())
398  {
399  ss << ":protocol " << mProtocol << std::endl;
400  }
401 
402  if(!mConversationId.empty())
403  {
404  ss << ":conversation-id " << mConversationId << std::endl;
405  }
406 
407  if(!mReplyWith.empty())
408  {
409  ss << ":reply-with " << mReplyWith << std::endl;
410  }
411 
412  if(!mInReplyTo.empty())
413  {
414  ss << ":in-reply-to " << mInReplyTo << std::endl;
415  }
416 
417  if(!mReplyBy.isNull())
418  {
419  ss << ":reply-by " << mReplyBy.toString() << std::endl;
420  }
421 
422  if(!mParameters.empty())
423  {
424  BOOST_FOREACH(const UserdefParam& param, mParameters)
425  {
426  ss << param.getName() << " " << param.getValue() << std::endl;
427  }
428  }
429 
430  if(!mContent.empty())
431  {
432  ss << ":content " << mContent << std::endl;
433  }
434 
435 
436  ss << ")" << std::endl;
437  return ss.str();
438 }
439 
440 }//end of acl namespace
441 
442 }// end of fipa namespace
const std::string & getValue() const
Definition: userdef_param.h:65
std::string getLanguage() const
Definition: acl_message.h:268
std::string getConversationID() const
Definition: acl_message.h:227
const std::string & getName() const
Definition: userdef_param.h:77
AgentID getSender() const
Definition: acl_message.h:311
bool operator==(const ACLMessage &other) const
AgentIDList getAllReplyTo() const
Definition: acl_message.h:192
static bool compareEqual(const AgentID &a, const AgentID &b, int depth)
alternative function for equality operator; the depth can be specified through the depth param ...
Definition: agent_id.cpp:90
std::string toString() const
std::string getContent() const
Definition: acl_message.h:294
void setUserdefParams(const std::vector< UserdefParam > &p)
void deleteReplyTo(const AgentID &aid)
std::vector< UserdefParam > getUserdefParams() const
Definition: acl_message.h:323
std::string getReplyWith() const
Definition: acl_message.h:217
std::vector< AgentID > AgentIDList
Definition: agent_id.h:20
void addReplyTo(const AgentID &aid)
bool hasBinaryContent() const
const std::string illegalWordStart
Definition: acl_message.cpp:40
AgentIDList getAllReceivers() const
Definition: acl_message.h:166
Performative
an enum of all the predefined fipa message performatives so far, presented in the order used in the m...
Definition: acl_message.h:64
std::string getEncoding() const
Definition: acl_message.h:258
describes the general data structure of a message in conformity with the fipa specifications. The methods are pretty straight forward getter and setter methods. The set container is used for various colective fields, in order to avoid duplicates
const std::string & getName() const
setter and getter methods for all fields; they do not result in deep-copies assignments/retreivals, but this can be easily changed if needed through the overloaded operator which do
Definition: agent_id.h:90
void addUserdefParam(const UserdefParam &p)
static int msResolverComparisonDepth
Definition: agent_id.h:65
std::map< ACLMessage::Performative, std::string > PerformativeTxt
Definition: acl_message.cpp:15
std::string getPerformative() const
Definition: acl_message.h:139
This class provides a representation of a message conforming to the FIPA specification SC00061...
Definition: acl_message.h:55
static Performative performativeFromString(const std::string &performative)
Definition: acl_message.cpp:42
overloaded equality operator for UserdefParam class objects
Definition: userdef_param.h:25
void addReceiver(const AgentID &aid)
std::string getInReplyTo() const
Definition: acl_message.h:207
void deleteReceiver(const AgentID &aid)
std::string getProtocol() const
Definition: acl_message.h:238
void setPerformative(Performative perf)
Set performative.
const std::string illegalWordChars
Definition: acl_message.cpp:39
Implements the general AgentID functionality, which is present throughout the fipa specifications(FIP...
Definition: agent_id.h:37
Foundation of Physical Intelligent Agents.
Definition: conversation.cpp:6
void setProtocol(const std::string &str)
the method checks whether the passed protocol string is a word or not(according to the fipa spec) ...
ACLMessage()
Default constructor.
Definition: acl_message.cpp:56
base::Time getReplyBy() const
Definition: acl_message.h:334
std::string getOntology() const
Definition: acl_message.h:248