Syndication

atom/document.cpp
1/*
2 This file is part of the syndication library
3 SPDX-FileCopyrightText: 2006 Frank Osterfeld <osterfeld@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "document.h"
9#include "atomtools.h"
10#include "category.h"
11#include "constants.h"
12#include "entry.h"
13#include "generator.h"
14#include "link.h"
15#include "person.h"
16
17#include <documentvisitor.h>
18#include <tools.h>
19
20#include <QDomElement>
21#include <QList>
22#include <QString>
23
24#include <vector>
25
26namespace Syndication
27{
28namespace Atom
29{
34
36 : ElementWrapper(element)
37{
38}
39
41{
42 return visitor->visitAtomFeedDocument(this);
43}
44
46{
47 const QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("author"));
48 QList<Person> list;
49 list.reserve(a.count());
50
51 std::transform(a.cbegin(), a.cend(), std::back_inserter(list), [](const QDomElement &element) {
52 return Person(element);
53 });
54
55 return list;
56}
57
59{
60 const QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("contributor"));
61 QList<Person> list;
62 list.reserve(a.count());
63
64 std::transform(a.cbegin(), a.cend(), std::back_inserter(list), [](const QDomElement &element) {
65 return Person(element);
66 });
67
68 return list;
69}
70
72{
73 const QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("category"));
74 QList<Category> list;
75 list.reserve(a.count());
76
77 std::transform(a.cbegin(), a.cend(), std::back_inserter(list), [](const QDomElement &element) {
78 return Category(element);
79 });
80
81 return list;
82}
83
85{
86 return Generator(firstElementByTagNameNS(atom1Namespace(), QStringLiteral("generator")));
87}
88
90{
91 const QString iconPath = extractElementTextNS(atom1Namespace(), QStringLiteral("icon"));
92 if (iconPath.isEmpty()) {
93 return {};
94 }
95 return completeURI(iconPath);
96}
97
99{
100 return completeURI(extractElementTextNS(atom1Namespace(), QStringLiteral("logo")));
101}
102
104{
105 return extractElementTextNS(atom1Namespace(), QStringLiteral("id"));
106}
107
109{
110 return extractAtomText(*this, QStringLiteral("rights"));
111}
112
114{
115 return extractAtomText(*this, QStringLiteral("title"));
116}
117
119{
120 return extractAtomText(*this, QStringLiteral("subtitle"));
121}
122
124{
125 QString upd = extractElementTextNS(atom1Namespace(), QStringLiteral("updated"));
126 return parseDate(upd, ISODate);
127}
128
130{
131 const QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("link"));
132 QList<Link> list;
133 list.reserve(a.count());
134
135 std::transform(a.cbegin(), a.cend(), std::back_inserter(list), [](const QDomElement &element) {
136 return Link(element);
137 });
138
139 return list;
140}
141
143{
144 const QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("entry"));
145 QList<Entry> list;
146 list.reserve(a.count());
147
148 const QList<Person> feedAuthors = authors();
149
150 std::transform(a.cbegin(), a.cend(), std::back_inserter(list), [&feedAuthors](const QDomElement &element) {
151 Entry entry(element);
152 entry.setFeedAuthors(feedAuthors);
153 return entry;
154 });
155
156 return list;
157}
158
160{
161 // TODO: do not hardcode this list here
162 static std::vector<ElementType> handled; // QVector would require a default ctor, and ElementType is too big for QList
163 if (handled.empty()) {
164 handled.reserve(13);
165 handled.push_back(ElementType(QStringLiteral("author"), atom1Namespace()));
166 handled.push_back(ElementType(QStringLiteral("contributor"), atom1Namespace()));
167 handled.push_back(ElementType(QStringLiteral("category"), atom1Namespace()));
168 handled.push_back(ElementType(QStringLiteral("generator"), atom1Namespace()));
169 handled.push_back(ElementType(QStringLiteral("icon"), atom1Namespace()));
170 handled.push_back(ElementType(QStringLiteral("logo"), atom1Namespace()));
171 handled.push_back(ElementType(QStringLiteral("id"), atom1Namespace()));
172 handled.push_back(ElementType(QStringLiteral("rights"), atom1Namespace()));
173 handled.push_back(ElementType(QStringLiteral("title"), atom1Namespace()));
174 handled.push_back(ElementType(QStringLiteral("subtitle"), atom1Namespace()));
175 handled.push_back(ElementType(QStringLiteral("updated"), atom1Namespace()));
176 handled.push_back(ElementType(QStringLiteral("link"), atom1Namespace()));
177 handled.push_back(ElementType(QStringLiteral("entry"), atom1Namespace()));
178 }
179
180 QList<QDomElement> notHandled;
181
182 QDomNodeList children = element().childNodes();
183 const int numChildren = children.size();
184 for (int i = 0; i < numChildren; ++i) {
185 QDomElement el = children.at(i).toElement();
186 if (!el.isNull() //
187 && std::find(handled.cbegin(), handled.cend(), ElementType(el.localName(), el.namespaceURI())) == handled.cend()) {
188 notHandled.append(el);
189 }
190 }
191
192 return notHandled;
193}
194
196{
197 return !isNull();
198}
199
201{
202 QString info = QLatin1String("### FeedDocument: ###################\n");
203 if (!title().isEmpty()) {
204 info += QLatin1String("title: #") + title() + QLatin1String("#\n");
205 }
206 if (!subtitle().isEmpty()) {
207 info += QLatin1String("subtitle: #") + subtitle() + QLatin1String("#\n");
208 }
209 if (!id().isEmpty()) {
210 info += QLatin1String("id: #") + id() + QLatin1String("#\n");
211 }
212
213 if (!rights().isEmpty()) {
214 info += QLatin1String("rights: #") + rights() + QLatin1String("#\n");
215 }
216 if (!icon().isEmpty()) {
217 info += QLatin1String("icon: #") + icon() + QLatin1String("#\n");
218 }
219 if (!logo().isEmpty()) {
220 info += QLatin1String("logo: #") + logo() + QLatin1String("#\n");
221 }
222 if (!generator().isNull()) {
223 info += generator().debugInfo();
224 }
225
226 QString dupdated = dateTimeToString(updated());
227 if (!dupdated.isNull()) {
228 info += QLatin1String("updated: #") + dupdated + QLatin1String("#\n");
229 }
230
231 const QList<Link> dlinks = links();
232 for (const auto &link : dlinks) {
233 info += link.debugInfo();
234 }
235
236 const QList<Category> dcats = categories();
237 for (const auto &cat : dcats) {
238 info += cat.debugInfo();
239 }
240
241 info += QLatin1String("### Authors: ###################\n");
242
243 const QList<Person> dauthors = authors();
244 for (const auto &author : dauthors) {
245 info += author.debugInfo();
246 }
247
248 info += QLatin1String("### Contributors: ###################\n");
249
250 const QList<Person> dcontri = contributors();
251 for (const auto &person : dcontri) {
252 info += person.debugInfo();
253 }
254
255 const QList<Entry> dentries = entries();
256 for (const auto &entry : dentries) {
257 info += entry.debugInfo();
258 }
259
260 info += QLatin1String("### FeedDocument end ################\n");
261
262 return info;
263}
264
269
271 : ElementWrapper(element)
272{
273}
274
276{
277 return visitor->visitAtomEntryDocument(this);
278}
279
281{
282 return Entry(element());
283}
284
286{
287 return !isNull();
288}
289
291{
292 QString info;
293 info += QLatin1String("### EntryDocument: ##################\n");
294
295 Entry dentry = entry();
296 if (!dentry.isNull()) {
297 info += dentry.debugInfo();
298 }
299
300 info += QLatin1String("### EntryDocument end ###############\n");
301 return info;
302}
303
304} // namespace Atom
305} // namespace Syndication
bool isValid() const override
returns whether this document is valid or not.
bool accept(DocumentVisitor *visitor) override
Used by visitors for double dispatch.
EntryDocument()
default constructor, creates a null document, which is invalid.
Entry entry() const
returns the single entry described in the source.
QString debugInfo() const override
returns a description of this entry document for debugging purposes.
an Atom entry, equivalent to the "items" in the RSS world.
Definition entry.h:39
QString debugInfo() const
returns a description of this entry for debugging purposes
Definition entry.cpp:178
time_t updated() const
The datetime of the last modification of the feed content.
bool isValid() const override
returns whether this document is valid or not.
bool accept(DocumentVisitor *visitor) override
Used by visitors for double dispatch.
QString subtitle() const
description or subtitle of the feed (optional).
QString logo() const
URL of an image serving as a feed logo (optional)
QList< QDomElement > unhandledElements() const
returns all child elements of this feed not covered by this class.
QList< Link > links() const
a list of links.
QString debugInfo() const override
returns a description of this feed document for debugging purposes.
QString rights() const
copyright information (optional)
QList< Category > categories() const
a list of categories this feed is assigned to (optional)
QList< Entry > entries() const
a list of the entries (items) in this feed.
QList< Person > contributors() const
a list of persons who contribute to this feed.
QString icon() const
URL of an image serving as a feed icon (optional)
FeedDocument()
default constructor, creates a null feed, which is invalid.
QList< Person > authors() const
a list of persons who are the authors of this feed.
QString title() const
feed title (required).
Generator generator() const
description of the agent used to generate the feed.
QString id() const
a string that unambiguously identifies the feed (required)
Description of the agent used to generate the feed.
Definition generator.h:26
QString debugInfo() const
a description of this generator for debugging purposes.
Definition generator.cpp:42
Visitor interface, following the Visitor design pattern.
virtual bool visitAtomFeedDocument(Syndication::Atom::FeedDocument *document)
reimplement this method to handle Atom feed documents (most Atom feeds are of this type).
virtual bool visitAtomEntryDocument(Syndication::Atom::EntryDocument *document)
reimplement this method to handle Atom entry documents.
A wrapper for XML elements.
const QDomElement & element() const
returns the wrapped resource.
QDomElement firstElementByTagNameNS(const QString &nsURI, const QString &tagName) const
searches the direct children of the wrapped element for an element with a given namespace and tag nam...
QString completeURI(const QString &uri) const
completes relative URIs with a prefix specified via xml:base.
bool isNull() const
returns whether the wrapped element is a null element
QList< QDomElement > elementsByTagNameNS(const QString &nsURI, const QString &tagName) const
returns all child elements with tag name tagname and namespace URI nsURI.
QString extractElementTextNS(const QString &namespaceURI, const QString &localName) const
extracts the text from a child element, respecting namespaces.
QString atom1Namespace()
namespace used by Atom 1.0 elements
QString extractAtomText(const Syndication::ElementWrapper &parent, const QString &tagname)
extracts the content of an atomTextConstruct.
Definition atomtools.cpp:21
QDomNodeList childNodes() const const
bool isNull() const const
QString localName() const const
QString namespaceURI() const const
QDomElement toElement() const const
QDomNode at(int index) const const
int size() const const
void append(QList< T > &&value)
const_iterator cbegin() const const
const_iterator cend() const const
qsizetype count() const const
void reserve(qsizetype size)
bool isEmpty() const const
bool isNull() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 22 2024 12:02:57 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.