QtDataSync  4.2.0
A simple offline-first synchronisation framework, to synchronize data of Qt applications between devices
conflictresolver.h
1 #ifndef QTDATASYNC_CONFLICTRESOLVER_H
2 #define QTDATASYNC_CONFLICTRESOLVER_H
3 
4 #include <QtCore/qobject.h>
5 #include <QtCore/qscopedpointer.h>
6 
7 #include <QtJsonSerializer/qjsonserializer.h>
8 
9 #include "QtDataSync/qtdatasync_global.h"
10 #include "QtDataSync/defaults.h"
11 #include "QtDataSync/logger.h"
12 
13 namespace QtDataSync {
14 
15 class ConflictResolverPrivate;
17 class Q_DATASYNC_EXPORT ConflictResolver : public QObject
18 {
19  Q_OBJECT
20 
21 public:
23  explicit ConflictResolver(QObject *parent = nullptr);
24  ~ConflictResolver() override;
25 
27  void setDefaults(const Defaults &defaults);
28 
30  QString setupName() const;
32  virtual QByteArray name() const;
34  virtual QJsonObject resolveConflict(int typeId, const QJsonObject &data1, const QJsonObject &data2) const = 0;
35 
36 protected:
38  Defaults defaults() const;
40  Logger *logger() const;
42  QSettings *settings() const;
43 
44 private:
46 };
47 
49 template <typename T1, typename... Args>
51 {
52 public:
54  inline GenericConflictResolver(QObject *parent = nullptr) :
55  GenericConflictResolver<Args...>(parent)
56  {}
57 
59  inline QJsonObject resolveConflict(int typeId, const QJsonObject &data1, const QJsonObject &data2) const override {
60  if(typeId == qMetaTypeId<T1>()) {
61  try {
62  QObject scope;
63  const QJsonSerializer *ser = this->defaults().serializer();
64  auto d1 = ser->deserialize<T1>(data1, &scope);
65  auto d2 = ser->deserialize<T1>(data2, &scope);
66  return ser->serialize<T1>(resolveConflict(d1, d2, &scope));
67  } catch(NoConflictResultException&) {
68  return QJsonObject();
69  }
70  } else
71  return GenericConflictResolver<Args...>::resolveConflict(typeId, data1, data2);
72  }
73 
74 protected:
76  using NoConflictResultException = typename GenericConflictResolver<Args...>::NoConflictResultException;
77  //must be documented here because doxygen wont find it otherwise
103  virtual T1 resolveConflict(T1 data1, T1 data2, QObject *parent) const = 0;
104 };
105 
107 template <typename T1>
109 {
110 public:
112  inline GenericConflictResolver(QObject *parent = nullptr) :
113  ConflictResolver(parent)
114  {}
115 
116  inline QJsonObject resolveConflict(int typeId, const QJsonObject &data1, const QJsonObject &data2) const override {
117  if(typeId == qMetaTypeId<T1>()) {
118  try {
119  QObject scope;
120  const QJsonSerializer *ser = this->defaults().serializer();
121  auto d1 = ser->deserialize<T1>(data1, &scope);
122  auto d2 = ser->deserialize<T1>(data2, &scope);
123  return ser->serialize<T1>(resolveConflict(d1, d2, &scope));
124  } catch(NoConflictResultException&) {
125  return QJsonObject();
126  }
127  } else
128  return resolveUnknownConflict(typeId, data1, data2);
129  }
130 
131 protected:
133  class NoConflictResultException {};
134  //must be documented here because doxygen wont find it otherwise
160  virtual T1 resolveConflict(T1 data1, T1 data2, QObject *parent) const = 0;
161 
170  virtual inline QJsonObject resolveUnknownConflict(int typeId, const QJsonObject &data1, const QJsonObject &data2) const {
171  Q_UNUSED(data1)
172  Q_UNUSED(data2)
173  QT_DATASYNC_LOG_BASE.warning(logger()->loggingCategory()) << "Unsupported type in conflict resolver:"
174  << QMetaType::typeName(typeId);
175  return QJsonObject();
176  }
177 };
178 
179 }
180 
181 #endif // QTDATASYNC_CONFLICTRESOLVER_H
QJsonObject resolveConflict(int typeId, const QJsonObject &data1, const QJsonObject &data2) const override
The method called to resolve conflicts between two datasets.
#define QT_DATASYNC_LOG_BASE
Internal macro.
Definition: logger.h:38
virtual QJsonObject resolveUnknownConflict(int typeId, const QJsonObject &data1, const QJsonObject &data2) const
QJsonObject resolveConflict(int typeId, const QJsonObject &data1, const QJsonObject &data2) const override
The method called to resolve conflicts between two datasets.
A generic variant of the ConflictResolver to handel dataobjects instead of json data.
The primary namespace of the QtDataSync library.
GenericConflictResolver(QObject *parent=nullptr)
Default constructor.
QVariant deserialize(const QJsonValue &json, int metaTypeId, QObject *parent=nullptr) const
GenericConflictResolver(QObject *parent=nullptr)
Default constructor.
Interface to implement a custom conflict handler for sync conflicts.
const char * typeName(int typeId)
A helper class to get defaults per datasync instance (threadsafe)
Definition: defaults.h:61
QJsonValue serialize(const QVariant &data) const
A Helper class for simple and structured logging.
Definition: logger.h:14