File indexing completed on 2024-09-01 03:51:07
0001 /* 0002 This file is part of the syndication library 0003 SPDX-FileCopyrightText: 2006 Frank Osterfeld <osterfeld@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #ifndef SYNDICATION_MAPPER_H 0009 #define SYNDICATION_MAPPER_H 0010 0011 #include "syndication_export.h" 0012 0013 namespace Syndication 0014 { 0015 class SpecificDocument; 0016 //@cond PRIVATE 0017 typedef QSharedPointer<SpecificDocument> SpecificDocumentPtr; 0018 //@endcond 0019 0020 /** 0021 * @brief A mapper maps an SpecificDocument to something else. 0022 * The type of this "something else" is specified by the template 0023 * parameter T. 0024 * In the default implementation it is used with the Feed interface, 0025 * but it is not limited to that. T can be an arbitrary class. 0026 * 0027 * There are three (advanced and hopefully rare) use cases 0028 * that require you to implement your own mapper. 0029 * For more information on the possible uses, see TODO: link docs. 0030 * 0031 * 1) Add your own feed parser. In case you need support for another 0032 * feed format (Okay! News, CDF, completely backward-incompatible Atom 5.0, 0033 * you name it), you can 0034 * implement AbstractParser and SpecificDocument for it and provide a 0035 * Mapper<Feed> 0036 * 0037 * * @code 0038 * class OkayNewsMapper : public Mapper<Feed> 0039 * { 0040 * public: 0041 * 0042 * virtual FeedPtr map(SpecificDocumentPtr doc) const { ... } 0043 * }; 0044 * 0045 * parserCollection()->registerParser(new OkayNews::Parser, new OkayNewsMapper); 0046 * @endcode 0047 * 0048 * 2) Implement your own mapper for the Feed abstraction, for an 0049 * existing parser. E.g. if you think Syndication does map Atom 0050 * all wrong, you can implement your own Atom mapper and use that instead 0051 * of the default one. 0052 * 0053 * @code 0054 * class MyAtomMapper : public Mapper<Feed> 0055 * { 0056 * public: 0057 * 0058 * virtual FeedPtr map(SpecificDocumentPtr doc) const { ... } 0059 * }; 0060 * 0061 * parserCollection()->changeMapper("atom", new MyAtomMapper); 0062 * @endcode 0063 * 0064 * 3) Use your own abstraction. In case the Feed interface 0065 * does not fit your needs, you can use your own interface, let's 0066 * say "MyFeed". Be aware you have to implement custom mappings for 0067 * all feed formats then: 0068 * 0069 * @code 0070 * class MyFeed 0071 * { 0072 * public: 0073 * 0074 * QString title() const; // my special title 0075 * QList<Article> articles() const; // I name it articles 0076 * }; 0077 * 0078 * class MyAtomMapper : public Mapper<MyFeed> { ... }; 0079 * class MyRDFMapper : public Mapper<MyFeed> { ... }; 0080 * class MyRSS2Mapper : public Mapper<MyFeed> { ... }; 0081 * 0082 * ParserCollection<MyFeed>* coll = new ParserCollection<MyFeed>; 0083 * coll->registerParser(new Atom::Parser, new MyAtomMapper); 0084 * coll->registerParser(new RDF::Parser, new MyRDFMapper); 0085 coll->registerParser(new RSS2::Parser, new MyRSS2Mapper); 0086 * @endcode 0087 * 0088 * @author Frank Osterfeld 0089 */ 0090 template<class T> 0091 class SYNDICATION_EXPORT Mapper 0092 { 0093 public: 0094 /** 0095 * virtual destructor 0096 */ 0097 virtual ~Mapper() 0098 { 0099 } 0100 0101 /** 0102 * maps a format-specific document to abstraction of type 0103 * @c T. 0104 * 0105 * \note implementations may assume @c doc to have the 0106 * type whose mapping they implement and may just statically cast 0107 * to the subclass without further checking. If you register your 0108 * own mapper, it's your responsibility to register the mapper 0109 * only for the format it actually handles. 0110 * 0111 * @param doc the document to map. 0112 * @return a newly created object implementing the abstraction 0113 * @c T. 0114 */ 0115 virtual QSharedPointer<T> map(SpecificDocumentPtr doc) const = 0; 0116 }; 0117 0118 } // namespace syndication 0119 0120 #endif // SYNDICATION_MAPPER_H