File indexing completed on 2024-04-14 03:58:30

0001 /*
0002     This file is part of the syndication library
0003     SPDX-FileCopyrightText: 2005 Frank Osterfeld <osterfeld@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef SYNDICATION_PARSERCOLLECTIONIMPL_H
0009 #define SYNDICATION_PARSERCOLLECTIONIMPL_H
0010 
0011 #include <syndication/abstractparser.h>
0012 #include <syndication/documentsource.h>
0013 #include <syndication/feed.h>
0014 #include <syndication/global.h>
0015 #include <syndication/mapper.h>
0016 #include <syndication/parsercollection.h>
0017 #include <syndication/specificdocument.h>
0018 
0019 #include <QDomDocument>
0020 #include <QHash>
0021 #include <QString>
0022 
0023 namespace Syndication
0024 {
0025 //@cond PRIVATE
0026 /** @internal
0027  */
0028 // default implementation of ParserCollection. This is separated
0029 // from the interface to move the implementation out of the public API
0030 // (template classes require implementations to be in the header)
0031 
0032 template<class T>
0033 class SYNDICATION_EXPORT ParserCollectionImpl : public ParserCollection<T>
0034 {
0035 public:
0036     ParserCollectionImpl();
0037 
0038     ~ParserCollectionImpl() override;
0039 
0040     QSharedPointer<T> parse(const DocumentSource &source, const QString &formatHint = QString()) override;
0041 
0042     bool registerParser(AbstractParser *parser, Mapper<T> *mapper) override;
0043 
0044     void changeMapper(const QString &format, Mapper<T> *mapper) override;
0045 
0046     ErrorCode lastError() const override;
0047 
0048 private:
0049     ParserCollectionImpl(const ParserCollectionImpl &);
0050     ParserCollectionImpl &operator=(const ParserCollectionImpl &);
0051     QHash<QString, AbstractParser *> m_parsers;
0052     QHash<QString, Mapper<T> *> m_mappers;
0053     QList<AbstractParser *> m_parserList;
0054 
0055     ErrorCode m_lastError;
0056 };
0057 
0058 //@endcond
0059 
0060 // template <class T>
0061 // class ParserCollectionImpl<T>::ParserCollectionImplPrivate
0062 
0063 template<class T>
0064 ParserCollectionImpl<T>::ParserCollectionImpl()
0065 {
0066 }
0067 
0068 template<class T>
0069 ParserCollectionImpl<T>::~ParserCollectionImpl()
0070 {
0071     // Delete the values
0072     qDeleteAll(m_parsers);
0073     qDeleteAll(m_mappers);
0074 }
0075 
0076 template<class T>
0077 bool ParserCollectionImpl<T>::registerParser(AbstractParser *parser, Mapper<T> *mapper)
0078 {
0079     if (m_parsers.contains(parser->format())) {
0080         return false;
0081     }
0082 
0083     m_parserList.append(parser);
0084     m_parsers.insert(parser->format(), parser);
0085     m_mappers.insert(parser->format(), mapper);
0086     return true;
0087 }
0088 template<class T>
0089 void ParserCollectionImpl<T>::changeMapper(const QString &format, Mapper<T> *mapper)
0090 {
0091     m_mappers[format] = mapper;
0092 }
0093 
0094 template<class T>
0095 QSharedPointer<T> ParserCollectionImpl<T>::parse(const DocumentSource &source, const QString &formatHint)
0096 {
0097     m_lastError = Syndication::Success;
0098 
0099     if (!formatHint.isNull() && m_parsers.contains(formatHint)) {
0100         if (m_parsers[formatHint]->accept(source)) {
0101             SpecificDocumentPtr doc = m_parsers[formatHint]->parse(source);
0102             if (!doc->isValid()) {
0103                 m_lastError = InvalidFormat;
0104                 return FeedPtr();
0105             }
0106 
0107             return m_mappers[formatHint]->map(doc);
0108         }
0109     }
0110 
0111     for (AbstractParser *i : std::as_const(m_parserList)) {
0112         if (i->accept(source)) {
0113             SpecificDocumentPtr doc = i->parse(source);
0114             if (!doc->isValid()) {
0115                 m_lastError = InvalidFormat;
0116                 return FeedPtr();
0117             }
0118 
0119             return m_mappers[i->format()]->map(doc);
0120         }
0121     }
0122     if (source.asDomDocument().isNull()) {
0123         m_lastError = InvalidXml;
0124     } else {
0125         m_lastError = XmlNotAccepted;
0126     }
0127 
0128     return FeedPtr();
0129 }
0130 
0131 template<class T>
0132 Syndication::ErrorCode ParserCollectionImpl<T>::lastError() const
0133 {
0134     return m_lastError;
0135 }
0136 
0137 template<class T>
0138 ParserCollectionImpl<T>::ParserCollectionImpl(const ParserCollectionImpl &)
0139 {
0140 }
0141 
0142 template<class T>
0143 ParserCollectionImpl<T> &ParserCollectionImpl<T>::operator=(const ParserCollectionImpl &)
0144 {
0145     return *this;
0146 }
0147 
0148 } // namespace Syndication
0149 
0150 #endif // SYNDICATION_PARSERCOLLECTIONIMPL_H