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
const char * constData() const const
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
QStringView left(qsizetype length) const const
QStringView mid(qsizetype start, qsizetype length) const const
const_pointer constData() const const
qsizetype indexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
qsizetype size() const const
QByteArray toUtf8() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 4 2024 16:28:48 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.