fw4spl
ConfigLauncher.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwServices/helper/ConfigLauncher.hpp"
8 
9 #include <fwServices/macros.hpp>
10 
11 #include <fwData/Composite.hpp>
12 #include <fwData/String.hpp>
13 
14 #include <fwDataCamp/getObject.hpp>
15 
16 #include <fwTools/fwID.hpp>
17 
18 #include <boost/property_tree/xml_parser.hpp>
19 
20 namespace fwServices
21 {
22 namespace helper
23 {
24 
25 //------------------------------------------------------------------------------
26 
27 const std::string ConfigLauncher::s_SELF_KEY = "self";
28 const std::string ConfigLauncher::s_GENERIC_UID_KEY = "GENERIC_UID";
29 
30 //------------------------------------------------------------------------------
31 
33  m_configIsRunning(false)
34 {
35 }
36 
37 //------------------------------------------------------------------------------
38 
40 {
41 }
42 
43 //------------------------------------------------------------------------------
44 
45 void ConfigLauncher::parseConfig(const ::fwServices::IService::ConfigType& config,
46  const ::fwServices::IService::sptr& service)
47 {
48  ::fwServices::IService::ConfigType srvCfg;
49  const ::fwServices::IService::ConfigType* curConfig = &config;
50 
51  const ::fwServices::IService::ConfigType& oldConfig = config;
52  SLM_ASSERT("There must be only one <appConfig/> element.", oldConfig.count("appConfig") == 1 );
53 
54  const ::fwServices::IService::ConfigType& appConfig = oldConfig.get_child("appConfig");
55  const std::string appCfgId = appConfig.get<std::string>("<xmlattr>.id");
56 
57  srvCfg.add("config.appConfig.<xmlattr>.id", appCfgId);
58  ::fwServices::IService::ConfigType& newCfg = srvCfg.get_child("config.appConfig");
59  curConfig = &srvCfg;
60 
61  auto inoutsCfg = oldConfig.equal_range("inout");
62  for (auto itCfg = inoutsCfg.first; itCfg != inoutsCfg.second; ++itCfg)
63  {
64  ::fwServices::IService::ConfigType parameterCfg;
65 
66  const std::string key = itCfg->second.get<std::string>("<xmlattr>.key");
67  SLM_ASSERT("[" + appCfgId + "] Missing 'key' tag.", !key.empty());
68 
69  const std::string uid = itCfg->second.get<std::string>("<xmlattr>.uid");
70  SLM_ASSERT("[" + appCfgId + "] Missing 'uid' tag.", !uid.empty());
71 
72  parameterCfg.add("<xmlattr>.replace", key);
73 
74  const std::string strOptional = itCfg->second.get<std::string>("<xmlattr>.optional", "no");
75  const bool optional = strOptional == "yes" ? true : false;
76 
77  auto obj = service->getInOut< ::fwData::Object>(key);
78  if(optional)
79  {
80  parameterCfg.add("<xmlattr>.uid", uid);
81  }
82  else
83  {
84  SLM_ASSERT("Object key '" + key + "'with uid '" + uid + "' does not exist.", obj);
85  parameterCfg.add("<xmlattr>.uid", obj->getID());
86  }
87 
88  newCfg.add_child("parameters.parameter", parameterCfg);
89  }
90 
91  // @deprecated This is no longer necessary to use "uid" to get the prefix replacement, since
92  // this is now done in AppConfig. However we keep that code for a while for backward compatibility
93  auto paramsCfg = oldConfig.equal_range("parameter");
94  for (auto itCfg = paramsCfg.first; itCfg != paramsCfg.second; ++itCfg)
95  {
96  ::fwServices::IService::ConfigType parameterCfg;
97 
98  const std::string replace = itCfg->second.get<std::string>("<xmlattr>.replace");
99  SLM_ASSERT("[" + appCfgId + "] Missing 'replace' tag.", !replace.empty());
100 
101  parameterCfg.add("<xmlattr>.replace", replace);
102 
103  if(itCfg->second.get_child("<xmlattr>").count("uid") == 1)
104  {
105  const std::string uid = itCfg->second.get<std::string>("<xmlattr>.uid");
106  parameterCfg.add("<xmlattr>.uid", uid);
107  }
108  else
109  {
110  const std::string by = itCfg->second.get<std::string>("<xmlattr>.by");
111  parameterCfg.add("<xmlattr>.by", by);
112  }
113 
114  newCfg.add_child("parameters.parameter", parameterCfg);
115  }
116 
117  SLM_ASSERT("There must be only one <config/> element.", curConfig->count("config") == 1 );
118 
119  const ::fwServices::IService::ConfigType& srvconfig = curConfig->get_child("config");
120 
121  SLM_ASSERT("There must be only one <appConfig/> element.", srvconfig.count("appConfig") == 1 );
122 
123  const ::fwServices::IService::ConfigType& appConfigCfg = srvconfig.get_child("appConfig");
124  m_appConfig = ::fwActivities::registry::ActivityAppConfig(appConfigCfg);
125 }
126 
127 //------------------------------------------------------------------------------
128 
129 void ConfigLauncher::startConfig(::fwServices::IService::sptr srv,
130  const FieldAdaptorType& optReplaceMap )
131 {
132  typedef ::fwActivities::registry::ActivityAppConfig AppConfig;
133  FieldAdaptorType replaceMap(optReplaceMap);
134 
135  // Generate generic UID
136  const std::string genericUidAdaptor = ::fwServices::registry::AppConfig::getUniqueIdentifier( srv->getID() );
137  replaceMap[ConfigLauncher::s_GENERIC_UID_KEY] = genericUidAdaptor;
138 
139  for(const AppConfig::ActivityAppConfigParamsType::value_type& param : m_appConfig.parameters)
140  {
141  replaceMap[param.replace] = param.by;
142  }
143 
144  // Init manager
145  m_appConfigManager = ::fwServices::IAppConfigManager::New();
146  m_appConfigManager->setConfig( m_appConfig.id, replaceMap );
147 
148  // Launch config
149  m_appConfigManager->launch();
150 
151  m_configIsRunning = true;
152 }
153 
154 //------------------------------------------------------------------------------
155 
157 {
158  if( m_configIsRunning )
159  {
160  // Delete manager
161  m_appConfigManager->stopAndDestroy();
162  m_appConfigManager.reset();
163  }
164  m_configIsRunning = false;
165 }
166 
167 //------------------------------------------------------------------------------
168 
169 } // helper
170 } // fwServices
Namespace fwServices is dedicated to (mimic) the dynamic affectation of methods to (pure data) object...
bool m_configIsRunning
to know if AppConfig is running
virtual FWSERVICES_API ~ConfigLauncher()
Destructor. Do nothing.
virtual FWSERVICES_API void stopConfig()
Stop/destroy AppConfig and disconnect connection with config root object.
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308
Base class for each data object.
static FWSERVICES_API std::shared_ptr< IAppConfigManager > New()
static FWSERVICES_API std::string getUniqueIdentifier(const std::string &serviceUid="")
Create an unique identifier.
Definition: AppConfig.cpp:269
FWSERVICES_API ConfigLauncher()
Constructor. Do nothing.
virtual FWSERVICES_API void parseConfig(const ::fwServices::IService::ConfigType &config, const ::fwServices::IService::sptr &service)
Parse a ConfigLauncher configuration.
virtual FWSERVICES_API void startConfig(std::shared_ptr< ::fwServices::IService > srv, const FieldAdaptorType &optReplaceMap=FieldAdaptorType())
Launch Appconfig.