Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkPropertyListsXmlFileReaderAndWriter.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
18 #include "mitkProperties.h"
20 #include <itksys/SystemTools.hxx>
21 #include <tinyxml.h>
22 
23 namespace mitk
24 {
27  TiXmlElement *elem) const
28  {
29  if (!elem)
30  {
31  return false;
32  }
33 
34  bool readOp = false;
35  std::string type = "";
36  readOp = elem->QueryStringAttribute("type", &type) == TIXML_SUCCESS;
37  if (readOp)
38  readOp = elem->QueryStringAttribute("name", &name) == TIXML_SUCCESS;
39  else
40  MITK_WARN << "type"
41  << " attribute not found in a property";
42 
43  if (readOp)
44  {
45  if (type == "BoolProperty")
46  {
47  int val = 0;
48  readOp = elem->QueryIntAttribute("value", &val) == TIXML_SUCCESS;
49  if (readOp)
50  {
51  prop = mitk::BoolProperty::New(val == 1 ? true : false);
52  }
53  }
54  else if (type == "StringProperty")
55  {
56  std::string val = "";
57  readOp = elem->QueryStringAttribute("value", &val) == TIXML_SUCCESS;
58  if (readOp)
59  {
60  prop = mitk::StringProperty::New(val);
61  }
62  }
63  else if (type == "IntProperty")
64  {
65  int val = 0;
66  readOp = elem->QueryIntAttribute("value", &val) == TIXML_SUCCESS;
67  if (readOp)
68  {
69  prop = mitk::IntProperty::New(val);
70  }
71  }
72  else if (type == "DoubleProperty")
73  {
74  double val = 0;
75  readOp = elem->QueryDoubleAttribute("value", &val) == TIXML_SUCCESS;
76  if (readOp)
77  {
78  prop = mitk::DoubleProperty::New(val);
79  }
80  }
81  else if (type == "FloatProperty")
82  {
83  float val = 0;
84  readOp = elem->QueryFloatAttribute("value", &val) == TIXML_SUCCESS;
85  if (readOp)
86  {
87  prop = mitk::FloatProperty::New(val);
88  }
89  }
90  else
91  {
92  readOp = false;
93  MITK_WARN << "type"
94  << " attribute unknown. Only BoolProperty, StringProperty, IntProperty, DoubleProperty or "
95  "FloatProperty allowed.";
96  }
97  }
98  else
99  MITK_WARN << "name"
100  << " attribute not found in a property";
101 
102  if (!readOp)
103  MITK_WARN << "value"
104  << " attribute not found in a property";
105 
106  return readOp;
107  }
109  const mitk::BaseProperty *prop,
110  TiXmlElement *elem) const
111  {
112  if (!prop || !elem)
113  {
114  return false;
115  }
116 
117  const mitk::IntProperty *intProp = nullptr;
118  const mitk::FloatProperty *floatProp = nullptr;
119  const mitk::DoubleProperty *doubleProp = nullptr;
120  const mitk::BoolProperty *boolProp = nullptr;
121  const mitk::StringProperty *stringProp = nullptr;
122  bool writeOp = true;
123 
124  if ((boolProp = dynamic_cast<const BoolProperty *>(prop)))
125  {
126  elem->SetAttribute(GetPropertyListIdElementName(), name);
127  elem->SetAttribute("value", boolProp->GetValue() ? 1 : 0);
128  elem->SetAttribute("type", "BoolProperty");
129  }
130  else if ((stringProp = dynamic_cast<const StringProperty *>(prop)))
131  {
132  elem->SetAttribute(GetPropertyListIdElementName(), name);
133  elem->SetAttribute("value", stringProp->GetValue());
134  elem->SetAttribute("type", "StringProperty");
135  }
136  else if ((intProp = dynamic_cast<const IntProperty *>(prop)))
137  {
138  elem->SetAttribute(GetPropertyListIdElementName(), name);
139  elem->SetAttribute("value", intProp->GetValue());
140  elem->SetAttribute("type", "IntProperty");
141  }
142  else if ((doubleProp = dynamic_cast<const DoubleProperty *>(prop)))
143  {
144  elem->SetAttribute(GetPropertyListIdElementName(), name);
145  elem->SetDoubleAttribute("value", doubleProp->GetValue());
146  elem->SetAttribute("type", "DoubleProperty");
147  }
148  else if ((floatProp = dynamic_cast<const FloatProperty *>(prop)))
149  {
150  elem->SetAttribute(GetPropertyListIdElementName(), name);
151  elem->SetDoubleAttribute("value", static_cast<float>(floatProp->GetValue()));
152  elem->SetAttribute("type", "FloatProperty");
153  }
154  else
155  {
156  MITK_WARN("PropertyListImportFromXmlFile") << "Base property " << name << " is unknown";
157  writeOp = false;
158  }
159  return writeOp;
160  }
162  const std::string &fileName, const std::map<std::string, mitk::PropertyList::Pointer> &_PropertyLists) const
163  {
164  TiXmlDocument doc;
165 
166  auto decl = new TiXmlDeclaration("1.0", "", "");
167  doc.LinkEndChild(decl);
168  // create root
169  auto propertyListsElem = new TiXmlElement("PropertyLists");
170 
171  bool allPropsConverted = true;
172  auto it = _PropertyLists.begin();
173  while (it != _PropertyLists.end())
174  {
175  const std::string &id = (*it).first;
176  const PropertyList *propList = (*it).second;
177  auto propertyListElem = new TiXmlElement("PropertyList");
178  propertyListElem->SetAttribute(GetPropertyListIdElementName(), id);
179 
180  const std::map<std::string, BaseProperty::Pointer> *propMap = propList->GetMap();
181  auto propMapIt = propMap->begin();
182  while (propMapIt != propMap->end())
183  {
184  const std::string &propName = (*propMapIt).first;
185  const BaseProperty *prop = (*propMapIt).second;
186  auto propertyElem = new TiXmlElement("Property");
187 
188  if (!this->PropertyToXmlElem(propName, prop, propertyElem))
189  allPropsConverted = false;
190 
191  propertyListElem->LinkEndChild(propertyElem);
192  ++propMapIt;
193  }
194 
195  propertyListsElem->LinkEndChild(propertyListElem);
196  ++it;
197  }
198 
199  doc.LinkEndChild(propertyListsElem);
200 
201  return (allPropsConverted && doc.SaveFile(fileName.c_str()));
202  }
204  const std::string &fileName, std::map<std::string, mitk::PropertyList::Pointer> &_PropertyLists) const
205  {
206  // reread
207  TiXmlDocument doc(fileName);
208  doc.LoadFile();
209 
210  TiXmlHandle docHandle(&doc);
211  TiXmlElement *elem = docHandle.FirstChildElement("PropertyLists").FirstChildElement("PropertyList").ToElement();
212 
213  if (!elem)
214  {
215  MITK_WARN("PropertyListFromXml") << "Cannot find a PropertyList element (inside a PropertyLists element)";
216  return false;
217  }
218 
219  bool opRead = false;
220  while (elem)
221  {
222  std::string propListId;
223  opRead = elem->QueryStringAttribute(GetPropertyListIdElementName(), &propListId) == TIXML_SUCCESS;
224  if (!opRead)
225  break;
226 
228 
229  TiXmlElement *propElem = elem->FirstChildElement("Property");
230 
231  while (propElem)
232  {
233  std::string name;
235  opRead = this->PropertyFromXmlElem(name, prop, propElem);
236  if (!opRead)
237  break;
238  propList->SetProperty(name, prop);
239  propElem = propElem->NextSiblingElement("Property");
240  }
241 
242  if (!opRead)
243  break;
244  _PropertyLists[propListId] = propList;
245  elem = elem->NextSiblingElement("PropertyList");
246  }
247 
248  return opRead;
249  }
250 
254 }
bool ReadLists(const std::string &fileName, std::map< std::string, mitk::PropertyList::Pointer > &_PropertyLists) const
static Pointer New()
static Pointer New()
DataCollection - Class to facilitate loading/accessing structured data.
Key-value list holding instances of BaseProperty.
virtual const char * GetValue() const
static Pointer New()
Abstract base class for properties.
#define MITK_WARN
Definition: mitkLogMacros.h:23
bool PropertyFromXmlElem(std::string &name, mitk::BaseProperty::Pointer &prop, TiXmlElement *elem) const
bool PropertyToXmlElem(const std::string &name, const mitk::BaseProperty *prop, TiXmlElement *elem) const
static Pointer New()
static Pointer New()
bool WriteLists(const std::string &fileName, const std::map< std::string, mitk::PropertyList::Pointer > &_PropertyLists) const
Property for strings.
static Pointer New()
const PropertyMap * GetMap() const
virtual T GetValue() const