Skip to content
Snippets Groups Projects
Commit a1e223ba authored by Christoph Lehmann's avatar Christoph Lehmann
Browse files

[BL] added config tree builder

parent d3aabd94
No related branches found
No related tags found
No related merge requests found
/**
* \copyright
* Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include <boost/property_tree/xml_parser.hpp>
#include "ConfigTreeUtil.h"
namespace BaseLib
{
ConfigTreeTopLevel::ConfigTreeTopLevel(
const std::string& filepath,
const bool be_ruthless,
ConfigTreeNew::PTree&& ptree)
: _ptree(std::move(ptree))
, _ctree(_ptree, filepath,
be_ruthless ? ConfigTreeNew::onerror : ConfigTreeNew::onwarning)
{
}
ConfigTreeNew const&
ConfigTreeTopLevel::operator*() const
{
return _ctree;
}
ConfigTreeNew const*
ConfigTreeTopLevel::operator->() const
{
return &_ctree;
}
void
ConfigTreeTopLevel::checkAndInvalidate()
{
::BaseLib::checkAndInvalidate(_ctree);
}
ConfigTreeTopLevel
makeConfigTree(const std::string& filepath, const bool be_ruthless,
const std::string& toplevel_tag)
{
ConfigTreeNew::PTree ptree;
// note: Trimming whitespace and ignoring comments is crucial in order
// for our configuration tree implementation to work!
try {
read_xml(filepath, ptree,
boost::property_tree::xml_parser::no_comments |
boost::property_tree::xml_parser::trim_whitespace);
} catch (boost::property_tree::xml_parser_error e) {
ERR("Error while parsing XML file `%s' at line %lu: %s.",
e.filename().c_str(), e.line(), e.message().c_str());
std::abort();
}
DBUG("Project configuration from file \'%s\' read.", filepath.c_str());
if (auto child = std::move(ptree.get_child_optional(toplevel_tag))) {
return ConfigTreeTopLevel(filepath, be_ruthless, std::move(*child));
} else {
ERR("Tag <%s> has not been found in file `%s'.",
toplevel_tag.c_str(), filepath.c_str());
std::abort();
}
}
}
/**
* \copyright
* Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#ifndef BASELIB_CONFIGTREEUTIL
#define BASELIB_CONFIGTREEUTIL
#include "ConfigTreeNew.h"
namespace BaseLib
{
/*! Manages a ConfigTree and the <tt>boost::property_tree</tt> it depends on.
*
* The whole purpose of this class is making the management of said dependency easy.
*/
class ConfigTreeTopLevel final
{
public:
/*! Construct a new instance from the given data.
*
* \param filepath stored for use in error/warning messages
* \param be_ruthless if true, then warnings will raise errors, .i.e. lead to program abortion,
* else warnings will only warn
* \param ptree the underlying ptree of the created ConfigTree
*/
explicit ConfigTreeTopLevel(std::string const& filepath,
bool const be_ruthless,
ConfigTreeNew::PTree&& ptree);
/*! Access the contained ConfigTree.
*
* The non-const version of this method has not been implemented in order to prevent invalidating
* the \c _ctree when it is passed around. In order to check and invalidate \c _ctree use the provided
* member function.
*/
ConfigTreeNew const& operator*() const;
/*! Access the contained ConfigTree.
*
* The non-const version of this method has not been implemented in order to prevent invalidating
* the \c _ctree when it is passed around. In order to check and invalidate \c _ctree use the provided
* member function.
*/
ConfigTreeNew const* operator->() const;
/*! Check if the contained ConfigTree has been processed entirely.
*
* This only checks the top level, as usual with ConfigTree instances.
*
* \post Afterwards the contained ConfigTree instance must not be used anymore!
*/
void checkAndInvalidate();
private:
ConfigTreeNew::PTree const _ptree; //!< <tt>boost::property_tree</tt> that underlies \c _ctree
ConfigTreeNew _ctree; //!< ConfigTree depending on \c _ptree
};
/*! Create a ConfigTree from an XML file.
*
* \param filepath see ConfigTreeTopLevel::ConfigTreeTopLevel()
* \param be_ruthless see ConfigTreeTopLevel::ConfigTreeTopLevel()
* \param toplevel_tag name of the outermost tag in the XML file. The returned ConfigTree is rooted
* one level below that tag.
*
* The parameter \c toplevel_tag is provided for compatibility with our existing configuration
* files whose toplevel tags are written in camel case, which conflicts with the naming rules of
* ConfigTree. Via that parameter the naming rules do not apply to the toplevel tag.
*
* Unfortunately the XML parser shipped with <tt>boost::property_tree</tt> does not fully support
* the XML standard. Additionally there might be encoding issues. From their docs:
*
* > Please note that RapidXML does not understand the encoding specification. If you pass it a
* > character buffer, it assumes the data is already correctly encoded; if you pass it a filename,
* > it will read the file using the character conversion of the locale you give it (or the global
* > locale if you give it none). This means that, in order to parse a UTF-8-encoded XML file into
* > a wptree, you have to supply an alternate locale, either directly or by replacing the global one.
*
* \see http://www.boost.org/doc/libs/1_60_0/doc/html/property_tree/parsers.html
*/
ConfigTreeTopLevel
makeConfigTree(std::string const& filepath, bool const be_ruthless,
std::string const& toplevel_tag);
}
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment