Akonadi

xmlwritejob.cpp
1/*
2 SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "xmlwritejob.h"
8#include "xmldocument.h"
9#include "xmlwriter.h"
10
11#include "collectionfetchjob.h"
12#include "item.h"
13#include "itemfetchjob.h"
14#include "itemfetchscope.h"
15
16#include <QDebug>
17
18#include <QDomElement>
19#include <QStack>
20
21using namespace Akonadi;
22
23namespace Akonadi
24{
25class XmlWriteJobPrivate
26{
27public:
28 explicit XmlWriteJobPrivate(XmlWriteJob *parent)
29 : q(parent)
30 {
31 }
32
33 XmlWriteJob *const q;
34 Collection::List roots;
35 QStack<Collection::List> pendingSiblings;
36 QStack<QDomElement> elementStack;
37 QString fileName;
38 XmlDocument document;
39
40 void collectionFetchResult(KJob *job);
41 void processCollection();
42 void itemFetchResult(KJob *job);
43 void processItems();
44};
45
46} // namespace Akonadi
47
48void XmlWriteJobPrivate::collectionFetchResult(KJob *job)
49{
50 if (job->error()) {
51 return;
52 }
53 auto fetch = qobject_cast<CollectionFetchJob *>(job);
54 Q_ASSERT(fetch);
55 if (fetch->collections().isEmpty()) {
56 processItems();
57 } else {
58 pendingSiblings.push(fetch->collections());
59 processCollection();
60 }
61}
62
63void XmlWriteJobPrivate::processCollection()
64{
65 if (!pendingSiblings.isEmpty() && pendingSiblings.top().isEmpty()) {
66 pendingSiblings.pop();
67 if (pendingSiblings.isEmpty()) {
68 q->done();
69 return;
70 }
71 processItems();
72 return;
73 }
74
75 if (pendingSiblings.isEmpty()) {
76 q->done();
77 return;
78 }
79
80 const Collection current = pendingSiblings.top().first();
81 qDebug() << "Writing " << current.name() << "into" << elementStack.top().attribute(QStringLiteral("name"));
82 elementStack.push(XmlWriter::writeCollection(current, elementStack.top()));
83 auto subfetch = new CollectionFetchJob(current, CollectionFetchJob::FirstLevel, q);
84 q->connect(subfetch, &CollectionFetchJob::result, q, [this](KJob *job) {
85 collectionFetchResult(job);
86 });
87}
88
89void XmlWriteJobPrivate::processItems()
90{
91 const Collection collection = pendingSiblings.top().first();
92 auto fetch = new ItemFetchJob(collection, q);
93 fetch->fetchScope().fetchAllAttributes();
94 fetch->fetchScope().fetchFullPayload();
95 q->connect(fetch, &ItemFetchJob::result, q, [this](KJob *job) {
96 itemFetchResult(job);
97 });
98}
99
100void XmlWriteJobPrivate::itemFetchResult(KJob *job)
101{
102 if (job->error()) {
103 return;
104 }
105 auto fetch = qobject_cast<ItemFetchJob *>(job);
106 Q_ASSERT(fetch);
107 const Akonadi::Item::List lstItems = fetch->items();
108 for (const Item &item : lstItems) {
109 XmlWriter::writeItem(item, elementStack.top());
110 }
111 pendingSiblings.top().removeFirst();
112 elementStack.pop();
113 processCollection();
114}
115
116XmlWriteJob::XmlWriteJob(const Collection &root, const QString &fileName, QObject *parent)
117 : Job(parent)
118 , d(new XmlWriteJobPrivate(this))
119{
120 d->roots.append(root);
121 d->fileName = fileName;
122}
123
124XmlWriteJob::XmlWriteJob(const Collection::List &roots, const QString &fileName, QObject *parent)
125 : Job(parent)
126 , d(new XmlWriteJobPrivate(this))
127{
128 d->roots = roots;
129 d->fileName = fileName;
130}
131
132XmlWriteJob::~XmlWriteJob() = default;
133
135{
136 d->elementStack.push(d->document.document().documentElement());
137 auto job = new CollectionFetchJob(d->roots, this);
138 connect(job, &CollectionFetchJob::result, this, [this](KJob *job) {
139 d->collectionFetchResult(job);
140 });
141}
142
143void XmlWriteJob::done() // cannot be in the private class due to emitResult()
144{
145 if (!d->document.writeToFile(d->fileName)) {
147 setErrorText(d->document.lastError());
148 }
149 emitResult();
150}
151
152#include "moc_xmlwritejob.cpp"
Job that fetches collections from the Akonadi storage.
@ FirstLevel
Only list direct sub-collections of the base collection.
Represents a collection of PIM items.
Definition collection.h:62
Job that fetches items from the Akonadi storage.
Base class for all actions in the Akonadi storage.
Definition job.h:81
@ Unknown
Unknown error.
Definition job.h:102
Represents a document of the KNUT XML serialization format for Akonadi objects.
Definition xmldocument.h:27
Serializes a given Akonadi collection into a XML file.
Definition xmlwritejob.h:25
void doStart() override
This method must be reimplemented in the concrete jobs.
void setErrorText(const QString &errorText)
void emitResult()
int error() const
void result(KJob *job)
void setError(int errorCode)
AKONADI_XML_EXPORT QDomElement writeItem(const Item &item, QDomElement &parentElem)
Serializes the given item into a DOM element and attaches it to the given item.
AKONADI_XML_EXPORT QDomElement writeCollection(const Collection &collection, QDomElement &parentElem)
Serializes the given collection into a DOM element with the given parent.
Definition xmlwriter.cpp:70
Helper integration between Akonadi and Qt.
QString attribute(const QString &name, const QString &defValue) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void push(const T &t)
T & top()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:38 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.