KItinerary

extractordocumentprocessor.cpp
1/*
2 SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "extractordocumentprocessor.h"
8#include "extractorfilter.h"
9#include "extractorresult.h"
10#include "logging.h"
11
12#include <QJSEngine>
13#include <QJSValue>
14#include <QMetaProperty>
15
16using namespace KItinerary;
17
18ExtractorDocumentProcessor::~ExtractorDocumentProcessor() = default;
19
20bool ExtractorDocumentProcessor::canHandleData([[maybe_unused]] const QByteArray &encodedData, [[maybe_unused]] QStringView fileName) const
21{
22 return false;
23}
24
26{
27 return {};
28}
29
31{
33 node.setContent(decodedData);
34 return node;
35}
36
37void ExtractorDocumentProcessor::expandNode([[maybe_unused]] ExtractorDocumentNode &node, [[maybe_unused]] const ExtractorEngine *engine) const
38{
39}
40
42{
43 for (const auto &child : node.childNodes()) {
44 node.addResult(child.result());
45 if (!child.usedExtractor().isEmpty()) {
46 node.setUsedExtractor(child.usedExtractor());
47 }
48 }
49}
50
51void ExtractorDocumentProcessor::preExtract([[maybe_unused]] ExtractorDocumentNode &node, [[maybe_unused]] const ExtractorEngine *engine) const
52{
53}
54
56{
57 // QObject content
58 if (node.content().canConvert<QObject*>()) {
59 const auto obj = node.content().value<QObject*>();
60 if (!obj) {
61 return false;
62 }
63 const auto value = obj->property(filter.fieldName().toUtf8().constData());
64 return filter.matches(value.toString());
65 }
66
67 // Q_GADGET content
68 const auto mo = QMetaType(node.content().userType()).metaObject();
69 return matchesGadget(filter, mo, node.content().constData());
70}
71
72static bool matchesGadgetInternal(const ExtractorFilter &filter, QStringView propName, const QMetaObject *mo, const void *obj)
73{
74 if (!mo) {
75 return false;
76 }
77
78 const auto propNameIdx = propName.indexOf(QLatin1Char('.'));
79 if (propNameIdx == 0 || propName.isEmpty()) {
80 qCWarning(Log) << "invalid gadget property name:" << propName << filter.fieldName();
81 return false;
82 }
83
84 const auto propIdx = mo->indexOfProperty(propName.left(propNameIdx < 0 ? propName.size() : propNameIdx).toUtf8().constData());
85 if (propIdx < 0) {
86 return false;
87 }
88 const auto prop = mo->property(propIdx);
89 const auto value = prop.readOnGadget(obj);
90
91 if (propNameIdx > 0) { // recursive matching
92 const auto mo = QMetaType(value.userType()).metaObject();
93 return matchesGadgetInternal(filter, propName.mid(propNameIdx + 1), mo, value.constData());
94 }
95 return filter.matches(value.toString());
96}
97
98bool ExtractorDocumentProcessor::matchesGadget(const ExtractorFilter &filter, const QMetaObject *mo, const void *obj)
99{
100 return matchesGadgetInternal(filter, filter.fieldName(), mo, obj);
101}
102
103void ExtractorDocumentProcessor::postExtract([[maybe_unused]] ExtractorDocumentNode &node, [[maybe_unused]] const ExtractorEngine *engine) const
104{
105}
106
108{
109 return engine->toScriptValue(node.content());
110}
111
113{
114}
115
116#include "moc_extractordocumentprocessor.cpp"
A node in the extracted document object tree.
QJSValue content
The decoded content of this node.
void addResult(ExtractorResult &&result)
Add additional results from an extraction step.
QVariantList childNodes
Child nodes, for QJSEngine access.
void setContent(const QVariant &content)
Set decoded content.
virtual bool matches(const ExtractorFilter &filter, const ExtractorDocumentNode &node) const
Checks whether the given filter matches node.
virtual bool canHandleData(const QByteArray &encodedData, QStringView fileName) const
Fast check whether the given encoded data can possibly be processed by this instance.
virtual void preExtract(ExtractorDocumentNode &node, const ExtractorEngine *engine) const
Called before extractors are applied to node.
virtual void postExtract(ExtractorDocumentNode &node, const ExtractorEngine *engine) const
Called after extractors have been applied to node.
virtual void expandNode(ExtractorDocumentNode &node, const ExtractorEngine *engine) const
Create child nodes for node, as far as that's necessary for this document type.
virtual QJSValue contentToScriptValue(const ExtractorDocumentNode &node, QJSEngine *engine) const
Create a QJSValue for the node content.
virtual void reduceNode(ExtractorDocumentNode &node) const
Propagate results from child nodes up to node.
virtual ExtractorDocumentNode createNodeFromData(const QByteArray &encodedData) const
Create a document node from raw data.
virtual void destroyNode(ExtractorDocumentNode &node) const
Destroys type-specific data in node.
virtual ExtractorDocumentNode createNodeFromContent(const QVariant &decodedData) const
Create a document node from an already decoded data type.
Semantic data extraction engine.
Determines whether an extractor is applicable to a given email.
Classes for reservation/travel data models, data extraction and data augmentation.
Definition berelement.h:17
QJSValue toScriptValue(const T &value)
int indexOfProperty(const char *name) const const
QMetaProperty property(int index) const const
QVariant readOnGadget(const void *gadget) const const
const QMetaObject * metaObject() const const
QVariant property(const char *name) const const
qsizetype indexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QStringView left(qsizetype length) const const
QStringView mid(qsizetype start) const const
qsizetype size() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sun Feb 25 2024 18:40:32 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.