dbusoperationqueuehandler.cpp
1 /*
2  * This file is part of signon
3  *
4  * Copyright (C) 2009-2010 Nokia Corporation.
5  *
6  * Contact: Aurel Popirtac <ext-aurel.popirtac@nokia.com>
7  * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * version 2.1 as published by the Free Software Foundation.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  */
23 
24 #include "dbusoperationqueuehandler.h"
25 
26 #include <QMetaMethod>
27 #include <QDebug>
28 #include <QMetaType>
29 
30 #include "libsignoncommon.h"
31 #include "identityinfo.h"
32 
33 /*
34  * @cond IMPL
35  */
36 namespace SignOn {
37 
38 /* --------------- DBusOperationQueueHandler::Operation ---------------- */
39 
40 DBusOperationQueueHandler::Operation::Operation(const char *name,
41  QList<QGenericArgument *> args)
42 {
43  copy(name, args);
44  qDeleteAll(args);
45 }
46 
47 void DBusOperationQueueHandler::Operation::copy(const char *name,
48  const QList<QGenericArgument *> &args)
49 {
50  Q_ASSERT(name != NULL);
51 
52  m_name = new char[qstrlen(name) + 1];
53  qstrcpy(m_name, name);
54 
55  QListIterator<QGenericArgument *> it(args);
56  while (it.hasNext()) {
57  QGenericArgument *arg = it.next();
58  int type = QMetaType::type(arg->name());
59  if (!QMetaType::isRegistered(type)) {
60  qCritical()
61  << Q_FUNC_INFO
62  << QString(QLatin1String("Type %1 not registered."))
63  .arg(QLatin1String(arg->name()));
64  } else {
65  Q_ASSERT(arg->name() != NULL);
66 
67  char *localName = new char[qstrlen(arg->name()) + 1];
68  qstrcpy(localName, arg->name());
69 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
70  void *localData = QMetaType::construct(type, arg->data());
71 #else
72  void *localData = QMetaType::create(type, arg->data());
73 #endif
74 
75  m_args << (new QGenericArgument(localName, localData));
76  }
77  }
78 }
79 
80 DBusOperationQueueHandler::Operation::~Operation()
81 {
82  if (m_name)
83  delete [] m_name;
84 
85  foreach (QGenericArgument *arg, m_args) {
86  QMetaType::destroy(QMetaType::type(arg->name()), arg->data());
87  if (arg->name())
88  delete [] arg->name();
89  delete arg;
90  }
91 }
92 
93 /* --------------------- DBusOperationQueueHandler --------------------- */
94 
95 DBusOperationQueueHandler::DBusOperationQueueHandler(QObject *clientObject):
96  m_clientObject(clientObject),
97  m_maxNumberOfOperationParameters(6),
98  m_operationsStopped(false)
99 {
100 }
101 
102 DBusOperationQueueHandler::~DBusOperationQueueHandler()
103 {
104 }
105 
106 void DBusOperationQueueHandler::enqueueOperation(Operation *operation)
107 {
108  m_operationsQueue.enqueue(operation);
109 }
110 
111 void DBusOperationQueueHandler::enqueueOperation(const char *name,
112  QList<QGenericArgument *> args)
113 {
114  m_operationsQueue.enqueue(new Operation(name, args));
115 }
116 
117 void DBusOperationQueueHandler::execQueuedOperations()
118 {
119  m_operationsStopped = false;
120 
121  while (m_operationsStopped == false && !m_operationsQueue.empty()) {
122  Operation *op = m_operationsQueue.dequeue();
123 
124  if (op->m_args.size() > m_maxNumberOfOperationParameters) {
125  qWarning() << "DBusOperationQueueHandler::execQueuedOperations(): "
126  "Maximum number of operation parameters exceeded(6).";
127  continue;
128  }
129 
130  int indexOfMethod = m_clientObject->metaObject()->indexOfMethod(
131  QMetaObject::normalizedSignature(op->m_name));
132 
133  QMetaMethod method = m_clientObject->metaObject()->method(indexOfMethod);
134 
135  TRACE() << "Executing cached oparation: SIGNATURE:" <<
136 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
137  method.signature();
138 #else
139  method.methodSignature();
140 #endif
141 
142  switch (op->m_args.count()) {
143  case 0: TRACE(); method.invoke(m_clientObject); break;
144  case 1: TRACE(); method.invoke(
145  m_clientObject,
146  *(op->m_args.at(0))); break;
147  case 2: TRACE(); method.invoke(
148  m_clientObject,
149  *(op->m_args.at(0)),
150  *(op->m_args.at(1))); break;
151  case 3: TRACE(); method.invoke(
152  m_clientObject,
153  *(op->m_args.at(0)),
154  *(op->m_args.at(1)),
155  *(op->m_args.at(2))); break;
156  case 4: TRACE(); method.invoke(
157  m_clientObject,
158  *(op->m_args.at(0)),
159  *(op->m_args.at(1)),
160  *(op->m_args.at(2)),
161  *(op->m_args.at(3))); break;
162  case 5: TRACE(); method.invoke(
163  m_clientObject,
164  *(op->m_args.at(0)),
165  *(op->m_args.at(1)),
166  *(op->m_args.at(2)),
167  *(op->m_args.at(3)),
168  *(op->m_args.at(4))); break;
169  case 6: TRACE(); method.invoke(
170  m_clientObject,
171  *(op->m_args.at(0)),
172  *(op->m_args.at(1)),
173  *(op->m_args.at(2)),
174  *(op->m_args.at(3)),
175  *(op->m_args.at(4)),
176  *(op->m_args.at(5))); break;
177  default: TRACE(); method.invoke(m_clientObject); break;
178  }
179  delete op;
180  }
181 }
182 
183 void DBusOperationQueueHandler::removeOperation(const char *name, bool removeAll)
184 {
185  foreach (Operation *operation, m_operationsQueue) {
186  if (operation != NULL && qstrcmp(operation->m_name, name) == 0) {
187  m_operationsQueue.removeOne(operation);
188  if (!removeAll)
189  break;
190  }
191  }
192 }
193 
194 bool DBusOperationQueueHandler::queueContainsOperation(const char *name)
195 {
196  foreach (Operation *operation, m_operationsQueue)
197  if (operation != NULL && qstrcmp(operation->m_name, name) == 0)
198  return true;
199 
200  return false;
201 }
202 
203 } //SignOn
204 /*
205  * @endcond IMPL
206  */