Libkdav2

davitemsfetchjob.cpp
1/*
2 Copyright (c) 2010 Grégory Oestreicher <greg@kamago.net>
3 Based on DavItemsListJob which is copyright (c) 2010 Tobias Koenig <tokoe@kde.org>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18*/
19
20#include "davitemsfetchjob.h"
21
22#include "davmanager.h"
23#include "davmultigetprotocol.h"
24#include "utils.h"
25#include "daverror.h"
26#include "davjob.h"
27
28using namespace KDAV2;
29
30DavItemsFetchJob::DavItemsFetchJob(const DavUrl &collectionUrl, const QStringList &urls, QObject *parent)
31 : DavJobBase(parent), mCollectionUrl(collectionUrl), mUrls(urls)
32{
33}
34
36{
37 const DavMultigetProtocol *protocol =
38 dynamic_cast<const DavMultigetProtocol *>(DavManager::self()->davProtocol(mCollectionUrl.protocol()));
39 if (!protocol) {
40 setError(ERR_NO_MULTIGET);
41 setErrorTextFromDavError();
42 emitResult();
43 return;
44 }
45
46 if (mUrls.isEmpty()) {
47 setError(ERR_PROBLEM_WITH_REQUEST);
48 setErrorText("DavItemsFetchJob without urls.");
49 emitResult();
50 return;
51 }
52
53 const QDomDocument report = protocol->itemsReportQuery(mUrls)->buildQuery();
54 DavJob *job = DavManager::self()->createReportJob(mCollectionUrl.url(), report, QStringLiteral("0"));
55 connect(job, &DavJob::result, this, &DavItemsFetchJob::davJobFinished);
56}
57
59{
60 DavItem::List values;
61 values.reserve(mItems.size());
62 Q_FOREACH (const auto &value, mItems) {
63 values << value;
64 }
65 return values;
66}
67
69{
70 return mItems.value(url);
71}
72
73void DavItemsFetchJob::davJobFinished(KJob *job)
74{
75 auto davJob = static_cast<DavJob *>(job);
76 if (davJob->error()) {
77 setErrorFromJob(davJob);
78 emitResult();
79 return;
80 }
81
82 const DavMultigetProtocol *protocol =
83 static_cast<const DavMultigetProtocol *>(DavManager::self()->davProtocol(mCollectionUrl.protocol()));
84
85 const QDomDocument document = davJob->response();
86 const QDomElement documentElement = document.documentElement();
87
88 QDomElement responseElement = Utils::firstChildElementNS(documentElement, QStringLiteral("DAV:"), QStringLiteral("response"));
89
90 while (!responseElement.isNull()) {
91 QDomElement propstatElement = Utils::firstChildElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("propstat"));
92
93 if (propstatElement.isNull()) {
94 responseElement = Utils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response"));
95 continue;
96 }
97
98 // Check for errors
99 const QDomElement statusElement = Utils::firstChildElementNS(propstatElement, QStringLiteral("DAV:"), QStringLiteral("status"));
100 if (!statusElement.text().contains(QLatin1String("200"))) {
101 responseElement = Utils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response"));
102 continue;
103 }
104
105 const QDomElement propElement = Utils::firstChildElementNS(propstatElement, QStringLiteral("DAV:"), QStringLiteral("prop"));
106
108
109 // extract path
110 const QDomElement hrefElement = Utils::firstChildElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("href"));
111 const QString href = hrefElement.text();
112
113 QUrl url = davJob->url();
114 if (href.startsWith(QLatin1Char('/'))) {
115 // href is only a path, use request url to complete
116 url.setPath(href, QUrl::TolerantMode);
117 } else {
118 // href is a complete url
119 url = QUrl::fromUserInput(href);
120 }
121
122 auto _url = url;
123 _url.setUserInfo(mCollectionUrl.url().userInfo());
124 item.setUrl(DavUrl(_url, mCollectionUrl.protocol()));
125
126 // extract etag
127 const QDomElement getetagElement = Utils::firstChildElementNS(propElement, QStringLiteral("DAV:"), QStringLiteral("getetag"));
128 item.setEtag(getetagElement.text());
129
130 // extract content
132 protocol->responseNamespace(),
133 protocol->dataTagName());
134
135 if (dataElement.isNull()) {
136 responseElement = Utils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response"));
137 continue;
138 }
139
140 const QByteArray data = dataElement.firstChild().toText().data().toUtf8();
141 if (data.isEmpty()) {
142 responseElement = Utils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response"));
143 continue;
144 }
145
146 item.setData(data);
147
148 mItems.insert(item.url().toDisplayString(), item);
149 responseElement = Utils::nextSiblingElementNS(responseElement, QStringLiteral("DAV:"), QStringLiteral("response"));
150 }
151
152 emitResult();
153}
A helper class to store information about DAV resources.
Definition davitem.h:52
DavUrl url() const
Returns the url that identifies the item.
Definition davitem.cpp:84
void setEtag(const QString &etag)
Sets the etag of the item.
Definition davitem.cpp:109
void setUrl(const DavUrl &url)
Sets the url that identifies the item.
Definition davitem.cpp:79
void setData(const QByteArray &data)
Sets the raw content data of the item.
Definition davitem.cpp:99
DavItem item(const QString &url) const
Return the item found at url.
DavItemsFetchJob(const DavUrl &collectionUrl, const QStringList &urls, QObject *parent=nullptr)
Creates a new items fetch job.
void start() override
Starts the job.
DavItem::List items() const
Returns the list of fetched items.
base class for the jobs used by the resource.
Definition davjobbase.h:38
void setErrorFromJob(DavJob *, ErrorNumber jobErrorCode=ERR_PROBLEM_WITH_REQUEST)
Set the error of this job from a failed DavJob (executed by this job).
static DavManager * self()
Returns the global instance of the DAV manager.
DavJob * createReportJob(const QUrl &url, const QDomDocument &document, const QString &depth=QStringLiteral("1"))
Returns a preconfigured DAV REPORT job.
const DavProtocolBase * davProtocol(Protocol protocol)
Returns the DAV protocol dialect object for the given DAV protocol.
Base class for protocols that implement multiget capabilities.
virtual XMLQueryBuilder::Ptr itemsReportQuery(const QStringList &urls) const =0
Returns the XML document that represents a MULTIGET DAV query to list all DAV resources with the give...
virtual QString dataTagName() const =0
Returns the tag name of data elements found in responses.
virtual QString responseNamespace() const =0
Returns the namespace used by protocol-specific elements found in responses.
A helper class to combine url and protocol of a DAV url.
Definition davurl.h:36
QUrl url() const
Returns the url that identifies the DAV object.
Definition davurl.cpp:41
Protocol protocol() const
Returns the DAV protocol dialect that is used to retrieve the DAV object.
Definition davurl.cpp:51
QString toDisplayString() const
Returns the url in a userfriendly way without login informations.
Definition davurl.cpp:56
void setErrorText(const QString &errorText)
void emitResult()
void result(KJob *job)
void setError(int errorCode)
QDomElement KPIMKDAV2_EXPORT firstChildElementNS(const QDomElement &parent, const QString &namespaceUri, const QString &tagName)
Returns the first child element of parent that has the given tagName and is part of the namespaceUri.
Definition utils.cpp:37
QDomElement KPIMKDAV2_EXPORT nextSiblingElementNS(const QDomElement &element, const QString &namespaceUri, const QString &tagName)
Returns the next sibling element of element that has the given tagName and is part of the namespaceUr...
Definition utils.cpp:51
bool isEmpty() const const
QDomElement documentElement() const const
QString text() const const
bool isNull() const const
bool isEmpty() const const
void reserve(qsizetype size)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
TolerantMode
QUrl fromUserInput(const QString &userInput, const QString &workingDirectory, UserInputResolutionOptions options)
void setPath(const QString &path, ParsingMode mode)
void setUserInfo(const QString &userInfo, ParsingMode mode)
QString url(FormattingOptions options) const const
QString userInfo(ComponentFormattingOptions options) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:08:18 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.