Commit 76fd9a3d authored by Volker Krause's avatar Volker Krause
Browse files

Implement matching ExtractorFilter against the new document nodes

This is more explicit than the old method, taking the filter scope into
account, and no longer contains type-specific code.
parent 7287f0ac
Pipeline #54990 passed with stages
in 11 minutes and 47 seconds
......@@ -24,6 +24,7 @@ set(kitinerary_lib_srcs
engine/abstractextractor.cpp
engine/extractordocumentnode.cpp
engine/extractordocumentprocessor.cpp
engine/extractorfilter.cpp
engine/extractorresult.cpp
era/ssbticket.cpp
......@@ -85,7 +86,6 @@ set(kitinerary_lib_srcs
extractor.cpp
extractorcapabilities.cpp
extractorengine.cpp
extractorfilter.cpp
extractorinput.cpp
extractorpostprocessor.cpp
extractorrepository.cpp
......@@ -167,7 +167,6 @@ ecm_generate_headers(KItinerary_FORWARDING_HEADERS
Extractor
ExtractorCapabilities
ExtractorEngine
ExtractorFilter
ExtractorInput
ExtractorPostprocessor
ExtractorRepository
......@@ -217,6 +216,7 @@ ecm_generate_headers(KItinerary_Engine_FORWARDING_HEADERS
HEADER_NAMES
AbstractExtractor
ExtractorDocumentNode
ExtractorFilter
ExtractorResult
PREFIX KItinerary
REQUIRED_HEADERS KItinerary_Engine_HEADERS
......@@ -257,6 +257,7 @@ install(FILES
${KItinerary_FORWARDING_HEADERS}
${KItinerary_KnowledgeDb_FORWARDING_HEADERS}
${KItinerary_Datatypes_FORWARDING_HEADERS}
${KItinerary_Engine_FORWARDING_HEADERS}
${KItinerary_Pdf_FORWARDING_HEADERS}
${KItinerary_Uic9183_FORWARDING_HEADERS}
${KItinerary_Vdv_FORWARDING_HEADERS}
......@@ -267,6 +268,7 @@ install(FILES
${KItinerary_AirportDb_HEADERS}
${KItinerary_Datatypes_HEADERS}
${KItinerary_KnowledgeDb_HEADERS}
${KItinerary_Engine_HEADERS}
${KItinerary_Pdf_HEADERS}
${KItinerary_Uic9183_HEADERS}
${KItinerary_Vdv_HEADERS}
......
......@@ -5,6 +5,9 @@
*/
#include "extractorfilter.h"
#include "extractordocumentnode.h"
#include "extractordocumentprocessor.h"
#include "extractorresult.h"
#include "logging.h"
#include <QJsonObject>
......@@ -142,3 +145,72 @@ void ExtractorFilter::setScope(Scope scope)
d.detach();
d->m_scope = scope;
}
static QString valueForJsonPath(const QJsonObject &obj, const QString &path)
{
const auto pathSections = path.splitRef(QLatin1Char('.'));
QJsonValue v(obj);
for (const auto &pathSection : pathSections) {
if (!v.isObject()) {
return {};
}
v = v.toObject().value(pathSection.toString());
}
return v.toString();
}
static ExtractorDocumentNode filterMachesNode(const ExtractorFilter &filter, ExtractorFilter::Scope scope, const ExtractorDocumentNode &node)
{
if (node.isNull()) {
return {};
}
if (filter.mimeType() == node.mimeType() && node.processor()->matches(filter, node)) {
return node;
}
if (scope != ExtractorFilter::Ancestors && filter.mimeType() == QLatin1String("application/ld+json") && !node.result().isEmpty()) {
const auto res = node.result().jsonLdResult();
for (const auto &elem : res) {
const auto property = valueForJsonPath(elem.toObject(), filter.fieldName());
if (filter.matches(property)) {
return node;
}
}
}
if (scope == ExtractorFilter::Ancestors) {
return filterMachesNode(filter, scope, node.parent());
}
if (scope == ExtractorFilter::Descendants) {
for (const auto &child : node.childNodes()) {
const auto m = filterMachesNode(filter, ExtractorFilter::Descendants, child);
if (!m.isNull()) {
return m;
}
}
}
return {};
}
ExtractorDocumentNode ExtractorFilter::matches(const ExtractorDocumentNode &node) const
{
switch (d->m_scope) {
case ExtractorFilter::Current:
return filterMachesNode(*this, ExtractorFilter::Current, node);
case ExtractorFilter::Parent:
return filterMachesNode(*this, ExtractorFilter::Current, node.parent());
case ExtractorFilter::Ancestors:
return filterMachesNode(*this, ExtractorFilter::Ancestors, node.parent());
case ExtractorFilter::Children:
case ExtractorFilter::Descendants:
for (const auto &child : node.childNodes()) {
const auto m = filterMachesNode(*this, d->m_scope == ExtractorFilter::Descendants ? d->m_scope : ExtractorFilter::Current, child);
if (!m.isNull()) {
return m;
}
}
}
return {};
}
......@@ -18,6 +18,7 @@ class QJsonObject;
namespace KItinerary {
class ExtractorDocumentNode;
class ExtractorFilterPrivate;
/** Determines whether an extractor is applicable to a given email. */
......@@ -55,6 +56,12 @@ public:
/** Evaluation scope of this filter, in relation to the node being extracted. */
Scope scope() const;
/** Checks whether this filter applies to @p node.
* @returns An invalid node if the filter doesn't match, or the node that ended up matching the filter.
* This can differ from @p node depending on scope().
*/
ExtractorDocumentNode matches(const ExtractorDocumentNode &node) const;
///@cond internal
/** Load filter from @p obj. */
bool load(const QJsonObject &obj);
......
......@@ -5,7 +5,7 @@
*/
#include "extractor.h"
#include "extractorfilter.h"
#include <KItinerary/ExtractorFilter>
#include "logging.h"
#include <QFile>
......
......@@ -7,7 +7,7 @@
#include "config-kitinerary.h"
#include "extractorrepository.h"
#include "extractor.h"
#include "extractorfilter.h"
#include <KItinerary/ExtractorFilter>
#include "logging.h"
#ifdef HAVE_KCAL
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment