--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/midppush/pushcontroller/src/pushserverconnpluginmanager.cpp Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,462 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "pushserverconnpluginmanager.h"
+#include "logger.h"
+#include "applicationstatecontroller.h"
+#include "serverconnectionfactory.h"
+#include "serverconnection.h"
+#include "pusherrorcodes.h"
+#include "pushexception.h"
+#include "pushconstant.h"
+
+using namespace java::push;
+using namespace java::util;
+using namespace java::runtime;
+
+/**
+ *
+ */
+PushServerConnPluginManager::PushServerConnPluginManager
+(ConnectionListener* aListener,PendingConnectionListener* aPendingConnListener,
+ ConnManagedInterface* aConnManagedInterface)
+ : mConnListener(aListener),mPendingConnListener(aPendingConnListener),
+ mConnManagedInterface(aConnManagedInterface)
+{
+ JELOG2(EJavaPush);
+}
+
+/**
+ *
+ */
+PushServerConnPluginManager::~PushServerConnPluginManager()
+{
+ JELOG2(EJavaPush);
+ try
+ {
+ for (SrvConnContainerIter_t iter = mSrvConnContainer.begin(); iter != mSrvConnContainer.end(); ++iter)
+ {
+ iter->second.mServerConnFactory.closeAllConnections();
+ delete(iter->second.mSrvConnLibAccess);
+ iter->second.mSrvConnLibAccess = 0;
+ }
+ mSrvConnContainer.clear();
+ }
+ catch (...)
+ {
+ ELOG(EJavaPush,"ERROR!!! ~PushServerConnPluginManager(): Unexpected exception was caught");
+ }
+}
+
+/**
+ *
+ */
+void PushServerConnPluginManager::startListen(UriList_t& aUriList,bool aThrowException,
+ bool aCallConnectionHandled)
+{
+ JELOG2(EJavaPush);
+
+ if (0 == aUriList.size())
+ return;
+
+ for (UriListIter_t iter = aUriList.begin(); iter != aUriList.end(); ++iter)
+ {
+ try
+ {
+ LOG1WSTR(EJavaPush,EInfo, "startListen() URI: %s",iter->mUri);
+ std::wstring schemeStr;
+ loadAndStoreDll(iter->mUri,schemeStr);
+ createAndOpenConn((*iter),schemeStr);
+ if (true == aCallConnectionHandled)
+ mConnManagedInterface->connCompleted(iter->mUri);
+ }
+ catch (ExceptionBase& ex)
+ {
+ //std::exception is caught here to get a debug print.
+ ELOG1(EJavaPush,"ERROR!!! PushServerConnPluginManager::startListen(): %s",
+ ex.toString().c_str());
+ if (true == aThrowException)
+ throw;
+ }
+ catch (...)
+ {
+ //Exception is not thrown from this situation. It is better just ignore unsupported
+ //URI.
+ ELOG(EJavaPush,
+ "ERROR!!! PushServerConnPluginManager::startListen() Cannot open plugin for push URI");
+ if (true == aThrowException)
+ throw;
+ }
+ }//end for
+
+ if (0 == getNumOfSuccessfulPushConns())
+ {
+ throw PushException(INIT_OF_ALL_PUSH_CONNS_FAILED,"Creation of all push connections failed",
+ __FILE__,__FUNCTION__,__LINE__);
+ }
+}
+
+/**
+ *
+ */
+void PushServerConnPluginManager::updatePushRegs(UriList_t& aUriList,
+ PushControllerErrorHandlerInterface& aErrorHandler)
+{
+ JELOG2(EJavaPush);
+
+ //First is retrieved current connections. This is needed to find out whether
+ //push connection was registered or unregistered.
+ std::list<std::wstring> existingUriList;
+ listConnections(false,existingUriList);
+
+ //We can stop execution of this operation if size of both list is equal.
+ //This should not never happened.
+ if (aUriList.size() == existingUriList.size())
+ return;
+
+ if (aUriList.size() < existingUriList.size())
+ {
+ //In this case one push req has been removed from other MIDlet.
+ findAndDeleteUnregPushConns(existingUriList,aUriList,aErrorHandler);
+ }
+ else if (aUriList.size() > existingUriList.size())
+ {
+ //In this case push req has been added to the MIDlet from the other MIDlet.
+ findAndAddNewPushConns(existingUriList,aUriList);
+ }
+}
+
+/**
+ *
+ */
+void PushServerConnPluginManager::listConnections(bool aAvailable,
+ std::list<std::wstring>& aUriList)
+{
+ JELOG2(EJavaPush);
+ for (SrvConnContainerIter_t iter = mSrvConnContainer.begin(); iter != mSrvConnContainer.end(); ++iter)
+ {
+ iter->second.mServerConnFactory.getPushConnections(aAvailable,aUriList);
+ }//end for
+}
+
+/**
+ *
+ */
+ServerConnection& PushServerConnPluginManager::getPushConnection(const std::wstring& aUri)
+{
+ JELOG2(EJavaPush);
+ std::wstring schemeStr = resolveScheme(aUri);
+ ServerConnectionFactory* srvConnFac = getDllFromContainer(schemeStr);
+ if (0 == srvConnFac)
+ {
+ std::string errTxt("Server Connection Plugin by URI is not found");
+ ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str());
+ throw PushException(SRV_CONN_NOT_FOUND,errTxt,__FILE__,__FUNCTION__,__LINE__);
+ }
+ ServerConnection* srvConn = srvConnFac->getPushConnection(aUri);
+ if (0 == srvConn)
+ {
+ std::string errTxt("ServerConnection object by URI is not found");
+ ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str());
+ throw PushException(SRV_CONN_NOT_FOUND,errTxt,__FILE__,__FUNCTION__,__LINE__);
+ }
+ return *srvConn;
+}
+
+/**
+ *
+ */
+void PushServerConnPluginManager::unregisterDynamicPushConn(const std::wstring& aUri)
+{
+ JELOG2(EJavaPush);
+
+ std::wstring schemeStr = resolveScheme(aUri);
+ ServerConnectionFactory* srvConnFac = getDllFromContainer(schemeStr);
+ if (0 != srvConnFac)
+ srvConnFac->deletePushConnection(aUri);
+ //Unregisterd connection must be removed from "is connection opened successfully"
+ //list.
+ mSuccessPushConnList.erase(aUri);
+}
+
+/**
+ *
+ */
+int PushServerConnPluginManager::setConnFailed(const std::wstring& aUri)
+{
+ JELOG2(EJavaPush);
+ ScopedLock lockObj(mMutex);
+
+ SuccessPushConnListIter_t iter = mSuccessPushConnList.find(aUri);
+ if (iter != mSuccessPushConnList.end())
+ {
+ iter->second = false;
+ }
+ return getNumOfSuccessfulPushConns();
+}
+
+/**
+ *
+ */
+void PushServerConnPluginManager::deletePushServerConn(const std::wstring& aUri)
+{
+ JELOG2(EJavaPush);
+
+ try
+ {
+ std::wstring schemeStr = resolveScheme(aUri);
+ ServerConnectionFactory* srvConnFac = getDllFromContainer(schemeStr);
+ if (0 != srvConnFac)
+ srvConnFac->deletePushConnection(aUri);
+ }
+ catch (...)
+ {
+ ELOG(EJavaPush,"ERROR!!! deletePushServerConn() Unexpected exception was caught");
+ }
+}
+
+/**
+ *
+ */
+bool PushServerConnPluginManager::isValidPushUri(const std::wstring& aUri)
+{
+ JELOG2(EJavaPush);
+
+ ServerConnection* srvConn = 0;
+ std::wstring schemeStr;
+ try
+ {
+ ServerConnectionFactory& srvConnFac = loadAndStoreDll(aUri,schemeStr);
+
+ //This checks that push connetion is not reserved by this MIDlet.
+ srvConn = srvConnFac.getPushConnection(aUri);
+ if (0 != srvConn)
+ return false;
+
+ //If creation of the server connection succeeds then URI is unique.
+ //Connection is closed immediately.
+ srvConn = srvConnFac.create(aUri);
+ srvConn->open(mConnListener);
+ srvConn->close();
+ srvConnFac.releaseConnection(aUri);
+ return true;
+ }
+ catch (...)
+ {
+ ELOG(EJavaPush,"ERROR!!! checkUniquenessOfUri() Exception was caught");
+ try
+ {
+ if (0 != srvConn)
+ {
+ srvConn->close();
+ ServerConnectionFactory& srvConnFac = loadAndStoreDll(aUri,schemeStr);
+ srvConnFac.releaseConnection(aUri);
+ }
+ }
+ catch (...) {}
+ return false;
+ }
+}
+
+/**
+ *
+ */
+ServerConnectionFactory* PushServerConnPluginManager::getDllFromContainer(const std::wstring& aScheme)
+{
+ JELOG2(EJavaPush);
+
+ SrvConnContainerIter_t iter = mSrvConnContainer.find(aScheme);
+ if (iter != mSrvConnContainer.end())
+ return &(iter->second.mServerConnFactory);
+ return 0;
+}
+
+/**
+ *
+ */
+ServerConnectionFactory& PushServerConnPluginManager::loadAndStoreDll(const std::wstring& aUri,
+ std::wstring& aOutScheme)
+{
+ JELOG2(EJavaPush);
+ aOutScheme = resolveScheme(aUri);
+ ServerConnectionFactory* srvConnFac = getDllFromContainer(aOutScheme);
+ if (0 != srvConnFac)
+ return *srvConnFac;
+
+ std::string dllName = resolveDllName(aOutScheme);
+ std::auto_ptr<java::util::DynamicLibLoader> tmpLoader(0);
+ ServerConnectionFactory& conn =
+ ServerConnectionFactory::getServerConnectionFactory(dllName,tmpLoader);
+
+ ServerConnectionPluginData pluginData(tmpLoader.release(),conn);
+ std::pair<std::wstring,ServerConnectionPluginData> pairObj(aOutScheme,pluginData);
+ mSrvConnContainer.insert(pairObj);
+ return conn;
+}
+
+/**
+ *
+ */
+void PushServerConnPluginManager::createAndOpenConn(const PushRegData& aData,
+ const std::wstring& aScheme)
+{
+ JELOG2(EJavaPush);
+
+ SrvConnContainerIter_t connIter;
+ try
+ {
+ connIter = mSrvConnContainer.find(aScheme);
+ if (mSrvConnContainer.end() == connIter)
+ return;
+
+ connIter->second.mServerConnFactory.createPushServerConn
+ (aData.mUri,aData.mFilter,mConnListener,mPendingConnListener);
+
+ ScopedLock lockObj(mMutex);
+ mSuccessPushConnList.insert(std::pair<std::wstring,bool>(aData.mUri,true));
+ }
+ catch (...)
+ {
+ ELOG(EJavaPush,"ERROR!!! PushServerConnPluginManager::createAndOpenConn()");
+ throw;
+ }
+}
+
+/**
+ *
+ */
+std::wstring PushServerConnPluginManager::resolveScheme(const std::wstring& aUri) const
+{
+ JELOG2(EJavaPush);
+
+ std::wstring::size_type schemeIndex = aUri.find(L":");
+ if (std::string::npos == schemeIndex)
+ {
+ std::string errTxt("URI does not contain scheme");
+ ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str());
+ throw PushException(INVALID_URI,errTxt,__FILE__,__FUNCTION__,__LINE__);
+ }
+ std::wstring schemeStr = aUri.substr(0,schemeIndex);
+ if (L"secure-element" == schemeStr)
+ return L"secureelement";
+ return schemeStr;
+}
+
+/**
+ *
+ */
+std::string PushServerConnPluginManager::resolveDllName(const std::wstring& aScheme) const
+{
+ JELOG2(EJavaPush);
+ std::string schemeStr(aScheme.begin(),aScheme.end());
+ std::string dllNameStr(PREFIX_OF_SRV_CONN_PLUGIN);
+ dllNameStr.append(schemeStr);
+ dllNameStr.append(SUFFIX_OF_SRV_CONN_PLUGIN);
+ WLOG1(EJavaPush,"Name of the loaded dll: %s",dllNameStr.c_str());
+ return dllNameStr;
+}
+
+/**
+ *
+ */
+int PushServerConnPluginManager::getNumOfSuccessfulPushConns()
+{
+ JELOG2(EJavaPush);
+ ScopedLock lockObj(mMutex);
+
+ int successConnections = 0;
+ for (SuccessPushConnListIter_t iter = mSuccessPushConnList.begin();
+ iter != mSuccessPushConnList.end(); ++iter)
+ {
+ if (true == iter->second)
+ successConnections++;
+ }
+ return successConnections;
+}
+
+/**
+ *
+ */
+void PushServerConnPluginManager::findAndDeleteUnregPushConns
+(std::list<std::wstring>& aExistingUriList,UriList_t& aNewUriListFromStorage,
+ PushControllerErrorHandlerInterface& aErrorHandler)
+{
+ JELOG2(EJavaPush);
+
+ //First is removed all valid push connections(=not push regs which will be unregistered)
+ //from the 'existingUriList' list.
+ //After the loop 'aExistingUriList' list contains connections which will be removed.
+ for (UriListIter_t iter = aNewUriListFromStorage.begin();
+ iter != aNewUriListFromStorage.end(); ++iter)
+ {
+ aExistingUriList.remove(iter->mUri);
+ }//end for
+
+ //Unregistering connections. Actually this list should contains only one item because
+ //dynamic push regs are unregistered one by one from PushRegstry class.
+ for (std::list<std::wstring>::iterator iter2 = aExistingUriList.begin();
+ iter2 != aExistingUriList.end(); ++iter2)
+ {
+ unregisterDynamicPushConn((*iter2));
+ mConnManagedInterface->connCompleted((*iter2));
+ }//end for
+
+ //Next is checked whether this MIDlet has any push connections. Below
+ //is also checked whether listening of all push connections are failed.
+ std::list<std::wstring> existingPushConns;
+ listConnections(false,existingPushConns);
+ if (0 < existingPushConns.size())
+ {
+ //MIDlet has push connections. Next is checked whether opening
+ //of all MIDlets has been done successfully.
+ if (0 == getNumOfSuccessfulPushConns())
+ {
+ //Initialization of all connections has been failed.
+ aErrorHandler.sendAllConnsFailedMsg();
+ //No active connections so we can inform runtime to close a process.
+ aErrorHandler.closeRuntime();
+ }
+ }
+ else if (0 == existingPushConns.size())
+ {
+ //No connections so runtime can be informed to close an application.
+ aErrorHandler.closeRuntime();
+ }
+}
+
+/**
+ *
+ */
+void PushServerConnPluginManager::findAndAddNewPushConns
+(std::list<std::wstring>& aExistingUriList,UriList_t& aNewUriListFromStorage)
+{
+ JELOG2(EJavaPush);
+
+ //First is removed all push connections from 'aNewUriListFromStorage' list which
+ //already exists in the push plugins.
+ for (std::list<std::wstring>::iterator iter = aExistingUriList.begin();
+ iter != aExistingUriList.end(); ++iter)
+ {
+ PushRegData tmpObj((*iter),L"*");
+ aNewUriListFromStorage.remove(tmpObj);
+ }//end for
+
+ //Now 'aNewUriListFromStorage' list contains only new dynamic push regs.
+ startListen(aNewUriListFromStorage,false,true);
+}
+