1 | /* |
2 | This file is part of the syndication library |
3 | SPDX-FileCopyrightText: 2005 Frank Osterfeld <osterfeld@kde.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | #ifndef SYNDICATION_PARSERCOLLECTIONIMPL_H |
9 | #define SYNDICATION_PARSERCOLLECTIONIMPL_H |
10 | |
11 | #include <syndication/abstractparser.h> |
12 | #include <syndication/documentsource.h> |
13 | #include <syndication/feed.h> |
14 | #include <syndication/global.h> |
15 | #include <syndication/mapper.h> |
16 | #include <syndication/parsercollection.h> |
17 | #include <syndication/specificdocument.h> |
18 | |
19 | #include <QDomDocument> |
20 | #include <QHash> |
21 | #include <QString> |
22 | |
23 | namespace Syndication |
24 | { |
25 | //@cond PRIVATE |
26 | /** @internal |
27 | */ |
28 | // default implementation of ParserCollection. This is separated |
29 | // from the interface to move the implementation out of the public API |
30 | // (template classes require implementations to be in the header) |
31 | |
32 | template<class T> |
33 | class SYNDICATION_EXPORT ParserCollectionImpl : public ParserCollection<T> |
34 | { |
35 | public: |
36 | ParserCollectionImpl(); |
37 | |
38 | ~ParserCollectionImpl() override; |
39 | |
40 | QSharedPointer<T> parse(const DocumentSource &source, const QString &formatHint = QString()) override; |
41 | |
42 | bool registerParser(AbstractParser *parser, Mapper<T> *mapper) override; |
43 | |
44 | void changeMapper(const QString &format, Mapper<T> *mapper) override; |
45 | |
46 | ErrorCode lastError() const override; |
47 | |
48 | private: |
49 | ParserCollectionImpl(const ParserCollectionImpl &); |
50 | ParserCollectionImpl &operator=(const ParserCollectionImpl &); |
51 | QHash<QString, AbstractParser *> m_parsers; |
52 | QHash<QString, Mapper<T> *> m_mappers; |
53 | QList<AbstractParser *> m_parserList; |
54 | |
55 | ErrorCode m_lastError; |
56 | }; |
57 | |
58 | //@endcond |
59 | |
60 | // template <class T> |
61 | // class ParserCollectionImpl<T>::ParserCollectionImplPrivate |
62 | |
63 | template<class T> |
64 | ParserCollectionImpl<T>::ParserCollectionImpl() |
65 | { |
66 | } |
67 | |
68 | template<class T> |
69 | ParserCollectionImpl<T>::~ParserCollectionImpl() |
70 | { |
71 | // Delete the values |
72 | qDeleteAll(m_parsers); |
73 | qDeleteAll(m_mappers); |
74 | } |
75 | |
76 | template<class T> |
77 | bool ParserCollectionImpl<T>::registerParser(AbstractParser *parser, Mapper<T> *mapper) |
78 | { |
79 | if (m_parsers.contains(parser->format())) { |
80 | return false; |
81 | } |
82 | |
83 | m_parserList.append(parser); |
84 | m_parsers.insert(parser->format(), parser); |
85 | m_mappers.insert(parser->format(), mapper); |
86 | return true; |
87 | } |
88 | template<class T> |
89 | void ParserCollectionImpl<T>::changeMapper(const QString &format, Mapper<T> *mapper) |
90 | { |
91 | m_mappers[format] = mapper; |
92 | } |
93 | |
94 | template<class T> |
95 | QSharedPointer<T> ParserCollectionImpl<T>::parse(const DocumentSource &source, const QString &formatHint) |
96 | { |
97 | m_lastError = Syndication::Success; |
98 | |
99 | if (!formatHint.isNull() && m_parsers.contains(formatHint)) { |
100 | if (m_parsers[formatHint]->accept(source)) { |
101 | SpecificDocumentPtr doc = m_parsers[formatHint]->parse(source); |
102 | if (!doc->isValid()) { |
103 | m_lastError = InvalidFormat; |
104 | return FeedPtr(); |
105 | } |
106 | |
107 | return m_mappers[formatHint]->map(doc); |
108 | } |
109 | } |
110 | |
111 | for (AbstractParser *i : std::as_const(m_parserList)) { |
112 | if (i->accept(source)) { |
113 | SpecificDocumentPtr doc = i->parse(source); |
114 | if (!doc->isValid()) { |
115 | m_lastError = InvalidFormat; |
116 | return FeedPtr(); |
117 | } |
118 | |
119 | return m_mappers[i->format()]->map(doc); |
120 | } |
121 | } |
122 | if (source.asDomDocument().isNull()) { |
123 | m_lastError = InvalidXml; |
124 | } else { |
125 | m_lastError = XmlNotAccepted; |
126 | } |
127 | |
128 | return FeedPtr(); |
129 | } |
130 | |
131 | template<class T> |
132 | Syndication::ErrorCode ParserCollectionImpl<T>::lastError() const |
133 | { |
134 | return m_lastError; |
135 | } |
136 | |
137 | template<class T> |
138 | ParserCollectionImpl<T>::ParserCollectionImpl(const ParserCollectionImpl &) |
139 | { |
140 | } |
141 | |
142 | template<class T> |
143 | ParserCollectionImpl<T> &ParserCollectionImpl<T>::operator=(const ParserCollectionImpl &) |
144 | { |
145 | return *this; |
146 | } |
147 | |
148 | } // namespace Syndication |
149 | |
150 | #endif // SYNDICATION_PARSERCOLLECTIONIMPL_H |
151 | |