123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- /*
- * ctkNetworkConnectorQXMLRPC.cpp
- * ctkEventBus
- *
- * Created by Daniele Giunchi on 11/04/10.
- * Copyright 2009 B3C. All rights reserved.
- *
- * See Licence at: http://tiny.cc/QXJ4D
- *
- */
- #include "ctkNetworkConnectorQXMLRPC.h"
- #include "ctkEventBusManager.h"
- #include <service/event/ctkEvent.h>
- using namespace ctkEventBus;
- ctkNetworkConnectorQXMLRPC::ctkNetworkConnectorQXMLRPC() : ctkNetworkConnector(), m_Client(NULL), m_Server(NULL), m_RequestId(0) {
- //generate remote signal, this signal must map in the
- //possible connection with the remote server.
- //Server, in this case XMLRPC, will register a method with id REMOTE_COMMUNICATION
- //and parameters QVariantList
- m_Protocol = "XMLRPC";
- }
- void ctkNetworkConnectorQXMLRPC::initializeForEventBus() {
- ctkRegisterRemoteSignal("ctk/remote/eventBus/comunication/send/xmlrpc", this, "remoteCommunication(const QString, ctkEventArgumentsList *)");
- ctkRegisterRemoteCallback("ctk/remote/eventBus/comunication/send/xmlrpc", this, "send(const QString, ctkEventArgumentsList *)");
- }
- ctkNetworkConnectorQXMLRPC::~ctkNetworkConnectorQXMLRPC() {
- if(m_Client) {
- delete m_Client;
- m_Client = NULL;
- }
- if(m_Server) {
- stopServer();
- }
- }
- //retrieve an instance of the object
- ctkNetworkConnector *ctkNetworkConnectorQXMLRPC::clone() {
- ctkNetworkConnectorQXMLRPC *copy = new ctkNetworkConnectorQXMLRPC();
- return copy;
- }
- void ctkNetworkConnectorQXMLRPC::createClient(const QString hostName, const unsigned int port) {
- bool result(false);
- if(m_Client == NULL) {
- m_Client = new xmlrpc::Client(NULL);
- result = connect( m_Client, SIGNAL(done( int, QVariant )),
- this, SLOT(processReturnValue( int, QVariant )) );
- result = connect( m_Client, SIGNAL(failed( int, int, QString )),
- this, SLOT(processFault( int, int, QString )) );
- }
- m_Client->setHost( hostName, port );
- }
- void ctkNetworkConnectorQXMLRPC::createServer(const unsigned int port) {
- if(m_Server != NULL) {
- unsigned int p = m_Server->property("port").toUInt();
- if(p != port) {
- stopServer();
- }
- }
- m_Server = new xmlrpc::Server(NULL);
- m_Server->setProperty("port", port);
- // Create a new ID to allow methods registration on new server instance.
- QString id_name(tr("ctk/remote/eventbus/communication/send/xmlrpc/serverMethods%1").arg(port));
- // Register the signal to the event bus.
- /*mafRegisterRemoteSignal(id_name, this, "registerMethodsServer(mafRegisterMethodsMap)");
- connect(this, SIGNAL(registerMethodsServer(mafRegisterMethodsMap)),
- this, SLOT(registerServerMethod(mafRegisterMethodsMap)));*/
- QList<QVariant::Type> parametersForRegisterteredFunction;
- parametersForRegisterteredFunction.append(QVariant::String); //return argument
- parametersForRegisterteredFunction.append(QVariant::List); //parameters to send, event control parameters
- parametersForRegisterteredFunction.append(QVariant::List); //parameters to send, data parameters
- //registration of the method maf.remote.eventBus.comunication.xmlrpc at XMLRPC level
- // the connect uses function name ad signature defined by parametersForRegisterteredFunction
- mafRegisterMethodsMap methodsMapping;
- methodsMapping.insert("ctk/remote/eventBus/comunication/send/xmlrpc", parametersForRegisterteredFunction);
- registerServerMethod(methodsMapping);
- //if a user want to register another method, it is important to know that ctkEventDispatcherRemote allows
- // the registration of function with QVariantList parameter.
- }
- void ctkNetworkConnectorQXMLRPC::stopServer() {
- unsigned int p = m_Server->property("port").toUInt();
- if(p != 0) {
- // get the ID for the previous server;
- /*QString old_id_name(tr("ctk/remote/eventbus/communication/send/xmlrpc/serverMethods%1").arg(p));
- // Remove the old signal.
- ctkBusEvent props;
- props[TOPIC] = old_id_name;
- props[TYPE] = ctkEventTypeRemote;
- props[SIGNATURE] = "registerMethodsServer(mafRegisterMethodsMap)";
- ctkEventBusManager::instance()->removeEventProperty(props);*/
- // Delete (and stop) the previous instance of the server.
- if(m_Server) {
- delete m_Server;
- m_Server = NULL;
- }
- }
- }
- void ctkNetworkConnectorQXMLRPC::registerServerMethod(mafRegisterMethodsMap registerMethodsList) {
- if(m_Server->isListening()) {
- qDebug("%s", tr("Server is already listening on port %1").arg(m_Server->property("port").toUInt()).toAscii().data());
- return;
- }
- // cycle over map: method name and parameter list
- foreach (QString key, registerMethodsList.keys()) {
- const unsigned int parametersNumber = registerMethodsList.value(key).count();
- switch(parametersNumber) {
- case 1:
- m_Server->registerMethod(key, registerMethodsList.value(key).at(0) );
- break;
- case 2:
- m_Server->registerMethod(key, registerMethodsList.value(key).at(0), registerMethodsList.value(key).at(1));
- break;
- case 3:
- m_Server->registerMethod(key, registerMethodsList.value(key).at(0), registerMethodsList.value(key).at(1), registerMethodsList.value(key).at(2));
- break;
- case 4:
- m_Server->registerMethod(key, registerMethodsList.value(key).at(0), registerMethodsList.value(key).at(1), registerMethodsList.value(key).at(2), registerMethodsList.value(key).at(3));
- break;
- case 5:
- m_Server->registerMethod(key, registerMethodsList.value(key).at(0), registerMethodsList.value(key).at(1), registerMethodsList.value(key).at(2), registerMethodsList.value(key).at(3) , registerMethodsList.value(key).at(4));
- break;
- default:
- break;
- }
- }
- }
- void ctkNetworkConnectorQXMLRPC::startListen() {
- connect( m_Server, SIGNAL(incomingRequest( int, QString, QList<xmlrpc::Variant>)),
- this, SLOT(processRequest( int, QString, QList<xmlrpc::Variant>)));
- unsigned int port = m_Server->property("port").toInt();
- if( m_Server->listen( port ) ) {
- qDebug() << "Listening for XML-RPC requests on port" << port;
- } else {
- qDebug() << "Error listening port" << port;
- }
- }
- void ctkNetworkConnectorQXMLRPC::send(const QString event_id, ctkEventArgumentsList *argList) {
- QList<xmlrpc::Variant> *vl = NULL;
- if(argList != NULL) {
- vl = new QList<xmlrpc::Variant>();
- int i=0, size = argList->count();
- for(;i<size;i++) {
- QString typeArgument;
- typeArgument = argList->at(i).name();
- if(typeArgument != "QVariantList") {
- qDebug() << typeArgument;
- qWarning("%s", tr("Remote Dispatcher need to have arguments that are QVariantList").toAscii().data());
- delete vl;
- return;
- }
- void *vp = argList->at(i).data();
- QVariantList *l;
- l = (QVariantList *)vp;
- xmlrpc::Variant var;
- var.setValue(*l);
- vl->push_back(var); //only the first parameter represent the whole list of arguments
- }
- if(size == 0) {
- qWarning("%s", tr("Remote Dispatcher need to have at least one argument that is a QVariantList").toAscii().data());
- return;
- }
- }
- xmlrpcSend(event_id, *vl);
- delete vl;
- }
- void ctkNetworkConnectorQXMLRPC::xmlrpcSend(const QString &methodName, QList<xmlrpc::Variant> parameters) {
- const unsigned int parametersNumber = parameters.count();
- switch(parametersNumber) {
- case 1:
- m_RequestId = m_Client->request(methodName, parameters.at(0) );
- break;
- case 2:
- m_RequestId = m_Client->request(methodName, parameters.at(0), parameters.at(1));
- break;
- case 3:
- m_RequestId = m_Client->request(methodName, parameters.at(0), parameters.at(1), parameters.at(2));
- break;
- case 4:
- m_RequestId = m_Client->request(methodName, parameters.at(0), parameters.at(1), parameters.at(2), parameters.at(3));
- break;
- default:
- break;
- }
- }
- void ctkNetworkConnectorQXMLRPC::processReturnValue( int requestId, QVariant value ) {
- Q_UNUSED( requestId );
- Q_ASSERT( value.canConvert( QVariant::String ) );
- qDebug("%s", value.toString().toAscii().data());
- ctkEventBusManager::instance()->notifyEvent("ctk/local/eventBus/remoteCommunicationDone", ctkEventTypeLocal);
- }
- void ctkNetworkConnectorQXMLRPC::processFault( int requestId, int errorCode, QString errorString ) {
- // Log the error.
- qDebug("%s", tr("Process Fault for requestID %1 with error %2 - %3").arg(QString::number(requestId), QString::number(errorCode), errorString).toAscii().data());
- ctkEventBusManager::instance()->notifyEvent("ctk/local/eventBus/remoteCommunicationFailed", ctkEventTypeLocal);
- }
- void ctkNetworkConnectorQXMLRPC::processRequest( int requestId, QString methodName, QList<xmlrpc::Variant> parameters ) {
- Q_UNUSED( methodName );
- //first parameter is ctkEventBus message
- enum {
- EVENT_PARAMETERS,
- DATA_PARAMETERS,
- };
- enum {
- EVENT_ID,
- EVENT_ITEM_TYPE,
- EVENT_SIGNATURE_TYPE,
- EVENT_METHOD_SIGNATURE,
- };
- if(parameters.at(EVENT_PARAMETERS).toList().count() == 0) {
- m_Server->sendReturnValue( requestId, QString("No Command to Execute, command list is empty") );
- }
- //here eventually can be used a filter for events
- //first argument regards local signal to be called.
- QString id_name = parameters.at(EVENT_PARAMETERS).toList().at(EVENT_ID).toString();
- int size = parameters.count();
- ctkEventArgumentsList *argList = NULL;
- QVariantList p;
- p.append((parameters.at(1).value< QVariantList >()));
- if(size > 1 && p.count() != 0) {
- argList = new ctkEventArgumentsList();
- argList->push_back(Q_ARG(QVariantList, p));
- }
- if ( ctkEventBusManager::instance()->isLocalSignalPresent(id_name) ) {
- ctkBusEvent dictionary(id_name,ctkEventTypeLocal,0,NULL,"");
- /*dictionary.setEventTopic(id_name);
- dictionary.setEventType(ctkEventTypeLocal);*/
- ctkEventBusManager::instance()->notifyEvent(dictionary, argList);
- m_Server->sendReturnValue( requestId, QString("OK") );
- } else {
- m_Server->sendReturnValue( requestId, QString("FAIL") );
- }
- if(argList){
- delete argList;
- argList = NULL;
- }
- }
|