smf/smfservermodule/smfserver/pluginmgr/smfpluginmanager.cpp
changeset 10 1d94eb8df9c2
parent 9 b85b0c039c14
equal deleted inserted replaced
9:b85b0c039c14 10:1d94eb8df9c2
     1 /**
       
     2  * Copyright (c) 2010 Sasken Communication Technologies Ltd.
       
     3  * All rights reserved.
       
     4  * This component and the accompanying materials are made available
       
     5  * under the terms of the "Eclipse Public License v1.0" 
       
     6  * which accompanies  this distribution, and is available
       
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html"
       
     8  *
       
     9  * Initial Contributors:
       
    10  * Chandradeep Gandhi, Sasken Communication Technologies Ltd - Initial contribution
       
    11  *
       
    12  * Contributors:
       
    13  * Manasij Roy, Nalina Hariharan
       
    14  * 
       
    15  * Description:
       
    16  * The Plugin Manager class manages the loading and unloading of plug-ins
       
    17  *
       
    18  */
       
    19 
       
    20 #include <QDir>
       
    21 #include <QLibraryInfo>
       
    22 #include <QFileSystemWatcher>
       
    23 #include <QPluginLoader>
       
    24 #include <QList>
       
    25 #include <smfpluginbase.h>
       
    26 #include <smfpluginutil.h>
       
    27 #include <smfprovider.h>
       
    28 
       
    29 #include "smfpluginmanager.h"
       
    30 #include "smfpluginmanagerutil.h"
       
    31 #include "smftransportmanagerutil.h"
       
    32 
       
    33 // Static data initialisation
       
    34 SmfPluginManager* SmfPluginManager::m_myInstance = NULL;
       
    35 
       
    36 
       
    37 /**
       
    38  * Method to get the instance of SmfPluginManager class
       
    39  * @param aServer The Smf server instance
       
    40  * @return The instance of SmfPluginManager class
       
    41  */
       
    42 SmfPluginManager* SmfPluginManager::getInstance ( SmfServer *aServer)
       
    43 	{
       
    44 	if(NULL == m_myInstance)
       
    45 		m_myInstance = new SmfPluginManager(aServer);
       
    46 	return m_myInstance;
       
    47 	}
       
    48 
       
    49 
       
    50 /**
       
    51  * Constructor with default argument
       
    52  * @param aServer The Smf server instance
       
    53  */
       
    54 SmfPluginManager::SmfPluginManager ( SmfServer *aServer )
       
    55 	{
       
    56 	// Save the server instance
       
    57 	m_server = aServer;
       
    58 	
       
    59 	m_server->writeLog("Inside SmfPluginManager::SmfPluginManager()");
       
    60 	
       
    61 	// initialize the file watcher to monitor plugin addition/upgradation/removal
       
    62 	initializeFileWatcher ( );
       
    63 	
       
    64 	// create a database to store the folder structure of the path "c://resource//qt//plugins"
       
    65 	initializeSmfPluginDataBase ( );
       
    66 	
       
    67 	// create teh Plugin Manager utility class instance
       
    68 	m_util = new SmfPluginManagerUtil(this);
       
    69 	
       
    70 	// Get handle to the Transport MAnager utility instance
       
    71 	m_transMngrUtil = SmfTransportManagerUtil::getInstance();
       
    72 	}
       
    73 
       
    74 
       
    75 /**
       
    76  * Destructor
       
    77  */
       
    78 SmfPluginManager::~SmfPluginManager ( )
       
    79 	{
       
    80 	m_server->writeLog("Inside SmfPluginManager::~SmfPluginManager()");
       
    81 	if(m_fileWatcher)
       
    82 		delete m_fileWatcher;
       
    83 	
       
    84 	if(m_tempStruct)
       
    85 		delete m_tempStruct;
       
    86 	
       
    87 	if(m_waitingPluginHash.count() > 0)
       
    88 		{
       
    89 		foreach(SmfWaitingPluginInfoStruc *str, m_waitingPluginHash.values())
       
    90 			delete str;
       
    91 		}
       
    92 	
       
    93 	if(m_util)
       
    94 		delete m_util;
       
    95 	
       
    96 	if(m_pluginDataBase.isOpen())
       
    97 		{
       
    98 		m_pluginDataBase.close();
       
    99 		m_pluginDataBase.removeDatabase("SmfPluginsInfoDatabase");
       
   100 		}
       
   101 	
       
   102 	// unload all loaded plugins
       
   103 	unload(m_pluginLoaderHash.keys());
       
   104 	
       
   105 	if(m_myInstance)
       
   106 		delete m_myInstance;
       
   107 	}
       
   108 
       
   109 
       
   110 /**
       
   111  * Method called by Smf server to create a web query.
       
   112  * Plugin Manager calls the appropriate web query creation method 
       
   113  * using the aOperation and aInputData parameters. Once the web request 
       
   114  * is ready, it calls the appropriate methods exposed by the Transport 
       
   115  * Manager to send the network request.
       
   116  * @param aSessionID The session ID provided by Smf Server
       
   117  * @param aPluginID The plugin ID that need to perform this operation
       
   118  * @param aOperation The type of operation to be performed
       
   119  * @param aInputData The data required to create the web query
       
   120  * @return SmfPluginManagerResult The result of the operation
       
   121  * @see smfglobal.h
       
   122  */
       
   123 SmfPluginManagerResult SmfPluginManager::createRequest ( const quint32& aSessionID, 
       
   124 		const QString& aPluginID, 
       
   125 		const SmfRequestTypeID& aOperation, 
       
   126 		QByteArray& aInputData )
       
   127 	{
       
   128 	m_server->writeLog("Inside SmfPluginManager::createRequest()");
       
   129 	
       
   130 	SmfPluginManagerResult result = SmfPluginUnknownError;
       
   131 
       
   132 	// Load the plugin
       
   133 	QObject *plugin = load(aPluginID, result);
       
   134 	
       
   135 	// Check if plugin is loaded
       
   136 	if(plugin && (SmfPluginLoaded == result))
       
   137 		{
       
   138 		m_server->writeLog("Plugin loaded");
       
   139 		SmfPluginBase* instance = qobject_cast<SmfPluginBase *>(plugin);
       
   140 		
       
   141 		if(instance)
       
   142 		{
       
   143 		// Get the registration token of the plugin
       
   144 		QString regToken = instance->getProviderInfo()->smfRegistrationId();
       
   145 		QList<QUrl> urlList;
       
   146 		SmfPluginRequestData reqData;
       
   147 
       
   148 		// check if the plugin is authorised (with CSM)
       
   149 		if( authorisePlugin(regToken, urlList ))
       
   150 			{
       
   151 			m_server->writeLog("Plugin authorised");
       
   152 			
       
   153 			// call the utility method to create plugin specific request
       
   154 			m_util->createRequest(plugin, aOperation, aInputData, reqData, result);
       
   155 
       
   156 			// If the request is created successfully, call the TM method to send the request
       
   157 			if( SmfPluginRequestCreated == result )
       
   158 				{
       
   159 				m_server->writeLog("Plugin request creation successful");
       
   160 				m_tempStruct = new SmfWaitingPluginInfoStruc();
       
   161 				m_tempStruct->iSessionID = aSessionID;
       
   162 				m_tempStruct->iPluginId = aPluginID;
       
   163 				m_tempStruct->iInstance = instance;
       
   164 				m_tempStruct->iOperation = aOperation;
       
   165 				m_tempStruct->iInputData = aInputData;
       
   166 				m_tempStruct->iUrlList = urlList;
       
   167 			
       
   168 				// send the request
       
   169 				sendRequest ( reqData, result, urlList );
       
   170 				}
       
   171 			}
       
   172 		
       
   173 		else
       
   174 			{
       
   175 			// plugin not authorised, so unload
       
   176 			m_server->writeLog("Plugin not authorised!!!");
       
   177 			unload(instance);
       
   178 			result = SmfPluginNotAuthorised;
       
   179 			}
       
   180 		}
       
   181 		else
       
   182 			{
       
   183 			// plugin instance cannot be casted, so unload
       
   184 			m_server->writeLog("Plugin instance cannot be casted to SmfPluginBase*!!!");
       
   185 			unload(instance);
       
   186 			result = SmfPluginLoadError;
       
   187 			}
       
   188 		}
       
   189 
       
   190 	else
       
   191 		{
       
   192 		// plugin not loaded
       
   193 		m_server->writeLog("Plugin not loaded!!!");
       
   194 		result = SmfPluginLoadError;
       
   195 		}
       
   196 	
       
   197 	return result;
       
   198 	}
       
   199 
       
   200 
       
   201 /**
       
   202  * Method called by Transport Manager when network response is available
       
   203  * @param aTransportResult The result of Transport Operation
       
   204  * @param aReply The QNetworkReply instance that requested 
       
   205  * this transaction
       
   206  * @param aResponse The network response data, may be NULL for error
       
   207  */
       
   208 void SmfPluginManager::responseAvailable ( 
       
   209 		const SmfTransportResult &aTransportResult, 
       
   210 		QNetworkReply *aReply,
       
   211 		QByteArray *aResponse )
       
   212 	{
       
   213 	m_server->writeLog("Inside SmfPluginManager::responseAvailable()");
       
   214 		
       
   215 	// For request success or For request cancellation
       
   216 	if((SmfTransportOpNoError == aTransportResult) || 
       
   217 			(SmfTransportOpOperationCanceledError == aTransportResult))
       
   218 			{
       
   219 		m_server->writeLog("no transport error/ cancellation");
       
   220 
       
   221 			// get the details of the plugin which made this request
       
   222 			SmfWaitingPluginInfoStruc* info = m_waitingPluginHash.value(aReply);
       
   223 			quint32 sessionId = m_waitingPluginHash.value(aReply)->iSessionID;
       
   224 			QString pluginId = m_waitingPluginHash.value(aReply)->iPluginId;
       
   225 			SmfRequestTypeID operation = m_waitingPluginHash.value(aReply)->iOperation;
       
   226 			QByteArray inputData = m_waitingPluginHash.value(aReply)->iInputData;
       
   227 			
       
   228 			QVariant result;
       
   229 			SmfPluginRetType retType = SmfRequestError;
       
   230 			SmfResultPage pageResult;
       
   231 			
       
   232 			m_server->writeLog("Before m_util->responseAvailable");
       
   233 			
       
   234 			// call the utility method to send response to appropriate plugins
       
   235 			SmfPluginManagerResult retValue = m_util->responseAvailable( info->iInstance, operation, 
       
   236 				aTransportResult, aResponse, &result, retType, pageResult );
       
   237 			
       
   238 			// remove the plugin from the waiting list
       
   239 			delete m_waitingPluginHash.value(aReply);
       
   240 			m_waitingPluginHash.remove(aReply);
       
   241 		
       
   242 			QByteArray arr;
       
   243 			QDataStream stream(&arr, QIODevice::ReadWrite);
       
   244 			if( SmfPluginResponseParsed == retValue )
       
   245 				{
       
   246 				m_server->writeLog("Parsing successful");
       
   247 				
       
   248 				// serialize the response to suitable class and pass the data to server
       
   249 				serializeResult(operation, &result, stream);
       
   250 			
       
   251 				////TODO:- send error in enums-by manasij
       
   252 				// Send the response data to the server
       
   253 				m_server->resultsAvailable(sessionId, &arr, SmfNoError);
       
   254 				}
       
   255 		
       
   256 			// Send the request again
       
   257 			else if( SmfPluginSendRequestAgain == retValue )
       
   258 				{
       
   259 				m_server->writeLog("Send request again");
       
   260 				
       
   261 				// create the request again (with same paramaters)
       
   262 				retValue = createRequest( sessionId, pluginId, operation, inputData );
       
   263 				}
       
   264 			
       
   265 			// Error
       
   266 			else
       
   267 				{
       
   268 				m_server->writeLog("Parsing failed!!");
       
   269 				
       
   270 				// Error in parsing, sent to server
       
   271 				m_server->resultsAvailable(sessionId, &arr, SmfpluginResponseParseFailure);
       
   272 				}
       
   273 		
       
   274 			// delete aReply later, when event loop is re-entered
       
   275 			aReply->deleteLater();
       
   276 			}
       
   277 	
       
   278 	// Any other error
       
   279 	else
       
   280 		{
       
   281 		m_server->writeLog("Error in SmfPluginManager::responseAvailable, Transport failure code : ");
       
   282 		QString err = QString::number(aTransportResult);
       
   283 		m_server->writeLog(err);
       
   284 		
       
   285 		//Added by manasij, send all kind of errors to the server
       
   286 		//TODO:- to be refined by PM owner
       
   287 		quint32 sessionId = m_waitingPluginHash.value(aReply)->iSessionID;
       
   288 		QByteArray arr;
       
   289 		m_server->resultsAvailable(sessionId, &arr, SmftransportInitNetworkNotAvailable);
       
   290 		}
       
   291 	}
       
   292 
       
   293 
       
   294 /**
       
   295  * Method to cancel the service request
       
   296  * @param aPluginId The plugin whose current operation 
       
   297  * is to be cancelled
       
   298  */
       
   299 bool SmfPluginManager::cancelRequest ( const QString& aPluginId )
       
   300 	{
       
   301 	bool retValue = false;
       
   302 	m_server->writeLog("Inside SmfPluginManager::cancelRequest()");
       
   303 	
       
   304 	// Get the plugin for which cancel is requested
       
   305 	foreach(SmfWaitingPluginInfoStruc* iPluginInfo, m_waitingPluginHash.values())
       
   306 		{
       
   307 		if( 0 == iPluginInfo->iPluginId.compare(aPluginId))
       
   308 			{
       
   309 			m_server->writeLog("Plugin to be cancelled found in the waiting list");
       
   310 			
       
   311 			// Notify Transport Manager
       
   312 			m_transMngrUtil->cancelRequest(m_waitingPluginHash.key(iPluginInfo));
       
   313 			
       
   314 			// Notify the plugin that the request has been cancelled
       
   315 			SmfPluginRetType retType;
       
   316 			SmfResultPage pageResult;
       
   317 			SmfPluginError ret = iPluginInfo->iInstance->responseAvailable( SmfTransportOpCancelled, 
       
   318 					NULL, NULL, retType, pageResult );
       
   319 			
       
   320 			// Remove that plugin from the waiting list
       
   321 			delete (m_waitingPluginHash.value(m_waitingPluginHash.key(iPluginInfo)));
       
   322 			m_waitingPluginHash.remove(m_waitingPluginHash.key(iPluginInfo));
       
   323 			
       
   324 			if(SmfPluginErrNone == ret)
       
   325 				retValue = true;
       
   326 			}
       
   327 		//else , cancel requested for a plugin which is not loaded, do nothing
       
   328 		else
       
   329 			{
       
   330 			m_server->writeLog("Plugin to be cancelled not found in the waiting list!!! - do nothing");
       
   331 			retValue =  false;
       
   332 		}
       
   333 		}
       
   334 	return retValue;
       
   335 	}
       
   336 
       
   337 
       
   338 /**
       
   339  * Method called to initialize the file watcher watching the file  
       
   340  * system for adition/upgradation/removal of plugins
       
   341  */
       
   342 void SmfPluginManager::initializeFileWatcher ( )
       
   343 	{
       
   344 	m_server->writeLog("Inside SmfPluginManager::initializeFileWatcher()");
       
   345 	
       
   346 	// Create the file watcher for the plugins in /Smf folder of the Qt plugin directory
       
   347 	m_fileWatcher = new QFileSystemWatcher(this);
       
   348 	
       
   349 	// Get the directory having the Qt plugin stubs
       
   350 	QDir dir(QLibraryInfo::location(QLibraryInfo::PluginsPath));
       
   351 	
       
   352 	// If Smf folder exists
       
   353 	if(dir.cd("smf/plugin"))
       
   354 		{
       
   355 		// Add each service provider folders to the file watcher
       
   356 		foreach(QString folder, dir.entryList(QDir::AllDirs))
       
   357 			{
       
   358 			dir.cd(folder);
       
   359 			m_fileWatcher->addPath(dir.absolutePath());
       
   360 			dir.cdUp();
       
   361 			}
       
   362 		}
       
   363 	else
       
   364 		m_fileWatcher->addPath(dir.absolutePath());
       
   365 	}
       
   366 
       
   367 
       
   368 
       
   369 /**
       
   370  * Method called to initialize the database holding the plugin 
       
   371  * directory sructure information. This is called only once when 
       
   372  * the Plugin Manager is instantiated.
       
   373  * This method creates and updates m_pluginIdPathHash member 
       
   374  * of this class
       
   375  */
       
   376 bool SmfPluginManager::initializeSmfPluginDataBase ( )
       
   377 	{
       
   378 	m_server->writeLog("Inside SmfPluginManager::initializeSmfPluginDataBase()");
       
   379 	
       
   380 	// Find QSQLite driver and create a connection to database
       
   381 	m_pluginDataBase.removeDatabase("SmfPluginsInfoDatabase");
       
   382 	m_pluginDataBase = QSqlDatabase::addDatabase("QSQLITE");
       
   383 	m_pluginDataBase.setDatabaseName("SmfPluginsInfoDatabase");
       
   384 	
       
   385 	// Open the database
       
   386 	bool opened = m_pluginDataBase.open();
       
   387 	if(!opened)
       
   388 		return false;
       
   389 	
       
   390 	m_server->writeLog("Database opened");
       
   391 	
       
   392 	// Create a query to create the DB table for Plugin Manager (if it doesn't exists)
       
   393 	QSqlQuery query;
       
   394 	bool tableCreated = false;
       
   395 
       
   396 	tableCreated = query.exec("CREATE TABLE IF NOT EXISTS pluginDetails ("
       
   397 			"pluginId TEXT PRIMARY KEY, interfaceName TEXT, serviceProvider TEXT, "
       
   398 			"description TEXT, serviceUrl TEXT, authAppId TEXT)");
       
   399 
       
   400 	// Error - table not created, Plugin Manager might not work properly
       
   401 	if(!tableCreated)
       
   402 		{
       
   403 		m_server->writeLog("Table not created, error = "+query.lastError().text());
       
   404 		return false;
       
   405 		}
       
   406 	
       
   407 	m_server->writeLog("Table created");
       
   408 	
       
   409 	// Get the directory having the Qt plugin stubs
       
   410 	QDir dir(QLibraryInfo::location(QLibraryInfo::PluginsPath));
       
   411 	
       
   412 	// If Smf folder exists
       
   413 	if(dir.cd("smf/plugin"))
       
   414 		{
       
   415 		m_server->writeLog("Smf/plugin folder exists");
       
   416 		// Get each interface folders names
       
   417 		foreach(QString intfName, dir.entryList(QDir::AllDirs))
       
   418 			{
       
   419 			dir.cd(intfName);
       
   420 			m_server->writeLog("Interface name : "+dir.dirName());
       
   421 			
       
   422 			// Get each plugin in this folder
       
   423 			foreach(QString pluginName, dir.entryList(QDir::Files))
       
   424 				{
       
   425 				m_server->writeLog("plugins for this Interface : "+pluginName);
       
   426 				
       
   427 				// load this plugin
       
   428 				QPluginLoader pluginLoader(dir.absoluteFilePath(pluginName));
       
   429 				QObject *instance = pluginLoader.instance();
       
   430 				if (instance)
       
   431 					{
       
   432 					m_server->writeLog("instance found");
       
   433 					SmfPluginBase* plugin = qobject_cast<SmfPluginBase *>(instance);
       
   434 				    if (plugin)
       
   435 				    	{
       
   436 						m_server->writeLog("SmfPluginBase found");
       
   437 						plugin->initialize(SmfPluginUtil::getInstance());
       
   438 				    
       
   439 						// get the plugin id
       
   440 						QString id = plugin->getProviderInfo()->pluginId();
       
   441 						
       
   442 						// get the interface implemented by the plugin
       
   443 						QString intfImplemented = dir.dirName();
       
   444 						intfImplemented.prepend("org.symbian.smf.plugin.");
       
   445 						m_server->writeLog("intfImplemented=");
       
   446 						m_server->writeLog(intfImplemented);
       
   447 						
       
   448 						// get the service provider
       
   449 						QString serProv = plugin->getProviderInfo()->serviceName();
       
   450 						
       
   451 						//get the description
       
   452 						QString desc = plugin->getProviderInfo()->description();
       
   453 						
       
   454 						// get the service URL
       
   455 						QString servURL = plugin->getProviderInfo()->serviceUrl().toString();
       
   456 						
       
   457 						// get the authentication application id
       
   458 						QString str;
       
   459 						QStringList list;
       
   460 						QString authAppId = plugin->getProviderInfo()->authenticationApp(
       
   461 								str, list, QIODevice::ReadWrite);
       
   462 						
       
   463 						// Update m_pluginIdPathHash
       
   464 						m_pluginIdPathHash.insert(id, dir.absoluteFilePath(pluginName));
       
   465 						
       
   466 						QSqlQuery rowInsertQuery;
       
   467 						
       
   468 						// insert into database
       
   469 						bool rowInserted = rowInsertQuery.exec(QString("INSERT INTO pluginDetails VALUES ('%1', "
       
   470 								"'%2', '%3', '%4', '%5', '%6')").arg(id).arg(intfImplemented).arg(serProv)
       
   471 								.arg(desc).arg(servURL).arg(authAppId));
       
   472 						
       
   473 						if(rowInserted)
       
   474 							m_server->writeLog("This Plugin's information is added to database : "+id+""
       
   475 									", "+intfImplemented+", "+serProv);
       
   476 						else
       
   477 							m_server->writeLog("plugins data not written to database, error = "+query.lastError().text());
       
   478 				    	}
       
   479 				    else
       
   480 				    	{
       
   481 						m_server->writeLog("Plugin could not be converted to SmfpluginBase* - returning");
       
   482 						
       
   483 						// Close the database
       
   484 						m_pluginDataBase.close();
       
   485 						
       
   486 				    	return false;
       
   487 				    	}
       
   488 				    
       
   489 				    pluginLoader.unload();
       
   490 					}
       
   491 				else
       
   492 					{
       
   493 					m_server->writeLog("Plugin could not be loaded - returning");
       
   494 					
       
   495 					// Close the database
       
   496 					m_pluginDataBase.close();
       
   497 										
       
   498 					return false;
       
   499 				}
       
   500 				}
       
   501 			dir.cdUp();
       
   502 			}
       
   503 		}
       
   504 	else
       
   505 		m_server->writeLog("No Smf plugins installed!!!");
       
   506 	
       
   507 	// Close the database
       
   508 	m_pluginDataBase.close();
       
   509 	
       
   510 	return true;
       
   511 	}
       
   512 
       
   513 
       
   514 
       
   515 /**
       
   516  * Method to load a plugin using its Plugin Id.
       
   517  * @param aPluginId The unique ID of the plugin 
       
   518  * @param aLoadResult [out] Output paramater indicating the result 
       
   519  * of the loading
       
   520  * @return The instance of the loaded plugin if loaded, else NULL
       
   521  */
       
   522 QObject* SmfPluginManager::load ( const QString &aPluginId,
       
   523 		SmfPluginManagerResult &aLoadResult)
       
   524 	{
       
   525 	m_server->writeLog("Inside SmfPluginManager::load()");
       
   526 	
       
   527 	QPluginLoader *pluginLoader;
       
   528 	
       
   529 	// Find the plugin Path
       
   530 	QString pluginPath = m_pluginIdPathHash.value(aPluginId);
       
   531 	
       
   532 	if(!pluginPath.isEmpty())
       
   533 		{
       
   534 		// create the plugin loader and load the plugin
       
   535 		pluginLoader = new QPluginLoader(pluginPath);
       
   536 		SmfPluginBase *plugin = qobject_cast<SmfPluginBase *>(pluginLoader->instance());
       
   537 		
       
   538 		// If the plugin is loaded
       
   539 		if( pluginLoader->isLoaded() && plugin )
       
   540 			{
       
   541 			// Initialize the plugin
       
   542 			plugin->initialize(SmfPluginUtil::getInstance());
       
   543 			
       
   544 			// update the plugin loader and the loaded plugin lists
       
   545 			m_pluginLoaderHash.insertMulti(plugin, pluginLoader);
       
   546 			aLoadResult = SmfPluginLoaded;
       
   547 			m_server->writeLog("Plugin loaded");
       
   548 			}
       
   549 		else
       
   550 			{
       
   551 			m_server->writeLog("Plugin not loaded");
       
   552 		
       
   553 			// Plugin could not be loaded, error
       
   554 			aLoadResult = SmfPluginNotLoaded;
       
   555 		}
       
   556 		}
       
   557 	else
       
   558 		{
       
   559 		m_server->writeLog("Plugin not found");
       
   560 		
       
   561 		// plugin not found in hash
       
   562 		aLoadResult = SmfPluginNotFound;
       
   563 		}
       
   564 	
       
   565 	return pluginLoader->instance();
       
   566 	}
       
   567 
       
   568 
       
   569 /**
       
   570  * Method to unload a loaded plugin. Returns true if success, else 
       
   571  * returns false.
       
   572  * @param aPlugin The plugin instance to be unloaded
       
   573  * @return Returns true if success, else returns false
       
   574  */
       
   575 bool SmfPluginManager::unload ( SmfPluginBase *aPlugin )
       
   576 	{
       
   577 	m_server->writeLog("Inside SmfPluginManager::unload()");
       
   578 	
       
   579 	// Get all the loaders for this plugin
       
   580 	QList<QPluginLoader*> loaderList = m_pluginLoaderHash.values(aPlugin);
       
   581 	bool unloaded = false;
       
   582 
       
   583 	foreach(QPluginLoader *loader, loaderList)
       
   584 		{
       
   585 		// for each loader unload the plugin
       
   586 		unloaded = loader->unload();
       
   587 		
       
   588 		// delete the instance of the loader
       
   589 		delete loader;
       
   590 		loader = NULL;
       
   591 		}
       
   592 	
       
   593 	// Remove the plugin and its associated loaders from the Hash
       
   594 	m_pluginLoaderHash.remove(aPlugin);
       
   595 	return unloaded;
       
   596 	}
       
   597 
       
   598 
       
   599 /**
       
   600  * Method to unload the list of loaded plugins. Returns true if all are 
       
   601  * success, else returns false if any one fails.
       
   602  * @param aPluginList The list of instances for all plugins that are 
       
   603  * to be unloaded
       
   604  * @return Returns true if all are success, else returns false if any 
       
   605  * one fails.
       
   606  */
       
   607 bool SmfPluginManager::unload ( const QList<SmfPluginBase *> &aPluginList)
       
   608 	{
       
   609 	m_server->writeLog("Inside SmfPluginManager::unload() - overloaded fn");
       
   610 	//unload all the required plugins
       
   611 	bool unloaded = true;
       
   612 	
       
   613 	foreach(SmfPluginBase *plugin, aPluginList)
       
   614 		{
       
   615 		// unload individual plugins in the list
       
   616 		bool ret = unload(plugin);
       
   617 		
       
   618 		// indicate error if any one of the plugin failed to unload
       
   619 		if(!ret)
       
   620 			unloaded = ret;
       
   621 		}
       
   622 	return unloaded;
       
   623 	}
       
   624 
       
   625 
       
   626 /**
       
   627  * Method that calls the Transport Manager Utility class method to 
       
   628  * send the request created by the plugins over the network
       
   629  * @param aReqData The request data created by the plugin
       
   630  * @param aResult [out] The output parameter indicating the result 
       
   631  * of this method
       
   632  * @param aUrlList The list of accessible Urls for this plugin
       
   633  * @see smfglobal.h
       
   634  */
       
   635 void SmfPluginManager::sendRequest ( SmfPluginRequestData &aReqData, 
       
   636 		SmfPluginManagerResult &aResult,
       
   637 		const QList<QUrl> &aUrlList )
       
   638 	{
       
   639 	m_server->writeLog("Inside SmfPluginManager::sendRequest()");
       
   640 	
       
   641 	QNetworkReply* reply;
       
   642 	bool sopCompliant = false;
       
   643 	
       
   644 	// Check the type of Http operation to be performed
       
   645 	switch(aReqData.iHttpOperationType)
       
   646 		{
       
   647 		// Http HEAD
       
   648 		case QNetworkAccessManager::HeadOperation:
       
   649 			reply = m_transMngrUtil->head(aReqData.iNetworkRequest, aUrlList, sopCompliant);
       
   650 			break;
       
   651 		
       
   652 		// Http GET
       
   653 		case QNetworkAccessManager::GetOperation:
       
   654 			reply = m_transMngrUtil->get(aReqData.iNetworkRequest, aUrlList, sopCompliant);
       
   655 			break;
       
   656 			
       
   657 		// Http PUT	
       
   658 		case QNetworkAccessManager::PutOperation:
       
   659 			reply = m_transMngrUtil->put(aReqData.iNetworkRequest, aReqData.iPostData->buffer(), aUrlList, sopCompliant);
       
   660 			break;
       
   661 			
       
   662 		// Http POST
       
   663 		case QNetworkAccessManager::PostOperation:
       
   664 			reply = m_transMngrUtil->post(aReqData.iNetworkRequest, aReqData.iPostData->buffer(), aUrlList, sopCompliant);
       
   665 			break;
       
   666 			
       
   667 		// Http DELETE
       
   668 		case QNetworkAccessManager::DeleteOperation:
       
   669 			reply = m_transMngrUtil->deleteResource(aReqData.iNetworkRequest, aUrlList, sopCompliant);
       
   670 			break;
       
   671 			
       
   672 		default:
       
   673 			aResult = SmfPluginUnknownService;
       
   674 			return;
       
   675 		}
       
   676 	
       
   677 	if( sopCompliant )
       
   678 		{
       
   679 		if( reply )
       
   680 			{
       
   681 			// SOP compliant, sending successful
       
   682 			m_waitingPluginHash.insert(reply, m_tempStruct);
       
   683 			m_tempStruct = NULL;
       
   684 			aResult = SmfPluginNoError;
       
   685 			
       
   686 			m_server->writeLog("No error, request sent");
       
   687 			
       
   688 			}
       
   689 		// reply is NULL, sending failed
       
   690 		else
       
   691 			{
       
   692 			m_server->writeLog("QNEtrworkReply returned error - not sent");
       
   693 			aResult = SmfPluginRequestSendingFailed;
       
   694 		}
       
   695 		}
       
   696 	
       
   697 	// SOP violation
       
   698 	else
       
   699 		{
       
   700 		m_server->writeLog("SOP checking failed");
       
   701 		aResult = SmfPluginSOPCheckFailed;
       
   702 	}
       
   703 	}
       
   704 
       
   705 
       
   706 /**
       
   707  * Method that checks if a plugin is authorised to make a request. 
       
   708  * This method communicates with Credential and Settings Manager 
       
   709  * through Smf server, giving the registration token and getting 
       
   710  * the valid url list if available for this plugin.
       
   711  * @param aRegToken The registration token given by the plugin
       
   712  * @param aUrlList [out] The list of Urls that the plugin can send 
       
   713  * request to (to be filled by CSM)
       
   714  * @return Returns true if plugin is authorised, else returns false.
       
   715  */
       
   716 bool SmfPluginManager::authorisePlugin( const QString &aRegToken, 
       
   717 		QList<QUrl> &aUrlList )
       
   718 	{
       
   719 	Q_UNUSED(aRegToken)
       
   720 	m_server->writeLog("Inside SmfPluginManager::authorisePlugin()");
       
   721 	
       
   722 #ifdef CSM_INTEGRATED
       
   723 // Get the valid URL list from CSM, giving the reg token
       
   724 	if(m_server->authorisePlugin(aRegToken, aUrlList))
       
   725 		return true;
       
   726 	else
       
   727 		return false;
       
   728 	
       
   729 #else
       
   730 // CSM STUBBING - start
       
   731 	QUrl url1 ("http://www.example.com");
       
   732 	QUrl url2 ("http://api.facebook.com");
       
   733 	QUrl url3 ("http://api.flickr.com");
       
   734 
       
   735 	aUrlList.append(url1);
       
   736 	aUrlList.append(url2);
       
   737 	aUrlList.append(url3);
       
   738 
       
   739 	return true;
       
   740 // CSM STUBBING - end
       
   741 #endif
       
   742 
       
   743 	}
       
   744 
       
   745 
       
   746 /**
       
   747  * Method to serialize the result of parsing (which is done by the 
       
   748  * plugins) to QByteArray to be sent to Smf server.
       
   749  * @param aOperation The type of operation to be performed
       
   750  * @param aResult The data to be serialized
       
   751  * @param aDataStream Stream to be written
       
   752  */
       
   753 void SmfPluginManager::serializeResult ( 
       
   754 		const SmfRequestTypeID &aOperation, 
       
   755 		QVariant* aResult,
       
   756 		QDataStream &aDataStream )
       
   757 	{
       
   758 	m_server->writeLog("Inside SmfPluginManager::serializeResult()");
       
   759 	
       
   760 	// Call the utlity class method to serialize the result
       
   761 	m_util->serializeResult(aOperation, aResult, aDataStream);
       
   762 	}
       
   763 
       
   764 
       
   765 /**
       
   766  * Method for the directoryChanged signal of QFileSystemWatcher.
       
   767  * This will update the iPluginHash member and also the Plugin 
       
   768  * Information List.
       
   769  * @param aPath The path of the directory that has changed
       
   770  */
       
   771 void SmfPluginManager::directoryChanged ( const QString &aPath )
       
   772 	{
       
   773 	m_server->writeLog("Inside SmfPluginManager::directoryChanged()");
       
   774 	
       
   775 	// Create a QDir instance with the given path
       
   776 	QDir dir(aPath);
       
   777 	QString pluginId;
       
   778 	QString oldpluginId;
       
   779 	QString interfaceName;
       
   780 	QString serviceProv;
       
   781 	QString authAppId;
       
   782 
       
   783 	// Get all the files in the directory at a specified path(sorted)
       
   784 	QStringList newPlugins = dir.entryList(QDir::Files, QDir::Name);
       
   785 	QStringList::const_iterator newListIterator = newPlugins.constBegin();
       
   786 	
       
   787 	// Get all plugins who were in this path, before this directory was changed
       
   788 	QStringList availablePlugins = m_pluginIdPathHash.keys(aPath);
       
   789 	availablePlugins.sort();
       
   790 	QStringList::const_iterator oldListIterator = availablePlugins.constBegin();
       
   791 	
       
   792 	// Open the database
       
   793 	bool opened = m_pluginDataBase.open();
       
   794 	if(!opened)
       
   795 		;//return;
       
   796 	
       
   797 	// If plugin is changed
       
   798 	if( newPlugins.count() == availablePlugins.count() )
       
   799 		{
       
   800 		// Check for equality
       
   801 		while( newListIterator != newPlugins.constEnd() )
       
   802 			{
       
   803 			if( *newListIterator == *oldListIterator )
       
   804 				{
       
   805 				newListIterator++;
       
   806 				oldListIterator++;
       
   807 				}
       
   808 			else
       
   809 				break;
       
   810 			}
       
   811 		// replace *oldListIterator with *newListIterator
       
   812 		QHash<QString, QString>::iterator i = m_pluginIdPathHash.find(*oldListIterator);
       
   813 		m_pluginIdPathHash.insert(*newListIterator, i.value());
       
   814 		m_pluginIdPathHash.remove(*oldListIterator);
       
   815 		
       
   816 		// Also update database with *newListIterator
       
   817 	    QSqlQuery updateQuery;
       
   818 	    
       
   819 	    bool updated = updateQuery.exec(QString("UPDATE pluginDetails SET pluginId = '%1' "
       
   820 	    		"WHERE pluginId = '%2'").arg(*newListIterator).arg(*oldListIterator));
       
   821 	    if (!updated)
       
   822 	    	m_server->writeLog("Database table not updated, error = "+updateQuery.lastError().text());
       
   823 		
       
   824 		
       
   825 		// Get the new and old plugin Ids
       
   826 		pluginId = *newListIterator;
       
   827 		oldpluginId = *oldListIterator;
       
   828 		
       
   829 		// Load the plugin and get its service provider name
       
   830 		SmfPluginManagerResult result;
       
   831 		SmfPluginBase* instance = qobject_cast<SmfPluginBase *>(load(pluginId, result));
       
   832 		
       
   833 		if(instance && (SmfPluginLoaded == result))
       
   834 			{
       
   835 			instance->initialize(SmfPluginUtil::getInstance());
       
   836 			serviceProv = instance->getProviderInfo()->serviceName();
       
   837 			interfaceName = dir.dirName();
       
   838 			}
       
   839 		
       
   840 		unload(instance);
       
   841 		// Inform server that plugin has been changed
       
   842 #ifdef CSM_INTEGRATED
       
   843 		//Remove after Server Integration
       
   844 		m_server->pluginChanged(oldPluginId, newPluginId, interfaceName, serviceProv);
       
   845 #endif
       
   846 		}
       
   847 		
       
   848 	// If plugin is added
       
   849 	else if(newPlugins.count() > availablePlugins.count())
       
   850 		{
       
   851 		// Check for equality
       
   852 		while( oldListIterator != availablePlugins.constEnd() )
       
   853 			{
       
   854 			if( *newListIterator == *oldListIterator )
       
   855 				{
       
   856 				newListIterator++;
       
   857 				oldListIterator++;
       
   858 				}
       
   859 			else
       
   860 				break;
       
   861 			}
       
   862 		// replace *oldListIterator with *newListIterator
       
   863 		m_pluginIdPathHash.insert(*newListIterator, aPath);
       
   864 		
       
   865 		// Get the plugin Id
       
   866 		pluginId = *newListIterator;
       
   867 		
       
   868 		// Load the plugin and get its service provider name
       
   869 		SmfPluginManagerResult result;
       
   870 		SmfPluginBase* instance = qobject_cast<SmfPluginBase *>(load(pluginId, result));
       
   871 		
       
   872 		if(instance && (SmfPluginLoaded == result))
       
   873 			{
       
   874 			instance->initialize(SmfPluginUtil::getInstance());
       
   875 			serviceProv = instance->getProviderInfo()->serviceName();
       
   876 			interfaceName = dir.dirName();
       
   877 			interfaceName.prepend("org.symbian.smf.plugin.");
       
   878 			QString prgm;
       
   879 			QStringList list;
       
   880 			authAppId = instance->getProviderInfo()->authenticationApp(prgm, list, QIODevice::ReadWrite);
       
   881 			}
       
   882 		
       
   883 		unload(instance);
       
   884 		
       
   885 		// Also add to the database the value newListIterator and aPath
       
   886 		QSqlQuery insertRowQuery;
       
   887 		bool rowInserted = insertRowQuery.exec(QString("INSERT INTO pluginDetails VALUES "
       
   888 				"('%1', '%2', '%3', '%4')").arg(pluginId).arg(interfaceName).arg(serviceProv).arg(authAppId));
       
   889 
       
   890 		 // Error
       
   891 		if (!rowInserted)
       
   892 			m_server->writeLog("Database table not inserted, error = "+insertRowQuery.lastError().text());
       
   893 		
       
   894 		// Inform server that plugin has been added
       
   895 #ifdef CSM_INTEGRATED
       
   896 		//Remove after Server Integration
       
   897 		m_server->pluginAdded(pluginId, interfaceName, serviceProv);
       
   898 #endif
       
   899 		}
       
   900 	
       
   901 	// If plugin is removed
       
   902 	else //for newPlugins.count() < availablePlugins.count()
       
   903 		{
       
   904 		// Check for equality
       
   905 		while( newListIterator != newPlugins.constEnd() )
       
   906 			{
       
   907 			if( *newListIterator == *oldListIterator )
       
   908 				{
       
   909 				newListIterator++;
       
   910 				oldListIterator++;
       
   911 				}
       
   912 			else
       
   913 				break;
       
   914 			}
       
   915 		// remove *oldListIterator
       
   916 		m_pluginIdPathHash.remove(*oldListIterator);
       
   917 		
       
   918 		// Also remove oldListIterator from the database
       
   919 		QSqlQuery deleteRowQuery;
       
   920 		bool rowDeleted = deleteRowQuery.exec(QString("DELETE FROM pluginDetails WHERE pluginId = '%1'")
       
   921 				.arg(*oldListIterator));
       
   922 		 
       
   923 		// Error
       
   924 		if (!rowDeleted)
       
   925 			m_server->writeLog("Database table row not deleted, error = "+deleteRowQuery.lastError().text());
       
   926 		
       
   927 		// Get the plugin Id
       
   928 		pluginId = *oldListIterator;
       
   929 		
       
   930 		// Load the plugin and get its service provider name
       
   931 		SmfPluginManagerResult result;
       
   932 		SmfPluginBase* instance = qobject_cast<SmfPluginBase *>(load(pluginId, result));
       
   933 		
       
   934 		if(instance && (SmfPluginLoaded == result))
       
   935 			{
       
   936 			instance->initialize(SmfPluginUtil::getInstance());
       
   937 			serviceProv = instance->getProviderInfo()->serviceName();
       
   938 			interfaceName = dir.dirName();
       
   939 			}
       
   940 		
       
   941 		unload(instance);
       
   942 		// Inform server that plugin has removed
       
   943 #ifdef CSM_INTEGRATED
       
   944 		//Remove after Server Integration
       
   945 		m_server->pluginRemoved(pluginId, interfaceName, serviceProv);
       
   946 #endif
       
   947 		}
       
   948 	// Close the database
       
   949 	m_pluginDataBase.close();
       
   950 	}
       
   951 
       
   952 
       
   953 /**
       
   954  * Method to get the list of the SmfProvider for all the plugins that implement 
       
   955  * the mentioned Interface 
       
   956  * @param aInterface The interface for which list of plugins is required 
       
   957  * @param aMap The map of pluginID and its corresponding SmfProvider
       
   958  */
       
   959 void SmfPluginManager::getPlugins(const QString& aInterface, QMap<QString,SmfProvider>& aMap)
       
   960 	{
       
   961 	m_server->writeLog("Inside SmfPluginManager::getPlugins()");
       
   962 	
       
   963 	// Open the database
       
   964 	bool opened = m_pluginDataBase.open();
       
   965 	if(!opened)
       
   966 		{
       
   967 		m_server->writeLog("Data base not opened, exiting getplugins()");
       
   968 		return;
       
   969 		}
       
   970 	
       
   971 	m_server->writeLog("Data base opened");
       
   972 	
       
   973 	// Query the database for all pluginIDs that implement the given interface
       
   974 	QSqlQuery query(QString("SELECT pluginId, interfaceName, serviceProvider, description, "
       
   975 			"serviceUrl FROM pluginDetails where interfaceName = '%1'").arg(aInterface));
       
   976 	
       
   977 	if (query.next())
       
   978 		{
       
   979 		m_server->writeLog("Query is success");
       
   980 
       
   981 		SmfProvider prov;
       
   982 		
       
   983 		// get the pluginId
       
   984 		QString pluginId = query.value(0).toString();
       
   985 		
       
   986 		// get the service type / interface name
       
   987 		QStringList servicetypes;
       
   988 		servicetypes.insert(0, query.value(1).toString());
       
   989 		prov.serviceTypes(servicetypes);
       
   990 		
       
   991 		// Get the serv provider
       
   992 		QString servName = query.value(2).toString();
       
   993 		prov.serviceName(servName);
       
   994 		
       
   995 		// Get the description
       
   996 		QString desc = query.value(3).toString();
       
   997 		prov.description(desc);
       
   998 		
       
   999 		// Get the service URL
       
  1000 		QUrl url(query.value(4).toString());
       
  1001 	prov.serviceUrl(url);
       
  1002 
       
  1003 		aMap.insert(pluginId, prov);
       
  1004 		}
       
  1005 	else
       
  1006 		m_server->writeLog("Data base query->next() returned false, error = "+query.lastError().text());
       
  1007 	
       
  1008 	// Close the database
       
  1009 	m_pluginDataBase.close();
       
  1010 	}
       
  1011 
       
  1012 
       
  1013 /**
       
  1014  * Method to get the pluginID for the mentioned interface and service provider 
       
  1015  * @param aInterface The interface implemented by the plugin
       
  1016  * @param aProv The plugin's service provider
       
  1017  * @param aPluginId The required pluginID
       
  1018  */
       
  1019 void SmfPluginManager::getPluginId(const QString& aInterface, const SmfProvider& aProv, QString& aPluginId)
       
  1020 	{
       
  1021 	m_server->writeLog("SmfPluginManager::getPluginId");
       
  1022 	
       
  1023 	// Open the database
       
  1024 	bool opened = m_pluginDataBase.open();
       
  1025 	if(!opened)
       
  1026 		{
       
  1027 		m_server->writeLog("Data base not opened, exiting");
       
  1028 		return;
       
  1029 		}
       
  1030 	
       
  1031 	m_server->writeLog("Data base opened");
       
  1032 
       
  1033 	// Query the database for a pluginID with given interface name and service provider
       
  1034 	QSqlQuery query(QString("SELECT pluginId FROM pluginDetails where interfaceName = '%1' AND "
       
  1035 			"serviceProvider = '%2'").arg(aInterface).arg(aProv.serviceName()));
       
  1036 	
       
  1037 	if (query.next())
       
  1038 		{
       
  1039 		m_server->writeLog("Query is success");
       
  1040 		
       
  1041 		// get the pluginId
       
  1042 		aPluginId = query.value(0).toString();
       
  1043 		}
       
  1044 	else
       
  1045 		m_server->writeLog("Data base query->next() returned false, error = "+query.lastError().text());
       
  1046 	
       
  1047 	m_server->writeLog("returned pluginID = "+aPluginId);
       
  1048 	
       
  1049 	// Close the database
       
  1050 	m_pluginDataBase.close();
       
  1051 	}