diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2021-09-06 14:17:01 +0900 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2021-09-10 12:50:22 +0200 |
commit | d41643593ad4c9557704ee629ef05ee0c0aecede (patch) | |
tree | b46d041908428620c51f148942d5c1800530d428 /sw/source | |
parent | 591dc3147a8e6d8a76392258d7b6dfca01dfd801 (diff) |
indexing: support JSON and XML as input for SearchResultLocator
JSON is much easier to deal with when using REST and javascript,
so support both.
Change-Id: I61035452d9a7ba889ac355a42201d79b9fafec6f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121742
Tested-by: Tomaž Vajngerl <quikee@gmail.com>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
(cherry picked from commit eac288d02cafc49c5a14fa27bb449c33eb4b1803)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121815
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Diffstat (limited to 'sw/source')
-rw-r--r-- | sw/source/core/inc/SearchResultLocator.hxx | 15 | ||||
-rw-r--r-- | sw/source/core/model/SearchResultLocator.cxx | 98 |
2 files changed, 79 insertions, 34 deletions
diff --git a/sw/source/core/inc/SearchResultLocator.hxx b/sw/source/core/inc/SearchResultLocator.hxx index 7dac632ae58f..fb46c85253eb 100644 --- a/sw/source/core/inc/SearchResultLocator.hxx +++ b/sw/source/core/inc/SearchResultLocator.hxx @@ -18,20 +18,20 @@ namespace sw::search { enum class NodeType { - Undefined, - WriterNode, - SdrObject + Undefined = 0, + WriterNode = 1, + SdrObject = 2 }; struct SearchIndexData { NodeType meType = NodeType::Undefined; - sal_uInt32 mnNodeIndex = 0; + sal_Int32 mnNodeIndex = 0; OUString maObjectName; SearchIndexData() {} - SearchIndexData(NodeType eType, sal_uInt32 nNodeIndex, OUString const& aObjectName = OUString()) + SearchIndexData(NodeType eType, sal_Int32 nNodeIndex, OUString const& aObjectName = OUString()) : meType(eType) , mnNodeIndex(nNodeIndex) , maObjectName(aObjectName) @@ -50,6 +50,10 @@ class SW_DLLPUBLIC SearchResultLocator SwDoc* mpDocument; void findOne(LocationResult& rResult, SearchIndexData const& rSearchIndexData); + static bool tryParseJSON(const char* pPayload, + std::vector<sw::search::SearchIndexData>& rDataVector); + static bool tryParseXML(const char* pPayload, + std::vector<sw::search::SearchIndexData>& rDataVector); public: SearchResultLocator(SwDoc* pDoc) @@ -58,7 +62,6 @@ public: } LocationResult find(std::vector<SearchIndexData> const& rSearchIndexDataVector); - LocationResult findForPayload(const char* pPayload); }; diff --git a/sw/source/core/model/SearchResultLocator.cxx b/sw/source/core/model/SearchResultLocator.cxx index d08e7835f7ee..25819c3bc6fe 100644 --- a/sw/source/core/model/SearchResultLocator.cxx +++ b/sw/source/core/model/SearchResultLocator.cxx @@ -21,6 +21,8 @@ #include <tools/XmlWalker.hxx> #include <tools/stream.hxx> +#include <boost/property_tree/json_parser.hpp> + #include <svx/svdpage.hxx> #include <svx/svdobj.hxx> @@ -31,7 +33,7 @@ void SearchResultLocator::findOne(LocationResult& rResult, SearchIndexData const if (rSearchIndexData.meType == NodeType::WriterNode) { SwNodes const& rNodes = mpDocument->GetNodes(); - if (rSearchIndexData.mnNodeIndex >= rNodes.Count()) + if (rSearchIndexData.mnNodeIndex >= sal_Int32(rNodes.Count())) return; SwNode* pNode = rNodes[rSearchIndexData.mnNodeIndex]; @@ -90,51 +92,91 @@ LocationResult SearchResultLocator::find(std::vector<SearchIndexData> const& rSe return aResult; } -LocationResult SearchResultLocator::findForPayload(const char* pPayload) +/** Trying to parse the payload as JSON + * + * Returns true if parsing was successful and the payload was identified as JSON, else false + */ +bool SearchResultLocator::tryParseJSON(const char* pPayload, + std::vector<sw::search::SearchIndexData>& rDataVector) { - LocationResult aResult; + boost::property_tree::ptree aTree; + std::stringstream aStream(pPayload); + try + { + boost::property_tree::read_json(aStream, aTree); + } + catch (const boost::property_tree::json_parser_error& /*exception*/) + { + return false; + } + for (auto& rEachNode : boost::make_iterator_range(aTree.equal_range(""))) + { + auto const& rEach = rEachNode.second; + + sal_Int32 nType = rEach.get<sal_Int32>("type", 0); + sal_Int32 nIndex = rEach.get<sal_Int32>("index", -1); + + // Don't add search data elements that don't have valid data + if (nType > 0 && nIndex >= 0) + rDataVector.emplace_back(sw::search::NodeType(nType), nIndex); + } + + return true; +} + +/** Trying to parse the payload as XML + * + * Returns true if parsing was successful and the payload was identified as XML, else false + */ +bool SearchResultLocator::tryParseXML(const char* pPayload, + std::vector<sw::search::SearchIndexData>& rDataVector) +{ const OString aPayloadString(pPayload); SvMemoryStream aStream(const_cast<char*>(aPayloadString.getStr()), aPayloadString.getLength(), StreamMode::READ); + tools::XmlWalker aWalker; if (!aWalker.open(&aStream)) - return aResult; + return false; - if (aWalker.name() == "indexing") + if (aWalker.name() != "indexing") + return true; + + aWalker.children(); + while (aWalker.isValid()) { - std::vector<sw::search::SearchIndexData> aDataVector; - aWalker.children(); - while (aWalker.isValid()) + if (aWalker.name() == "paragraph") { - if (aWalker.name() == "paragraph") - { - OString sType = aWalker.attribute("type"); - OString sIndex = aWalker.attribute("index"); + OString sType = aWalker.attribute("type"); + OString sIndex = aWalker.attribute("index"); - if (!sType.isEmpty() && !sIndex.isEmpty()) - { - sw::search::SearchIndexData aData; - aData.mnNodeIndex = sIndex.toInt32(); - aData.meType = sw::search::NodeType(sType.toInt32()); + if (!sType.isEmpty() && !sIndex.isEmpty()) + { + sw::search::SearchIndexData aData; + aData.mnNodeIndex = sIndex.toInt32(); + aData.meType = sw::search::NodeType(sType.toInt32()); - aDataVector.push_back(aData); - } + rDataVector.push_back(aData); } - aWalker.next(); - } - aWalker.parent(); - - if (!aDataVector.empty()) - { - for (auto const& rSearchIndexData : aDataVector) - findOne(aResult, rSearchIndexData); } + aWalker.next(); } + aWalker.parent(); + return true; +} - return aResult; +LocationResult SearchResultLocator::findForPayload(const char* pPayload) +{ + std::vector<sw::search::SearchIndexData> aDataVector; + + // Try parse the payload as JSON, if not recognised as JSON, try parse + // it as XML + tryParseJSON(pPayload, aDataVector) || tryParseXML(pPayload, aDataVector); + + return find(aDataVector); } } // end sw namespace |