3 #include <base-logging/Logging.hpp>
4 #include <boost/regex.hpp>
9 namespace conversation {
20 , timestamp(base::
Time::now())
32 boost::unique_lock<boost::mutex> lock(mEventsMutex);
33 return !mEvents.empty();
38 boost::unique_lock<boost::mutex> lock(mEventsMutex);
39 mEvents.push_back(event);
40 mCondition.notify_all();
47 boost::unique_lock<boost::mutex> lock(mutex);
50 mCondition.wait(lock);
62 boost::unique_lock<boost::mutex> lock(mEventsMutex);
68 event = mEvents.front();
69 mEvents.erase(mEvents.begin());
71 LOG_INFO(
"Retrieve event: type: '%s', msg content: '%s'", conversation::EventTypeTxt[event.
type].c_str(),
event.msg.getContent().c_str());
77 std::vector<fipa::acl::ConversationID> conversationIds;
79 boost::unique_lock<boost::mutex> lock(mObservablesMutex);
80 std::vector<ConversationObservablePtr>::const_iterator it = mObservables.begin();
81 for(; it != mObservables.end(); ++it)
83 conversationIds.push_back((*it)->getConversationId());
86 return conversationIds;
91 boost::unique_lock<boost::mutex> lock(mObservablesMutex);
93 std::vector<ConversationObservablePtr>::const_iterator it = std::find(mObservables.begin(), mObservables.end(), observable);
94 if(it == mObservables.end())
96 mObservables.push_back(observable);
103 , mNumberOfSubConversations(0)
109 LOG_DEBUG(
"Conversation created with id: %s\n", conversationId.c_str());
115 , mNumberOfSubConversations(0)
118 LOG_DEBUG(
"Conversation created with id: %s\n", initiator.
getConversationID().c_str());
124 , mOwner(other.mOwner)
125 , mProtocol(other.mProtocol)
126 , mContentLanguage(other.mContentLanguage)
127 , mNumberOfSubConversations(other.mNumberOfSubConversations)
128 , mMessages(other.mMessages)
129 , mStateMachine(other.mStateMachine)
139 return mContentLanguage;
144 boost::unique_lock<boost::mutex> lock(mMutex);
150 bool newConversation =
false;
154 if(mProtocol.empty())
158 if(!protocol.empty())
163 mProtocol = protocol;
168 LOG_ERROR(
"Protocol not set");
169 throw std::runtime_error(
"Protocol not set");
171 }
catch(
const std::runtime_error& e)
173 LOG_FATAL(
"Conversation could not retrieve statemachine for protocol '%s'. Check if protocol specification was loaded -- '%s'", protocol.c_str(), e.what());
177 newConversation =
true;
184 }
catch(
const std::runtime_error& e)
186 std::string errorMsg =
"Conversation: unexpected message with performative '" + msg.
getPerformative() +
"' for the protocol '" + msg.
getProtocol() +
"' ";
189 errorMsg +=
" -- " + std::string(e.what()) +
"\n";
193 notifyAll(msg,
false);
197 LOG_WARN(
"Conversation: received message has no protocol being set. Current conversation using '%s'", mProtocol.c_str());
202 LOG_INFO(
"Conversation: received message has not language being set. Current conversation using '%s'", mContentLanguage.c_str());
205 LOG_INFO(
"Conversation: message with different content language being inserted: current '%s' - to be inserted '%s'", mContentLanguage.c_str(), msg.
getLanguage().c_str());
211 }
catch(
const std::runtime_error& e)
213 std::string errorMsg =
"Conversation: unexpected message with performative '" + msg.
getPerformative() +
"' for the protocol '" + msg.
getProtocol() +
"' ";
216 errorMsg +=
" -- " + std::string(e.what()) +
"\n";
220 notifyAll(msg, newConversation);
231 mMessages.push_back(msg);
238 }
else if(newConversation) {
247 boost::unique_lock<boost::mutex> lock(mMutex);
248 return mMessages.back();
257 LOG_DEBUG(
"Conversation did not end");
261 LOG_DEBUG(
"Conversation ended");
264 catch(
const std::runtime_error& e)
269 LOG_WARN_S <<
"Runtime error when testing if conversation ended. Therefore not ended. Message: " << e.what();
276 boost::unique_lock<boost::mutex> lock(mMutex);
277 return !mMessages.empty();
290 char conversationId[37];
291 uuid_unparse(uuid, conversationId);
292 return std::string(conversationId) +
"--" + topic +
"--" + base::Time::now().toString();
297 std::stringstream ss;
298 std::vector<fipa::acl::ACLMessage>::const_iterator cit = messages.begin();
299 for(; cit != messages.end(); ++cit)
301 ss << cit->toString() << std::endl;
308 std::stringstream ss;
309 ss <<
"Conversation: " << std::endl;
310 if(!mMessages.empty())
312 ss <<
" id: " << mMessages.front().getConversationID();
315 ss <<
" owner: " << mOwner << std::endl;
316 ss <<
" protocol: " << mProtocol << std::endl;
317 ss <<
" language: " << mContentLanguage << std::endl;
318 ss <<
" # subconversations: " << mNumberOfSubConversations << std::endl;
319 ss <<
" # messages " << mMessages.size() << std::endl;
320 ss <<
"BEGIN " << std::endl;
321 ss <<
toString(mMessages) << std::endl;
322 ss <<
"END" << std::endl;
332 : mConversationId(other.mConversationId)
333 , mStatus(other.mStatus)
334 , mObservers(other.mObservers)
338 : mConversationId(conversationId)
349 boost::unique_lock<boost::mutex> lock(mObserverMutex);
350 return !mObservers.empty();
355 boost::unique_lock<boost::mutex> lock(mObserverMutex);
356 ConversationObserverList::const_iterator it = std::find(mObservers.begin(), mObservers.end(), observer);
357 if(it == mObservers.end())
359 mObservers.push_back(observer);
366 boost::unique_lock<boost::mutex> lock(mObserverMutex);
367 ConversationObserverList::iterator it = std::find(mObservers.begin(), mObservers.end(), observer);
368 if(it != mObservers.end())
370 mObservers.erase(it);
376 boost::unique_lock<boost::mutex> lock(mObserverMutex);
377 LOG_INFO(
"notify: message event: '%s', message content: '%s'", conversation::EventTypeTxt[eventType].c_str(), msg.
getContent().c_str());
378 ConversationObserverList::iterator it = mObservers.begin();
379 for(; it != mObservers.end(); ++it)
417 boost::unique_lock<boost::mutex> lock(mObserverMutex);
std::string ConversationID
bool hasObservers() const
void consumeMessage(const ACLMessage &msg)
boost::shared_ptr< ConversationObservable > ConversationObservablePtr
bool inFailureState() const
static fipa::acl::ConversationID generateConversationID(const std::string &topic="")
std::string getOwner() const
std::string getContent() const
std::string toString() const
static StateMachine getStateMachine(const std::string &protocol)
std::vector< ConversationObserverPtr > ConversationObserverList
boost::shared_ptr< ConversationObserver > ConversationObserverPtr
bool inFinalState() const
fipa::acl::ContentLanguage getContentLanguage() const
bool getNextEvent(conversation::Event &msg)
void notify(const fipa::acl::ACLMessage &msg, conversation::EventType eventType)
std::string getPerformative() const
const RoleMapping & getRoleMapping() const
conversation::Status getStatus() const
void setSelf(const AgentID &self)
fipa::acl::ConversationID getConversationId() const
std::string getLanguage() const
ConversationObserverList getObservers() const
std::string getProtocol() const
fipa::acl::ACLMessage getLastMessage() const
void addObserver(const ConversationObserverPtr &observer)
This class provides a representation of a message conforming to the FIPA specification SC00061...
Conversation(const std::string &owner, const fipa::acl::ConversationID &conversationId=fipa::acl::ConversationID())
StateId getCurrentStateId() const
fipa::acl::ConversationID mConversationId
conversation::Event waitForNextEvent()
void consumeSubStateMachineMessage(const ACLMessage &msg, const fipa::acl::StateMachine &stateMachine, int numberOfSubConversations)
void removeObserver(const ConversationObserverPtr &observer)
void update(const fipa::acl::ACLMessage &msg)
Implements the general AgentID functionality, which is present throughout the fipa specifications(FIP...
std::string toString() const
std::string getConversationID() const
std::vector< fipa::acl::ConversationID > getConversationIdsOfObservables() const