diff -r e8e63152f320 -r 2a9601315dfc javaextensions/midppush/pushcontroller/src/pushserverconnpluginmanager.cpp --- /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 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& 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 tmpLoader(0); + ServerConnectionFactory& conn = + ServerConnectionFactory::getServerConnectionFactory(dllName,tmpLoader); + + ServerConnectionPluginData pluginData(tmpLoader.release(),conn); + std::pair 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(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& 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::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 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& 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::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); +} +