fipa_acl  1.4
agent_id.cpp
Go to the documentation of this file.
1 
7 #include "agent_id.h"
8 #include "acl_message.h"
9 #include <iostream>
10 #include <sstream>
11 #include <algorithm>
12 #include <base-logging/Logging.hpp>
13 
14 namespace fipa {
15 namespace acl {
16 
18 
19 const std::string AgentID::UNDEFINED = "agent_id:undefined";
20 
22 {
23  setName(AgentID::UNDEFINED);
24 }
25 
26 AgentID::AgentID(const std::string& name)
27 {
28  setName(name);
29 }
30 
31 bool AgentID::isValid() const
32 {
33  return mName != AgentID::UNDEFINED && !empty();
34 }
35 
36 void AgentID::setName(const std::string& name)
37 {
38  if ( (name.find_first_of(illegalWordChars) != std::string::npos) || (illegalWordStart.find_first_of(name.c_str()[0]) != std::string::npos) )
39  {
40  char buffer[128];
41  snprintf(buffer, 128, "fipa::acl::AgentID: name '%s' contains invalid characters", name.c_str());
42  throw std::runtime_error(buffer);
43  }
44 
45  mName = name;
46 }
47 
48 void AgentID::addAddress(const std::string& address)
49 {
50  if ( (address.find_first_of(illegalWordChars) != std::string::npos) || (illegalWordStart.find_first_of(address.c_str()[0]) != std::string::npos) )
51  {
52  char buffer[128];
53  snprintf(buffer, 128, "fipa::acl::AgentID: address '%s' contains invalid characters", address.c_str());
54  throw std::runtime_error(buffer);
55  }
56  mAddresses.push_back(address);
57 }
58 
59 void AgentID::addResolver(const AgentID& aid)
60 {
61  // prevent entering duplicates
62  // NOTE: this function searches for the resolver and uses the overloaded == op not the compareEqual()
63  if ( find(mResolvers.begin(), mResolvers.end(),aid) == mResolvers.end() )
64  {
65  mResolvers.push_back(aid);
66  }
67 }
68 
70 {
71  std::vector<AgentID>::iterator it = find(mResolvers.begin(), mResolvers.end(),aid);
72  // prevent entering duplicates
73  // NOTE: this function searches for the resolver using the overloaded == op not the compareEqual()
74  if( it != mResolvers.end() )
75  {
76  mResolvers.erase(it);
77  }
78 }
79 
81 {
82  mParameters.push_back(p);
83 }
84 
85 bool AgentID::operator==(const AgentID& other) const
86 {
87  return compareEqual(*this, other, AgentID::msResolverComparisonDepth);
88 }
89 
90 bool AgentID::compareEqual(const AgentID& a, const AgentID& b, int depth)
91 {
92  if (a.getName() != b.getName())
93  {
94  return false;
95  }
96 
97  // comparing addresses
98  std::vector<std::string> addrA = a.getAddresses();
99  std::vector<std::string> addrB = b.getAddresses();
100  std::vector<std::string>::iterator sita = addrA.begin();
101  std::vector<std::string>::iterator sitb = addrB.begin();
102  int found_one = 0; // flag variable to control flow through inner loops
103  while (sita != addrA.end())
104  {
105  found_one = 0;
106  sitb = addrB.begin();
107  while (sitb != addrB.end())
108  {
109  if (*sita == *sitb)
110  {
111  addrA.erase(sita);
112  sita = addrA.begin();
113  addrB.erase(sitb);
114  sitb = addrB.end();
115  found_one = 1;
116  } else {
117  sitb++;
118  }
119  }
120 
121  if (!found_one)
122  sita++;
123  }
124 
125  if (!addrA.empty())
126  return false;
127  if (!addrB.empty())
128  return false;
129 
130  // only check the resolvers if the resCompDepth > 0;
131  if (depth > 0 )
132  {
133  // the resolvers are compared with up to resCompDepth -1 in the resolver network
134  //AgentID::setResCompDepth(depth-1);
135  // comparing resolvers
136  std::vector<AgentID> agentsA = a.getResolvers();
137  std::vector<AgentID> agentsB = b.getResolvers();
138  std::vector<AgentID>::iterator ait = agentsA.begin();
139  std::vector<AgentID>::iterator bit = agentsB.begin();
140 
141  while (ait != agentsA.end())
142  {
143  found_one = 0;
144  bit = agentsB.begin();
145  while (bit != agentsB.end())
146  {
147  if ( compareEqual((*ait),(*bit),depth-1))
148  {
149  agentsA.erase(ait);
150  ait = agentsA.begin();
151  agentsB.erase(bit);
152  bit = agentsB.end();
153  found_one = 1;
154  } else {
155  ++bit;
156  }
157  }
158  if (!found_one)
159  ++ait;
160  }
161 
162  if (!agentsA.empty())
163  return false;
164  if (!agentsB.empty())
165  return false;
166  }
167 
168  // comparing userdefined parameters
169  // Copy lists and delete identical elements
170  // When both list are empty the compared objects are equal
171  std::vector<UserdefParam> paramsA = a.getUserdefParams();
172  std::vector<UserdefParam> paramsB = b.getUserdefParams();
173  std::vector<UserdefParam>::iterator pita = paramsA.begin();
174  std::vector<UserdefParam>::iterator pitb = paramsB.begin();
175 
176  while (pita != paramsA.end())
177  {
178  found_one = 0;
179  pitb = paramsB.begin();
180 
181  while (pitb != paramsB.end())
182  {
183  if (*pita == *pitb)
184  {
185  paramsA.erase(pita);
186  paramsB.erase(pitb);
187 
188  pita = paramsA.begin();
189  // in order to break the inner while, set it to end()
190  pitb = paramsB.end();
191 
192  found_one = 1;
193  } else {
194  pitb++;
195  }
196  }
197 
198  if (!found_one)
199  pita++;
200  }
201 
202  // Both lists are empty when they contained the same Parameters
203  // before
204  if ( paramsA.empty() && paramsB.empty())
205  return true;
206 
207  return false;
208 }
209 
210 bool AgentID::empty() const
211 {
212  return mName.empty();
213 }
214 
215 std::string AgentID::toString(size_t indent) const
216 {
217  std::string hspace(indent,' ');
218  std::stringstream ss;
219  ss << hspace << "AgentID: " << mName << std::endl;
220  ss << hspace << " addresses:" << std::endl;
221  std::vector<std::string>::const_iterator ait = mAddresses.begin();
222  for(; ait != mAddresses.end(); ++ait)
223  {
224  ss << hspace << *ait << std::endl;
225  }
226  ss << hspace << " resolvers:" << std::endl;
227  AgentIDList::const_iterator rit = mResolvers.begin();
228  for(; rit != mResolvers.end(); ++rit)
229  {
230  ss << rit->toString(indent + 4) << std::endl;
231  }
232  ss << hspace << " parameters:" << std::endl;
233  std::vector<UserdefParam>::const_iterator pit = mParameters.begin();
234  for(; pit != mParameters.end(); ++pit)
235  {
236  ss << hspace << pit->toString() << std::endl;
237  }
238  return ss.str();
239 }
240 
242  : AgentID()
243 {
245 }
246 
247 }//end of acl namespace
248 
249 }// end of fipa namespace
250 
251 
AgentID()
Default constructor.
Definition: agent_id.cpp:21
void deleteResolver(const AgentID &id)
Delete a resolver.
Definition: agent_id.cpp:69
std::string mName
Definition: agent_id.h:57
Defines the AgentID class.
void setName(const std::string &name)
the method checks whether the passed name string is a word or not(according to the fipa spec) ...
Definition: agent_id.cpp:36
const Resolvers & getResolvers() const
Get list of resolvers.
Definition: agent_id.h:127
bool empty() const
Check if AgentId is empty, i.e. does not contain a name.
Definition: agent_id.cpp:210
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
void addResolver(const AgentID &aid)
Add resolver.
Definition: agent_id.cpp:59
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 addAddress(const std::string &adr)
the method checks whether the passed address string is a word or not(according to the fipa spec) ...
Definition: agent_id.cpp:48
bool operator==(const AgentID &other) const
overloaded equality operator for AgentID; the signature of the function was intentionally changed fro...
Definition: agent_id.cpp:85
bool isValid() const
Definition: agent_id.cpp:31
const std::string illegalWordStart
Definition: acl_message.cpp:40
void addUserdefParam(const UserdefParam &p)
Add a userdefined parameter.
Definition: agent_id.cpp:80
const std::vector< std::string > & getAddresses() const
Retrieve list of addresses.
Definition: agent_id.h:110
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
static const std::string UNDEFINED
Definition: agent_id.h:60
static int msResolverComparisonDepth
Definition: agent_id.h:65
overloaded equality operator for UserdefParam class objects
Definition: userdef_param.h:25
const std::vector< UserdefParam > & getUserdefParams() const
Get the all userdefined parameter.
Definition: agent_id.h:150
std::string toString(size_t indent=0) const
Definition: agent_id.cpp:215
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