File indexing completed on 2024-06-16 04:50:14

0001 /*
0002     SPDX-FileCopyrightText: 2007 Till Adam <adam@kde.org>
0003     SPDX-FileCopyrightText: 2007 Volker Krause <vkrause@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #pragma once
0009 
0010 #include <QByteArray>
0011 #include <QSet>
0012 
0013 #include "akonadicore_export.h"
0014 #include "item.h"
0015 
0016 class QIODevice;
0017 
0018 namespace Akonadi
0019 {
0020 /**
0021  * @short The base class for item type serializer plugins.
0022  *
0023  * Serializer plugins convert between the payload of Akonadi::Item objects and
0024  * a textual or binary representation of the actual content data.
0025  * This allows to easily add support for new types to Akonadi.
0026  *
0027  * The following example shows how to implement a serializer plugin for
0028  * a new data type PimNote.
0029  *
0030  * The PimNote data structure:
0031  * @code
0032  * typedef struct {
0033  *   QString author;
0034  *   QDateTime dateTime;
0035  *   QString text;
0036  * } PimNote;
0037  * @endcode
0038  *
0039  * The serializer plugin code:
0040  * @code
0041  * #include <qplugin.h>
0042  *
0043  * class SerializerPluginPimNote : public QObject, public Akonadi::ItemSerializerPlugin
0044  * {
0045  *   Q_OBJECT
0046  *   Q_INTERFACES( Akonadi::ItemSerializerPlugin )
0047  *
0048  *   public:
0049  *     bool deserialize( Akonadi::Item& item, const QByteArray& label, QIODevice& data, int version )
0050  *     {
0051  *       // we don't handle versions in this example
0052  *       Q_UNUSED(version)
0053  *
0054  *       // we work only on full payload
0055  *       if ( label != Akonadi::Item::FullPayload )
0056  *         return false;
0057  *
0058  *       QDataStream stream( &data );
0059  *
0060  *       PimNote note;
0061  *       stream >> note.author;
0062  *       stream >> note.dateTime;
0063  *       stream >> note.text;
0064  *
0065  *       item.setPayload<PimNote>( note );
0066  *
0067  *       return true;
0068  *     }
0069  *
0070  *     void serialize( const Akonadi::Item& item, const QByteArray& label, QIODevice& data, int &version )
0071  *     {
0072  *       // we don't handle versions in this example
0073  *       Q_UNUSED(version)
0074  *
0075  *       if ( label != Akonadi::Item::FullPayload || !item.hasPayload<PimNote>() )
0076  *         return;
0077  *
0078  *       QDataStream stream( &data );
0079  *
0080  *       PimNote note = item.payload<PimNote>();
0081  *
0082  *       stream << note.author;
0083  *       stream << note.dateTime;
0084  *       stream << note.text;
0085  *     }
0086  * };
0087  *
0088  * Q_EXPORT_PLUGIN2( akonadi_serializer_pimnote, SerializerPluginPimNote )
0089  *
0090  * @endcode
0091  *
0092  * The desktop file:
0093  * @code
0094  * [Misc]
0095  * Name=Pim Note Serializer
0096  * Comment=An Akonadi serializer plugin for note objects
0097  *
0098  * [Plugin]
0099  * Type=application/x-pimnote
0100  * X-KDE-Library=akonadi_serializer_pimnote
0101  * @endcode
0102  *
0103  * @author Till Adam <adam@kde.org>, Volker Krause <vkrause@kde.org>
0104  */
0105 class AKONADICORE_EXPORT ItemSerializerPlugin
0106 {
0107 public:
0108     /**
0109      * Destroys the item serializer plugin.
0110      */
0111     virtual ~ItemSerializerPlugin();
0112 
0113     /**
0114      * Converts serialized item data provided in @p data into payload for @p item.
0115      *
0116      * @param item The item to which the payload should be added.
0117      *             It is guaranteed to have a mime type matching one of the supported
0118      *             mime types of this plugin.
0119      *             However it might contain a unsuited payload added manually
0120      *             by the application developer.
0121      *             Verifying the payload type in case a payload is already available
0122      *             is recommended therefore.
0123      * @param label The part identifier of the part to deserialize.
0124      *              @p label might be an unsupported item part, return @c false if this is the case.
0125      * @param data A QIODevice providing access to the serialized data.
0126      *             The QIODevice is opened in read-only mode and positioned at the beginning.
0127      *             The QIODevice is guaranteed to be valid.
0128      * @param version The version of the data format as set by the user in serialize() or @c 0 (default).
0129      * @return @c false if the specified part is not supported by this plugin, @c true if the part
0130      *            could be de-serialized successfully.
0131      */
0132     virtual bool deserialize(Item &item, const QByteArray &label, QIODevice &data, int version) = 0;
0133 
0134     /**
0135      * Convert the payload object provided in @p item into its serialzed form into @p data.
0136      *
0137      * @param item The item which contains the payload.
0138      *             It is guaranteed to have a mimetype matching one of the supported
0139      *             mimetypes of this plugin as well as the existence of a payload object.
0140      *             However it might contain an unsupported payload added manually by
0141      *             the application developer.
0142      *             Verifying the payload type is recommended therefore.
0143      * @param label The part identifier of the part to serialize.
0144      *              @p label will be one of the item parts returned by parts().
0145      * @param data The QIODevice where the serialized data should be written to.
0146      *             The QIODevice is opened in write-only mode and positioned at the beginning.
0147      *             The QIODevice is guaranteed to be valid.
0148      * @param version The version of the data format. Can be set by the user to handle different
0149      *                versions.
0150      */
0151     virtual void serialize(const Item &item, const QByteArray &label, QIODevice &data, int &version) = 0;
0152 
0153     /**
0154      * Returns a list of available parts for the given item payload.
0155      * The default implementation returns Item::FullPayload if a payload is set.
0156      *
0157      * @param item The item.
0158      */
0159     virtual QSet<QByteArray> parts(const Item &item) const;
0160 
0161     /**
0162      * Override the plugin-lookup with @p plugin.
0163      *
0164      * After calling this each lookup will always return @p plugin.
0165      * This is useful to inject a special plugin for testing purposes.
0166      * To reset the plugin, set to 0.
0167      *
0168      * @since 4.12
0169      */
0170     static void overridePluginLookup(QObject *plugin);
0171 
0172     /**
0173      * Merges the payload parts in @p other into @p item.
0174      *
0175      * The default implementation is slow as it requires serializing @p other, and deserializing @p item multiple times.
0176      * Reimplementing this is recommended if your type uses payload parts.
0177      * @param item receives merged parts from @p other
0178      * @param other the paylod parts to merge into @p item
0179      * @since 4.4
0180      */
0181     virtual void apply(Item &item, const Item &other);
0182 
0183     /**
0184      * Returns the parts available in the item @p item.
0185      *
0186      * This should be reimplemented to return available parts.
0187      *
0188      * The default implementation returns an empty set if the item has a payload,
0189      * and a set containing Item::FullPayload if the item has no payload.
0190      * @param item the item for which to list payload parts
0191      * @since 4.4
0192      */
0193     virtual QSet<QByteArray> availableParts(const Item &item) const;
0194 
0195     /**
0196      * Returns the parts available in the item @p item that can be stored using
0197      * foreign payload mechanism. Is only called for items whose payload has been
0198      * set via Item::setPayloadPath().
0199      *
0200      * By default returns "RFC822", which can always be stored as foreign payload.
0201      * Some implementations can also allow "HEAD" to be stored as foreign payload,
0202      * if HEAD is only a subset of RFC822 part.
0203      *
0204      * @since 5.7
0205      */
0206     virtual QSet<QByteArray> allowedForeignParts(const Item &item) const;
0207 
0208 protected:
0209     explicit ItemSerializerPlugin() = default;
0210 
0211 private:
0212     Q_DISABLE_COPY_MOVE(ItemSerializerPlugin)
0213 };
0214 
0215 }
0216 
0217 Q_DECLARE_INTERFACE(Akonadi::ItemSerializerPlugin, "org.freedesktop.Akonadi.ItemSerializerPlugin/2.0")