smf/smfservermodule/smfserver/pluginmgr/smfpluginmanager.cpp
changeset 7 be09cf1f39dd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smf/smfservermodule/smfserver/pluginmgr/smfpluginmanager.cpp	Tue May 18 17:37:12 2010 +0530
@@ -0,0 +1,1051 @@
+/**
+ * Copyright (c) 2010 Sasken Communication Technologies Ltd.
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the "Eclipse Public License v1.0" 
+ * which accompanies  this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html"
+ *
+ * Initial Contributors:
+ * Chandradeep Gandhi, Sasken Communication Technologies Ltd - Initial contribution
+ *
+ * Contributors:
+ * Manasij Roy, Nalina Hariharan
+ * 
+ * Description:
+ * The Plugin Manager class manages the loading and unloading of plug-ins
+ *
+ */
+
+#include <QDir>
+#include <QLibraryInfo>
+#include <QFileSystemWatcher>
+#include <QPluginLoader>
+#include <QList>
+#include <smfpluginbase.h>
+#include <smfpluginutil.h>
+#include <smfprovider.h>
+
+#include "smfpluginmanager.h"
+#include "smfpluginmanagerutil.h"
+#include "smftransportmanagerutil.h"
+
+// Static data initialisation
+SmfPluginManager* SmfPluginManager::m_myInstance = NULL;
+
+
+/**
+ * Method to get the instance of SmfPluginManager class
+ * @param aServer The Smf server instance
+ * @return The instance of SmfPluginManager class
+ */
+SmfPluginManager* SmfPluginManager::getInstance ( SmfServer *aServer)
+	{
+	if(NULL == m_myInstance)
+		m_myInstance = new SmfPluginManager(aServer);
+	return m_myInstance;
+	}
+
+
+/**
+ * Constructor with default argument
+ * @param aServer The Smf server instance
+ */
+SmfPluginManager::SmfPluginManager ( SmfServer *aServer )
+	{
+	// Save the server instance
+	m_server = aServer;
+	
+	m_server->writeLog("Inside SmfPluginManager::SmfPluginManager()");
+	
+	// initialize the file watcher to monitor plugin addition/upgradation/removal
+	initializeFileWatcher ( );
+	
+	// create a database to store the folder structure of the path "c://resource//qt//plugins"
+	initializeSmfPluginDataBase ( );
+	
+	// create teh Plugin Manager utility class instance
+	m_util = new SmfPluginManagerUtil(this);
+	
+	// Get handle to the Transport MAnager utility instance
+	m_transMngrUtil = SmfTransportManagerUtil::getInstance();
+	}
+
+
+/**
+ * Destructor
+ */
+SmfPluginManager::~SmfPluginManager ( )
+	{
+	m_server->writeLog("Inside SmfPluginManager::~SmfPluginManager()");
+	if(m_fileWatcher)
+		delete m_fileWatcher;
+	
+	if(m_tempStruct)
+		delete m_tempStruct;
+	
+	if(m_waitingPluginHash.count() > 0)
+		{
+		foreach(SmfWaitingPluginInfoStruc *str, m_waitingPluginHash.values())
+			delete str;
+		}
+	
+	if(m_util)
+		delete m_util;
+	
+	if(m_pluginDataBase.isOpen())
+		{
+		m_pluginDataBase.close();
+		m_pluginDataBase.removeDatabase("SmfPluginsInfoDatabase");
+		}
+	
+	// unload all loaded plugins
+	unload(m_pluginLoaderHash.keys());
+	
+	if(m_myInstance)
+		delete m_myInstance;
+	}
+
+
+/**
+ * Method called by Smf server to create a web query.
+ * Plugin Manager calls the appropriate web query creation method 
+ * using the aOperation and aInputData parameters. Once the web request 
+ * is ready, it calls the appropriate methods exposed by the Transport 
+ * Manager to send the network request.
+ * @param aSessionID The session ID provided by Smf Server
+ * @param aPluginID The plugin ID that need to perform this operation
+ * @param aOperation The type of operation to be performed
+ * @param aInputData The data required to create the web query
+ * @return SmfPluginManagerResult The result of the operation
+ * @see smfglobal.h
+ */
+SmfPluginManagerResult SmfPluginManager::createRequest ( const quint32& aSessionID, 
+		const QString& aPluginID, 
+		const SmfRequestTypeID& aOperation, 
+		QByteArray& aInputData )
+	{
+	m_server->writeLog("Inside SmfPluginManager::createRequest()");
+	
+	SmfPluginManagerResult result = SmfPluginUnknownError;
+
+	// Load the plugin
+	QObject *plugin = load(aPluginID, result);
+	
+	// Check if plugin is loaded
+	if(plugin && (SmfPluginLoaded == result))
+		{
+		m_server->writeLog("Plugin loaded");
+		SmfPluginBase* instance = qobject_cast<SmfPluginBase *>(plugin);
+		
+		if(instance)
+		{
+		// Get the registration token of the plugin
+		QString regToken = instance->getProviderInfo()->smfRegistrationId();
+		QList<QUrl> urlList;
+		SmfPluginRequestData reqData;
+
+		// check if the plugin is authorised (with CSM)
+		if( authorisePlugin(regToken, urlList ))
+			{
+			m_server->writeLog("Plugin authorised");
+			
+			// call the utility method to create plugin specific request
+			m_util->createRequest(plugin, aOperation, aInputData, reqData, result);
+
+			// If the request is created successfully, call the TM method to send the request
+			if( SmfPluginRequestCreated == result )
+				{
+				m_server->writeLog("Plugin request creation successful");
+				m_tempStruct = new SmfWaitingPluginInfoStruc();
+				m_tempStruct->iSessionID = aSessionID;
+				m_tempStruct->iPluginId = aPluginID;
+				m_tempStruct->iInstance = instance;
+				m_tempStruct->iOperation = aOperation;
+				m_tempStruct->iInputData = aInputData;
+				m_tempStruct->iUrlList = urlList;
+			
+				// send the request
+				sendRequest ( reqData, result, urlList );
+				}
+			}
+		
+		else
+			{
+			// plugin not authorised, so unload
+			m_server->writeLog("Plugin not authorised!!!");
+			unload(instance);
+			result = SmfPluginNotAuthorised;
+			}
+		}
+		else
+			{
+			// plugin instance cannot be casted, so unload
+			m_server->writeLog("Plugin instance cannot be casted to SmfPluginBase*!!!");
+			unload(instance);
+			result = SmfPluginLoadError;
+			}
+		}
+
+	else
+		{
+		// plugin not loaded
+		m_server->writeLog("Plugin not loaded!!!");
+		result = SmfPluginLoadError;
+		}
+	
+	return result;
+	}
+
+
+/**
+ * Method called by Transport Manager when network response is available
+ * @param aTransportResult The result of Transport Operation
+ * @param aReply The QNetworkReply instance that requested 
+ * this transaction
+ * @param aResponse The network response data, may be NULL for error
+ */
+void SmfPluginManager::responseAvailable ( 
+		const SmfTransportResult &aTransportResult, 
+		QNetworkReply *aReply,
+		QByteArray *aResponse )
+	{
+	m_server->writeLog("Inside SmfPluginManager::responseAvailable()");
+		
+	// For request success or For request cancellation
+	if((SmfTransportOpNoError == aTransportResult) || 
+			(SmfTransportOpOperationCanceledError == aTransportResult))
+			{
+		m_server->writeLog("no transport error/ cancellation");
+
+			// get the details of the plugin which made this request
+			SmfWaitingPluginInfoStruc* info = m_waitingPluginHash.value(aReply);
+			quint32 sessionId = m_waitingPluginHash.value(aReply)->iSessionID;
+			QString pluginId = m_waitingPluginHash.value(aReply)->iPluginId;
+			SmfRequestTypeID operation = m_waitingPluginHash.value(aReply)->iOperation;
+			QByteArray inputData = m_waitingPluginHash.value(aReply)->iInputData;
+			
+			QVariant result;
+			SmfPluginRetType retType = SmfRequestError;
+			SmfResultPage pageResult;
+			
+			m_server->writeLog("Before m_util->responseAvailable");
+			
+			// call the utility method to send response to appropriate plugins
+			SmfPluginManagerResult retValue = m_util->responseAvailable( info->iInstance, operation, 
+				aTransportResult, aResponse, &result, retType, pageResult );
+			
+			// remove the plugin from the waiting list
+			delete m_waitingPluginHash.value(aReply);
+			m_waitingPluginHash.remove(aReply);
+		
+			QByteArray arr;
+			QDataStream stream(&arr, QIODevice::ReadWrite);
+			if( SmfPluginResponseParsed == retValue )
+				{
+				m_server->writeLog("Parsing successful");
+				
+				// serialize the response to suitable class and pass the data to server
+				serializeResult(operation, &result, stream);
+			
+				////TODO:- send error in enums-by manasij
+				// Send the response data to the server
+				m_server->resultsAvailable(sessionId, &arr, SmfNoError);
+				}
+		
+			// Send the request again
+			else if( SmfPluginSendRequestAgain == retValue )
+				{
+				m_server->writeLog("Send request again");
+				
+				// create the request again (with same paramaters)
+				retValue = createRequest( sessionId, pluginId, operation, inputData );
+				}
+			
+			// Error
+			else
+				{
+				m_server->writeLog("Parsing failed!!");
+				
+				// Error in parsing, sent to server
+				m_server->resultsAvailable(sessionId, &arr, SmfpluginResponseParseFailure);
+				}
+		
+			// delete aReply later, when event loop is re-entered
+			aReply->deleteLater();
+			}
+	
+	// Any other error
+	else
+		{
+		m_server->writeLog("Error in SmfPluginManager::responseAvailable, Transport failure code : ");
+		QString err = QString::number(aTransportResult);
+		m_server->writeLog(err);
+		
+		//Added by manasij, send all kind of errors to the server
+		//TODO:- to be refined by PM owner
+		quint32 sessionId = m_waitingPluginHash.value(aReply)->iSessionID;
+		QByteArray arr;
+		m_server->resultsAvailable(sessionId, &arr, SmftransportInitNetworkNotAvailable);
+		}
+	}
+
+
+/**
+ * Method to cancel the service request
+ * @param aPluginId The plugin whose current operation 
+ * is to be cancelled
+ */
+bool SmfPluginManager::cancelRequest ( const QString& aPluginId )
+	{
+	bool retValue = false;
+	m_server->writeLog("Inside SmfPluginManager::cancelRequest()");
+	
+	// Get the plugin for which cancel is requested
+	foreach(SmfWaitingPluginInfoStruc* iPluginInfo, m_waitingPluginHash.values())
+		{
+		if( 0 == iPluginInfo->iPluginId.compare(aPluginId))
+			{
+			m_server->writeLog("Plugin to be cancelled found in the waiting list");
+			
+			// Notify Transport Manager
+			m_transMngrUtil->cancelRequest(m_waitingPluginHash.key(iPluginInfo));
+			
+			// Notify the plugin that the request has been cancelled
+			SmfPluginRetType retType;
+			SmfResultPage pageResult;
+			SmfPluginError ret = iPluginInfo->iInstance->responseAvailable( SmfTransportOpCancelled, 
+					NULL, NULL, retType, pageResult );
+			
+			// Remove that plugin from the waiting list
+			delete (m_waitingPluginHash.value(m_waitingPluginHash.key(iPluginInfo)));
+			m_waitingPluginHash.remove(m_waitingPluginHash.key(iPluginInfo));
+			
+			if(SmfPluginErrNone == ret)
+				retValue = true;
+			}
+		//else , cancel requested for a plugin which is not loaded, do nothing
+		else
+			{
+			m_server->writeLog("Plugin to be cancelled not found in the waiting list!!! - do nothing");
+			retValue =  false;
+		}
+		}
+	return retValue;
+	}
+
+
+/**
+ * Method called to initialize the file watcher watching the file  
+ * system for adition/upgradation/removal of plugins
+ */
+void SmfPluginManager::initializeFileWatcher ( )
+	{
+	m_server->writeLog("Inside SmfPluginManager::initializeFileWatcher()");
+	
+	// Create the file watcher for the plugins in /Smf folder of the Qt plugin directory
+	m_fileWatcher = new QFileSystemWatcher(this);
+	
+	// Get the directory having the Qt plugin stubs
+	QDir dir(QLibraryInfo::location(QLibraryInfo::PluginsPath));
+	
+	// If Smf folder exists
+	if(dir.cd("smf/plugin"))
+		{
+		// Add each service provider folders to the file watcher
+		foreach(QString folder, dir.entryList(QDir::AllDirs))
+			{
+			dir.cd(folder);
+			m_fileWatcher->addPath(dir.absolutePath());
+			dir.cdUp();
+			}
+		}
+	else
+		m_fileWatcher->addPath(dir.absolutePath());
+	}
+
+
+
+/**
+ * Method called to initialize the database holding the plugin 
+ * directory sructure information. This is called only once when 
+ * the Plugin Manager is instantiated.
+ * This method creates and updates m_pluginIdPathHash member 
+ * of this class
+ */
+bool SmfPluginManager::initializeSmfPluginDataBase ( )
+	{
+	m_server->writeLog("Inside SmfPluginManager::initializeSmfPluginDataBase()");
+	
+	// Find QSQLite driver and create a connection to database
+	m_pluginDataBase.removeDatabase("SmfPluginsInfoDatabase");
+	m_pluginDataBase = QSqlDatabase::addDatabase("QSQLITE");
+	m_pluginDataBase.setDatabaseName("SmfPluginsInfoDatabase");
+	
+	// Open the database
+	bool opened = m_pluginDataBase.open();
+	if(!opened)
+		return false;
+	
+	m_server->writeLog("Database opened");
+	
+	// Create a query to create the DB table for Plugin Manager (if it doesn't exists)
+	QSqlQuery query;
+	bool tableCreated = false;
+
+	tableCreated = query.exec("CREATE TABLE IF NOT EXISTS pluginDetails ("
+			"pluginId TEXT PRIMARY KEY, interfaceName TEXT, serviceProvider TEXT, "
+			"description TEXT, serviceUrl TEXT, authAppId TEXT)");
+
+	// Error - table not created, Plugin Manager might not work properly
+	if(!tableCreated)
+		{
+		m_server->writeLog("Table not created, error = "+query.lastError().text());
+		return false;
+		}
+	
+	m_server->writeLog("Table created");
+	
+	// Get the directory having the Qt plugin stubs
+	QDir dir(QLibraryInfo::location(QLibraryInfo::PluginsPath));
+	
+	// If Smf folder exists
+	if(dir.cd("smf/plugin"))
+		{
+		m_server->writeLog("Smf/plugin folder exists");
+		// Get each interface folders names
+		foreach(QString intfName, dir.entryList(QDir::AllDirs))
+			{
+			dir.cd(intfName);
+			m_server->writeLog("Interface name : "+dir.dirName());
+			
+			// Get each plugin in this folder
+			foreach(QString pluginName, dir.entryList(QDir::Files))
+				{
+				m_server->writeLog("plugins for this Interface : "+pluginName);
+				
+				// load this plugin
+				QPluginLoader pluginLoader(dir.absoluteFilePath(pluginName));
+				QObject *instance = pluginLoader.instance();
+				if (instance)
+					{
+					m_server->writeLog("instance found");
+					SmfPluginBase* plugin = qobject_cast<SmfPluginBase *>(instance);
+				    if (plugin)
+				    	{
+						m_server->writeLog("SmfPluginBase found");
+						plugin->initialize(SmfPluginUtil::getInstance());
+				    
+						// get the plugin id
+						QString id = plugin->getProviderInfo()->pluginId();
+						
+						// get the interface implemented by the plugin
+						QString intfImplemented = dir.dirName();
+						intfImplemented.prepend("org.symbian.smf.plugin.");
+						m_server->writeLog("intfImplemented=");
+						m_server->writeLog(intfImplemented);
+						
+						// get the service provider
+						QString serProv = plugin->getProviderInfo()->serviceName();
+						
+						//get the description
+						QString desc = plugin->getProviderInfo()->description();
+						
+						// get the service URL
+						QString servURL = plugin->getProviderInfo()->serviceUrl().toString();
+						
+						// get the authentication application id
+						QString str;
+						QStringList list;
+						QString authAppId = plugin->getProviderInfo()->authenticationApp(
+								str, list, QIODevice::ReadWrite);
+						
+						// Update m_pluginIdPathHash
+						m_pluginIdPathHash.insert(id, dir.absoluteFilePath(pluginName));
+						
+						QSqlQuery rowInsertQuery;
+						
+						// insert into database
+						bool rowInserted = rowInsertQuery.exec(QString("INSERT INTO pluginDetails VALUES ('%1', "
+								"'%2', '%3', '%4', '%5', '%6')").arg(id).arg(intfImplemented).arg(serProv)
+								.arg(desc).arg(servURL).arg(authAppId));
+						
+						if(rowInserted)
+							m_server->writeLog("This Plugin's information is added to database : "+id+""
+									", "+intfImplemented+", "+serProv);
+						else
+							m_server->writeLog("plugins data not written to database, error = "+query.lastError().text());
+				    	}
+				    else
+				    	{
+						m_server->writeLog("Plugin could not be converted to SmfpluginBase* - returning");
+						
+						// Close the database
+						m_pluginDataBase.close();
+						
+				    	return false;
+				    	}
+				    
+				    pluginLoader.unload();
+					}
+				else
+					{
+					m_server->writeLog("Plugin could not be loaded - returning");
+					
+					// Close the database
+					m_pluginDataBase.close();
+										
+					return false;
+				}
+				}
+			dir.cdUp();
+			}
+		}
+	else
+		m_server->writeLog("No Smf plugins installed!!!");
+	
+	// Close the database
+	m_pluginDataBase.close();
+	
+	return true;
+	}
+
+
+
+/**
+ * Method to load a plugin using its Plugin Id.
+ * @param aPluginId The unique ID of the plugin 
+ * @param aLoadResult [out] Output paramater indicating the result 
+ * of the loading
+ * @return The instance of the loaded plugin if loaded, else NULL
+ */
+QObject* SmfPluginManager::load ( const QString &aPluginId,
+		SmfPluginManagerResult &aLoadResult)
+	{
+	m_server->writeLog("Inside SmfPluginManager::load()");
+	
+	QPluginLoader *pluginLoader;
+	
+	// Find the plugin Path
+	QString pluginPath = m_pluginIdPathHash.value(aPluginId);
+	
+	if(!pluginPath.isEmpty())
+		{
+		// create the plugin loader and load the plugin
+		pluginLoader = new QPluginLoader(pluginPath);
+		SmfPluginBase *plugin = qobject_cast<SmfPluginBase *>(pluginLoader->instance());
+		
+		// If the plugin is loaded
+		if( pluginLoader->isLoaded() && plugin )
+			{
+			// Initialize the plugin
+			plugin->initialize(SmfPluginUtil::getInstance());
+			
+			// update the plugin loader and the loaded plugin lists
+			m_pluginLoaderHash.insertMulti(plugin, pluginLoader);
+			aLoadResult = SmfPluginLoaded;
+			m_server->writeLog("Plugin loaded");
+			}
+		else
+			{
+			m_server->writeLog("Plugin not loaded");
+		
+			// Plugin could not be loaded, error
+			aLoadResult = SmfPluginNotLoaded;
+		}
+		}
+	else
+		{
+		m_server->writeLog("Plugin not found");
+		
+		// plugin not found in hash
+		aLoadResult = SmfPluginNotFound;
+		}
+	
+	return pluginLoader->instance();
+	}
+
+
+/**
+ * Method to unload a loaded plugin. Returns true if success, else 
+ * returns false.
+ * @param aPlugin The plugin instance to be unloaded
+ * @return Returns true if success, else returns false
+ */
+bool SmfPluginManager::unload ( SmfPluginBase *aPlugin )
+	{
+	m_server->writeLog("Inside SmfPluginManager::unload()");
+	
+	// Get all the loaders for this plugin
+	QList<QPluginLoader*> loaderList = m_pluginLoaderHash.values(aPlugin);
+	bool unloaded = false;
+
+	foreach(QPluginLoader *loader, loaderList)
+		{
+		// for each loader unload the plugin
+		unloaded = loader->unload();
+		
+		// delete the instance of the loader
+		delete loader;
+		loader = NULL;
+		}
+	
+	// Remove the plugin and its associated loaders from the Hash
+	m_pluginLoaderHash.remove(aPlugin);
+	return unloaded;
+	}
+
+
+/**
+ * Method to unload the list of loaded plugins. Returns true if all are 
+ * success, else returns false if any one fails.
+ * @param aPluginList The list of instances for all plugins that are 
+ * to be unloaded
+ * @return Returns true if all are success, else returns false if any 
+ * one fails.
+ */
+bool SmfPluginManager::unload ( const QList<SmfPluginBase *> &aPluginList)
+	{
+	m_server->writeLog("Inside SmfPluginManager::unload() - overloaded fn");
+	//unload all the required plugins
+	bool unloaded = true;
+	
+	foreach(SmfPluginBase *plugin, aPluginList)
+		{
+		// unload individual plugins in the list
+		bool ret = unload(plugin);
+		
+		// indicate error if any one of the plugin failed to unload
+		if(!ret)
+			unloaded = ret;
+		}
+	return unloaded;
+	}
+
+
+/**
+ * Method that calls the Transport Manager Utility class method to 
+ * send the request created by the plugins over the network
+ * @param aReqData The request data created by the plugin
+ * @param aResult [out] The output parameter indicating the result 
+ * of this method
+ * @param aUrlList The list of accessible Urls for this plugin
+ * @see smfglobal.h
+ */
+void SmfPluginManager::sendRequest ( SmfPluginRequestData &aReqData, 
+		SmfPluginManagerResult &aResult,
+		const QList<QUrl> &aUrlList )
+	{
+	m_server->writeLog("Inside SmfPluginManager::sendRequest()");
+	
+	QNetworkReply* reply;
+	bool sopCompliant = false;
+	
+	// Check the type of Http operation to be performed
+	switch(aReqData.iHttpOperationType)
+		{
+		// Http HEAD
+		case QNetworkAccessManager::HeadOperation:
+			reply = m_transMngrUtil->head(aReqData.iNetworkRequest, aUrlList, sopCompliant);
+			break;
+		
+		// Http GET
+		case QNetworkAccessManager::GetOperation:
+			reply = m_transMngrUtil->get(aReqData.iNetworkRequest, aUrlList, sopCompliant);
+			break;
+			
+		// Http PUT	
+		case QNetworkAccessManager::PutOperation:
+			reply = m_transMngrUtil->put(aReqData.iNetworkRequest, aReqData.iPostData->buffer(), aUrlList, sopCompliant);
+			break;
+			
+		// Http POST
+		case QNetworkAccessManager::PostOperation:
+			reply = m_transMngrUtil->post(aReqData.iNetworkRequest, aReqData.iPostData->buffer(), aUrlList, sopCompliant);
+			break;
+			
+		// Http DELETE
+		case QNetworkAccessManager::DeleteOperation:
+			reply = m_transMngrUtil->deleteResource(aReqData.iNetworkRequest, aUrlList, sopCompliant);
+			break;
+			
+		default:
+			aResult = SmfPluginUnknownService;
+			return;
+		}
+	
+	if( sopCompliant )
+		{
+		if( reply )
+			{
+			// SOP compliant, sending successful
+			m_waitingPluginHash.insert(reply, m_tempStruct);
+			m_tempStruct = NULL;
+			aResult = SmfPluginNoError;
+			
+			m_server->writeLog("No error, request sent");
+			
+			}
+		// reply is NULL, sending failed
+		else
+			{
+			m_server->writeLog("QNEtrworkReply returned error - not sent");
+			aResult = SmfPluginRequestSendingFailed;
+		}
+		}
+	
+	// SOP violation
+	else
+		{
+		m_server->writeLog("SOP checking failed");
+		aResult = SmfPluginSOPCheckFailed;
+	}
+	}
+
+
+/**
+ * Method that checks if a plugin is authorised to make a request. 
+ * This method communicates with Credential and Settings Manager 
+ * through Smf server, giving the registration token and getting 
+ * the valid url list if available for this plugin.
+ * @param aRegToken The registration token given by the plugin
+ * @param aUrlList [out] The list of Urls that the plugin can send 
+ * request to (to be filled by CSM)
+ * @return Returns true if plugin is authorised, else returns false.
+ */
+bool SmfPluginManager::authorisePlugin( const QString &aRegToken, 
+		QList<QUrl> &aUrlList )
+	{
+	Q_UNUSED(aRegToken)
+	m_server->writeLog("Inside SmfPluginManager::authorisePlugin()");
+	
+#ifdef CSM_INTEGRATED
+// Get the valid URL list from CSM, giving the reg token
+	if(m_server->authorisePlugin(aRegToken, aUrlList))
+		return true;
+	else
+		return false;
+	
+#else
+// CSM STUBBING - start
+	QUrl url1 ("http://www.example.com");
+	QUrl url2 ("http://api.facebook.com");
+	QUrl url3 ("http://api.flickr.com");
+
+	aUrlList.append(url1);
+	aUrlList.append(url2);
+	aUrlList.append(url3);
+
+	return true;
+// CSM STUBBING - end
+#endif
+
+	}
+
+
+/**
+ * Method to serialize the result of parsing (which is done by the 
+ * plugins) to QByteArray to be sent to Smf server.
+ * @param aOperation The type of operation to be performed
+ * @param aResult The data to be serialized
+ * @param aDataStream Stream to be written
+ */
+void SmfPluginManager::serializeResult ( 
+		const SmfRequestTypeID &aOperation, 
+		QVariant* aResult,
+		QDataStream &aDataStream )
+	{
+	m_server->writeLog("Inside SmfPluginManager::serializeResult()");
+	
+	// Call the utlity class method to serialize the result
+	m_util->serializeResult(aOperation, aResult, aDataStream);
+	}
+
+
+/**
+ * Method for the directoryChanged signal of QFileSystemWatcher.
+ * This will update the iPluginHash member and also the Plugin 
+ * Information List.
+ * @param aPath The path of the directory that has changed
+ */
+void SmfPluginManager::directoryChanged ( const QString &aPath )
+	{
+	m_server->writeLog("Inside SmfPluginManager::directoryChanged()");
+	
+	// Create a QDir instance with the given path
+	QDir dir(aPath);
+	QString pluginId;
+	QString oldpluginId;
+	QString interfaceName;
+	QString serviceProv;
+	QString authAppId;
+
+	// Get all the files in the directory at a specified path(sorted)
+	QStringList newPlugins = dir.entryList(QDir::Files, QDir::Name);
+	QStringList::const_iterator newListIterator = newPlugins.constBegin();
+	
+	// Get all plugins who were in this path, before this directory was changed
+	QStringList availablePlugins = m_pluginIdPathHash.keys(aPath);
+	availablePlugins.sort();
+	QStringList::const_iterator oldListIterator = availablePlugins.constBegin();
+	
+	// Open the database
+	bool opened = m_pluginDataBase.open();
+	if(!opened)
+		;//return;
+	
+	// If plugin is changed
+	if( newPlugins.count() == availablePlugins.count() )
+		{
+		// Check for equality
+		while( newListIterator != newPlugins.constEnd() )
+			{
+			if( *newListIterator == *oldListIterator )
+				{
+				newListIterator++;
+				oldListIterator++;
+				}
+			else
+				break;
+			}
+		// replace *oldListIterator with *newListIterator
+		QHash<QString, QString>::iterator i = m_pluginIdPathHash.find(*oldListIterator);
+		m_pluginIdPathHash.insert(*newListIterator, i.value());
+		m_pluginIdPathHash.remove(*oldListIterator);
+		
+		// Also update database with *newListIterator
+	    QSqlQuery updateQuery;
+	    
+	    bool updated = updateQuery.exec(QString("UPDATE pluginDetails SET pluginId = '%1' "
+	    		"WHERE pluginId = '%2'").arg(*newListIterator).arg(*oldListIterator));
+	    if (!updated)
+	    	m_server->writeLog("Database table not updated, error = "+updateQuery.lastError().text());
+		
+		
+		// Get the new and old plugin Ids
+		pluginId = *newListIterator;
+		oldpluginId = *oldListIterator;
+		
+		// Load the plugin and get its service provider name
+		SmfPluginManagerResult result;
+		SmfPluginBase* instance = qobject_cast<SmfPluginBase *>(load(pluginId, result));
+		
+		if(instance && (SmfPluginLoaded == result))
+			{
+			instance->initialize(SmfPluginUtil::getInstance());
+			serviceProv = instance->getProviderInfo()->serviceName();
+			interfaceName = dir.dirName();
+			}
+		
+		unload(instance);
+		// Inform server that plugin has been changed
+#ifdef CSM_INTEGRATED
+		//Remove after Server Integration
+		m_server->pluginChanged(oldPluginId, newPluginId, interfaceName, serviceProv);
+#endif
+		}
+		
+	// If plugin is added
+	else if(newPlugins.count() > availablePlugins.count())
+		{
+		// Check for equality
+		while( oldListIterator != availablePlugins.constEnd() )
+			{
+			if( *newListIterator == *oldListIterator )
+				{
+				newListIterator++;
+				oldListIterator++;
+				}
+			else
+				break;
+			}
+		// replace *oldListIterator with *newListIterator
+		m_pluginIdPathHash.insert(*newListIterator, aPath);
+		
+		// Get the plugin Id
+		pluginId = *newListIterator;
+		
+		// Load the plugin and get its service provider name
+		SmfPluginManagerResult result;
+		SmfPluginBase* instance = qobject_cast<SmfPluginBase *>(load(pluginId, result));
+		
+		if(instance && (SmfPluginLoaded == result))
+			{
+			instance->initialize(SmfPluginUtil::getInstance());
+			serviceProv = instance->getProviderInfo()->serviceName();
+			interfaceName = dir.dirName();
+			interfaceName.prepend("org.symbian.smf.plugin.");
+			QString prgm;
+			QStringList list;
+			authAppId = instance->getProviderInfo()->authenticationApp(prgm, list, QIODevice::ReadWrite);
+			}
+		
+		unload(instance);
+		
+		// Also add to the database the value newListIterator and aPath
+		QSqlQuery insertRowQuery;
+		bool rowInserted = insertRowQuery.exec(QString("INSERT INTO pluginDetails VALUES "
+				"('%1', '%2', '%3', '%4')").arg(pluginId).arg(interfaceName).arg(serviceProv).arg(authAppId));
+
+		 // Error
+		if (!rowInserted)
+			m_server->writeLog("Database table not inserted, error = "+insertRowQuery.lastError().text());
+		
+		// Inform server that plugin has been added
+#ifdef CSM_INTEGRATED
+		//Remove after Server Integration
+		m_server->pluginAdded(pluginId, interfaceName, serviceProv);
+#endif
+		}
+	
+	// If plugin is removed
+	else //for newPlugins.count() < availablePlugins.count()
+		{
+		// Check for equality
+		while( newListIterator != newPlugins.constEnd() )
+			{
+			if( *newListIterator == *oldListIterator )
+				{
+				newListIterator++;
+				oldListIterator++;
+				}
+			else
+				break;
+			}
+		// remove *oldListIterator
+		m_pluginIdPathHash.remove(*oldListIterator);
+		
+		// Also remove oldListIterator from the database
+		QSqlQuery deleteRowQuery;
+		bool rowDeleted = deleteRowQuery.exec(QString("DELETE FROM pluginDetails WHERE pluginId = '%1'")
+				.arg(*oldListIterator));
+		 
+		// Error
+		if (!rowDeleted)
+			m_server->writeLog("Database table row not deleted, error = "+deleteRowQuery.lastError().text());
+		
+		// Get the plugin Id
+		pluginId = *oldListIterator;
+		
+		// Load the plugin and get its service provider name
+		SmfPluginManagerResult result;
+		SmfPluginBase* instance = qobject_cast<SmfPluginBase *>(load(pluginId, result));
+		
+		if(instance && (SmfPluginLoaded == result))
+			{
+			instance->initialize(SmfPluginUtil::getInstance());
+			serviceProv = instance->getProviderInfo()->serviceName();
+			interfaceName = dir.dirName();
+			}
+		
+		unload(instance);
+		// Inform server that plugin has removed
+#ifdef CSM_INTEGRATED
+		//Remove after Server Integration
+		m_server->pluginRemoved(pluginId, interfaceName, serviceProv);
+#endif
+		}
+	// Close the database
+	m_pluginDataBase.close();
+	}
+
+
+/**
+ * Method to get the list of the SmfProvider for all the plugins that implement 
+ * the mentioned Interface 
+ * @param aInterface The interface for which list of plugins is required 
+ * @param aMap The map of pluginID and its corresponding SmfProvider
+ */
+void SmfPluginManager::getPlugins(const QString& aInterface, QMap<QString,SmfProvider>& aMap)
+	{
+	m_server->writeLog("Inside SmfPluginManager::getPlugins()");
+	
+	// Open the database
+	bool opened = m_pluginDataBase.open();
+	if(!opened)
+		{
+		m_server->writeLog("Data base not opened, exiting getplugins()");
+		return;
+		}
+	
+	m_server->writeLog("Data base opened");
+	
+	// Query the database for all pluginIDs that implement the given interface
+	QSqlQuery query(QString("SELECT pluginId, interfaceName, serviceProvider, description, "
+			"serviceUrl FROM pluginDetails where interfaceName = '%1'").arg(aInterface));
+	
+	if (query.next())
+		{
+		m_server->writeLog("Query is success");
+
+		SmfProvider prov;
+		
+		// get the pluginId
+		QString pluginId = query.value(0).toString();
+		
+		// get the service type / interface name
+		QStringList servicetypes;
+		servicetypes.insert(0, query.value(1).toString());
+		prov.serviceTypes(servicetypes);
+		
+		// Get the serv provider
+		QString servName = query.value(2).toString();
+		prov.serviceName(servName);
+		
+		// Get the description
+		QString desc = query.value(3).toString();
+		prov.description(desc);
+		
+		// Get the service URL
+		QUrl url(query.value(4).toString());
+	prov.serviceUrl(url);
+
+		aMap.insert(pluginId, prov);
+		}
+	else
+		m_server->writeLog("Data base query->next() returned false, error = "+query.lastError().text());
+	
+	// Close the database
+	m_pluginDataBase.close();
+	}
+
+
+/**
+ * Method to get the pluginID for the mentioned interface and service provider 
+ * @param aInterface The interface implemented by the plugin
+ * @param aProv The plugin's service provider
+ * @param aPluginId The required pluginID
+ */
+void SmfPluginManager::getPluginId(const QString& aInterface, const SmfProvider& aProv, QString& aPluginId)
+	{
+	m_server->writeLog("SmfPluginManager::getPluginId");
+	
+	// Open the database
+	bool opened = m_pluginDataBase.open();
+	if(!opened)
+		{
+		m_server->writeLog("Data base not opened, exiting");
+		return;
+		}
+	
+	m_server->writeLog("Data base opened");
+
+	// Query the database for a pluginID with given interface name and service provider
+	QSqlQuery query(QString("SELECT pluginId FROM pluginDetails where interfaceName = '%1' AND "
+			"serviceProvider = '%2'").arg(aInterface).arg(aProv.serviceName()));
+	
+	if (query.next())
+		{
+		m_server->writeLog("Query is success");
+		
+		// get the pluginId
+		aPluginId = query.value(0).toString();
+		}
+	else
+		m_server->writeLog("Data base query->next() returned false, error = "+query.lastError().text());
+	
+	m_server->writeLog("returned pluginID = "+aPluginId);
+	
+	// Close the database
+	m_pluginDataBase.close();
+	}