fipa_acl  1.4
statemachine_factory.cpp
Go to the documentation of this file.
1 #include "statemachine_factory.h"
2 #include <boost/filesystem/operations.hpp>
3 #include <base-logging/Logging.hpp>
4 #include "statemachine_reader.h"
5 #include "transition.h"
6 
7 namespace fs = boost::filesystem;
8 
9 namespace fipa {
10 namespace acl {
11 
12 bool StateMachineFactory::msPreparedResourceDir = false;
13 std::vector<std::string> StateMachineFactory::msResourceDirs;
14 std::map<std::string, StateMachine> StateMachineFactory::msStateMachines;
15 
16 StateMachineReader StateMachineFactory::msStateMachineReader;
17 
18 void StateMachineFactory::setProtocolResourceDir(const std::string& resourceDir)
19 {
20  msResourceDirs.clear();
21  addProtocolResourceDir(resourceDir);
22 }
23 
24 void StateMachineFactory::addProtocolResourceDir(const std::string& resourceDir)
25 {
26  fs::path protocolDir = fs::path(resourceDir);
27  if(fs::is_directory(protocolDir))
28  {
29  std::vector<std::string>::iterator resourcesIt = std::find(msResourceDirs.begin(), msResourceDirs.end(), protocolDir.string());
30  if(resourcesIt == msResourceDirs.end())
31  {
32  msResourceDirs.push_back(protocolDir.string());
33  msPreparedResourceDir = false;
34  LOG_INFO("Add protocol resource dir: '%s'", protocolDir.string().c_str());
35  } else {
36  LOG_WARN("Protocol resource dir '%s' already added", protocolDir.string().c_str());
37  }
38  } else {
39  std::string msg = "Could not add resource dir: '" + resourceDir + "', since it does not exist";
40  throw std::runtime_error(msg);
41  }
42 }
43 
44 void StateMachineFactory::prepareProtocolsFromResourceDirs()
45 {
46  std::vector<std::string>::const_iterator it = msResourceDirs.begin();
47  for(; it != msResourceDirs.end(); ++it)
48  {
50  }
51 }
52 
53 void StateMachineFactory::prepareProtocolsFromResourceDir(const std::string& resourceDir)
54 {
55  fs::path protocolDir = fs::path(resourceDir);
56  LOG_INFO("Prepare protocols from: '%s'", protocolDir.string().c_str());
57  if(fs::is_directory(protocolDir))
58  {
59  std::vector<fs::path> files;
60  std::copy(fs::directory_iterator(protocolDir), fs::directory_iterator(), std::back_inserter(files));
61 
62  std::vector<fs::path>::iterator it = files.begin();
63  for(;it != files.end(); ++it)
64  {
65  if(fs::is_regular_file(*it))
66  {
67  // Extract protocol name
68  std::string protocolName = it->string();
69  size_t pos = protocolName.find_last_of("/");
70  protocolName.erase(0, pos+1);
71 
72  try {
73  // Loading the state machine from the given spec
74  StateMachine statemachine = msStateMachineReader.loadSpecification(it->string());
75  LOG_INFO("Register protocol %s", protocolName.c_str());
76  std::map<std::string, StateMachine>::const_iterator statemachinesIt = msStateMachines.find(protocolName);
77  if( statemachinesIt != msStateMachines.end())
78  {
79  LOG_WARN("Protocol '%s' already registered - will use statemachine specification from '%s'", protocolName.c_str(), it->string().c_str());
80  }
81  msStateMachines[protocolName] = statemachine;
82  } catch(const std::runtime_error& e)
83  {
84  LOG_ERROR("Error loading specification for: '%s' - %s", protocolName.c_str(), e.what());
85  }
86  }
87  }
88  }
89 
90  msPreparedResourceDir = true;
91 }
92 
94 {
95  if(!msPreparedResourceDir)
96  {
97  StateMachineFactory::prepareProtocolsFromResourceDirs();
98  }
99 
100  std::map<std::string, StateMachine>::iterator it = msStateMachines.find(protocol);
101 
102  if(it != msStateMachines.end())
103  {
104  return it->second;
105  }
106 
107  LOG_WARN("StateMachine for protocol '%s' not found", protocol.c_str());
108  throw std::runtime_error("State machine for requested protocol does not exist");
109 }
110 
111 } // end namespace acl
112 } // end namespace fipa
113 
describes the structure and operation of a transition of the state machine
static StateMachine getStateMachine(const std::string &protocol)
static void prepareProtocolsFromResourceDir(const std::string &directory)
static void setProtocolResourceDir(const std::string &resourceDir)
static void addProtocolResourceDir(const std::string &resourceDir)
StateMachine loadSpecification(const std::string &file)
defines the StateMachineReader Class, used to generate a state macine from a spec. file