Syndication

atom/document.cpp
1 /*
2  This file is part of the syndication library
3  SPDX-FileCopyrightText: 2006 Frank Osterfeld <[email protected]>
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 
26 namespace Syndication
27 {
28 namespace Atom
29 {
31  : ElementWrapper()
32 {
33 }
34 
36  : ElementWrapper(element)
37 {
38 }
39 
41 {
42  return visitor->visitAtomFeedDocument(this);
43 }
44 
46 {
47  QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("author"));
48  QList<Person> list;
49  list.reserve(a.count());
50 
53 
54  for (; it != end; ++it) {
55  list.append(Person(*it));
56  }
57 
58  return list;
59 }
60 
62 {
63  QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("contributor"));
64  QList<Person> list;
65  list.reserve(a.count());
66 
69 
70  for (; it != end; ++it) {
71  list.append(Person(*it));
72  }
73 
74  return list;
75 }
76 
78 {
79  QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("category"));
80  QList<Category> list;
81  list.reserve(a.count());
82 
85 
86  for (; it != end; ++it) {
87  list.append(Category(*it));
88  }
89 
90  return list;
91 }
92 
94 {
95  return Generator(firstElementByTagNameNS(atom1Namespace(), QStringLiteral("generator")));
96 }
97 
99 {
100  const QString iconPath = extractElementTextNS(atom1Namespace(), QStringLiteral("icon"));
101  if (iconPath.isEmpty()) {
102  return {};
103  }
104  return completeURI(iconPath);
105 }
106 
108 {
109  return completeURI(extractElementTextNS(atom1Namespace(), QStringLiteral("logo")));
110 }
111 
113 {
114  return extractElementTextNS(atom1Namespace(), QStringLiteral("id"));
115 }
116 
118 {
119  return extractAtomText(*this, QStringLiteral("rights"));
120 }
121 
123 {
124  return extractAtomText(*this, QStringLiteral("title"));
125 }
126 
128 {
129  return extractAtomText(*this, QStringLiteral("subtitle"));
130 }
131 
132 time_t FeedDocument::updated() const
133 {
134  QString upd = extractElementTextNS(atom1Namespace(), QStringLiteral("updated"));
135  return parseDate(upd, ISODate);
136 }
137 
139 {
140  QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("link"));
141  QList<Link> list;
142  list.reserve(a.count());
143 
146 
147  for (; it != end; ++it) {
148  list.append(Link(*it));
149  }
150 
151  return list;
152 }
153 
155 {
156  QList<QDomElement> a = elementsByTagNameNS(atom1Namespace(), QStringLiteral("entry"));
157  QList<Entry> list;
158  list.reserve(a.count());
159 
160  QList<Person> feedAuthors = authors();
163 
164  for (; it != end; ++it) {
165  Entry entry(*it);
166  entry.setFeedAuthors(feedAuthors);
167  list.append(entry);
168  }
169 
170  return list;
171 }
172 
174 {
175  // TODO: do not hardcode this list here
176  static std::vector<ElementType> handled; // QVector would require a default ctor, and ElementType is too big for QList
177  if (handled.empty()) {
178  handled.reserve(13);
179  handled.push_back(ElementType(QStringLiteral("author"), atom1Namespace()));
180  handled.push_back(ElementType(QStringLiteral("contributor"), atom1Namespace()));
181  handled.push_back(ElementType(QStringLiteral("category"), atom1Namespace()));
182  handled.push_back(ElementType(QStringLiteral("generator"), atom1Namespace()));
183  handled.push_back(ElementType(QStringLiteral("icon"), atom1Namespace()));
184  handled.push_back(ElementType(QStringLiteral("logo"), atom1Namespace()));
185  handled.push_back(ElementType(QStringLiteral("id"), atom1Namespace()));
186  handled.push_back(ElementType(QStringLiteral("rights"), atom1Namespace()));
187  handled.push_back(ElementType(QStringLiteral("title"), atom1Namespace()));
188  handled.push_back(ElementType(QStringLiteral("subtitle"), atom1Namespace()));
189  handled.push_back(ElementType(QStringLiteral("updated"), atom1Namespace()));
190  handled.push_back(ElementType(QStringLiteral("link"), atom1Namespace()));
191  handled.push_back(ElementType(QStringLiteral("entry"), atom1Namespace()));
192  }
193 
194  QList<QDomElement> notHandled;
195 
196  QDomNodeList children = element().childNodes();
197  const int numChildren = children.size();
198  for (int i = 0; i < numChildren; ++i) {
199  QDomElement el = children.at(i).toElement();
200  if (!el.isNull() //
201  && std::find(handled.cbegin(), handled.cend(), ElementType(el.localName(), el.namespaceURI())) == handled.cend()) {
202  notHandled.append(el);
203  }
204  }
205 
206  return notHandled;
207 }
208 
210 {
211  return !isNull();
212 }
213 
215 {
216  QString info = QLatin1String("### FeedDocument: ###################\n");
217  if (!title().isEmpty()) {
218  info += QLatin1String("title: #") + title() + QLatin1String("#\n");
219  }
220  if (!subtitle().isEmpty()) {
221  info += QLatin1String("subtitle: #") + subtitle() + QLatin1String("#\n");
222  }
223  if (!id().isEmpty()) {
224  info += QLatin1String("id: #") + id() + QLatin1String("#\n");
225  }
226 
227  if (!rights().isEmpty()) {
228  info += QLatin1String("rights: #") + rights() + QLatin1String("#\n");
229  }
230  if (!icon().isEmpty()) {
231  info += QLatin1String("icon: #") + icon() + QLatin1String("#\n");
232  }
233  if (!logo().isEmpty()) {
234  info += QLatin1String("logo: #") + logo() + QLatin1String("#\n");
235  }
236  if (!generator().isNull()) {
237  info += generator().debugInfo();
238  }
239 
240  QString dupdated = dateTimeToString(updated());
241  if (!dupdated.isNull()) {
242  info += QLatin1String("updated: #") + dupdated + QLatin1String("#\n");
243  }
244 
245  QList<Link> dlinks = links();
246  QList<Link>::ConstIterator endlinks = dlinks.constEnd();
247  for (QList<Link>::ConstIterator it = dlinks.constBegin(); it != endlinks; ++it) {
248  info += (*it).debugInfo();
249  }
250 
251  QList<Category> dcats = categories();
252  QList<Category>::ConstIterator endcats = dcats.constEnd();
253  for (QList<Category>::ConstIterator it = dcats.constBegin(); it != endcats; ++it) {
254  info += (*it).debugInfo();
255  }
256 
257  info += QLatin1String("### Authors: ###################\n");
258 
259  QList<Person> dauthors = authors();
260  QList<Person>::ConstIterator endauthors = dauthors.constEnd();
261  for (QList<Person>::ConstIterator it = dauthors.constBegin(); it != endauthors; ++it) {
262  info += (*it).debugInfo();
263  }
264 
265  info += QLatin1String("### Contributors: ###################\n");
266 
267  QList<Person> dcontri = contributors();
268  QList<Person>::ConstIterator endcontri = dcontri.constEnd();
269  for (QList<Person>::ConstIterator it = dcontri.constBegin(); it != endcontri; ++it) {
270  info += (*it).debugInfo();
271  }
272 
273  QList<Entry> dentries = entries();
274  QList<Entry>::ConstIterator endentries = dentries.constEnd();
275  for (QList<Entry>::ConstIterator it = dentries.constBegin(); it != endentries; ++it) {
276  info += (*it).debugInfo();
277  }
278 
279  info += QLatin1String("### FeedDocument end ################\n");
280 
281  return info;
282 }
283 
285  : ElementWrapper()
286 {
287 }
288 
290  : ElementWrapper(element)
291 {
292 }
293 
295 {
296  return visitor->visitAtomEntryDocument(this);
297 }
298 
300 {
301  return Entry(element());
302 }
303 
305 {
306  return !isNull();
307 }
308 
310 {
311  QString info;
312  info += QLatin1String("### EntryDocument: ##################\n");
313 
314  Entry dentry = entry();
315  if (!dentry.isNull()) {
316  info += dentry.debugInfo();
317  }
318 
319  info += QLatin1String("### EntryDocument end ###############\n");
320  return info;
321 }
322 
323 } // namespace Atom
324 } // namespace Syndication
QList< QDomElement > elementsByTagNameNS(const QString &nsURI, const QString &tagName) const
returns all child elements with tag name tagname and namespace URI nsURI.
A category for categorizing items or whole feeds.
Definition: atom/category.h:31
Description of the agent used to generate the feed.
Definition: generator.h:25
QString rights() const
copyright information (optional)
QList< Person > authors() const
a list of persons who are the authors of this feed.
QString debugInfo() const override
returns a description of this feed document for debugging purposes.
A wrapper for XML elements.
void reserve(int alloc)
QList< Category > categories() const
a list of categories this feed is assigned to (optional)
QString namespaceURI() const const
bool isValid() const override
returns whether this document is valid or not.
QList< Link > links() const
a list of links.
QString debugInfo() const
a description of this generator for debugging purposes.
Definition: generator.cpp:42
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...
QDomNodeList childNodes() const const
bool isNull() const const
bool isValid() const override
returns whether this document is valid or not.
QDomElement toElement() const const
QString title() const
feed title (required).
bool accept(DocumentVisitor *visitor) override
Used by visitors for double dispatch.
int count(const T &value) const const
void append(const T &value)
QString localName() const const
FeedDocument()
default constructor, creates a null feed, which is invalid.
virtual bool visitAtomEntryDocument(Syndication::Atom::EntryDocument *document)
reimplement this method to handle Atom entry documents.
QList< Entry > entries() const
a list of the entries (items) in this feed.
EntryDocument()
default constructor, creates a null document, which is invalid.
bool isEmpty() const const
KCALUTILS_EXPORT QString dateTimeToString(const QDateTime &date, bool dateOnly=false, bool shortfmt=true)
QString atom1Namespace()
namespace used by Atom 1.0 elements
void setFeedAuthors(const QList< Person > &feedAuthors)
Sets the list of the containing feed&#39;s authors, which will be used as a fallback in authors() in case...
Definition: entry.cpp:39
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.
QString extractAtomText(const Syndication::ElementWrapper &parent, const QString &tagname)
extracts the content of an atomTextConstruct.
Definition: atomtools.cpp:21
QString icon() const
URL of an image serving as a feed icon (optional)
bool isNull() const
returns whether the wrapped element is a null element
QString completeURI(const QString &uri) const
completes relative URIs with a prefix specified via xml:base.
bool isNull() const const
an Atom entry, equivalent to the "items" in the RSS world.
Definition: entry.h:38
virtual bool visitAtomFeedDocument(Syndication::Atom::FeedDocument *document)
reimplement this method to handle Atom feed documents (most Atom feeds are of this type)...
QString subtitle() const
description or subtitle of the feed (optional).
QString id() const
a string that unambigously identifies the feed (required)
QString debugInfo() const override
returns a description of this entry document for debugging purposes.
bool accept(DocumentVisitor *visitor) override
Used by visitors for double dispatch.
const QDomElement & element() const
returns the wrapped resource.
QString extractElementTextNS(const QString &namespaceURI, const QString &localName) const
extracts the text from a child element, respecting namespaces.
Visitor interface, following the Visitor design pattern.
describes a person, with name and optional URI and e-mail address.
Definition: atom/person.h:26
QString debugInfo() const
returns a description of this entry for debugging purposes
Definition: entry.cpp:193
int size() const const
QList::const_iterator constEnd() const const
Generator generator() const
description of the agent used to generate the feed.
QList::const_iterator constBegin() const const
Entry entry() const
returns the single entry described in the source.
QList< Person > contributors() const
a list of persons who contribute to this feed.
time_t updated() const
The datetime of the last modification of the feed content.
QDomNode at(int index) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Jun 22 2021 23:02:03 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.