Akonadi

xmlwritejob.cpp
1 /*
2  Copyright (c) 2009 Volker Krause <[email protected]>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #include "xmlwritejob.h"
21 #include "xmldocument.h"
22 #include "xmlwriter.h"
23 
24 #include "collection.h"
25 #include "collectionfetchjob.h"
26 #include "item.h"
27 #include "itemfetchjob.h"
28 #include "itemfetchscope.h"
29 
30 #include <QDebug>
31 
32 #include <QDomElement>
33 #include <QStack>
34 
35 using namespace Akonadi;
36 
37 namespace Akonadi
38 {
39 
40 class XmlWriteJobPrivate
41 {
42 public:
43  XmlWriteJobPrivate(XmlWriteJob *parent) : q(parent) {}
44 
45  XmlWriteJob *const q;
46  Collection::List roots;
47  QStack<Collection::List> pendingSiblings;
48  QStack<QDomElement> elementStack;
49  QString fileName;
50  XmlDocument document;
51 
52  void collectionFetchResult(KJob *job);
53  void processCollection();
54  void itemFetchResult(KJob *job);
55  void processItems();
56 };
57 
58 }
59 
60 void XmlWriteJobPrivate::collectionFetchResult(KJob *job)
61 {
62  if (job->error()) {
63  return;
64  }
65  CollectionFetchJob *fetch = qobject_cast<CollectionFetchJob *>(job);
66  Q_ASSERT(fetch);
67  if (fetch->collections().isEmpty()) {
68  processItems();
69  } else {
70  pendingSiblings.push(fetch->collections());
71  processCollection();
72  }
73 }
74 
75 void XmlWriteJobPrivate::processCollection()
76 {
77  if (!pendingSiblings.isEmpty() && pendingSiblings.top().isEmpty()) {
78  pendingSiblings.pop();
79  if (pendingSiblings.isEmpty()) {
80  q->done();
81  return;
82  }
83  processItems();
84  return;
85  }
86 
87  if (pendingSiblings.isEmpty()) {
88  q->done();
89  return;
90  }
91 
92  const Collection current = pendingSiblings.top().first();
93  qDebug() << "Writing " << current.name() << "into" << elementStack.top().attribute(QStringLiteral("name"));
94  elementStack.push(XmlWriter::writeCollection(current, elementStack.top()));
96  q->connect(subfetch, &CollectionFetchJob::result, q, [this](KJob *job) {collectionFetchResult(job); });
97 }
98 
99 void XmlWriteJobPrivate::processItems()
100 {
101  const Collection collection = pendingSiblings.top().first();
102  ItemFetchJob *fetch = new ItemFetchJob(collection, q);
103  fetch->fetchScope().fetchAllAttributes();
104  fetch->fetchScope().fetchFullPayload();
105  q->connect(fetch, &ItemFetchJob::result, q, [this](KJob *job) { itemFetchResult(job); } );
106 }
107 
108 void XmlWriteJobPrivate::itemFetchResult(KJob *job)
109 {
110  if (job->error()) {
111  return;
112  }
113  ItemFetchJob *fetch = qobject_cast<ItemFetchJob *>(job);
114  Q_ASSERT(fetch);
115  const Akonadi::Item::List lstItems = fetch->items();
116  for (const Item &item : lstItems) {
117  XmlWriter::writeItem(item, elementStack.top());
118  }
119  pendingSiblings.top().removeFirst();
120  elementStack.pop();
121  processCollection();
122 }
123 
124 XmlWriteJob::XmlWriteJob(const Collection &root, const QString &fileName, QObject *parent) :
125  Job(parent),
126  d(new XmlWriteJobPrivate(this))
127 {
128  d->roots.append(root);
129  d->fileName = fileName;
130 }
131 
132 XmlWriteJob::XmlWriteJob(const Collection::List &roots, const QString &fileName, QObject *parent) :
133  Job(parent),
134  d(new XmlWriteJobPrivate(this))
135 {
136  d->roots = roots;
137  d->fileName = fileName;
138 }
139 
140 XmlWriteJob::~XmlWriteJob()
141 {
142  delete d;
143 }
144 
146 {
147  d->elementStack.push(d->document.document().documentElement());
148  CollectionFetchJob *job = new CollectionFetchJob(d->roots, this);
149  connect(job, &CollectionFetchJob::result, this, [this](KJob *job) {d->collectionFetchResult(job);});
150 }
151 
152 void XmlWriteJob::done() // cannot be in the private class due to emitResult()
153 {
154  if (!d->document.writeToFile(d->fileName)) {
155  setError(Unknown);
156  setErrorText(d->document.lastError());
157  }
158  emitResult();
159 }
160 
161 #include "moc_xmlwritejob.cpp"
Collection::List collections() const
Returns the list of fetched collection.
QString name() const
Returns the i18n&#39;ed name of the collection.
Definition: collection.cpp:225
void fetchAllAttributes(bool fetch=true)
Sets whether all available attributes should be fetched.
Serializes a given Akonadi collection into a XML file.
Definition: xmlwritejob.h:35
Only list direct sub-collections of the base collection.
Represents a document of the KNUT XML serialization format for Akonadi objects.
Definition: xmldocument.h:38
Represents a collection of PIM items.
Definition: collection.h:76
Job that fetches collections from the Akonadi storage.
Base class for all actions in the Akonadi storage.
Definition: job.h:93
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:82
void doStart() override
This method must be reimplemented in the concrete jobs.
void fetchFullPayload(bool fetch=true)
Sets whether the full payload shall be fetched.
Item::List items() const
Returns the fetched items.
ItemFetchScope & fetchScope()
Returns the item fetch scope.
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.
Definition: xmlwriter.cpp:123
bool isEmpty() const const
Helper integration between Akonadi and Qt.
Job that fetches items from the Akonadi storage.
Definition: itemfetchjob.h:84
void result(KJob *job)
int error() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Wed May 27 2020 22:43:41 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.