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  void *localData = QMetaType::construct(type, arg->data());
70 
71  m_args << (new QGenericArgument(localName, localData));
72  }
73  }
74 }
75 
76 DBusOperationQueueHandler::Operation::~Operation()
77 {
78  if (m_name)
79  delete [] m_name;
80 
81  foreach (QGenericArgument *arg, m_args) {
82  QMetaType::destroy(QMetaType::type(arg->name()), arg->data());
83  if (arg->name())
84  delete [] arg->name();
85  delete arg;
86  }
87 }
88 
89 /* --------------------- DBusOperationQueueHandler --------------------- */
90 
91 DBusOperationQueueHandler::DBusOperationQueueHandler(QObject *clientObject):
92  m_clientObject(clientObject),
93  m_maxNumberOfOperationParameters(6),
94  m_operationsStopped(false)
95 {
96 }
97 
98 DBusOperationQueueHandler::~DBusOperationQueueHandler()
99 {
100 }
101 
102 void DBusOperationQueueHandler::enqueueOperation(Operation *operation)
103 {
104  m_operationsQueue.enqueue(operation);
105 }
106 
107 void DBusOperationQueueHandler::enqueueOperation(const char *name,
108  QList<QGenericArgument *> args)
109 {
110  m_operationsQueue.enqueue(new Operation(name, args));
111 }
112 
113 void DBusOperationQueueHandler::execQueuedOperations()
114 {
115  m_operationsStopped = false;
116 
117  while (m_operationsStopped == false && !m_operationsQueue.empty()) {
118  Operation *op = m_operationsQueue.dequeue();
119 
120  if (op->m_args.size() > m_maxNumberOfOperationParameters) {
121  qWarning() << "DBusOperationQueueHandler::execQueuedOperations(): "
122  "Maximum number of operation parameters exceeded(6).";
123  continue;
124  }
125 
126  int indexOfMethod = m_clientObject->metaObject()->indexOfMethod(
127  QMetaObject::normalizedSignature(op->m_name));
128 
129  QMetaMethod method = m_clientObject->metaObject()->method(indexOfMethod);
130 
131  TRACE() << "Executing cached oparation: SIGNATURE:" <<
132  method.signature();
133 
134  switch (op->m_args.count()) {
135  case 0: TRACE(); method.invoke(m_clientObject); break;
136  case 1: TRACE(); method.invoke(
137  m_clientObject,
138  *(op->m_args.at(0))); break;
139  case 2: TRACE(); method.invoke(
140  m_clientObject,
141  *(op->m_args.at(0)),
142  *(op->m_args.at(1))); break;
143  case 3: TRACE(); method.invoke(
144  m_clientObject,
145  *(op->m_args.at(0)),
146  *(op->m_args.at(1)),
147  *(op->m_args.at(2))); break;
148  case 4: TRACE(); method.invoke(
149  m_clientObject,
150  *(op->m_args.at(0)),
151  *(op->m_args.at(1)),
152  *(op->m_args.at(2)),
153  *(op->m_args.at(3))); break;
154  case 5: TRACE(); method.invoke(
155  m_clientObject,
156  *(op->m_args.at(0)),
157  *(op->m_args.at(1)),
158  *(op->m_args.at(2)),
159  *(op->m_args.at(3)),
160  *(op->m_args.at(4))); break;
161  case 6: TRACE(); method.invoke(
162  m_clientObject,
163  *(op->m_args.at(0)),
164  *(op->m_args.at(1)),
165  *(op->m_args.at(2)),
166  *(op->m_args.at(3)),
167  *(op->m_args.at(4)),
168  *(op->m_args.at(5))); break;
169  default: TRACE(); method.invoke(m_clientObject); break;
170  }
171  delete op;
172  }
173 }
174 
175 void DBusOperationQueueHandler::removeOperation(const char *name, bool removeAll)
176 {
177  foreach (Operation *operation, m_operationsQueue) {
178  if (operation != NULL && qstrcmp(operation->m_name, name) == 0) {
179  m_operationsQueue.removeOne(operation);
180  if (!removeAll)
181  break;
182  }
183  }
184 }
185 
186 bool DBusOperationQueueHandler::queueContainsOperation(const char *name)
187 {
188  foreach (Operation *operation, m_operationsQueue)
189  if (operation != NULL && qstrcmp(operation->m_name, name) == 0)
190  return true;
191 
192  return false;
193 }
194 
195 } //SignOn
196 /*
197  * @endcond IMPL
198  */