Akonadi

dbus.cpp
1 /*
2  SPDX-FileCopyrightText: 2011 Volker Krause <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "dbus_p.h"
8 #include "instance_p.h"
9 
10 #include <QString>
11 #include <QStringList>
12 #include <QStringView>
13 #include <QVector>
14 
15 #include <array>
16 
17 using namespace Akonadi;
18 
19 #define AKONADI_DBUS_SERVER_SERVICE u"org.freedesktop.Akonadi"
20 #define AKONADI_DBUS_CONTROL_SERVICE u"org.freedesktop.Akonadi.Control"
21 #define AKONADI_DBUS_CONTROL_SERVICE_LOCK u"org.freedesktop.Akonadi.Control.lock"
22 #define AKONADI_DBUS_AGENTSERVER_SERVICE u"org.freedesktop.Akonadi.AgentServer"
23 #define AKONADI_DBUS_STORAGEJANITOR_SERVICE u"org.freedesktop.Akonadi.Janitor"
24 #define AKONADI_DBUS_SERVER_SERVICE_UPGRADING u"org.freedesktop.Akonadi.upgrading"
25 
26 static QString makeServiceName(QStringView base)
27 {
28  if (!Instance::hasIdentifier()) {
29  return base.toString();
30  }
31  return base + QLatin1Char('.') + Instance::identifier();
32 }
33 
34 QString DBus::serviceName(DBus::ServiceType serviceType)
35 {
36  switch (serviceType) {
37  case Server:
38  return makeServiceName(AKONADI_DBUS_SERVER_SERVICE);
39  case Control:
40  return makeServiceName(AKONADI_DBUS_CONTROL_SERVICE);
41  case ControlLock:
42  return makeServiceName(AKONADI_DBUS_CONTROL_SERVICE_LOCK);
43  case AgentServer:
44  return makeServiceName(AKONADI_DBUS_AGENTSERVER_SERVICE);
45  case StorageJanitor:
46  return makeServiceName(AKONADI_DBUS_STORAGEJANITOR_SERVICE);
47  case UpgradeIndicator:
48  return makeServiceName(AKONADI_DBUS_SERVER_SERVICE_UPGRADING);
49  }
50  Q_ASSERT(!"WTF?");
51  return QString();
52 }
53 
54 std::optional<DBus::AgentService> DBus::parseAgentServiceName(const QString &serviceName)
55 {
56  if (!serviceName.startsWith(AKONADI_DBUS_SERVER_SERVICE ".")) {
57  return std::nullopt;
58  }
59 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
60  const auto parts = serviceName.midRef(QStringView(AKONADI_DBUS_SERVER_SERVICE ".").length()).split(QLatin1Char('.'));
61 #else
62  const auto parts = QStringView(serviceName).mid(QStringView(AKONADI_DBUS_SERVER_SERVICE ".").length()).split(QLatin1Char('.'));
63 #endif
64  if ((parts.size() == 2 && !Akonadi::Instance::hasIdentifier())
65  || (parts.size() == 3 && Akonadi::Instance::hasIdentifier() && Akonadi::Instance::identifier() == parts.at(2))) {
66  // switch on parts.at( 0 )
67  if (parts.at(0) == QLatin1String("Agent")) {
68  return AgentService{parts.at(1).toString(), DBus::Agent};
69  } else if (parts.at(0) == QLatin1String("Resource")) {
70  return AgentService{parts.at(1).toString(), DBus::Resource};
71  } else if (parts.at(0) == QLatin1String("Preprocessor")) {
72  return AgentService{parts.at(1).toString(), DBus::Preprocessor};
73  } else {
74  return std::nullopt;
75  }
76  }
77 
78  return std::nullopt;
79 }
80 
81 QString DBus::agentServiceName(const QString &agentIdentifier, DBus::AgentType agentType)
82 {
83  Q_ASSERT(!agentIdentifier.isEmpty());
84  Q_ASSERT(agentType != Unknown);
85  QString serviceName = QStringLiteral(AKONADI_DBUS_SERVER_SERVICE ".");
86  switch (agentType) {
87  case Agent:
88  serviceName += QLatin1String("Agent.");
89  break;
90  case Resource:
91  serviceName += QLatin1String("Resource.");
92  break;
93  case Preprocessor:
94  serviceName += QLatin1String("Preprocessor.");
95  break;
96  default:
97  Q_ASSERT(!"WTF?");
98  }
99  serviceName += agentIdentifier;
100  if (Akonadi::Instance::hasIdentifier()) {
101  serviceName += QLatin1Char('.') % Akonadi::Instance::identifier();
102  }
103  return serviceName;
104 }
105 
106 std::optional<QString> DBus::parseInstanceIdentifier(const QString &serviceName)
107 {
108  constexpr std::array<QStringView, 5> services = {QStringView{AKONADI_DBUS_STORAGEJANITOR_SERVICE},
109  QStringView{AKONADI_DBUS_SERVER_SERVICE_UPGRADING},
110  QStringView{AKONADI_DBUS_AGENTSERVER_SERVICE},
111  QStringView{AKONADI_DBUS_CONTROL_SERVICE_LOCK},
112  QStringView{AKONADI_DBUS_CONTROL_SERVICE}};
113  for (const auto &service : services) {
114  if (serviceName.startsWith(service)) {
115  if (serviceName != service) {
116  return serviceName.mid(service.length() + 1); // +1 for the separator "."
117  }
118  return std::nullopt;
119  }
120  }
121 
122  if (serviceName.startsWith(QStringView{AKONADI_DBUS_SERVER_SERVICE})) {
123 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
124  const auto split = serviceName.splitRef(QLatin1Char('.'));
125 #else
126  const auto split = QStringView(serviceName).split(QLatin1Char('.'));
127 #endif
128  if (split.size() <= 3) {
129  return std::nullopt;
130  }
131 
132  // [0]org.[1]freedesktop.[2]Akonadi.[3]type.[4]identifier.[5]instance
133  if (split[3] == QStringView{u"Agent"} || split[3] == QStringView{u"Resource"} || split[3] == QStringView{u"Preprocessor"}) {
134  if (split.size() == 6) {
135  return split[5].toString();
136  } else {
137  return std::nullopt;
138  }
139  } else {
140  return split[3].toString();
141  }
142  }
143 
144  return std::nullopt;
145 }
QChar at(qsizetype n) const const
QStringRef midRef(int position, int n) const const
QStringView mid(qsizetype start) const const
QString toString() const const
bool isEmpty() const const
QVector< QStringRef > splitRef(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
Provides methods to control the Akonadi server process.
Definition: control.h:53
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
QVector< QStringRef > split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QString mid(int position, int n) const const
Helper integration between Akonadi and Qt.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Mon Jun 27 2022 04:01:06 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.