dbusoperationqueuehandler.cpp
00001 /*
00002  * This file is part of signon
00003  *
00004  * Copyright (C) 2009-2010 Nokia Corporation.
00005  *
00006  * Contact: Aurel Popirtac <ext-aurel.popirtac@nokia.com>
00007  * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public License
00011  * version 2.1 as published by the Free Software Foundation.
00012  *
00013  * This library is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00021  * 02110-1301 USA
00022  */
00023 
00024 #include "dbusoperationqueuehandler.h"
00025 
00026 #include <QMetaMethod>
00027 #include <QDebug>
00028 #include <QMetaType>
00029 
00030 #include "libsignoncommon.h"
00031 #include "identityinfo.h"
00032 
00033 /*
00034  * @cond IMPL
00035  */
00036 namespace SignOn {
00037 
00038 /* --------------- DBusOperationQueueHandler::Operation ---------------- */
00039 
00040 DBusOperationQueueHandler::Operation::Operation(const char *name,
00041                                                 QList<QGenericArgument *> args)
00042 {
00043     copy(name, args);
00044     qDeleteAll(args);
00045 }
00046 
00047 void DBusOperationQueueHandler::Operation::copy(const char *name,
00048                                                 const QList<QGenericArgument *> &args)
00049 {
00050     Q_ASSERT(name != NULL);
00051 
00052     m_name = new char[qstrlen(name) + 1];
00053     qstrcpy(m_name, name);
00054 
00055     QListIterator<QGenericArgument *> it(args);
00056     while (it.hasNext()) {
00057         QGenericArgument *arg = it.next();
00058         int type = QMetaType::type(arg->name());
00059         if (!QMetaType::isRegistered(type)) {
00060             qCritical()
00061                 << Q_FUNC_INFO
00062                 << QString(QLatin1String("Type %1 not registered."))
00063                 .arg(QLatin1String(arg->name()));
00064         } else {
00065             Q_ASSERT(arg->name() != NULL);
00066 
00067             char *localName = new char[qstrlen(arg->name()) + 1];
00068             qstrcpy(localName, arg->name());
00069             void *localData = QMetaType::construct(type, arg->data());
00070 
00071             m_args << (new QGenericArgument(localName, localData));
00072         }
00073     }
00074 }
00075 
00076 DBusOperationQueueHandler::Operation::~Operation()
00077 {
00078     if (m_name)
00079         delete [] m_name;
00080 
00081     foreach (QGenericArgument *arg, m_args) {
00082         QMetaType::destroy(QMetaType::type(arg->name()), arg->data());
00083         if (arg->name())
00084             delete [] arg->name();
00085         delete arg;
00086     }
00087 }
00088 
00089 /* --------------------- DBusOperationQueueHandler --------------------- */
00090 
00091 DBusOperationQueueHandler::DBusOperationQueueHandler(QObject *clientObject):
00092     m_clientObject(clientObject),
00093     m_maxNumberOfOperationParameters(6),
00094     m_operationsStopped(false)
00095 {
00096 }
00097 
00098 DBusOperationQueueHandler::~DBusOperationQueueHandler()
00099 {
00100 }
00101 
00102 void DBusOperationQueueHandler::enqueueOperation(Operation *operation)
00103 {
00104     m_operationsQueue.enqueue(operation);
00105 }
00106 
00107 void DBusOperationQueueHandler::enqueueOperation(const char *name,
00108                                                  QList<QGenericArgument *> args)
00109 {
00110     m_operationsQueue.enqueue(new Operation(name, args));
00111 }
00112 
00113 void DBusOperationQueueHandler::execQueuedOperations()
00114 {
00115     m_operationsStopped = false;
00116 
00117     while (m_operationsStopped == false && !m_operationsQueue.empty()) {
00118         Operation *op = m_operationsQueue.dequeue();
00119 
00120         if (op->m_args.size() > m_maxNumberOfOperationParameters) {
00121             qWarning() << "DBusOperationQueueHandler::execQueuedOperations(): "
00122                           "Maximum number of operation parameters exceeded(6).";
00123             continue;
00124         }
00125 
00126         int indexOfMethod = m_clientObject->metaObject()->indexOfMethod(
00127                                 QMetaObject::normalizedSignature(op->m_name));
00128 
00129         QMetaMethod method = m_clientObject->metaObject()->method(indexOfMethod);
00130 
00131         TRACE() << "Executing cached oparation: SIGNATURE:" <<
00132             method.signature();
00133 
00134         switch (op->m_args.count()) {
00135         case 0: TRACE(); method.invoke(m_clientObject); break;
00136         case 1: TRACE(); method.invoke(
00137                                     m_clientObject,
00138                                     *(op->m_args.at(0))); break;
00139         case 2: TRACE(); method.invoke(
00140                                     m_clientObject,
00141                                     *(op->m_args.at(0)),
00142                                     *(op->m_args.at(1))); break;
00143         case 3: TRACE(); method.invoke(
00144                                     m_clientObject,
00145                                     *(op->m_args.at(0)),
00146                                     *(op->m_args.at(1)),
00147                                     *(op->m_args.at(2))); break;
00148         case 4: TRACE(); method.invoke(
00149                                     m_clientObject,
00150                                     *(op->m_args.at(0)),
00151                                     *(op->m_args.at(1)),
00152                                     *(op->m_args.at(2)),
00153                                     *(op->m_args.at(3))); break;
00154         case 5: TRACE(); method.invoke(
00155                                     m_clientObject,
00156                                     *(op->m_args.at(0)),
00157                                     *(op->m_args.at(1)),
00158                                     *(op->m_args.at(2)),
00159                                     *(op->m_args.at(3)),
00160                                     *(op->m_args.at(4))); break;
00161         case 6: TRACE(); method.invoke(
00162                                     m_clientObject,
00163                                     *(op->m_args.at(0)),
00164                                     *(op->m_args.at(1)),
00165                                     *(op->m_args.at(2)),
00166                                     *(op->m_args.at(3)),
00167                                     *(op->m_args.at(4)),
00168                                     *(op->m_args.at(5))); break;
00169         default: TRACE(); method.invoke(m_clientObject); break;
00170         }
00171         delete op;
00172     }
00173 }
00174 
00175 void DBusOperationQueueHandler::removeOperation(const char *name, bool removeAll)
00176 {
00177     foreach (Operation *operation, m_operationsQueue) {
00178         if (operation != NULL && qstrcmp(operation->m_name, name) == 0) {
00179             m_operationsQueue.removeOne(operation);
00180             if (!removeAll)
00181                 break;
00182         }
00183     }
00184 }
00185 
00186 bool DBusOperationQueueHandler::queueContainsOperation(const char *name)
00187 {
00188     foreach (Operation *operation, m_operationsQueue)
00189         if (operation != NULL && qstrcmp(operation->m_name, name) == 0)
00190             return true;
00191 
00192     return false;
00193 }
00194 
00195 } //SignOn
00196 /*
00197  * @endcond IMPL
00198  */