KItinerary

extractordocumentprocessor.cpp
1 /*
2  SPDX-FileCopyrightText: 2021 Volker Krause <[email protected]>
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 
16 using namespace KItinerary;
17 
18 ExtractorDocumentProcessor::~ExtractorDocumentProcessor() = default;
19 
20 bool 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 
37 void 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  }
46 }
47 
48 void ExtractorDocumentProcessor::preExtract([[maybe_unused]] ExtractorDocumentNode &node, [[maybe_unused]] const ExtractorEngine *engine) const
49 {
50 }
51 
53 {
54  // QObject content
55  if (node.content().canConvert<QObject*>()) {
56  const auto obj = node.content().value<QObject*>();
57  if (!obj) {
58  return false;
59  }
60  const auto value = obj->property(filter.fieldName().toUtf8().constData());
61  return filter.matches(value.toString());
62  }
63 
64  // Q_GADGET content
65  const auto mo = QMetaType(node.content().userType()).metaObject();
66  return matchesGadget(filter, mo, node.content().constData());
67 }
68 
69 static bool matchesGadgetInternal(const ExtractorFilter &filter, QStringView propName, const QMetaObject *mo, const void *obj)
70 {
71  if (!mo) {
72  return false;
73  }
74 
75  const auto propNameIdx = propName.indexOf(QLatin1Char('.'));
76  if (propNameIdx == 0 || propName.isEmpty()) {
77  qCWarning(Log) << "invalid gadget property name:" << propName << filter.fieldName();
78  return false;
79  }
80 
81  const auto propIdx = mo->indexOfProperty(propName.left(propNameIdx < 0 ? propName.size() : propNameIdx).toUtf8().constData());
82  if (propIdx < 0) {
83  return false;
84  }
85  const auto prop = mo->property(propIdx);
86  const auto value = prop.readOnGadget(obj);
87 
88  if (propNameIdx > 0) { // recursive matching
89  const auto mo = QMetaType(value.userType()).metaObject();
90  return matchesGadgetInternal(filter, propName.mid(propNameIdx + 1), mo, value.constData());
91  }
92  return filter.matches(value.toString());
93 }
94 
95 bool ExtractorDocumentProcessor::matchesGadget(const ExtractorFilter &filter, const QMetaObject *mo, const void *obj)
96 {
97  return matchesGadgetInternal(filter, filter.fieldName(), mo, obj);
98 }
99 
101 {
102 }
103 
105 {
106  return engine->toScriptValue(node.content());
107 }
108 
110 {
111 }
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 void postExtract(ExtractorDocumentNode &node) const
Called after extractors have been applied to node.
A node in the extracted document object tree.
Determines whether an extractor is applicable to a given email.
QVariant readOnGadget(const void *gadget) const const
const QMetaObject * metaObject() const const
QStringView mid(qsizetype start) const const
QStringView left(qsizetype length) const const
virtual void reduceNode(ExtractorDocumentNode &node) const
Propagate results from child nodes up to node.
QByteArray toUtf8() const const
virtual ExtractorDocumentNode createNodeFromContent(const QVariant &decodedData) const
Create a document node from an already decoded data type.
qsizetype size() const const
QVariantList childNodes
Child nodes, for QJSEngine access.
virtual bool canHandleData(const QByteArray &encodedData, QStringView fileName) const
Fast check whether the given encoded data can possibly be processed by this instance.
void addResult(ExtractorResult &&result)
Add additional results from an extraction step.
virtual bool matches(const ExtractorFilter &filter, const ExtractorDocumentNode &node) const
Checks whether the given filter matches node.
virtual void destroyNode(ExtractorDocumentNode &node) const
Destroys type-specific data in node.
virtual QJSValue contentToScriptValue(const ExtractorDocumentNode &node, QJSEngine *engine) const
Create a QJSValue for the node content.
virtual void preExtract(ExtractorDocumentNode &node, const ExtractorEngine *engine) const
Called before extractors are applied to node.
virtual ExtractorDocumentNode createNodeFromData(const QByteArray &encodedData) const
Create a document node from raw data.
bool isEmpty() const const
QMetaProperty property(int index) const const
const char * constData() const const
Semantic data extraction engine.
QJSValue content
The decoded content of this node.
void setContent(const QVariant &content)
Set decoded content.
qsizetype indexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs) const const
int indexOfProperty(const char *name) const const
QJSValue toScriptValue(const T &value)
QVariant property(const char *name) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Mon Jun 27 2022 04:16:14 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.