diff --git a/src/App/Metadata.cpp b/src/App/Metadata.cpp index 05c61b35b8..2d900baeb6 100644 --- a/src/App/Metadata.cpp +++ b/src/App/Metadata.cpp @@ -23,15 +23,15 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include +#include +#include +#include #endif #include "Metadata.h" -#include #include +#include #include "App/Application.h" #include "App/Expression.h" @@ -57,37 +57,37 @@ using namespace App; namespace fs = boost::filesystem; XERCES_CPP_NAMESPACE_USE -namespace MetadataInternal { - class XMLErrorHandler : public HandlerBase { - void warning(const SAXParseException& toCatch) override - { - // Don't deal with warnings at all - boost::ignore_unused(toCatch); - } +namespace MetadataInternal +{ +class XMLErrorHandler: public HandlerBase +{ + void warning(const SAXParseException &toCatch) override + { + // Don't deal with warnings at all + boost::ignore_unused(toCatch); + } - void error(const SAXParseException& toCatch) override - { - std::stringstream message; - message << "Error at file \"" << StrX(toCatch.getSystemId()) - << "\", line " << toCatch.getLineNumber() - << ", column " << toCatch.getColumnNumber() + void error(const SAXParseException &toCatch) override + { + std::stringstream message; + message << "Error at file \"" << StrX(toCatch.getSystemId()) << "\", line " + << toCatch.getLineNumber() << ", column " << toCatch.getColumnNumber() << "\n Message: " << StrX(toCatch.getMessage()) << std::endl; - throw Base::XMLBaseException(message.str()); - } + throw Base::XMLBaseException(message.str()); + } - void fatalError(const SAXParseException& toCatch) override - { - std::stringstream message; - message << "Fatal error at file \"" << StrX(toCatch.getSystemId()) - << "\", line " << toCatch.getLineNumber() - << ", column " << toCatch.getColumnNumber() + void fatalError(const SAXParseException &toCatch) override + { + std::stringstream message; + message << "Fatal error at file \"" << StrX(toCatch.getSystemId()) << "\", line " + << toCatch.getLineNumber() << ", column " << toCatch.getColumnNumber() << "\n Message: " << StrX(toCatch.getMessage()) << std::endl; - throw Base::XMLBaseException(message.str()); - } - }; -} + throw Base::XMLBaseException(message.str()); + } +}; +}// namespace MetadataInternal -Metadata::Metadata(const fs::path& metadataFile) +Metadata::Metadata(const fs::path &metadataFile) { // Any exception thrown by the XML code propagates out and prevents object creation XMLPlatformUtils::Initialize(); @@ -99,8 +99,8 @@ Metadata::Metadata(const fs::path& metadataFile) auto errHandler = std::make_unique(); _parser->setErrorHandler(errHandler.get()); -#if defined (FC_OS_WIN32) - _parser->parse(reinterpret_cast(metadataFile.wstring().c_str())); +#if defined(FC_OS_WIN32) + _parser->parse(reinterpret_cast(metadataFile.wstring().c_str())); #else _parser->parse(metadataFile.string().c_str()); #endif @@ -110,264 +110,149 @@ Metadata::Metadata(const fs::path& metadataFile) auto rootTagName = StrXUTF8(_dom->getTagName()).str; if (rootTagName != "package") - throw Base::XMLBaseException("Malformed package.xml document: Root group not found"); + throw Base::XMLBaseException( + "Malformed package.xml document: Root group not found"); auto formatVersion = XMLString::parseInt(_dom->getAttribute(XUTF8Str("format").unicodeForm())); switch (formatVersion) { - case 1: - parseVersion1(_dom); - break; - default: - throw Base::XMLBaseException("package.xml format version is not supported by this version of FreeCAD"); + case 1: parseVersion1(_dom); break; + default: + throw Base::XMLBaseException( + "package.xml format version is not supported by this version of FreeCAD"); } } -Metadata::Metadata() : _dom(nullptr) -{ -} +Metadata::Metadata() : _dom(nullptr) {} -Metadata::Metadata(const DOMNode* domNode, int format) : _dom(nullptr) +Metadata::Metadata(const DOMNode *domNode, int format) : _dom(nullptr) { - auto element = dynamic_cast(domNode); + auto element = dynamic_cast(domNode); if (element) { switch (format) { - case 1: - parseVersion1(element); - break; - default: - throw Base::XMLBaseException("package.xml format version is not supported by this version of FreeCAD"); + case 1: parseVersion1(element); break; + default: + throw Base::XMLBaseException( + "package.xml format version is not supported by this version of FreeCAD"); } } } Metadata::~Metadata() = default; -std::string Metadata::name() const -{ - return _name; -} +std::string Metadata::name() const { return _name; } -Meta::Version Metadata::version() const -{ - return _version; } +Meta::Version Metadata::version() const { return _version; } -std::string App::Metadata::date() const -{ - return _date; -} +std::string App::Metadata::date() const { return _date; } -std::string Metadata::description() const -{ - return _description; -} +std::string Metadata::description() const { return _description; } -std::vector Metadata::maintainer() const -{ - return _maintainer; -} +std::vector Metadata::maintainer() const { return _maintainer; } -std::vector Metadata::license() const -{ - return _license; -} +std::vector Metadata::license() const { return _license; } -std::vector Metadata::url() const -{ - return _url; -} +std::vector Metadata::url() const { return _url; } -std::vector Metadata::author() const -{ - return _author; -} +std::vector Metadata::author() const { return _author; } -std::vector Metadata::depend() const -{ - return _depend; -} +std::vector Metadata::depend() const { return _depend; } -std::vector Metadata::conflict() const -{ - return _conflict; -} +std::vector Metadata::conflict() const { return _conflict; } -std::vector Metadata::replace() const -{ - return _replace; -} +std::vector Metadata::replace() const { return _replace; } -std::vector Metadata::tag() const -{ - return _tag; -} +std::vector Metadata::tag() const { return _tag; } -fs::path Metadata::icon() const -{ - return _icon; -} +fs::path Metadata::icon() const { return _icon; } -std::string Metadata::classname() const -{ - return _classname; -} +std::string Metadata::classname() const { return _classname; } -boost::filesystem::path Metadata::subdirectory() const -{ - return _subdirectory; -} +boost::filesystem::path Metadata::subdirectory() const { return _subdirectory; } -std::vector Metadata::file() const -{ - return _file; -} +std::vector Metadata::file() const { return _file; } -Meta::Version Metadata::freecadmin() const -{ - return _freecadmin; -} +Meta::Version Metadata::freecadmin() const { return _freecadmin; } -Meta::Version Metadata::freecadmax() const -{ - return _freecadmax; } +Meta::Version Metadata::freecadmax() const { return _freecadmax; } -Meta::Version Metadata::pythonmin() const -{ - return _pythonmin; -} +Meta::Version Metadata::pythonmin() const { return _pythonmin; } -std::multimap Metadata::content() const -{ - return _content; -} +std::multimap Metadata::content() const { return _content; } -std::vector Metadata::operator[](const std::string& tag) const +std::vector Metadata::operator[](const std::string &tag) const { std::vector returnValue; auto range = _genericMetadata.equal_range(tag); - for (auto item = range.first; item != range.second; ++item) - returnValue.push_back(item->second); + for (auto item = range.first; item != range.second; ++item) returnValue.push_back(item->second); return returnValue; } -XERCES_CPP_NAMESPACE::DOMElement* Metadata::dom() const -{ - return _dom; -} +XERCES_CPP_NAMESPACE::DOMElement *Metadata::dom() const { return _dom; } -void Metadata::setName(const std::string& name) +void Metadata::setName(const std::string &name) { - std::string invalidCharacters = "/\\?%*:|\"<>"; // Should cover all OSes + std::string invalidCharacters = "/\\?%*:|\"<>";// Should cover all OSes if (_name.find_first_of(invalidCharacters) != std::string::npos) throw Base::RuntimeError("Name cannot contain any of: " + invalidCharacters); _name = name; } -void Metadata::setVersion(const Meta::Version& version) -{ - _version = version; } +void Metadata::setVersion(const Meta::Version &version) { _version = version; } -void App::Metadata::setDate(const std::string &date) -{ - _date = date; -} +void App::Metadata::setDate(const std::string &date) { _date = date; } -void Metadata::setDescription(const std::string& description) -{ - _description = description; -} +void Metadata::setDescription(const std::string &description) { _description = description; } -void Metadata::addMaintainer(const Meta::Contact& maintainer) -{ - _maintainer.push_back(maintainer); -} +void Metadata::addMaintainer(const Meta::Contact &maintainer) { _maintainer.push_back(maintainer); } -void Metadata::addLicense(const Meta::License& license) -{ - _license.push_back(license); -} +void Metadata::addLicense(const Meta::License &license) { _license.push_back(license); } -void Metadata::addUrl(const Meta::Url& url) -{ - _url.push_back(url); -} +void Metadata::addUrl(const Meta::Url &url) { _url.push_back(url); } -void Metadata::addAuthor(const Meta::Contact& author) -{ - _author.push_back(author); -} +void Metadata::addAuthor(const Meta::Contact &author) { _author.push_back(author); } -void Metadata::addDepend(const Meta::Dependency& dep) -{ - _depend.push_back(dep); -} +void Metadata::addDepend(const Meta::Dependency &dep) { _depend.push_back(dep); } -void Metadata::addConflict(const Meta::Dependency& dep) -{ - _conflict.push_back(dep); -} +void Metadata::addConflict(const Meta::Dependency &dep) { _conflict.push_back(dep); } -void Metadata::addReplace(const Meta::Dependency& dep) -{ - _replace.push_back(dep); -} +void Metadata::addReplace(const Meta::Dependency &dep) { _replace.push_back(dep); } -void Metadata::addTag(const std::string& tag) -{ - _tag.push_back(tag); -} +void Metadata::addTag(const std::string &tag) { _tag.push_back(tag); } -void Metadata::setIcon(const fs::path& path) -{ - _icon = path; -} +void Metadata::setIcon(const fs::path &path) { _icon = path; } -void Metadata::setClassname(const std::string& name) -{ - _classname = name; -} +void Metadata::setClassname(const std::string &name) { _classname = name; } -void Metadata::setSubdirectory(const boost::filesystem::path& path) -{ - _subdirectory = path; -} +void Metadata::setSubdirectory(const boost::filesystem::path &path) { _subdirectory = path; } -void Metadata::addFile(const fs::path& path) -{ - _file.push_back(path); -} +void Metadata::addFile(const fs::path &path) { _file.push_back(path); } -void Metadata::addContentItem(const std::string& tag, const Metadata& item) +void Metadata::addContentItem(const std::string &tag, const Metadata &item) { _content.insert(std::make_pair(tag, item)); } -void Metadata::setFreeCADMin(const Meta::Version& version) -{ - _freecadmin = version; -} +void Metadata::setFreeCADMin(const Meta::Version &version) { _freecadmin = version; } -void Metadata::setPythonMin(const Meta::Version &version) -{ - _pythonmin = version; -} +void Metadata::setPythonMin(const Meta::Version &version) { _pythonmin = version; } -void Metadata::setFreeCADMax(const Meta::Version& version) -{ - _freecadmax = version; -} +void Metadata::setFreeCADMax(const Meta::Version &version) { _freecadmax = version; } -void Metadata::addGenericMetadata(const std::string& tag, const Meta::GenericMetadata& genericMetadata) +void Metadata::addGenericMetadata(const std::string &tag, + const Meta::GenericMetadata &genericMetadata) { _genericMetadata.insert(std::make_pair(tag, genericMetadata)); } -void Metadata::removeContentItem(const std::string& tag, const std::string& itemName) +void Metadata::removeContentItem(const std::string &tag, const std::string &itemName) { auto tagRange = _content.equal_range(tag); - auto foundItem = std::find_if(tagRange.first, tagRange.second, [&itemName](const auto& check) -> bool { return itemName == check.second.name(); }); - if (foundItem != tagRange.second) - _content.erase(foundItem); + auto foundItem = + std::find_if(tagRange.first, tagRange.second, [&itemName](const auto &check) -> bool { + return itemName == check.second.name(); + }); + if (foundItem != tagRange.second) _content.erase(foundItem); } void Metadata::removeMaintainer(const Meta::Contact &maintainer) @@ -397,12 +282,10 @@ void Metadata::removeAuthor(const Meta::Contact &author) void Metadata::removeDepend(const Meta::Dependency &dep) { bool found = false; - for (const auto& check : _depend) { - if (dep == check) - found = true; + for (const auto &check : _depend) { + if (dep == check) found = true; } - if (!found) - throw Base::RuntimeError("No match found for dependency to remove"); + if (!found) throw Base::RuntimeError("No match found for dependency to remove"); auto new_end = std::remove(_depend.begin(), _depend.end(), dep); _depend.erase(new_end, _depend.end()); } @@ -432,76 +315,44 @@ void Metadata::removeFile(const boost::filesystem::path &path) } -void Metadata::clearContent() -{ - _content.clear(); -} +void Metadata::clearContent() { _content.clear(); } -void Metadata::clearMaintainer() -{ - _maintainer.clear(); -} +void Metadata::clearMaintainer() { _maintainer.clear(); } -void Metadata::clearLicense() -{ - _license.clear(); -} +void Metadata::clearLicense() { _license.clear(); } -void Metadata::clearUrl() -{ - _url.clear(); -} +void Metadata::clearUrl() { _url.clear(); } -void Metadata::clearAuthor() -{ - _author.clear(); -} +void Metadata::clearAuthor() { _author.clear(); } -void Metadata::clearDepend() -{ - _depend.clear(); -} +void Metadata::clearDepend() { _depend.clear(); } -void Metadata::clearConflict() -{ - _conflict.clear(); -} +void Metadata::clearConflict() { _conflict.clear(); } -void Metadata::clearReplace() -{ - _replace.clear(); -} +void Metadata::clearReplace() { _replace.clear(); } -void Metadata::clearTag() -{ - _tag.clear(); -} +void Metadata::clearTag() { _tag.clear(); } -void Metadata::clearFile() -{ - _file.clear(); -} +void Metadata::clearFile() { _file.clear(); } - -DOMElement* appendSimpleXMLNode(DOMElement* baseNode, const std::string& nodeName, const std::string& nodeContents) +DOMElement *appendSimpleXMLNode(DOMElement *baseNode, const std::string &nodeName, + const std::string &nodeContents) { // For convenience (and brevity of final output) don't create nodes that don't have contents - if (nodeContents.empty()) - return nullptr; + if (nodeContents.empty()) return nullptr; auto doc = baseNode->getOwnerDocument(); - DOMElement* namedElement = doc->createElement(XUTF8Str(nodeName.c_str()).unicodeForm()); + DOMElement *namedElement = doc->createElement(XUTF8Str(nodeName.c_str()).unicodeForm()); baseNode->appendChild(namedElement); - DOMText* namedNode = doc->createTextNode(XUTF8Str(nodeContents.c_str()).unicodeForm()); + DOMText *namedNode = doc->createTextNode(XUTF8Str(nodeContents.c_str()).unicodeForm()); namedElement->appendChild(namedNode); return namedElement; } -void addAttribute(DOMElement* node, const std::string& key, const std::string& value) +void addAttribute(DOMElement *node, const std::string &key, const std::string &value) { - if (value.empty()) - return; + if (value.empty()) return; node->setAttribute(XUTF8Str(key.c_str()).unicodeForm(), XUTF8Str(value.c_str()).unicodeForm()); } @@ -520,23 +371,16 @@ void addAttribute(DOMElement *node, const std::string &key, Meta::DependencyType // available (using C++17) std::string stringified("automatic"); switch (value) { - case Meta::DependencyType::automatic: - stringified = "automatic"; - break; - case Meta::DependencyType::internal: - stringified = "internal"; - break; - case Meta::DependencyType::addon: - stringified = "addon"; - break; - case Meta::DependencyType::python: - stringified = "python"; - break; + case Meta::DependencyType::automatic: stringified = "automatic"; break; + case Meta::DependencyType::internal: stringified = "internal"; break; + case Meta::DependencyType::addon: stringified = "addon"; break; + case Meta::DependencyType::python: stringified = "python"; break; } - node->setAttribute(XUTF8Str(key.c_str()).unicodeForm(), XUTF8Str(stringified.c_str()).unicodeForm()); + node->setAttribute(XUTF8Str(key.c_str()).unicodeForm(), + XUTF8Str(stringified.c_str()).unicodeForm()); } -void addDependencyNode(DOMElement* root, const std::string& name, const Meta::Dependency& depend) +void addDependencyNode(DOMElement *root, const std::string &name, const Meta::Dependency &depend) { auto element = appendSimpleXMLNode(root, name, depend.package); if (element) { @@ -551,20 +395,21 @@ void addDependencyNode(DOMElement* root, const std::string& name, const Meta::De } } -void Metadata::write(const fs::path& file) const +void Metadata::write(const fs::path &file) const { - DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(XUTF8Str("Core LS").unicodeForm()); + DOMImplementation *impl = + DOMImplementationRegistry::getDOMImplementation(XUTF8Str("Core LS").unicodeForm()); - DOMDocument* doc = impl->createDocument(nullptr, XUTF8Str("package").unicodeForm(), nullptr); - DOMElement* root = doc->getDocumentElement(); + DOMDocument *doc = impl->createDocument(nullptr, XUTF8Str("package").unicodeForm(), nullptr); + DOMElement *root = doc->getDocumentElement(); root->setAttribute(XUTF8Str("format").unicodeForm(), XUTF8Str("1").unicodeForm()); root->setAttribute(XUTF8Str("xmlns").unicodeForm(), XUTF8Str("https://wiki.freecad.org/Package_Metadata").unicodeForm()); appendToElement(root); - DOMLSSerializer* theSerializer = ((DOMImplementationLS*)impl)->createLSSerializer(); - DOMConfiguration* config = theSerializer->getDomConfig(); + DOMLSSerializer *theSerializer = ((DOMImplementationLS *)impl)->createLSSerializer(); + DOMConfiguration *config = theSerializer->getDomConfig(); if (config->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true)) config->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true); @@ -576,8 +421,8 @@ void Metadata::write(const fs::path& file) const config->setParameter(XMLUni::fgDOMWRTDiscardDefaultContent, true); try { - XMLFormatTarget* myFormTarget = new LocalFileFormatTarget(file.string().c_str()); - DOMLSOutput* theOutput = ((DOMImplementationLS*)impl)->createLSOutput(); + XMLFormatTarget *myFormTarget = new LocalFileFormatTarget(file.string().c_str()); + DOMLSOutput *theOutput = ((DOMImplementationLS *)impl)->createLSOutput(); theOutput->setByteStream(myFormTarget); theSerializer->write(doc, theOutput); @@ -586,14 +431,14 @@ void Metadata::write(const fs::path& file) const theSerializer->release(); delete myFormTarget; } - catch (const XMLException& toCatch) { - char* message = XMLString::transcode(toCatch.getMessage()); + catch (const XMLException &toCatch) { + char *message = XMLString::transcode(toCatch.getMessage()); std::string what = message; XMLString::release(&message); throw Base::XMLBaseException(what); } - catch (const DOMException& toCatch) { - char* message = XMLString::transcode(toCatch.getMessage()); + catch (const DOMException &toCatch) { + char *message = XMLString::transcode(toCatch.getMessage()); std::string what = message; XMLString::release(&message); throw Base::XMLBaseException(what); @@ -602,21 +447,20 @@ void Metadata::write(const fs::path& file) const doc->release(); } -bool Metadata::satisfies(const Meta::Dependency& dep) +bool Metadata::satisfies(const Meta::Dependency &dep) { - if (dep.package != _name) - return false; + if (dep.package != _name) return false; // The "condition" attribute allows an expression to enable or disable this dependency check: it must contain a valid // FreeCAD Expression. If it evaluates to false, this dependency is bypassed (e.g. this function returns false). if (!dep.condition.empty()) { auto injectedString = dep.condition; std::map replacements; - std::map& config = App::Application::Config(); + std::map &config = App::Application::Config(); replacements.insert(std::make_pair("$BuildVersionMajor", config["BuildVersionMajor"])); replacements.insert(std::make_pair("$BuildVersionMinor", config["BuildVersionMinor"])); replacements.insert(std::make_pair("$BuildRevision", config["BuildRevision"])); - for (const auto& replacement : replacements) { + for (const auto &replacement : replacements) { auto pos = injectedString.find(replacement.first); while (pos != std::string::npos) { injectedString.replace(pos, replacement.first.length(), replacement.second); @@ -625,30 +469,24 @@ bool Metadata::satisfies(const Meta::Dependency& dep) } auto parsedExpression = App::Expression::parse(nullptr, dep.condition); auto result = parsedExpression->eval(); - if (!boost::any_cast (result->getValueAsAny())) - return false; + if (!boost::any_cast(result->getValueAsAny())) return false; } - if (!dep.version_eq.empty()) - return _version == Meta::Version(dep.version_eq); + if (!dep.version_eq.empty()) return _version == Meta::Version(dep.version_eq); // Any of the others might be specified in pairs, so only return the "false" case if (!dep.version_lt.empty()) - if (!(_version < Meta::Version(dep.version_lt))) - return false; + if (!(_version < Meta::Version(dep.version_lt))) return false; if (!dep.version_lte.empty()) - if (!(_version <= Meta::Version(dep.version_lt))) - return false; + if (!(_version <= Meta::Version(dep.version_lt))) return false; if (!dep.version_gt.empty()) - if (!(_version > Meta::Version(dep.version_lt))) - return false; + if (!(_version > Meta::Version(dep.version_lt))) return false; if (!dep.version_gte.empty()) - if (!(_version >= Meta::Version(dep.version_lt))) - return false; + if (!(_version >= Meta::Version(dep.version_lt))) return false; return true; } @@ -657,20 +495,20 @@ bool Metadata::supportsCurrentFreeCAD() const { static auto fcVersion = Meta::Version(); if (fcVersion == Meta::Version()) { - std::map& config = App::Application::Config(); + std::map &config = App::Application::Config(); std::stringstream ss; - ss << config["BuildVersionMajor"] << "." << config["BuildVersionMinor"] << "." << (config["BuildRevision"].empty() ? "0" : config["BuildRevision"]); + ss << config["BuildVersionMajor"] << "." << config["BuildVersionMinor"] << "." + << (config["BuildRevision"].empty() ? "0" : config["BuildRevision"]); fcVersion = Meta::Version(ss.str()); } - if (_freecadmin != Meta::Version() && _freecadmin > fcVersion) - return false; + if (_freecadmin != Meta::Version() && _freecadmin > fcVersion) return false; else if (_freecadmax != Meta::Version() && _freecadmax < fcVersion) return false; return true; } -void Metadata::appendToElement(DOMElement* root) const +void Metadata::appendToElement(DOMElement *root) const { appendSimpleXMLNode(root, "name", _name); appendSimpleXMLNode(root, "description", _description); @@ -678,41 +516,35 @@ void Metadata::appendToElement(DOMElement* root) const // Only append version if it's not 0.0.0 appendSimpleXMLNode(root, "version", _version.str()); - if (!_date.empty()) - appendSimpleXMLNode(root, "date", _date); + if (!_date.empty()) appendSimpleXMLNode(root, "date", _date); - for (const auto& maintainer : _maintainer) { + for (const auto &maintainer : _maintainer) { auto element = appendSimpleXMLNode(root, "maintainer", maintainer.name); - if (element) - addAttribute(element, "email", maintainer.email); + if (element) addAttribute(element, "email", maintainer.email); } - for (const auto& license : _license) { + for (const auto &license : _license) { auto element = appendSimpleXMLNode(root, "license", license.name); - if (element) - addAttribute(element, "file", license.file.string()); + if (element) addAttribute(element, "file", license.file.string()); } - if (_freecadmin != Meta::Version()) - appendSimpleXMLNode(root, "freecadmin", _freecadmin.str()); + if (_freecadmin != Meta::Version()) appendSimpleXMLNode(root, "freecadmin", _freecadmin.str()); - if (_freecadmax != Meta::Version()) - appendSimpleXMLNode(root, "freecadmax", _freecadmax.str()); + if (_freecadmax != Meta::Version()) appendSimpleXMLNode(root, "freecadmax", _freecadmax.str()); - if (_pythonmin != Meta::Version()) - appendSimpleXMLNode(root, "pythonmin", _pythonmin.str()); + if (_pythonmin != Meta::Version()) appendSimpleXMLNode(root, "pythonmin", _pythonmin.str()); - for (const auto& url : _url) { + for (const auto &url : _url) { auto element = appendSimpleXMLNode(root, "url", url.location); if (element) { std::string typeAsString("website"); switch (url.type) { - case Meta::UrlType::website: typeAsString = "website"; break; - case Meta::UrlType::repository: typeAsString = "repository"; break; - case Meta::UrlType::bugtracker: typeAsString = "bugtracker"; break; - case Meta::UrlType::readme: typeAsString = "readme"; break; - case Meta::UrlType::documentation: typeAsString = "documentation"; break; - case Meta::UrlType::discussion: typeAsString = "discussion"; break; + case Meta::UrlType::website: typeAsString = "website"; break; + case Meta::UrlType::repository: typeAsString = "repository"; break; + case Meta::UrlType::bugtracker: typeAsString = "bugtracker"; break; + case Meta::UrlType::readme: typeAsString = "readme"; break; + case Meta::UrlType::documentation: typeAsString = "documentation"; break; + case Meta::UrlType::discussion: typeAsString = "discussion"; break; } addAttribute(element, "type", typeAsString); if (url.type == Meta::UrlType::repository) { @@ -721,23 +553,18 @@ void Metadata::appendToElement(DOMElement* root) const } } - for (const auto& author : _author) { + for (const auto &author : _author) { auto element = appendSimpleXMLNode(root, "author", author.name); - if (element) - addAttribute(element, "email", author.email); + if (element) addAttribute(element, "email", author.email); } - for (const auto& depend : _depend) - addDependencyNode(root, "depend", depend); + for (const auto &depend : _depend) addDependencyNode(root, "depend", depend); - for (const auto& conflict : _conflict) - addDependencyNode(root, "conflict", conflict); + for (const auto &conflict : _conflict) addDependencyNode(root, "conflict", conflict); - for (const auto& replace : _replace) - addDependencyNode(root, "replace", replace); + for (const auto &replace : _replace) addDependencyNode(root, "replace", replace); - for (const auto& tag : _tag) - appendSimpleXMLNode(root, "tag", tag); + for (const auto &tag : _tag) appendSimpleXMLNode(root, "tag", tag); appendSimpleXMLNode(root, "icon", _icon.string()); @@ -745,21 +572,21 @@ void Metadata::appendToElement(DOMElement* root) const appendSimpleXMLNode(root, "subdirectory", _subdirectory.string()); - for (const auto& file : _file) - appendSimpleXMLNode(root, "file", file.string()); + for (const auto &file : _file) appendSimpleXMLNode(root, "file", file.string()); - for (const auto& md : _genericMetadata) { + for (const auto &md : _genericMetadata) { auto element = appendSimpleXMLNode(root, md.first, md.second.contents); - for (const auto& attr : md.second.attributes) + for (const auto &attr : md.second.attributes) addAttribute(element, attr.first, attr.second); } if (!_content.empty()) { auto doc = root->getOwnerDocument(); - DOMElement* contentRootElement = doc->createElement(XUTF8Str("content").unicodeForm()); + DOMElement *contentRootElement = doc->createElement(XUTF8Str("content").unicodeForm()); root->appendChild(contentRootElement); - for (const auto& content : _content) { - DOMElement* contentElement = doc->createElement(XUTF8Str(content.first.c_str()).unicodeForm()); + for (const auto &content : _content) { + DOMElement *contentElement = + doc->createElement(XUTF8Str(content.first.c_str()).unicodeForm()); contentRootElement->appendChild(contentElement); content.second.appendToElement(contentElement); } @@ -767,21 +594,19 @@ void Metadata::appendToElement(DOMElement* root) const } -void Metadata::parseVersion1(const DOMNode* startNode) +void Metadata::parseVersion1(const DOMNode *startNode) { auto children = startNode->getChildNodes(); for (XMLSize_t i = 0; i < children->getLength(); ++i) { auto child = children->item(i); - auto element = dynamic_cast(child); - if (!element) - continue; + auto element = dynamic_cast(child); + if (!element) continue; auto tag = element->getNodeName(); auto tagString = StrXUTF8(tag).str; - if (tagString == "name") - _name = StrXUTF8(element->getTextContent()).str; + if (tagString == "name") _name = StrXUTF8(element->getTextContent()).str; else if (tagString == "version") _version = Meta::Version(StrXUTF8(element->getTextContent()).str); else if (tagString == "date") @@ -819,26 +644,25 @@ void Metadata::parseVersion1(const DOMNode* startNode) else if (tagString == "icon") _icon = fs::path(StrXUTF8(element->getTextContent()).str); else if (tagString == "content") - parseContentNodeVersion1(element); // Recursive call + parseContentNodeVersion1(element);// Recursive call else { // If none of this node's children have children of their own, it is a simple element and we // can handle it as a GenericMetadata object auto children = element->getChildNodes(); bool hasGrandchildren = false; for (XMLSize_t i = 0; i < children->getLength() && !hasGrandchildren; ++i) - if (children->item(i)->getChildNodes()->getLength() > 0) - hasGrandchildren = true; + if (children->item(i)->getChildNodes()->getLength() > 0) hasGrandchildren = true; if (!hasGrandchildren) _genericMetadata.insert(std::make_pair(tagString, Meta::GenericMetadata(element))); } } } -void Metadata::parseContentNodeVersion1(const DOMElement* contentNode) +void Metadata::parseContentNodeVersion1(const DOMElement *contentNode) { auto children = contentNode->getChildNodes(); for (XMLSize_t i = 0; i < children->getLength(); ++i) { - auto child = dynamic_cast(children->item(i)); + auto child = dynamic_cast(children->item(i)); if (child) { auto tag = StrXUTF8(child->getTagName()).str; _content.insert(std::make_pair(tag, Metadata(child, 1))); @@ -846,14 +670,12 @@ void Metadata::parseContentNodeVersion1(const DOMElement* contentNode) } } -Meta::Contact::Contact(const std::string& name, const std::string& email) : - name(name), - email(email) +Meta::Contact::Contact(const std::string &name, const std::string &email) : name(name), email(email) { // This has to be provided manually since we have another constructor } -Meta::Contact::Contact(const XERCES_CPP_NAMESPACE::DOMElement* e) +Meta::Contact::Contact(const XERCES_CPP_NAMESPACE::DOMElement *e) { auto emailAttribute = e->getAttribute(XUTF8Str("email").unicodeForm()); name = StrXUTF8(e->getTextContent()).str; @@ -862,46 +684,37 @@ Meta::Contact::Contact(const XERCES_CPP_NAMESPACE::DOMElement* e) bool App::Meta::Contact::operator==(const Contact &rhs) const { - return name==rhs.name && email==rhs.email; + return name == rhs.name && email == rhs.email; } -Meta::License::License(const std::string& name, fs::path file) : - name(name), - file(file) +Meta::License::License(const std::string &name, fs::path file) : name(name), file(file) { // This has to be provided manually since we have another constructor } -Meta::License::License(const XERCES_CPP_NAMESPACE::DOMElement* e) +Meta::License::License(const XERCES_CPP_NAMESPACE::DOMElement *e) { auto fileAttribute = e->getAttribute(XUTF8Str("file").unicodeForm()); - if (XMLString::stringLen(fileAttribute) > 0) { - file = fs::path(StrXUTF8(fileAttribute).str); - } + if (XMLString::stringLen(fileAttribute) > 0) { file = fs::path(StrXUTF8(fileAttribute).str); } name = StrXUTF8(e->getTextContent()).str; } bool App::Meta::License::operator==(const License &rhs) const { - return name==rhs.name && file==rhs.file; + return name == rhs.name && file == rhs.file; } -App::Meta::Url::Url() : location(""), type(App::Meta::UrlType::website) -{ -} +App::Meta::Url::Url() : location(""), type(App::Meta::UrlType::website) {} -Meta::Url::Url(const std::string &location, UrlType type) : - location(location), - type(type) +Meta::Url::Url(const std::string &location, UrlType type) : location(location), type(type) { // This has to be provided manually since we have another constructor } -Meta::Url::Url(const XERCES_CPP_NAMESPACE::DOMElement* e) +Meta::Url::Url(const XERCES_CPP_NAMESPACE::DOMElement *e) { auto typeAttribute = StrXUTF8(e->getAttribute(XUTF8Str("type").unicodeForm())).str; - if (typeAttribute.empty() || typeAttribute == "website") - type = UrlType::website; + if (typeAttribute.empty() || typeAttribute == "website") type = UrlType::website; else if (typeAttribute == "bugtracker") type = UrlType::bugtracker; else if (typeAttribute == "repository") @@ -923,18 +736,17 @@ Meta::Url::Url(const XERCES_CPP_NAMESPACE::DOMElement* e) bool App::Meta::Url::operator==(const Url &rhs) const { - if (type == UrlType::repository && branch != rhs.branch) - return false; - return type==rhs.type && location==rhs.location; + if (type == UrlType::repository && branch != rhs.branch) return false; + return type == rhs.type && location == rhs.location; } -App::Meta::Dependency::Dependency() : optional(false), dependencyType(App::Meta::DependencyType::automatic) -{ -} +App::Meta::Dependency::Dependency() + : optional(false), dependencyType(App::Meta::DependencyType::automatic) +{} -App::Meta::Dependency::Dependency(const std::string &pkg) : package(pkg), optional(false), dependencyType(App::Meta::DependencyType::automatic) -{ -} +App::Meta::Dependency::Dependency(const std::string &pkg) + : package(pkg), optional(false), dependencyType(App::Meta::DependencyType::automatic) +{} Meta::Dependency::Dependency(const XERCES_CPP_NAMESPACE::DOMElement *e) { @@ -945,7 +757,8 @@ Meta::Dependency::Dependency(const XERCES_CPP_NAMESPACE::DOMElement *e) version_gt = StrXUTF8(e->getAttribute(XUTF8Str("version_gt").unicodeForm())).str; condition = StrXUTF8(e->getAttribute(XUTF8Str("condition").unicodeForm())).str; std::string opt_string = StrXUTF8(e->getAttribute(XUTF8Str("optional").unicodeForm())).str; - if (opt_string == "true" || opt_string == "True") // Support Python capitalization in this one case... + if (opt_string == "true" + || opt_string == "True")// Support Python capitalization in this one case... optional = true; else optional = false; @@ -968,36 +781,19 @@ Meta::Dependency::Dependency(const XERCES_CPP_NAMESPACE::DOMElement *e) bool App::Meta::Dependency::operator==(const Dependency &rhs) const { - return package == rhs.package && - version_lt == rhs.version_lt && - version_lte == rhs.version_lte && - version_eq == rhs.version_eq && - version_gte == rhs.version_gte && - version_gt == rhs.version_gt && - condition == rhs.condition && - optional == rhs.optional && - dependencyType == rhs.dependencyType; + return package == rhs.package && version_lt == rhs.version_lt && version_lte == rhs.version_lte + && version_eq == rhs.version_eq && version_gte == rhs.version_gte + && version_gt == rhs.version_gt && condition == rhs.condition && optional == rhs.optional + && dependencyType == rhs.dependencyType; } -Meta::Version::Version() : - major(0), - minor(0), - patch(0) -{ -} +Meta::Version::Version() : major(0), minor(0), patch(0) {} -Meta::Version::Version(int major, int minor, int patch, const std::string& suffix) : - major(major), - minor(minor), - patch(patch), - suffix(suffix) -{ +Meta::Version::Version(int major, int minor, int patch, const std::string &suffix) + : major(major), minor(minor), patch(patch), suffix(suffix) +{} -} - -Meta::Version::Version(const std::string& versionString) : - minor(0), - patch(0) +Meta::Version::Version(const std::string &versionString) : minor(0), patch(0) { std::istringstream stream(versionString); char separator; @@ -1011,54 +807,56 @@ Meta::Version::Version(const std::string& versionString) : std::string Meta::Version::str() const { - if (*this == Meta::Version()) - return ""; + if (*this == Meta::Version()) return ""; std::ostringstream stream; stream << major << "." << minor << "." << patch << suffix; return stream.str(); } -bool Meta::Version::operator<(const Version& rhs) const +bool Meta::Version::operator<(const Version &rhs) const { - return std::tie(major, minor, patch, suffix) < std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); + return std::tie(major, minor, patch, suffix) + < std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); } -bool Meta::Version::operator>(const Version& rhs) const +bool Meta::Version::operator>(const Version &rhs) const { - return std::tie(major, minor, patch, suffix) > std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); + return std::tie(major, minor, patch, suffix) + > std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); } -bool Meta::Version::operator<=(const Version& rhs) const +bool Meta::Version::operator<=(const Version &rhs) const { - return std::tie(major, minor, patch, suffix) <= std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); + return std::tie(major, minor, patch, suffix) + <= std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); } -bool Meta::Version::operator>=(const Version& rhs) const +bool Meta::Version::operator>=(const Version &rhs) const { - return std::tie(major, minor, patch, suffix) >= std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); + return std::tie(major, minor, patch, suffix) + >= std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); } -bool Meta::Version::operator==(const Version& rhs) const +bool Meta::Version::operator==(const Version &rhs) const { - return std::tie(major, minor, patch, suffix) == std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); + return std::tie(major, minor, patch, suffix) + == std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); } -bool Meta::Version::operator!=(const Version& rhs) const +bool Meta::Version::operator!=(const Version &rhs) const { - return std::tie(major, minor, patch, suffix) != std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); + return std::tie(major, minor, patch, suffix) + != std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); } -Meta::GenericMetadata::GenericMetadata(const XERCES_CPP_NAMESPACE::DOMElement* e) +Meta::GenericMetadata::GenericMetadata(const XERCES_CPP_NAMESPACE::DOMElement *e) { contents = StrXUTF8(e->getTextContent()).str; for (XMLSize_t i = 0; i < e->getAttributes()->getLength(); ++i) { auto a = e->getAttributes()->item(i); - attributes.insert(std::make_pair(StrXUTF8(a->getNodeName()).str, - StrXUTF8(a->getTextContent()).str)); + attributes.insert( + std::make_pair(StrXUTF8(a->getNodeName()).str, StrXUTF8(a->getTextContent()).str)); } } -App::Meta::GenericMetadata::GenericMetadata(const std::string& contents) : - contents(contents) -{ -} +App::Meta::GenericMetadata::GenericMetadata(const std::string &contents) : contents(contents) {} diff --git a/src/App/Metadata.h b/src/App/Metadata.h index dc3828b53f..33696ec837 100644 --- a/src/App/Metadata.h +++ b/src/App/Metadata.h @@ -36,119 +36,130 @@ #include -namespace App { +namespace App +{ - namespace Meta { +namespace Meta +{ - /** +/** * \struct Contact * \brief A person or company representing a point of contact for the package (either author or maintainer). */ - struct AppExport Contact { - Contact() = default; - Contact(const std::string& name, const std::string& email); - explicit Contact(const XERCES_CPP_NAMESPACE::DOMElement* e); - std::string name; //< Contact name - required - std::string email; //< Contact email - may be optional - bool operator==(const Contact &rhs) const; - }; +struct AppExport Contact { + Contact() = default; + Contact(const std::string &name, const std::string &email); + explicit Contact(const XERCES_CPP_NAMESPACE::DOMElement *e); + std::string name; //< Contact name - required + std::string email;//< Contact email - may be optional + bool operator==(const Contact &rhs) const; +}; - /** +/** * \struct License * \brief A license that covers some or all of this package. * * Many licenses also require the inclusion of the complete license text, specified in this struct * using the "file" member. */ - struct AppExport License { - License() = default; - License(const std::string& name, boost::filesystem::path file); - explicit License(const XERCES_CPP_NAMESPACE::DOMElement* e); - std::string name; //< Short name of license, e.g. "LGPL2", "MIT", "Mozilla Public License", etc. - boost::filesystem::path file; //< Optional path to the license file, relative to the XML file's location - bool operator==(const License &rhs) const; - }; +struct AppExport License { + License() = default; + License(const std::string &name, boost::filesystem::path file); + explicit License(const XERCES_CPP_NAMESPACE::DOMElement *e); + std::string name;//< Short name of license, e.g. "LGPL2", "MIT", "Mozilla Public License", etc. + boost::filesystem::path + file;//< Optional path to the license file, relative to the XML file's location + bool operator==(const License &rhs) const; +}; - enum class UrlType { - website, - repository, - bugtracker, - readme, - documentation, - discussion - }; +enum class UrlType +{ + website, + repository, + bugtracker, + readme, + documentation, + discussion +}; - /** +/** * \struct Url * \brief A URL, including type information (e.g. website, repository, or bugtracker, in package.xml) */ - struct AppExport Url { - Url(); - Url(const std::string& location, UrlType type); - explicit Url(const XERCES_CPP_NAMESPACE::DOMElement* e); - std::string location; //< The actual URL, including protocol - UrlType type; //< What kind of URL this is - std::string branch; //< If it's a repository, which branch to use - bool operator==(const Url &rhs) const; - }; +struct AppExport Url { + Url(); + Url(const std::string &location, UrlType type); + explicit Url(const XERCES_CPP_NAMESPACE::DOMElement *e); + std::string location;//< The actual URL, including protocol + UrlType type; //< What kind of URL this is + std::string branch; //< If it's a repository, which branch to use + bool operator==(const Url &rhs) const; +}; - /** +/** * \struct Version * A semantic version structure providing comparison operators and conversion to and from std::string */ - struct AppExport Version { - Version(); - explicit Version(int major, int minor = 0, int patch = 0, const std::string& suffix = std::string()); - explicit Version(const std::string& semanticString); +struct AppExport Version { + Version(); + explicit Version(int major, int minor = 0, int patch = 0, + const std::string &suffix = std::string()); + explicit Version(const std::string &semanticString); - int major; - int minor; - int patch; - std::string suffix; + int major; + int minor; + int patch; + std::string suffix; - std::string str() const; + std::string str() const; - bool operator<(const Version&) const; - bool operator>(const Version&) const; - bool operator<=(const Version&) const; - bool operator>=(const Version&) const; - bool operator==(const Version&) const; - bool operator!=(const Version&) const; - }; + bool operator<(const Version &) const; + bool operator>(const Version &) const; + bool operator<=(const Version &) const; + bool operator>=(const Version &) const; + bool operator==(const Version &) const; + bool operator!=(const Version &) const; +}; - /** +/** * \enum DependencyType * The type of dependency. */ - enum class DependencyType - { - automatic, - internal, - addon, - python - }; +enum class DependencyType +{ + automatic, + internal, + addon, + python +}; - /** +/** * \struct Dependency * \brief Another package that this package depends on, conflicts with, or replaces */ - struct AppExport Dependency { - Dependency(); - explicit Dependency(const std::string &pkg); - explicit Dependency(const XERCES_CPP_NAMESPACE::DOMElement* e); - std::string package; //< Required: must exactly match the contents of the "name" element in the referenced package's package.xml file. - std::string version_lt; //< Optional: The dependency to the package is restricted to versions less than the stated version number. - std::string version_lte; //< Optional: The dependency to the package is restricted to versions less or equal than the stated version number. - std::string version_eq; //< Optional: The dependency to the package is restricted to a version equal than the stated version number. - std::string version_gte; //< Optional: The dependency to the package is restricted to versions greater or equal than the stated version number. - std::string version_gt; //< Optional: The dependency to the package is restricted to versions greater than the stated version number. - std::string condition; //< Optional: Conditional expression as documented in REP149. - bool optional;//< Optional: Whether this dependency is considered "optional" - DependencyType dependencyType; //< Optional: defaults to "automatic" - bool operator==(const Dependency &rhs) const; - }; +struct AppExport Dependency { + Dependency(); + explicit Dependency(const std::string &pkg); + explicit Dependency(const XERCES_CPP_NAMESPACE::DOMElement *e); + std::string + package;//< Required: must exactly match the contents of the "name" element in the referenced package's package.xml file. + std::string + version_lt;//< Optional: The dependency to the package is restricted to versions less than the stated version number. + std::string + version_lte;//< Optional: The dependency to the package is restricted to versions less or equal than the stated version number. + std::string + version_eq;//< Optional: The dependency to the package is restricted to a version equal than the stated version number. + std::string + version_gte;//< Optional: The dependency to the package is restricted to versions greater or equal than the stated version number. + std::string + version_gt;//< Optional: The dependency to the package is restricted to versions greater than the stated version number. + std::string condition; //< Optional: Conditional expression as documented in REP149. + bool optional; //< Optional: Whether this dependency is considered "optional" + DependencyType dependencyType;//< Optional: defaults to "automatic" + bool operator==(const Dependency &rhs) const; +}; - /** +/** * \struct GenericMetadata * A structure to hold unrecognized single-level metadata. * @@ -156,17 +167,17 @@ namespace App { * does not recognize, and that tag has no children, it is parsed into this data structure * for convenient access by client code. */ - struct AppExport GenericMetadata { - GenericMetadata() = default; - explicit GenericMetadata(const XERCES_CPP_NAMESPACE::DOMElement* e); - explicit GenericMetadata(const std::string &contents); - std::string contents; //< The contents of the tag - std::map attributes; //< The XML attributes of the tag - }; +struct AppExport GenericMetadata { + GenericMetadata() = default; + explicit GenericMetadata(const XERCES_CPP_NAMESPACE::DOMElement *e); + explicit GenericMetadata(const std::string &contents); + std::string contents; //< The contents of the tag + std::map attributes;//< The XML attributes of the tag +}; - } +}// namespace Meta - /** +/** * \class Metadata * \brief Reads data from a metadata file. * @@ -174,55 +185,66 @@ namespace App { * use. Full format documentation is available at the FreeCAD Wiki: * https://wiki.freecadweb.org/Package_Metadata */ - class AppExport Metadata { - public: +class AppExport Metadata +{ +public: + Metadata(); - Metadata(); - - /** + /** * Read the data from a file on disk * * This constructor takes a path to an XML file and loads the XML from that file as * metadata. */ - explicit Metadata(const boost::filesystem::path& metadataFile); + explicit Metadata(const boost::filesystem::path &metadataFile); - /** + /** * Construct a Metadata object from a DOM node. * * This node may have any tag name: it is only accessed via its children, which are * expected to follow the standard Metadata format for the contents of the element. */ - Metadata(const XERCES_CPP_NAMESPACE::DOMNode* domNode, int format); + Metadata(const XERCES_CPP_NAMESPACE::DOMNode *domNode, int format); - ~Metadata(); + ~Metadata(); - ////////////////////////////////////////////////////////////// - // Recognized Metadata - ////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////// + // Recognized Metadata + ////////////////////////////////////////////////////////////// - std::string name() const; //< A short name for this package, often used as a menu entry. - Meta::Version version() const; //< Version string in symantic triplet format, e.g. "1.2.3". - std::string date() const; //< Date string -- currently arbitrary (when C++20 is well-supported we can revisit) - std::string description() const; //< Text-only description of the package. No markup. - std::vector maintainer() const; //< Must be at least one, and must specify an email address. - std::vector license() const; //< Must be at least one, and most licenses require including a license file. - std::vector url() const; //< Any number of URLs may be specified, but at least one repository URL must be included at the package level. - std::vector author() const; //< Any number of authors may be specified, and email addresses are optional. - std::vector depend() const; //< Zero or more packages this package requires prior to use. - std::vector conflict() const; //< Zero of more packages this package conflicts with. - std::vector replace() const; //< Zero or more packages this package is intended to replace. - std::vector tag() const; //< Zero or more text tags related to this package. - boost::filesystem::path icon() const; //< Path to an icon file. - std::string classname() const; //< Recognized for convenience -- generally only used by Workbenches. - boost::filesystem::path subdirectory() const; //< Optional, override the default subdirectory name for this item. - std::vector file() const; //< Arbitrary files associated with this package or content item. - Meta::Version freecadmin() const; //< The minimum FreeCAD version. - Meta::Version freecadmax() const; //< The maximum FreeCAD version. - Meta::Version pythonmin() const; //< The minimum Python version. + std::string name() const; //< A short name for this package, often used as a menu entry. + Meta::Version version() const;//< Version string in symantic triplet format, e.g. "1.2.3". + std::string date() + const;//< Date string -- currently arbitrary (when C++20 is well-supported we can revisit) + std::string description() const;//< Text-only description of the package. No markup. + std::vector + maintainer() const;//< Must be at least one, and must specify an email address. + std::vector + license() const;//< Must be at least one, and most licenses require including a license file. + std::vector url() + const;//< Any number of URLs may be specified, but at least one repository URL must be included at the package level. + std::vector + author() const;//< Any number of authors may be specified, and email addresses are optional. + std::vector + depend() const;//< Zero or more packages this package requires prior to use. + std::vector + conflict() const;//< Zero of more packages this package conflicts with. + std::vector + replace() const;//< Zero or more packages this package is intended to replace. + std::vector tag() const;//< Zero or more text tags related to this package. + boost::filesystem::path icon() const;//< Path to an icon file. + std::string + classname() const;//< Recognized for convenience -- generally only used by Workbenches. + boost::filesystem::path + subdirectory() const;//< Optional, override the default subdirectory name for this item. + std::vector + file() const;//< Arbitrary files associated with this package or content item. + Meta::Version freecadmin() const;//< The minimum FreeCAD version. + Meta::Version freecadmax() const;//< The maximum FreeCAD version. + Meta::Version pythonmin() const; //< The minimum Python version. - /** + /** * Access the metadata for the content elements of this package * * In addition to the overall package metadata, this class reads in metadata contained in a @@ -238,9 +260,9 @@ namespace App { * * */ - std::multimap content() const; + std::multimap content() const; - /** + /** * Convenience accessor for unrecognized simple metadata. * * If the XML parser encounters tags that it does not recognize, and those tags have @@ -248,113 +270,111 @@ namespace App { * operator[], which returns a (potentially empty) vector containing all instances of the * given tag. It cannot be used to *create* a new tag, however. See addGenericMetadata(). */ - std::vector operator[] (const std::string& tag) const; + std::vector operator[](const std::string &tag) const; - /** + /** * Directly access the DOM tree to support unrecognized multi-level metadata */ - XERCES_CPP_NAMESPACE::DOMElement* dom() const; + XERCES_CPP_NAMESPACE::DOMElement *dom() const; - // Setters - void setName(const std::string& name); - void setVersion(const Meta::Version& version); - void setDate(const std::string &date); - void setDescription(const std::string& description); - void addMaintainer(const Meta::Contact &maintainer); - void addLicense(const Meta::License &license); - void addUrl(const Meta::Url &url); - void addAuthor(const Meta::Contact &author); - void addDepend(const Meta::Dependency &dep); - void addConflict(const Meta::Dependency &dep); - void addReplace(const Meta::Dependency &dep); - void addTag(const std::string &tag); - void setIcon(const boost::filesystem::path& path); - void setClassname(const std::string& name); - void setSubdirectory(const boost::filesystem::path& path); - void addFile(const boost::filesystem::path &path); - void addContentItem(const std::string &tag, const Metadata &item); - void setFreeCADMin(const Meta::Version& version); - void setFreeCADMax(const Meta::Version &version); - void setPythonMin(const Meta::Version &version); - void addGenericMetadata(const std::string &tag, const Meta::GenericMetadata &genericMetadata); + // Setters + void setName(const std::string &name); + void setVersion(const Meta::Version &version); + void setDate(const std::string &date); + void setDescription(const std::string &description); + void addMaintainer(const Meta::Contact &maintainer); + void addLicense(const Meta::License &license); + void addUrl(const Meta::Url &url); + void addAuthor(const Meta::Contact &author); + void addDepend(const Meta::Dependency &dep); + void addConflict(const Meta::Dependency &dep); + void addReplace(const Meta::Dependency &dep); + void addTag(const std::string &tag); + void setIcon(const boost::filesystem::path &path); + void setClassname(const std::string &name); + void setSubdirectory(const boost::filesystem::path &path); + void addFile(const boost::filesystem::path &path); + void addContentItem(const std::string &tag, const Metadata &item); + void setFreeCADMin(const Meta::Version &version); + void setFreeCADMax(const Meta::Version &version); + void setPythonMin(const Meta::Version &version); + void addGenericMetadata(const std::string &tag, const Meta::GenericMetadata &genericMetadata); - // Deleters - void removeContentItem(const std::string &tag, const std::string &itemName); - void removeMaintainer(const Meta::Contact &maintainer); - void removeLicense(const Meta::License &license); - void removeUrl(const Meta::Url &url); - void removeAuthor(const Meta::Contact &author); - void removeDepend(const Meta::Dependency &dep); - void removeConflict(const Meta::Dependency &dep); - void removeReplace(const Meta::Dependency &dep); - void removeTag(const std::string &tag); - void removeFile(const boost::filesystem::path &path); + // Deleters + void removeContentItem(const std::string &tag, const std::string &itemName); + void removeMaintainer(const Meta::Contact &maintainer); + void removeLicense(const Meta::License &license); + void removeUrl(const Meta::Url &url); + void removeAuthor(const Meta::Contact &author); + void removeDepend(const Meta::Dependency &dep); + void removeConflict(const Meta::Dependency &dep); + void removeReplace(const Meta::Dependency &dep); + void removeTag(const std::string &tag); + void removeFile(const boost::filesystem::path &path); - // Utility functions to clear lists - void clearContent(); - void clearMaintainer(); - void clearLicense(); - void clearUrl(); - void clearAuthor(); - void clearDepend(); - void clearConflict(); - void clearReplace(); - void clearTag(); - void clearFile(); + // Utility functions to clear lists + void clearContent(); + void clearMaintainer(); + void clearLicense(); + void clearUrl(); + void clearAuthor(); + void clearDepend(); + void clearConflict(); + void clearReplace(); + void clearTag(); + void clearFile(); - /** + /** * Write the metadata to an XML file */ - void write(const boost::filesystem::path& file) const; + void write(const boost::filesystem::path &file) const; - /** + /** * Determine whether this package satisfies the given dependency */ - bool satisfies(const Meta::Dependency&); + bool satisfies(const Meta::Dependency &); - /** + /** * Determine whether the current metadata specifies support for the currently-running version of FreeCAD. * Does not interrogate content items, which must be querried individually. */ - bool supportsCurrentFreeCAD() const; + bool supportsCurrentFreeCAD() const; - private: +private: + std::string _name; + Meta::Version _version; + std::string _date; + std::string _description; + std::vector _maintainer; + std::vector _license; + std::vector _url; + std::vector _author; + std::vector _depend; + std::vector _conflict; + std::vector _replace; + std::vector _tag; + boost::filesystem::path _icon; + std::string _classname; + boost::filesystem::path _subdirectory; + std::vector _file; + Meta::Version _freecadmin; + Meta::Version _freecadmax; + Meta::Version _pythonmin; - std::string _name; - Meta::Version _version; - std::string _date; - std::string _description; - std::vector _maintainer; - std::vector _license; - std::vector _url; - std::vector _author; - std::vector _depend; - std::vector _conflict; - std::vector _replace; - std::vector _tag; - boost::filesystem::path _icon; - std::string _classname; - boost::filesystem::path _subdirectory; - std::vector _file; - Meta::Version _freecadmin; - Meta::Version _freecadmax; - Meta::Version _pythonmin; + std::multimap _content; - std::multimap _content; + std::multimap _genericMetadata; - std::multimap _genericMetadata; + XERCES_CPP_NAMESPACE::DOMElement *_dom; + std::shared_ptr _parser; - XERCES_CPP_NAMESPACE::DOMElement* _dom; - std::shared_ptr _parser; + void parseVersion1(const XERCES_CPP_NAMESPACE::DOMNode *startNode); + void parseContentNodeVersion1(const XERCES_CPP_NAMESPACE::DOMElement *contentNode); - void parseVersion1(const XERCES_CPP_NAMESPACE::DOMNode* startNode); - void parseContentNodeVersion1(const XERCES_CPP_NAMESPACE::DOMElement* contentNode); + void appendToElement(XERCES_CPP_NAMESPACE::DOMElement *root) const; +}; - void appendToElement(XERCES_CPP_NAMESPACE::DOMElement* root) const; - - }; - -} +}// namespace App #endif