diff options
| -rw-r--r-- | src/xml/XmlAttributeHandler.hpp | 138 | ||||
| -rw-r--r-- | src/xml/XmlReader.cpp | 49 | ||||
| -rw-r--r-- | src/xml/XmlReader.hpp | 13 | 
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:  	/**  | 
