summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-03-06 11:50:53 +0000
committerandreas <andreas@daaaf23c-2e50-4459-9457-1e69db5a47bf>2014-03-06 11:50:53 +0000
commit247945811adbfb5ddaa1ba4e1f3dfc20cd7eb058 (patch)
treecad76062be455d4324d03f5ce38c9b599f6b7e25
parent36a1402be747136711edc19f7bce45f36a625eb4 (diff)
added attribute handler
git-svn-id: file:///var/local/svn/basicwriter@28 daaaf23c-2e50-4459-9457-1e69db5a47bf
-rw-r--r--src/xml/XmlAttributeHandler.hpp138
-rw-r--r--src/xml/XmlReader.cpp49
-rw-r--r--src/xml/XmlReader.hpp13
3 files changed, 197 insertions, 3 deletions
diff --git a/src/xml/XmlAttributeHandler.hpp b/src/xml/XmlAttributeHandler.hpp
new file mode 100644
index 0000000..8fae6c3
--- /dev/null
+++ b/src/xml/XmlAttributeHandler.hpp
@@ -0,0 +1,138 @@
+/*
+ Ousía
+ Copyright (C) 2014 Benjamin Paaßen, Andreas Stöckel
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _OUSIA_XML_XML_ATTRIBUTE_HANDLER_HPP_
+#define _OUSIA_XML_XML_ATTRIBUTE_HANDLER_HPP_
+
+#include <functional>
+#include <string>
+
+namespace ousia {
+namespace xml {
+
+/**
+ * The attribute handler class is responsible for handling attributes. It
+ * performs type checks and conversion. Note that the name of the attribute is
+ * not stored inside the handler, as the attribute handlers are meant to be used
+ * alongside a map.
+ */
+class XmlAttributeHandler {
+
+private:
+ /**
+ * Specifies whether this attribute was actually handled (set to true once
+ * the setter is called).
+ */
+ bool handled;
+
+ /**
+ * Specifies whether this attribute is required or not.
+ */
+ bool required;
+
+ /**
+ * Function which returns true if the given string is a valid entry for the
+ * type the attribute handler represents.
+ */
+ std::function<bool(const std::string&)> valid;
+
+ /**
+ * Function which gets the attribute value and sets the type.
+ */
+ std::function<void(const std::string&)> setter;
+
+ /**
+ * Default value (as string) that should be used if no other value for that
+ * attribute is given.
+ */
+ const char *defaultValue;
+
+public:
+
+ /**
+ * Constructor of the XmlAttributeHandler class.
+ *
+ * @param required if true, the attribute is marked as "required" and it
+ * must occur in the xml.
+ * @param valid is a function reference which specifies whether the given
+ * string is valid.
+ * @param setter is the function that is meant to actually set the value
+ * of the attached class.
+ * @param defaultValue if given (it does not equal the nullptr), the setter
+ * is automatically called with the default value, unless the attribute is
+ * actually specified in the XML.
+ */
+ XmlAttributeHandler(bool required,
+ const std::function<bool(const std::string&)> &valid,
+ const std::function<void(const std::string&)> &setter,
+ const char *defaultValue = nullptr) :
+ handled(false), required(required), valid(valid), setter(setter),
+ defaultValue(defaultValue)
+ {
+ // Do nothing here
+ }
+
+ /**
+ * Returns true if the given value for this attribute is valid.
+ */
+ bool isValid(const std::string &value)
+ {
+ return valid(value);
+ }
+
+ /**
+ * Calls the setter with the given value. The value should have been checked
+ * for validity first.
+ */
+ void executeSettter(const std::string &value)
+ {
+ handled = true;
+ setter(value);
+ }
+
+ /**
+ * Returns true if this element is required.
+ */
+ bool isRequired()
+ {
+ return required;
+ }
+
+ /**
+ * Returns the default value.
+ */
+ const char* getDefaultValue()
+ {
+ return defaultValue;
+ }
+
+ /**
+ * Returns true if the attribute was handled.
+ */
+ bool isHandled()
+ {
+ return handled;
+ }
+
+};
+
+}
+}
+
+#endif /* _OUSIA_XML_XML_ATTRIBUTE_HANDLER_HPP_ */
+
diff --git a/src/xml/XmlReader.cpp b/src/xml/XmlReader.cpp
index c7de564..95f326c 100644
--- a/src/xml/XmlReader.cpp
+++ b/src/xml/XmlReader.cpp
@@ -18,9 +18,11 @@
#include <QXmlStreamReader>
-#include <sstream>
+#include <functional>
#include <iostream>
+#include <sstream>
+#include "XmlAttributeHandler.hpp"
#include "XmlElementHandler.hpp"
#include "XmlReader.hpp"
@@ -72,6 +74,51 @@ bool XmlReader::expectOneOf(std::vector<XmlElementHandler> &handlers)
return false;
}
+bool XmlReader::parseArguments(std::map<std::string, XmlAttributeHandler> &handlers)
+{
+ // Iterate the attributes of the current xml node
+ for (auto &attr : xml.attributes()) {
+ // Convert the name to a std string
+ const std::string name = attr.name().toString().toStdString();
+ const std::string value = attr.value().toString().toStdString();
+
+ // Try to fetch a corresponding attribute in the handlers map
+ auto it = handlers.find(name);
+ if (it != handlers.end()) {
+ XmlAttributeHandler &handler = (*it).second;
+ if (handler.isValid(value)) {
+ handler.executeSettter(value);
+ } else {
+ std::cout << "Invalid attribute value \"" << value
+ << "\" for attribute " << name << std::endl;
+ return false;
+ }
+ } else {
+ std::cout << "Unexpected attribute " << name << std::endl;
+ return false;
+ }
+ }
+
+ // Iterate over all handlers to check whether all required handlers have
+ // been handled and in order to pass the default value to unhandled handlers
+ for (auto &it : handlers) {
+ // Fetch the name of the attribute and the handler
+ const std::string &name = it.first;
+ XmlAttributeHandler &handler = it.second;
+ if (!handler.isHandled()) {
+ if (handler.isRequired()) {
+ std::cout << "Attribute " << name
+ << " is required but was not set!" << std::endl;
+ return false;
+ } else if (handler.getDefaultValue()) {
+ handler.executeSettter(handler.getDefaultValue());
+ }
+ }
+ }
+
+ return true;
+}
+
std::shared_ptr<model::GraphNode> XmlReader::process()
{
std::shared_ptr<model::GraphNode> res{nullptr};
diff --git a/src/xml/XmlReader.hpp b/src/xml/XmlReader.hpp
index d8f30a7..f9b949b 100644
--- a/src/xml/XmlReader.hpp
+++ b/src/xml/XmlReader.hpp
@@ -19,8 +19,9 @@
#ifndef _OUSIA_XML_XML_READER_HPP_
#define _OUSIA_XML_XML_READER_HPP_
-#include <functional>
+#include <map>
#include <memory>
+#include <string>
#include <vector>
#include <model/GraphNode.hpp>
@@ -32,6 +33,7 @@ namespace ousia {
namespace xml {
class XmlElementHandler;
+class XmlAttributeHandler;
/**
* The XmlReader class is responsible for parsing the ousia XML documents and
@@ -52,10 +54,17 @@ private:
std::shared_ptr<model::domain::Domain> readDomain();
/**
- * Used internally in order to conveniently expect one of a set of elements.
+ * Used internally in order to conveniently expect one xml tag in a set of
+ * elements. Returns true if there was an error while waiting for the tag,
+ * false otherwise.
*/
bool expectOneOf(std::vector<XmlElementHandler> &handlers);
+ /**
+ * Used internally to parse the current argument map.
+ */
+ bool parseArguments(std::map<std::string, XmlAttributeHandler> &handlers);
+
public:
/**