1 | /* |
2 | * This file is part of the syndication library |
3 | * |
4 | * Copyright (C) 2005 Frank Osterfeld <osterfeld@kde.org> |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public License |
17 | * along with this library; see the file COPYING.LIB. If not, write to |
18 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | * Boston, MA 02110-1301, USA. |
20 | * |
21 | */ |
22 | |
23 | #ifndef SYNDICATION_PARSERCOLLECTIONIMPL_H |
24 | #define SYNDICATION_PARSERCOLLECTIONIMPL_H |
25 | |
26 | #include <syndication/specificdocument.h> |
27 | #include <syndication/abstractparser.h> |
28 | #include <syndication/documentsource.h> |
29 | #include <syndication/parsercollection.h> |
30 | #include <syndication/feed.h> |
31 | #include <syndication/global.h> |
32 | #include <syndication/mapper.h> |
33 | |
34 | #include <QtXml/QDomDocument> |
35 | #include <QtCore/QHash> |
36 | #include <QtCore/QString> |
37 | |
38 | namespace Syndication { |
39 | |
40 | //@cond PRIVATE |
41 | /** @internal |
42 | */ |
43 | // default implementation of ParserCollection. This is separated |
44 | // from the interface to move the implementation out of the public API |
45 | // (template classes require implementations to be in the header) |
46 | |
47 | template <class T> |
48 | class SYNDICATION_EXPORT ParserCollectionImpl : public ParserCollection<T> |
49 | { |
50 | public: |
51 | |
52 | ParserCollectionImpl(); |
53 | |
54 | virtual ~ParserCollectionImpl(); |
55 | |
56 | boost::shared_ptr<T> parse(const DocumentSource& source, |
57 | const QString& formatHint=QString()); |
58 | |
59 | |
60 | bool registerParser(AbstractParser* parser, Mapper<T>* mapper); |
61 | |
62 | void changeMapper(const QString& format, Mapper<T>* mapper); |
63 | |
64 | ErrorCode lastError() const; |
65 | |
66 | private: |
67 | |
68 | ParserCollectionImpl(const ParserCollectionImpl&); |
69 | ParserCollectionImpl& operator=(const ParserCollectionImpl&); |
70 | QHash<QString, AbstractParser*> m_parsers; |
71 | QHash<QString, Mapper<T>*> m_mappers; |
72 | QList<AbstractParser*> m_parserList; |
73 | |
74 | ErrorCode m_lastError; |
75 | }; |
76 | |
77 | //@endcond |
78 | |
79 | //template <class T> |
80 | //class ParserCollectionImpl<T>::ParserCollectionImplPrivate |
81 | |
82 | template <class T> |
83 | ParserCollectionImpl<T>::ParserCollectionImpl() |
84 | { |
85 | } |
86 | |
87 | template <class T> |
88 | ParserCollectionImpl<T>::~ParserCollectionImpl() |
89 | { |
90 | QList<AbstractParser*> list = m_parsers.values(); |
91 | QList<AbstractParser*>::ConstIterator it = list.constBegin(); |
92 | QList<AbstractParser*>::ConstIterator end = list.constEnd(); |
93 | |
94 | for ( ; it != end; ++it) |
95 | delete *it; |
96 | |
97 | QList<QString> m = m_mappers.keys(); |
98 | QList<QString>::ConstIterator itm = m.constBegin(); |
99 | QList<QString>::ConstIterator endm = m.constEnd(); |
100 | |
101 | for ( ; itm != endm; ++itm) |
102 | delete m_mappers[*itm]; |
103 | |
104 | } |
105 | |
106 | template <class T> |
107 | bool ParserCollectionImpl<T>::registerParser(AbstractParser* parser, Mapper<T>* mapper) |
108 | { |
109 | if (m_parsers.contains(parser->format())) |
110 | return false; |
111 | |
112 | m_parserList.append(parser); |
113 | m_parsers.insert(parser->format(), parser); |
114 | m_mappers.insert(parser->format(), mapper); |
115 | return true; |
116 | } |
117 | template <class T> |
118 | void ParserCollectionImpl<T>::changeMapper(const QString& format, Mapper<T>* mapper) |
119 | { |
120 | m_mappers[format] = mapper; |
121 | } |
122 | |
123 | template <class T> |
124 | boost::shared_ptr<T> ParserCollectionImpl<T>::parse(const DocumentSource& source, const QString& formatHint) |
125 | { |
126 | m_lastError = Syndication::Success; |
127 | |
128 | if (!formatHint.isNull() && m_parsers.contains(formatHint)) |
129 | { |
130 | if (m_parsers[formatHint]->accept(source)) |
131 | { |
132 | SpecificDocumentPtr doc = m_parsers[formatHint]->parse(source); |
133 | if (!doc->isValid()) |
134 | { |
135 | m_lastError = InvalidFormat; |
136 | return FeedPtr(); |
137 | } |
138 | |
139 | return m_mappers[formatHint]->map(doc); |
140 | } |
141 | } |
142 | |
143 | Q_FOREACH (AbstractParser* i, m_parserList) |
144 | { |
145 | if (i->accept(source)) |
146 | { |
147 | SpecificDocumentPtr doc = i->parse(source); |
148 | if (!doc->isValid()) |
149 | { |
150 | m_lastError = InvalidFormat; |
151 | return FeedPtr(); |
152 | } |
153 | |
154 | return m_mappers[i->format()]->map(doc); |
155 | } |
156 | } |
157 | if (source.asDomDocument().isNull()) |
158 | m_lastError = InvalidXml; |
159 | else |
160 | m_lastError = XmlNotAccepted; |
161 | |
162 | return FeedPtr(); |
163 | } |
164 | |
165 | template <class T> |
166 | Syndication::ErrorCode ParserCollectionImpl<T>::lastError() const |
167 | { |
168 | return m_lastError; |
169 | } |
170 | |
171 | template <class T> |
172 | ParserCollectionImpl<T>::ParserCollectionImpl(const ParserCollectionImpl&) |
173 | { |
174 | } |
175 | |
176 | template <class T> |
177 | ParserCollectionImpl<T>& ParserCollectionImpl<T>::operator=(const ParserCollectionImpl&) |
178 | { |
179 | return *this; |
180 | } |
181 | |
182 | } // namespace Syndication |
183 | |
184 | #endif // SYNDICATION_PARSERCOLLECTIONIMPL_H |
185 | |