[dss-commits] digitalSTROM Server branch, master, updated. 933257e1afe3035f9744499c7127b77a56febcd2

git version control dss-commits at forum.digitalstrom.org
Tue Dec 15 15:14:18 CET 2009


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "digitalSTROM Server".

The branch, master has been updated
       via  933257e1afe3035f9744499c7127b77a56febcd2 (commit)
       via  2cf7e57add486c95b5e0aa6aa07243e4a74bba32 (commit)
       via  7f2712f45085cba7ad25a4debb8903d9b2c2e3a3 (commit)
       via  17105dd1bd8b9bea6aa22873e711392276a7279c (commit)
       via  87a10a0cc1490b7fbe77dd114b9a02251ed5e102 (commit)
       via  f40b88233d8b93a9711d3ad2be24928e248e255b (commit)
      from  f82ce5a310973d67d123ca76ecfecc53aeb580ed (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 933257e1afe3035f9744499c7127b77a56febcd2
Author: Patrick Stählin <pstaehlin at futurelab.ch>
Date:   Tue Dec 15 15:13:08 2009 +0100

    Save flaged properties of devices in apartment.xml
    
    Set the flag PropertyNode::Archive on the properties that need to be
    archived.

commit 2cf7e57add486c95b5e0aa6aa07243e4a74bba32
Author: Patrick Stählin <pstaehlin at futurelab.ch>
Date:   Tue Dec 15 14:28:11 2009 +0100

    Store PropertyNode-flags in XML output

commit 7f2712f45085cba7ad25a4debb8903d9b2c2e3a3
Author: Patrick Stählin <pstaehlin at futurelab.ch>
Date:   Tue Dec 15 13:59:11 2009 +0100

    Removed some obsolete references to xmlwrapper.h

commit 17105dd1bd8b9bea6aa22873e711392276a7279c
Author: Patrick Stählin <pstaehlin at futurelab.ch>
Date:   Tue Dec 15 13:54:43 2009 +0100

    Use Poco::XML to parse apartment.xml
    
    References #233

commit 87a10a0cc1490b7fbe77dd114b9a02251ed5e102
Author: Patrick Stählin <pstaehlin at futurelab.ch>
Date:   Tue Dec 15 12:27:56 2009 +0100

    Use Poco::XML to read/write properties
    
    References #233

commit f40b88233d8b93a9711d3ad2be24928e248e255b
Author: Patrick Stählin <pstaehlin at futurelab.ch>
Date:   Tue Dec 15 11:21:34 2009 +0100

    Use internal log-function in Apartment::*

-----------------------------------------------------------------------

Changes:
diff --git a/core/dss.cpp b/core/dss.cpp
index 423180e..d3a59fb 100644
--- a/core/dss.cpp
+++ b/core/dss.cpp
@@ -30,7 +30,6 @@
 
 #include "dss.h"
 #include "logger.h"
-#include "xmlwrapper.h"
 #include "propertysystem.h"
 #include "scripting/modeljs.h"
 #include "eventinterpreterplugins.h"
diff --git a/core/metering/series.h b/core/metering/series.h
index 1d31057..41dbe6e 100644
--- a/core/metering/series.h
+++ b/core/metering/series.h
@@ -23,7 +23,6 @@
 #define SERIES_H_INCLUDED
 
 #include "core/datetools.h"
-#include "core/xmlwrapper.h"
 #include "core/ds485types.h"
 
 #include <Poco/DOM/Document.h>
@@ -82,13 +81,6 @@ namespace dss {
       }
     } // mergeWith
 
-    virtual void readFromXMLNode(XMLNode& _node) {
-      m_TimeStamp = DateTime(dateFromISOString(_node.getAttributes()["timestamp"].c_str()));
-      m_Min = strToDouble(_node.getChildByName("min").getChildren()[0].getContent());
-      m_Max = strToDouble(_node.getChildByName("max").getChildren()[0].getContent());
-      m_Value = strToDouble(_node.getChildByName("value").getChildren()[0].getContent());
-    } // readFromXMLNode
-
     virtual void readFromXMLNode(Node* _node) {
       Element* elem = dynamic_cast<Element*>(_node);
 
diff --git a/core/metering/seriespersistence.cpp b/core/metering/seriespersistence.cpp
index 99009dd..0495616 100644
--- a/core/metering/seriespersistence.cpp
+++ b/core/metering/seriespersistence.cpp
@@ -21,7 +21,6 @@
 
 #include "seriespersistence.h"
 
-#include "core/xmlwrapper.h"
 #include "core/logger.h"
 #include "core/foreach.h"
 
diff --git a/core/model.cpp b/core/model.cpp
index 0363839..a790b2c 100644
--- a/core/model.cpp
+++ b/core/model.cpp
@@ -26,7 +26,6 @@
 #include "dss.h"
 #include "logger.h"
 #include "propertysystem.h"
-#include "xmlwrapper.h"
 #include "event.h"
 
 #include "foreach.h"
@@ -37,12 +36,15 @@
 
 #include <Poco/DOM/Document.h>
 #include <Poco/DOM/Element.h>
+#include <Poco/DOM/Node.h>
 #include <Poco/DOM/Attr.h>
 #include <Poco/DOM/Text.h>
 #include <Poco/DOM/ProcessingInstruction.h>
 #include <Poco/DOM/AutoPtr.h>
 #include <Poco/DOM/DOMWriter.h>
+#include <Poco/DOM/DOMParser.h>
 #include <Poco/XML/XMLWriter.h>
+#include <Poco/SAX/InputSource.h>
 
 using Poco::XML::Document;
 using Poco::XML::Element;
@@ -51,7 +53,10 @@ using Poco::XML::Text;
 using Poco::XML::ProcessingInstruction;
 using Poco::XML::AutoPtr;
 using Poco::XML::DOMWriter;
+using Poco::XML::DOMParser;
 using Poco::XML::XMLWriter;
+using Poco::XML::InputSource;
+using Poco::XML::Node;
 
 namespace dss {
 
@@ -74,17 +79,18 @@ namespace dss {
 
   void Device::publishToPropertyTree() {
     if(m_pPropertyNode == NULL) {
-      // don't publish stale devices for now
-      if(m_ShortAddress == ShortAddressStaleDevice) {
-        return;
-      } else {
-        if(m_pApartment->getPropertyNode() != NULL) {
-          m_pPropertyNode = m_pApartment->getPropertyNode()->createProperty("zones/zone0/" + m_DSID.toString());
-//          m_pPropertyNode->createProperty("name")->linkToProxy(PropertyProxyMemberFunction<Device, std::string>(*this, &Device::getName, &Device::setName));
-          m_pPropertyNode->createProperty("name")->linkToProxy(PropertyProxyReference<string>(m_Name));
-          m_pPropertyNode->createProperty("ModulatorID")->linkToProxy(PropertyProxyReference<int>(m_ModulatorID, false));
-          m_pPropertyNode->createProperty("ZoneID")->linkToProxy(PropertyProxyReference<int>(m_ZoneID, false));
-          m_pPropertyNode->createProperty("interrupt/mode")->setStringValue("ignore");
+      if(m_pApartment->getPropertyNode() != NULL) {
+        m_pPropertyNode = m_pApartment->getPropertyNode()->createProperty("zones/zone0/" + m_DSID.toString());
+//        m_pPropertyNode->createProperty("name")->linkToProxy(PropertyProxyMemberFunction<Device, std::string>(*this, &Device::getName, &Device::setName));
+        m_pPropertyNode->createProperty("name")->linkToProxy(PropertyProxyReference<string>(m_Name));
+        m_pPropertyNode->createProperty("ModulatorID")->linkToProxy(PropertyProxyReference<int>(m_ModulatorID, false));
+        m_pPropertyNode->createProperty("ZoneID")->linkToProxy(PropertyProxyReference<int>(m_ZoneID, false));
+        if(m_pPropertyNode->getProperty("interrupt/mode") == NULL) {
+          PropertyNodePtr interruptNode = m_pPropertyNode->createProperty("interrupt");
+          interruptNode->setFlag(PropertyNode::Archive, true);
+          PropertyNodePtr interruptModeNode = interruptNode->createProperty("mode");
+          interruptModeNode->setStringValue("ignore");
+          interruptModeNode->setFlag(PropertyNode::Archive, true);
         }
       }
     }
@@ -1092,7 +1098,7 @@ namespace dss {
     // load devices/modulators/etc. from a config-file
     std::string configFileName = DSS::getInstance()->getPropertySystem().getStringValue(getConfigPropertyBasePath() + "configfile");
     if(!boost::filesystem::exists(configFileName)) {
-      Logger::getInstance()->log(string("Apartment::execute: Could not open config-file for apartment: '") + configFileName + "'", lsWarning);
+      log(string("Apartment::execute: Could not open config-file for apartment: '") + configFileName + "'", lsWarning);
     } else {
       readConfigurationFromXML(configFileName);
     }
@@ -1139,106 +1145,117 @@ namespace dss {
   const int ApartmentConfigVersion = 1;
 
   void Apartment::readConfigurationFromXML(const std::string& _fileName) {
-    XMLDocumentFileReader reader(_fileName);
     setName("dSS");
-
-    XMLNode rootNode = reader.getDocument().getRootNode();
-    if(rootNode.getName() == "config") {
-      if(strToInt(rootNode.getAttributes()["version"]) == ApartmentConfigVersion) {
-        XMLNodeList nodes = rootNode.getChildren();
-        for(XMLNodeList::iterator iNode = nodes.begin(); iNode != nodes.end(); ++iNode) {
-          std::string nodeName = iNode->getName();
+    std::ifstream inFile(_fileName.c_str());
+
+    InputSource input(inFile);
+    DOMParser parser;
+    AutoPtr<Document> pDoc = parser.parse(&input);
+    Element* rootNode = pDoc->documentElement();
+
+    if(rootNode->localName() == "config") {
+      if(rootNode->hasAttribute("version") && (strToInt(rootNode->getAttribute("version")) == ApartmentConfigVersion)) {
+        Node* curNode = rootNode->firstChild();
+        while(curNode != NULL) {
+          std::string nodeName = curNode->localName();
           if(nodeName == "devices") {
-            loadDevices(*iNode);
+            loadDevices(curNode);
           } else if(nodeName == "modulators") {
-            loadModulators(*iNode);
+            loadModulators(curNode);
           } else if(nodeName == "zones") {
-            loadZones(*iNode);
+            loadZones(curNode);
           } else if(nodeName == "apartment") {
-            try {
-              XMLNode& nameNode = iNode->getChildByName("name");
-              if(!nameNode.getChildren().empty()) {
-                setName((nameNode.getChildren()[0]).getContent());
+            Element* elem = dynamic_cast<Element*>(curNode);
+            if(elem != NULL) {
+              Element* nameElem = elem->getChildElement("name");
+              if(nameElem->hasChildNodes()) {
+                setName(nameElem->firstChild()->nodeValue());
               }
-            } catch(std::runtime_error&) {
             }
           }
+          curNode = curNode->nextSibling();
         }
       } else {
-        Logger::getInstance()->log("Config file has the wrong version");
+        log("Config file has the wrong version");
       }
     }
   } // readConfigurationFromXML
 
-  void Apartment::loadDevices(XMLNode& _node) {
-    XMLNodeList devices = _node.getChildren();
-    for(XMLNodeList::iterator iNode = devices.begin(); iNode != devices.end(); ++iNode) {
-      if(iNode->getName() == "device") {
-        dsid_t dsid = dsid_t::fromString(iNode->getAttributes()["dsid"]);
-        std::string name;
-        try {
-          XMLNode& nameNode = iNode->getChildByName("name");
-          if(!nameNode.getChildren().empty()) {
-            name = (nameNode.getChildren()[0]).getContent();
+  void Apartment::loadDevices(Node* _node) {
+    Node* curNode = _node->firstChild();
+    while(curNode != NULL) {
+      if(curNode->localName() == "device") {
+        Element* elem = dynamic_cast<Element*>(curNode);
+        if((elem != NULL) && elem->hasAttribute("dsid")) {
+          dsid_t dsid = dsid_t::fromString(elem->getAttribute("dsid"));
+          std::string name;
+          Element* nameElem = elem->getChildElement("name");
+          if((nameElem != NULL) && nameElem->hasChildNodes()) {
+            name = nameElem->firstChild()->nodeValue();
+          }
+
+          DateTime firstSeen;
+          if(elem->hasAttribute("firstSeen")) {
+            firstSeen = DateTime(dateFromISOString(elem->getAttribute("firstSeen").c_str()));
+          }
+
+          Device& newDevice = allocateDevice(dsid);
+          if(!name.empty()) {
+            newDevice.setName(name);
+          }
+          newDevice.setFirstSeen(firstSeen);
+          Element* propertiesElem = elem->getChildElement("properties");
+          if(propertiesElem != NULL) {
+            newDevice.publishToPropertyTree();
+            newDevice.getPropertyNode()->loadChildrenFromNode(propertiesElem);
           }
-        } catch(XMLException& e) {
-          /* discard node not found exceptions */
-        }
-        
-        DateTime firstSeen; 
-        std::string firstSeenStr = iNode->getAttributes()["firstSeen"];
-        if(!firstSeenStr.empty()) {
-          firstSeen = DateTime(dateFromISOString(firstSeenStr.c_str()));
-        }
-        
-        Device& newDevice = allocateDevice(dsid);
-        if(!name.empty()) {
-          newDevice.setName(name);
         }
-        newDevice.setFirstSeen(firstSeen);
       }
+      curNode = curNode->nextSibling();
     }
   } // loadDevices
 
-  void Apartment::loadModulators(XMLNode& _node) {
-    XMLNodeList modulators = _node.getChildren();
-    for(XMLNodeList::iterator iModulator = modulators.begin(); iModulator != modulators.end(); ++iModulator) {
-      if(iModulator->getName() == "modulator") {
-        dsid_t id = dsid_t::fromString(iModulator->getAttributes()["id"]);
-        std::string name;
-        try {
-          XMLNode& nameNode = iModulator->getChildByName("name");
-          if(!nameNode.getChildren().empty()) {
-            name = (nameNode.getChildren()[0]).getContent();
+  void Apartment::loadModulators(Node* _node) {
+    Node* curNode = _node->firstChild();
+    while(curNode != NULL) {
+      if(curNode->localName() == "modulator") {
+        Element* elem = dynamic_cast<Element*>(curNode);
+        if((elem != NULL) && elem->hasAttribute("id")) {
+          dsid_t id = dsid_t::fromString(elem->getAttribute("id"));
+          std::string name;
+          Element* nameElem = elem->getChildElement("name");
+          if((nameElem != NULL) && nameElem->hasChildNodes()) {
+            name = nameElem->firstChild()->nodeValue();
+          }
+          Modulator& newModulator = allocateModulator(id);
+          if(!name.empty()) {
+            newModulator.setName(name);
           }
-        } catch(XMLException&) {
-        }
-        Modulator& newModulator = allocateModulator(id);
-        if(!name.empty()) {
-          newModulator.setName(name);
         }
       }
+      curNode = curNode->nextSibling();
     }
   } // loadModulators
 
-  void Apartment::loadZones(XMLNode& _node) {
-    XMLNodeList zones = _node.getChildren();
-    for(XMLNodeList::iterator iZone = zones.begin(); iZone != zones.end(); ++iZone) {
-      if(iZone->getName() == "zone") {
-        int id = strToInt(iZone->getAttributes()["id"]);
-        std::string name;
-        try {
-          XMLNode& nameNode = iZone->getChildByName("name");
-          if(!nameNode.getChildren().empty()) {
-            name = (nameNode.getChildren()[0]).getContent();
+  void Apartment::loadZones(Node* _node) {
+    Node* curNode = _node->firstChild();
+    while(curNode != NULL) {
+      if(curNode->localName() == "zone") {
+        Element* elem = dynamic_cast<Element*>(curNode);
+        if((elem != NULL) && elem->hasAttribute("id")) {
+          int id = strToInt(elem->getAttribute("id"));
+          std::string name;
+          Element* nameElem = elem->getChildElement("name");
+          if((nameElem != NULL) && nameElem->hasChildNodes()) {
+            name = nameElem->firstChild()->nodeValue();
+          }
+          Zone& newZone = allocateZone(id);
+          if(!name.empty()) {
+            newZone.setName(name);
           }
-        } catch(XMLException&) {
-        }
-        Zone& newZone = allocateZone(id);
-        if(!name.empty()) {
-          newZone.setName(name);
         }
       }
+      curNode = curNode->nextSibling();
     }
   } // loadZones
 
@@ -1252,6 +1269,11 @@ namespace dss {
       pDeviceNode->appendChild(pNameNode);
     }    
     pDeviceNode->setAttribute("firstSeen", _pDevice->getFirstSeen());
+    if(_pDevice->getPropertyNode() != NULL) {
+      AutoPtr<Element> pPropertiesNode = _pDocument->createElement("properties");
+      pDeviceNode->appendChild(pPropertiesNode);
+      _pDevice->getPropertyNode()->saveChildrenAsXML(_pDocument, pPropertiesNode, PropertyNode::Archive);
+    }
 
     _parentNode->appendChild(pDeviceNode);
   } // deviceToXML
@@ -1334,7 +1356,7 @@ namespace dss {
       // move it to the desired location
       rename(tmpOut.c_str(), _fileName.c_str());
     } else {
-      Logger::getInstance()->log("Could not open file '" + tmpOut + "' for writing", lsFatal);
+      log("Could not open file '" + tmpOut + "' for writing", lsFatal);
     }
   } // writeConfigurationToXML
 
diff --git a/core/model.h b/core/model.h
index 2f8d02f..9d2f26c 100644
--- a/core/model.h
+++ b/core/model.h
@@ -40,6 +40,12 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/tuple/tuple.hpp>
 
+namespace Poco {
+  namespace XML {
+    class Node;
+  }
+}
+
 namespace dss {
 
   class Device;
@@ -49,7 +55,6 @@ namespace dss {
   class Group;
   class Modulator;
   class PropertyNode;
-  class XMLNode;
   typedef boost::shared_ptr<PropertyNode> PropertyNodePtr;
 
   class PhysicalModelItem {
@@ -226,9 +231,6 @@ namespace dss {
     PropertyNodePtr m_pPropertyNode;
     PropertyNodePtr m_pAliasNode;
   protected:
-    /** Publishes the device to the property tree.
-     * @see DSS::getPropertySystem */
-    void publishToPropertyTree();
     /** Sends the application a note that something has changed.
      * This will cause the \c apartment.xml to be updated. */
     void dirty();
@@ -341,8 +343,13 @@ namespace dss {
      * the result of the function is not defined. */
     uint8_t dsLinkSend(uint8_t _value, bool _lastByte, bool _writeOnly);
 
+    const PropertyNodePtr& getPropertyNode() const { return m_pPropertyNode; }
     PropertyNodePtr getPropertyNode() { return m_pPropertyNode; }
 
+    /** Publishes the device to the property tree.
+     * @see DSS::getPropertySystem */
+    void publishToPropertyTree();
+
     /** Returns wheter two devices are equal.
      * Devices are considered equal if their DSID are a match.*/
     bool operator==(const Device& _other) const;
@@ -808,9 +815,9 @@ namespace dss {
     SyncEvent m_NewModelEvent;
     int m_RescanBusIn;
   private:
-    void loadDevices(XMLNode& _node);
-    void loadModulators(XMLNode& _node);
-    void loadZones(XMLNode& _node);
+    void loadDevices(Poco::XML::Node* _node);
+    void loadModulators(Poco::XML::Node* _node);
+    void loadZones(Poco::XML::Node* _node);
 
     void addDefaultGroupsToZone(Zone& _zone);
     /** Starts the event-processing */
diff --git a/core/propertysystem.cpp b/core/propertysystem.cpp
index b26dd1e..c3c5d0b 100644
--- a/core/propertysystem.cpp
+++ b/core/propertysystem.cpp
@@ -22,57 +22,43 @@
 
 #include "propertysystem.h"
 
-#include "base.h"
-
 #include <iostream>
 #include <sstream>
 #include <algorithm>
 #include <cassert>
 #include <cstring>
-
-#include "foreach.h"
+#include <fstream>
+
+#include <Poco/DOM/Document.h>
+#include <Poco/DOM/Attr.h>
+#include <Poco/DOM/Text.h>
+#include <Poco/DOM/AutoPtr.h>
+#include <Poco/DOM/ProcessingInstruction.h>
+#include <Poco/DOM/DOMWriter.h>
+#include <Poco/XML/XMLWriter.h>
+#include <Poco/DOM/DOMParser.h>
+#include <Poco/DOM/Element.h>
+#include <Poco/SAX/InputSource.h>
+
+using Poco::XML::Document;
+using Poco::XML::Attr;
+using Poco::XML::Text;
+using Poco::XML::ProcessingInstruction;
+using Poco::XML::DOMWriter;
+using Poco::XML::DOMParser;
+using Poco::XML::XMLWriter;
+using Poco::XML::Element;
+using Poco::XML::Node;
+using Poco::XML::AutoPtr;
+using Poco::XML::InputSource;
+
+#include "core/base.h"
+#include "core/foreach.h"
+#include "core/logger.h"
 
 namespace dss {
 
   const int PROPERTY_FORMAT_VERSION = 1;
-#define XML_ENCODING "utf-8"
-
-  xmlAttr* xmlSearchAttr(xmlNode* _pNode, xmlChar* _name) {
-    xmlAttr* curAttr = _pNode->properties;
-
-    while (curAttr != NULL) {
-      if (curAttr->type == XML_ATTRIBUTE_NODE) {
-        if (strcmp((char*) curAttr->name, (char*) _name) == 0) {
-          return curAttr;
-        }
-      }
-      curAttr = curAttr->next;
-    };
-
-    return NULL;
-  } // xmlSearchAttr
-
-  xmlNode* xmlSearchNode(xmlNode* _pNode, const char* _name, bool _recurse) {
-    xmlNode* result = _pNode->children;
-
-    while (result != NULL) {
-      if (result->type == XML_ELEMENT_NODE) {
-        if (strcmp((char*) result->name, _name) == 0) {
-          break;
-        } else {
-          if (_recurse) {
-            xmlNode* propRes = xmlSearchNode(result, _name, true);
-            if (propRes != NULL) {
-              result = propRes;
-              break;
-            }
-          }
-        }
-      }
-      result = result->next;
-    }
-    return result;
-  } // xmlSearchNode
 
   //=============================================== PropertySystem
 
@@ -85,94 +71,78 @@ namespace dss {
 
   bool PropertySystem::loadFromXML(const std::string& _fileName,
                                    PropertyNodePtr _rootNode) {
-    xmlDoc* doc = NULL;
-    xmlNode *rootElem = NULL;
+    PropertyNodePtr root = _rootNode;
+    if (root == NULL) {
+      root = getRootNode();
+    }
+
+    std::ifstream inFile(_fileName.c_str());
 
-    PropertyNodePtr rootNode = _rootNode;
-    if (rootNode == NULL) {
-      rootNode = getRootNode();
+    InputSource input(inFile);
+    DOMParser parser;
+    AutoPtr<Document> pDoc = parser.parse(&input);
+    Element* rootNode = pDoc->documentElement();
+    if(rootNode->localName() != "properties") {
+      Logger::getInstance()->log("PropertySystem::loadFromXML: root node must be named properties, got: '" + rootNode->localName() + "'", lsError);
+      return false;
+    }
+    if(!rootNode->hasAttribute("version")) {
+      Logger::getInstance()->log("PropertySystem::loadFromXML: missing version attribute", lsError);
+      return false;
     }
 
-    doc = xmlParseFile(_fileName.c_str());
-    if (doc == NULL) {
-      std::cerr << "Error loading properties from \"" << _fileName << "\"" << std::endl;
+    if(strToIntDef(rootNode->getAttribute("version"),-1) != PROPERTY_FORMAT_VERSION) {
+      Logger::getInstance()->log(std::string("PropertySystem::loadFromXML: Version mismatch, expected ") + intToString(PROPERTY_FORMAT_VERSION) + " got " + rootNode->getAttribute("version"),
+                                 lsError);
       return false;
     }
-    rootElem = xmlDocGetRootElement(doc);
-
-    bool versionOK = false;
-    if (strcmp((char*) rootElem->name, "properties") == 0) {
-      xmlAttr* versionAttr = xmlSearchAttr(rootElem, (xmlChar*) "version");
-      if ((versionAttr != NULL) && (versionAttr->children->content != NULL)) {
-        if (atoi((char*) versionAttr->children->content)
-            == PROPERTY_FORMAT_VERSION) {
-          versionOK = true;
-          if ((rootElem->children != NULL)) {
-            xmlNode* curNode = rootElem->children;
-            // search for the first property node and go on from there
-            while (curNode != NULL) {
-              if ((curNode->type == XML_ELEMENT_NODE)
-                  && (strcmp((char*) curNode->name, "property") == 0)) {
-                rootNode->loadFromNode(curNode);
-                break;
-              }
-              curNode = curNode->next;
-            }
-          }
-        }
+
+    Node* node = rootNode->firstChild();
+    while(node != NULL) {
+      if(node->localName() == "property") {
+        return root->loadFromNode(node);
       }
-    }
-    if (!versionOK) {
-      std::cerr << "Version mismatch while loading properties from \"" << _fileName
-          << "\"" << std::endl;
-      xmlFreeDoc(doc);
+      node = node->nextSibling();
     }
 
-    return versionOK;
+    return false;
   } // loadFromXML
 
   bool PropertySystem::saveToXML(const std::string& _fileName, PropertyNodePtr _rootNode) const {
-    int rc;
-    xmlTextWriterPtr writer;
-    PropertyNodePtr root = _rootNode;
-    if (root == NULL) {
-      root = m_RootNode;
-    }
+    AutoPtr<Document> pDoc = new Document;
 
-    writer = xmlNewTextWriterFilename(_fileName.c_str(), 0);
-    if (writer == NULL) {
-      return false;
-    }
+    AutoPtr<ProcessingInstruction> pXMLHeader = pDoc->createProcessingInstruction("xml", "version='1.0' encoding='utf-8'");
+    pDoc->appendChild(pXMLHeader);
 
-    rc = xmlTextWriterStartDocument(writer, NULL, XML_ENCODING, NULL);
-    if(rc < 0) {
-      return false;
-    }
+    AutoPtr<Element> pRoot = pDoc->createElement("properties");
+    pRoot->setAttribute("version", intToString(PROPERTY_FORMAT_VERSION));
+    pDoc->appendChild(pRoot);
 
-    rc = xmlTextWriterStartElement(writer, (xmlChar*)"properties");
-    if(rc < 0) {
-      return false;
+    PropertyNodePtr root = _rootNode;
+    if(root == NULL) {
+      root = m_RootNode;
     }
+    root->saveAsXML(pDoc, pRoot, 0);
 
-    rc = xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"version", "%d", PROPERTY_FORMAT_VERSION);
-    if(rc < 0) {
-      return false;
-    }
+    // TODO: factor those line into a function as it's a copy of
+    //       model.cpp/seriespersistance.cpp/metering.cpp
+    std::string tmpOut = _fileName + ".tmp";
+    std::ofstream ofs(tmpOut.c_str());
 
-    root->saveAsXML(writer, 0);
+    if(ofs) {
+      DOMWriter writer;
+      writer.setNewLine("\n");
+      writer.setOptions(XMLWriter::PRETTY_PRINT);
+      writer.writeNode(ofs, pDoc);
 
-    rc = xmlTextWriterEndElement(writer);
-    if(rc < 0) {
-      return false;
-    }
+      ofs.close();
 
-    rc = xmlTextWriterEndDocument(writer);
-    if(rc < 0) {
-      return false;
+      // move it to the desired location
+      rename(tmpOut.c_str(), _fileName.c_str());
+    } else {
+      Logger::getInstance()->log("Could not open file '" + tmpOut + "' for writing", lsFatal);
     }
 
-    xmlFreeTextWriter(writer);
-
     return true;
   } // saveToXML
 
@@ -752,68 +722,69 @@ namespace dss {
     }
   }
 
-  bool PropertyNode::saveAsXML(xmlTextWriterPtr _writer, const int _flagsMask) {
-    int rc = xmlTextWriterStartElement(_writer, (xmlChar*)"property");
-    if(rc < 0) {
-      return false;
-    }
+  bool PropertyNode::saveAsXML(AutoPtr<Document>& _doc, AutoPtr<Element>& _parent, const int _flagsMask) {
+    AutoPtr<Element> elem = _doc->createElement("property");
+    _parent->appendChild(elem);
 
-    rc = xmlTextWriterWriteAttribute(_writer, (xmlChar*)"type", (xmlChar*)getValueTypeAsString(getValueType()));
-    if(rc < 0) {
-      return false;
-    }
-
-    rc = xmlTextWriterWriteAttribute(_writer, (xmlChar*)"name", (xmlChar*)getDisplayName().c_str());
-    if(rc < 0) {
-      return false;
-    }
+    elem->setAttribute("type",getValueTypeAsString(getValueType()));
+    elem->setAttribute("name", getDisplayName());
 
     if(getValueType() != vTypeNone) {
-      xmlTextWriterWriteElement(_writer, (xmlChar*)"value", (xmlChar*)getAsString().c_str());
+      AutoPtr<Element> valueElem = _doc->createElement("value");
+      AutoPtr<Text> textElem = _doc->createTextNode(getAsString());
+      valueElem->appendChild(textElem);
+      elem->appendChild(valueElem);
+    }
+    if(hasFlag(Archive)) {
+      elem->setAttribute("archive", "true");
+    }
+    if(hasFlag(Readable)) {
+      elem->setAttribute("readable", "true");
+    }
+    if(hasFlag(Writeable)) {
+      elem->setAttribute("writeable", "true");
     }
 
+    return saveChildrenAsXML(_doc, elem, _flagsMask);
+  } // saveAsXML
+
+  bool PropertyNode::saveChildrenAsXML(Poco::AutoPtr<Poco::XML::Document>& _doc, Poco::AutoPtr<Poco::XML::Element>& _parent, const int _flagsMask) {
     for(PropertyList::iterator it = m_ChildNodes.begin();
          it != m_ChildNodes.end(); ++it) {
       if((_flagsMask == Flag(0)) || (*it)->hasFlag(Flag(_flagsMask))) {
-        if(!(*it)->saveAsXML(_writer, _flagsMask)) {
+        if(!(*it)->saveAsXML(_doc, _parent, _flagsMask)) {
           return false;
         }
       }
     }
-
-    rc = xmlTextWriterEndElement(_writer);
-    if(rc < 0) {
-      return false;
-    }
     return true;
-  } // saveAsXML
+  } // saveChildrenAsXML
 
-  bool PropertyNode::loadFromNode(xmlNode* _pNode) {
-    xmlAttr* nameAttr = xmlSearchAttr(_pNode, (xmlChar*)"name");
-    xmlAttr* typeAttr = xmlSearchAttr(_pNode, (xmlChar*)"type");
+  bool PropertyNode::loadFromNode(Node* _pNode) {
+    Element* elem = dynamic_cast<Element*>(_pNode);
 
-    if(nameAttr != NULL) {
-      std::string propName = (char*)nameAttr->children->content;
+    if(elem->hasAttribute("name")) {
+      std::string propName = elem->getAttribute("name");
       propName = dss::getProperty(propName);
       getAndRemoveIndexFromPropertyName(propName);
       if(m_Name.length() > 0) {
         assert(m_Name == propName);
       }
       m_Name = propName;
-      if(typeAttr != NULL) {
-        aValueType valueType = getValueTypeFromString((char*)typeAttr->children->content);
+      if(elem->hasAttribute("type")) {
+        aValueType valueType = getValueTypeFromString(elem->getAttribute("type").c_str());
         if(valueType != vTypeNone) {
-          xmlNode* valueNode = xmlSearchNode(_pNode, "value", false);
+          Element* valueNode = elem->getChildElement("value");
           if(valueNode != NULL) {
             switch(valueType) {
               case vTypeString:
-                setStringValue((char*)valueNode->children->content);
+                setStringValue(valueNode->firstChild()->getNodeValue());
                 break;
               case vTypeInteger:
-                setIntegerValue(atoi((char*)valueNode->children->content));
+                setIntegerValue(strToInt(valueNode->firstChild()->getNodeValue()));
                 break;
               case vTypeBoolean:
-                setBooleanValue(strcmp((char*)valueNode->children->content, "true") == 0);
+                setBooleanValue(valueNode->firstChild()->getNodeValue() == "true");
                 break;
               default:
                 assert(false);
@@ -821,22 +792,35 @@ namespace dss {
           }
         }
       }
-      xmlNode* curNode = _pNode->children;
-      while(curNode != NULL) {
-        if(curNode->type == XML_ELEMENT_NODE && strcmp((char*)curNode->name, "property") == 0) {
-          nameAttr = xmlSearchAttr(curNode, (xmlChar*)"name");
-          if(nameAttr != NULL) {
-            PropertyNodePtr candidate = createProperty(std::string((char*)nameAttr->children->content));
-            candidate->loadFromNode(curNode);
-          }
-        }
-        curNode = curNode->next;
+      if(elem->hasAttribute("writeable")) {
+        setFlag(Writeable, elem->getAttribute("writeable") == "true");
       }
-      return true;
+      if(elem->hasAttribute("readable")) {
+        setFlag(Readable, elem->getAttribute("readable") == "true");
+      }
+      if(elem->hasAttribute("archive")) {
+        setFlag(Archive, elem->getAttribute("archive") == "true");
+      }
+      return loadChildrenFromNode(_pNode);
     }
     return false;
   } // loadFromNode
 
+  bool PropertyNode::loadChildrenFromNode(Poco::XML::Node* _node) {
+    Node* curNode = _node->firstChild();
+    while(curNode != NULL) {
+      if(curNode->localName() == "property") {
+        Element* curElem = dynamic_cast<Element*>(curNode);
+        if((curElem != NULL) && curElem->hasAttribute("name")) {
+          PropertyNodePtr candidate = createProperty(curElem->getAttribute("name"));
+          candidate->loadFromNode(curNode);
+        }
+      }
+      curNode = curNode->nextSibling();
+    }
+    return true;
+  } // loadChildrenFromNode
+
   void PropertyNode::propertyChanged() {
     notifyListeners(&PropertyListener::propertyChanged);
   } // propertyChanged
diff --git a/core/propertysystem.h b/core/propertysystem.h
index 9748b37..96ae759 100644
--- a/core/propertysystem.h
+++ b/core/propertysystem.h
@@ -23,9 +23,6 @@
 #ifndef NEUROPROPERTYSYSTEM_H
 #define NEUROPROPERTYSYSTEM_H
 
-#include <libxml/tree.h>
-#include <libxml/xmlwriter.h>
-
 #include <boost/mpl/if.hpp>
 #include <boost/type_traits/is_class.hpp>
 
@@ -35,6 +32,16 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/enable_shared_from_this.hpp>
 
+namespace Poco {
+  namespace XML {
+    class Document;
+    class Node;
+    class Element;
+  }
+  template<class C>
+  class AutoPtr;
+}
+
 namespace dss {
 
   class PropertyNode;
@@ -471,9 +478,13 @@ namespace dss {
     }
   public:
     /** Writes the node to XML */
-    bool saveAsXML(xmlTextWriterPtr _writer, const int _flagsMask);
+    bool saveAsXML(Poco::AutoPtr<Poco::XML::Document>& _doc, Poco::AutoPtr<Poco::XML::Element>& _parent, const int _flagsMask);
+    /** Saves the nodes children to XML */
+    bool saveChildrenAsXML(Poco::AutoPtr<Poco::XML::Document>& _doc, Poco::AutoPtr<Poco::XML::Element>& _parent, const int _flagsMask);
     /** Loads the node from XML */
-    bool loadFromNode(xmlNode* _pNode);
+    bool loadFromNode(Poco::XML::Node* _node);
+    /** Loads children from XML */
+    bool loadChildrenFromNode(Poco::XML::Node* _node);
   }; // PropertyNode
 
   /** Exception that gets thrown if a incompatible assignment would take place. */


hooks/post-receive
-- 
digitalSTROM Server


More information about the dss-commits mailing list