fw4spl
ProfileReader.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2017.
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 "fwRuntime/io/ProfileReader.hpp"
8 
9 #include "fwRuntime/io/Validator.hpp"
10 #include "fwRuntime/operations.hpp"
11 #include "fwRuntime/profile/Activater.hpp"
12 #include "fwRuntime/profile/Profile.hpp"
13 #include "fwRuntime/profile/Starter.hpp"
14 #include "fwRuntime/Runtime.hpp"
15 #include "fwRuntime/RuntimeException.hpp"
16 
17 #include <boost/filesystem/operations.hpp>
18 
19 #include <libxml/parser.h>
20 
21 #include <sstream>
22 #include <string>
23 
24 namespace fwRuntime
25 {
26 
27 namespace io
28 {
29 
30 std::string ProfileReader::ID("id");
31 std::string ProfileReader::NAME("name");
32 std::string ProfileReader::VALUE("value");
33 std::string ProfileReader::VERSION("version");
34 std::string ProfileReader::CHECK_SINGLE_INSTANCE("check-single-instance");
35 std::string ProfileReader::ACTIVATE("activate");
36 std::string ProfileReader::START("start");
37 std::string ProfileReader::PARAM("param");
38 std::string ProfileReader::DIS_EXT_PT("disable-extension-point");
39 std::string ProfileReader::DIS_EXT("disable-extension");
40 
41 //------------------------------------------------------------------------------
42 
43 std::shared_ptr< ::fwRuntime::profile::Profile > ProfileReader::createProfile( const boost::filesystem::path& path )
44 {
45  // Normalizes the path.
46  boost::filesystem::path normalizedPath(path);
47  normalizedPath.normalize();
48 
49  // Asserts that the repository is a valid directory path.
50  if(boost::filesystem::exists(normalizedPath) == false || boost::filesystem::is_directory(normalizedPath) == true)
51  {
52  throw RuntimeException("'" + normalizedPath.string() + "': not a a file.");
53  }
54 
55  // Validation
56  auto profileXSDLocation = ::fwRuntime::getLibraryResourceFilePath("fwRuntime-" FWRUNTIME_VER "/profile.xsd");
57 
58  Validator validator(profileXSDLocation);
59 
60  if( validator.validate(normalizedPath) == false )
61  {
62  throw RuntimeException(validator.getErrorLog());
63  }
64 
65  // Get the document.
66  xmlDocPtr document = xmlParseFile(normalizedPath.string().c_str());
67  if(document == 0)
68  {
69  throw RuntimeException("Unable to read the profile file.");
70  }
71 
72  try
73  {
74  // Get the root node.
75  xmlNodePtr rootNode = xmlDocGetRootElement(document);
76 
77  char* pName = (char*) xmlGetProp(rootNode, (const xmlChar*) NAME.c_str());
78  char* pVersion = (char*) xmlGetProp(rootNode, (const xmlChar*) VERSION.c_str());
79  char* pChkInst = (char*) xmlGetProp(rootNode, (const xmlChar*) CHECK_SINGLE_INSTANCE.c_str());
80 
81  SLM_ASSERT("Application profile MUST have a name attribute", pName);
82  SLM_ASSERT("Application profile MUST have a version attribute", pVersion);
83 
84  std::string sName( pName );
85  std::string sVersion( pVersion );
86  bool checkSingleInstance = pChkInst && std::string(pChkInst) == "true";
87 
88  xmlFree(pName);
89  xmlFree(pVersion);
90  xmlFree(pChkInst);
91 
92  // Creates and process the profile element.
93  std::shared_ptr< ::fwRuntime::profile::Profile > profile = processProfile(rootNode);
94 
95  profile->setFilePath(normalizedPath);
96  profile->setName(sName);
97  profile->setVersion(sVersion);
98  profile->setCheckSingleInstance(checkSingleInstance);
99 
100  // Job's done!
101  xmlFreeDoc(document);
102  return profile;
103  }
104  catch(std::exception& exception)
105  {
106  xmlFreeDoc(document);
107  throw;
108  }
109 }
110 
111 //------------------------------------------------------------------------------
112 
113 std::shared_ptr< ::fwRuntime::profile::Profile > ProfileReader::processProfile(xmlNodePtr node)
114 {
115  using namespace ::fwRuntime::profile;
116 
117  // Process child nodes.
118  SPTR(Profile) profile = std::make_shared<Profile>();
119  xmlNodePtr curChild = node->children;
120  for(curChild = node->children; curChild != 0; curChild = curChild->next)
121  {
122  if(xmlStrcmp(curChild->name, (const xmlChar*) ACTIVATE.c_str()) == 0)
123  {
124  profile->add( processActivater(curChild) );
125  continue;
126  }
127 
128  if(xmlStrcmp(curChild->name, (const xmlChar*) START.c_str()) == 0)
129  {
130  profile->add( processStarter(curChild) );
131  continue;
132  }
133  }
134  return profile;
135 }
136 
137 //------------------------------------------------------------------------------
138 
139 std::shared_ptr< ::fwRuntime::profile::Activater > ProfileReader::processActivater(xmlNodePtr node)
140 {
141  // Processes all attributes.
142  xmlAttrPtr curAttr;
143  std::string identifier;
144  std::string version;
145  for(curAttr = node->properties; curAttr != 0; curAttr = curAttr->next)
146  {
147  if(xmlStrcmp(curAttr->name, (const xmlChar*) ID.c_str()) == 0)
148  {
149  identifier = (const char*) curAttr->children->content;
150  continue;
151  }
152 
153  if(xmlStrcmp(curAttr->name, (const xmlChar*) VERSION.c_str()) == 0)
154  {
155  version = (const char*) curAttr->children->content;
156  continue;
157  }
158  }
159 
160  // Creates the activater object.
161  using ::fwRuntime::profile::Activater;
162  std::shared_ptr< Activater > activater( new Activater(identifier, version) );
163 
164  // Processes child node that are the parameters
165  xmlNodePtr curChild = node->children;
166  for(curChild = node->children; curChild != 0; curChild = curChild->next)
167  {
168  if(xmlStrcmp(curChild->name, (const xmlChar*) PARAM.c_str()) == 0)
169  {
170  processActivaterParam( curChild, activater );
171  continue;
172  }
173 
174  if(xmlStrcmp(curChild->name, (const xmlChar*) DIS_EXT_PT.c_str()) == 0)
175  {
176  processActivaterDisableExtensionPoint( curChild, activater );
177  continue;
178  }
179 
180  if(xmlStrcmp(curChild->name, (const xmlChar*) DIS_EXT.c_str()) == 0)
181  {
182  processActivaterDisableExtension( curChild, activater );
183  continue;
184  }
185  }
186  // Job's done.
187  return activater;
188 }
189 
190 //------------------------------------------------------------------------------
191 
192 void ProfileReader::processActivaterParam(xmlNodePtr node, std::shared_ptr< ::fwRuntime::profile::Activater > activater)
193 {
194  // Processes all attributes.
195  xmlAttrPtr curAttr;
196  std::string identifier;
197  std::string value;
198  for(curAttr = node->properties; curAttr != 0; curAttr = curAttr->next)
199  {
200  if(xmlStrcmp(curAttr->name, (const xmlChar*) ID.c_str()) == 0)
201  {
202  identifier = (const char*) curAttr->children->content;
203  continue;
204  }
205 
206  if(xmlStrcmp(curAttr->name, (const xmlChar*) VALUE.c_str()) == 0)
207  {
208  value = (const char*) curAttr->children->content;
209  continue;
210  }
211  }
212  // Stores the parameter into the activater.
213  activater->addParameter( identifier, value );
214 }
215 
216 //------------------------------------------------------------------------------
217 
218 void ProfileReader::processActivaterDisableExtensionPoint(xmlNodePtr node,
219  std::shared_ptr< ::fwRuntime::profile::Activater > activater)
220 {
221  // Processes all attributes.
222  xmlAttrPtr curAttr;
223  std::string identifier;
224  for(curAttr = node->properties; curAttr != 0; curAttr = curAttr->next)
225  {
226  if(xmlStrcmp(curAttr->name, (const xmlChar*) ID.c_str()) == 0)
227  {
228  identifier = (const char*) curAttr->children->content;
229  continue;
230  }
231  }
232 
233  // Stores the parameter into the activater.
234  activater->addDisableExtensionPoint( identifier );
235 }
236 
237 //------------------------------------------------------------------------------
238 
239 void ProfileReader::processActivaterDisableExtension(xmlNodePtr node,
240  std::shared_ptr< ::fwRuntime::profile::Activater > activater)
241 {
242  // Processes all attributes.
243  xmlAttrPtr curAttr;
244  std::string identifier;
245  for(curAttr = node->properties; curAttr != 0; curAttr = curAttr->next)
246  {
247  if(xmlStrcmp(curAttr->name, (const xmlChar*) ID.c_str()) == 0)
248  {
249  identifier = (const char*) curAttr->children->content;
250  continue;
251  }
252  }
253 
254  // Stores the parameter into the activater.
255  activater->addDisableExtension( identifier );
256 }
257 
258 //------------------------------------------------------------------------------
259 
260 std::shared_ptr< ::fwRuntime::profile::Starter > ProfileReader::processStarter(xmlNodePtr node)
261 {
262  // Processes all attributes.
263  xmlAttrPtr curAttr;
264  std::string identifier;
265  std::string version;
266  for(curAttr = node->properties; curAttr != 0; curAttr = curAttr->next)
267  {
268  if(xmlStrcmp(curAttr->name, (const xmlChar*) ID.c_str()) == 0)
269  {
270  identifier = (const char*) curAttr->children->content;
271  continue;
272  }
273 
274  if(xmlStrcmp(curAttr->name, (const xmlChar*) VERSION.c_str()) == 0)
275  {
276  version = (const char*) curAttr->children->content;
277  continue;
278  }
279  }
280 
281  // Creates the activater object.
282  using ::fwRuntime::profile::Starter;
283  std::shared_ptr< Starter > starter( new Starter(identifier, Version(version)) );
284  return starter;
285 }
286 
287 //------------------------------------------------------------------------------
288 
289 } // namespace io
290 
291 } // namespace fwRuntime
The namespace fwRuntime::profile contains classes to manage bundle declares in profile.xml file (activate/start/stop).
#define SPTR(_cls_)
Defines the runtime exception class.
FWRUNTIME_API const std::string getErrorLog() const
Retrieves the error log content.
Definition: Validator.cpp:73
FWRUNTIME_API bool validate(const boost::filesystem::path &xmlFile)
Validates the given file.
Definition: Validator.cpp:120
The namespace fwRuntime contains classes to manage bundle, configuration element, extension point in ...
Implements an XML validator.
Definition: Validator.hpp:37
#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
static FWRUNTIME_API std::shared_ptr< ::fwRuntime::profile::Profile > createProfile(const boost::filesystem::path &path)
Creates a profile from an xml file located at the given path.
Holds version information for libraries and bundles.