javaextensions/midppush/pushcontroller/src/pushserverconnpluginmanager.cpp
changeset 21 2a9601315dfc
child 23 98ccebc37403
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "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 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "pushserverconnpluginmanager.h"
       
    20 #include "logger.h"
       
    21 #include "applicationstatecontroller.h"
       
    22 #include "serverconnectionfactory.h"
       
    23 #include "serverconnection.h"
       
    24 #include "pusherrorcodes.h"
       
    25 #include "pushexception.h"
       
    26 #include "pushconstant.h"
       
    27 
       
    28 using namespace java::push;
       
    29 using namespace java::util;
       
    30 using namespace java::runtime;
       
    31 
       
    32 /**
       
    33  *
       
    34  */
       
    35 PushServerConnPluginManager::PushServerConnPluginManager
       
    36 (ConnectionListener* aListener,PendingConnectionListener* aPendingConnListener,
       
    37  ConnManagedInterface* aConnManagedInterface)
       
    38         : mConnListener(aListener),mPendingConnListener(aPendingConnListener),
       
    39         mConnManagedInterface(aConnManagedInterface)
       
    40 {
       
    41     JELOG2(EJavaPush);
       
    42 }
       
    43 
       
    44 /**
       
    45  *
       
    46  */
       
    47 PushServerConnPluginManager::~PushServerConnPluginManager()
       
    48 {
       
    49     JELOG2(EJavaPush);
       
    50     try
       
    51     {
       
    52         for (SrvConnContainerIter_t iter = mSrvConnContainer.begin(); iter != mSrvConnContainer.end(); ++iter)
       
    53         {
       
    54             iter->second.mServerConnFactory.closeAllConnections();
       
    55             delete(iter->second.mSrvConnLibAccess);
       
    56             iter->second.mSrvConnLibAccess = 0;
       
    57         }
       
    58         mSrvConnContainer.clear();
       
    59     }
       
    60     catch (...)
       
    61     {
       
    62         ELOG(EJavaPush,"ERROR!!! ~PushServerConnPluginManager(): Unexpected exception was caught");
       
    63     }
       
    64 }
       
    65 
       
    66 /**
       
    67  *
       
    68  */
       
    69 void PushServerConnPluginManager::startListen(UriList_t& aUriList,bool aThrowException,
       
    70         bool aCallConnectionHandled)
       
    71 {
       
    72     JELOG2(EJavaPush);
       
    73 
       
    74     if (0 == aUriList.size())
       
    75         return;
       
    76 
       
    77     for (UriListIter_t iter = aUriList.begin(); iter != aUriList.end(); ++iter)
       
    78     {
       
    79         try
       
    80         {
       
    81             LOG1WSTR(EJavaPush,EInfo, "startListen() URI: %s",iter->mUri);
       
    82             std::wstring schemeStr;
       
    83             loadAndStoreDll(iter->mUri,schemeStr);
       
    84             createAndOpenConn((*iter),schemeStr);
       
    85             if (true == aCallConnectionHandled)
       
    86                 mConnManagedInterface->connCompleted(iter->mUri);
       
    87         }
       
    88         catch (ExceptionBase& ex)
       
    89         {
       
    90             //std::exception is caught here to get a debug print.
       
    91             ELOG1(EJavaPush,"ERROR!!! PushServerConnPluginManager::startListen(): %s",
       
    92                   ex.toString().c_str());
       
    93             if (true == aThrowException)
       
    94                 throw;
       
    95         }
       
    96         catch (...)
       
    97         {
       
    98             //Exception is not thrown from this situation. It is better just ignore unsupported
       
    99             //URI.
       
   100             ELOG(EJavaPush,
       
   101                  "ERROR!!! PushServerConnPluginManager::startListen() Cannot open plugin for push URI");
       
   102             if (true == aThrowException)
       
   103                 throw;
       
   104         }
       
   105     }//end for
       
   106 
       
   107     if (0 == getNumOfSuccessfulPushConns())
       
   108     {
       
   109         throw PushException(INIT_OF_ALL_PUSH_CONNS_FAILED,"Creation of all push connections failed",
       
   110                             __FILE__,__FUNCTION__,__LINE__);
       
   111     }
       
   112 }
       
   113 
       
   114 /**
       
   115  *
       
   116  */
       
   117 void PushServerConnPluginManager::updatePushRegs(UriList_t& aUriList,
       
   118         PushControllerErrorHandlerInterface& aErrorHandler)
       
   119 {
       
   120     JELOG2(EJavaPush);
       
   121 
       
   122     //First is retrieved current connections. This is needed to find out whether
       
   123     //push connection was registered or unregistered.
       
   124     std::list<std::wstring> existingUriList;
       
   125     listConnections(false,existingUriList);
       
   126 
       
   127     //We can stop execution of this operation if size of both list is equal.
       
   128     //This should not never happened.
       
   129     if (aUriList.size() == existingUriList.size())
       
   130         return;
       
   131 
       
   132     if (aUriList.size() < existingUriList.size())
       
   133     {
       
   134         //In this case one push req has been removed from other MIDlet.
       
   135         findAndDeleteUnregPushConns(existingUriList,aUriList,aErrorHandler);
       
   136     }
       
   137     else if (aUriList.size() > existingUriList.size())
       
   138     {
       
   139         //In this case push req has been added to the MIDlet from the other MIDlet.
       
   140         findAndAddNewPushConns(existingUriList,aUriList);
       
   141     }
       
   142 }
       
   143 
       
   144 /**
       
   145  *
       
   146  */
       
   147 void PushServerConnPluginManager::listConnections(bool aAvailable,
       
   148         std::list<std::wstring>& aUriList)
       
   149 {
       
   150     JELOG2(EJavaPush);
       
   151     for (SrvConnContainerIter_t iter = mSrvConnContainer.begin(); iter != mSrvConnContainer.end(); ++iter)
       
   152     {
       
   153         iter->second.mServerConnFactory.getPushConnections(aAvailable,aUriList);
       
   154     }//end for
       
   155 }
       
   156 
       
   157 /**
       
   158  *
       
   159  */
       
   160 ServerConnection& PushServerConnPluginManager::getPushConnection(const std::wstring& aUri)
       
   161 {
       
   162     JELOG2(EJavaPush);
       
   163     std::wstring schemeStr = resolveScheme(aUri);
       
   164     ServerConnectionFactory* srvConnFac = getDllFromContainer(schemeStr);
       
   165     if (0 == srvConnFac)
       
   166     {
       
   167         std::string errTxt("Server Connection Plugin by URI is not found");
       
   168         ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str());
       
   169         throw PushException(SRV_CONN_NOT_FOUND,errTxt,__FILE__,__FUNCTION__,__LINE__);
       
   170     }
       
   171     ServerConnection* srvConn = srvConnFac->getPushConnection(aUri);
       
   172     if (0 == srvConn)
       
   173     {
       
   174         std::string errTxt("ServerConnection object by URI is not found");
       
   175         ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str());
       
   176         throw PushException(SRV_CONN_NOT_FOUND,errTxt,__FILE__,__FUNCTION__,__LINE__);
       
   177     }
       
   178     return *srvConn;
       
   179 }
       
   180 
       
   181 /**
       
   182  *
       
   183  */
       
   184 void PushServerConnPluginManager::unregisterDynamicPushConn(const std::wstring& aUri)
       
   185 {
       
   186     JELOG2(EJavaPush);
       
   187 
       
   188     std::wstring schemeStr = resolveScheme(aUri);
       
   189     ServerConnectionFactory* srvConnFac = getDllFromContainer(schemeStr);
       
   190     if (0 != srvConnFac)
       
   191         srvConnFac->deletePushConnection(aUri);
       
   192     //Unregisterd connection must be removed from "is connection opened successfully"
       
   193     //list.
       
   194     mSuccessPushConnList.erase(aUri);
       
   195 }
       
   196 
       
   197 /**
       
   198  *
       
   199  */
       
   200 int PushServerConnPluginManager::setConnFailed(const std::wstring& aUri)
       
   201 {
       
   202     JELOG2(EJavaPush);
       
   203     ScopedLock lockObj(mMutex);
       
   204 
       
   205     SuccessPushConnListIter_t iter = mSuccessPushConnList.find(aUri);
       
   206     if (iter != mSuccessPushConnList.end())
       
   207     {
       
   208         iter->second = false;
       
   209     }
       
   210     return getNumOfSuccessfulPushConns();
       
   211 }
       
   212 
       
   213 /**
       
   214  *
       
   215  */
       
   216 void PushServerConnPluginManager::deletePushServerConn(const std::wstring& aUri)
       
   217 {
       
   218     JELOG2(EJavaPush);
       
   219 
       
   220     try
       
   221     {
       
   222         std::wstring schemeStr = resolveScheme(aUri);
       
   223         ServerConnectionFactory* srvConnFac = getDllFromContainer(schemeStr);
       
   224         if (0 != srvConnFac)
       
   225             srvConnFac->deletePushConnection(aUri);
       
   226     }
       
   227     catch (...)
       
   228     {
       
   229         ELOG(EJavaPush,"ERROR!!! deletePushServerConn() Unexpected exception was caught");
       
   230     }
       
   231 }
       
   232 
       
   233 /**
       
   234  *
       
   235  */
       
   236 bool PushServerConnPluginManager::isValidPushUri(const std::wstring& aUri)
       
   237 {
       
   238     JELOG2(EJavaPush);
       
   239 
       
   240     ServerConnection* srvConn = 0;
       
   241     std::wstring schemeStr;
       
   242     try
       
   243     {
       
   244         ServerConnectionFactory& srvConnFac = loadAndStoreDll(aUri,schemeStr);
       
   245 
       
   246         //This checks that push connetion is not reserved by this MIDlet.
       
   247         srvConn = srvConnFac.getPushConnection(aUri);
       
   248         if (0 != srvConn)
       
   249             return false;
       
   250 
       
   251         //If creation of the server connection succeeds then URI is unique.
       
   252         //Connection is closed immediately.
       
   253         srvConn = srvConnFac.create(aUri);
       
   254         srvConn->open(mConnListener);
       
   255         srvConn->close();
       
   256         srvConnFac.releaseConnection(aUri);
       
   257         return true;
       
   258     }
       
   259     catch (...)
       
   260     {
       
   261         ELOG(EJavaPush,"ERROR!!! checkUniquenessOfUri() Exception was caught");
       
   262         try
       
   263         {
       
   264             if (0 != srvConn)
       
   265             {
       
   266                 srvConn->close();
       
   267                 ServerConnectionFactory& srvConnFac = loadAndStoreDll(aUri,schemeStr);
       
   268                 srvConnFac.releaseConnection(aUri);
       
   269             }
       
   270         }
       
   271         catch (...) {}
       
   272         return false;
       
   273     }
       
   274 }
       
   275 
       
   276 /**
       
   277  *
       
   278  */
       
   279 ServerConnectionFactory* PushServerConnPluginManager::getDllFromContainer(const std::wstring& aScheme)
       
   280 {
       
   281     JELOG2(EJavaPush);
       
   282 
       
   283     SrvConnContainerIter_t iter = mSrvConnContainer.find(aScheme);
       
   284     if (iter != mSrvConnContainer.end())
       
   285         return &(iter->second.mServerConnFactory);
       
   286     return 0;
       
   287 }
       
   288 
       
   289 /**
       
   290  *
       
   291  */
       
   292 ServerConnectionFactory& PushServerConnPluginManager::loadAndStoreDll(const std::wstring& aUri,
       
   293         std::wstring& aOutScheme)
       
   294 {
       
   295     JELOG2(EJavaPush);
       
   296     aOutScheme = resolveScheme(aUri);
       
   297     ServerConnectionFactory* srvConnFac = getDllFromContainer(aOutScheme);
       
   298     if (0 != srvConnFac)
       
   299         return *srvConnFac;
       
   300 
       
   301     std::string dllName = resolveDllName(aOutScheme);
       
   302     std::auto_ptr<java::util::DynamicLibLoader> tmpLoader(0);
       
   303     ServerConnectionFactory& conn =
       
   304         ServerConnectionFactory::getServerConnectionFactory(dllName,tmpLoader);
       
   305 
       
   306     ServerConnectionPluginData pluginData(tmpLoader.release(),conn);
       
   307     std::pair<std::wstring,ServerConnectionPluginData> pairObj(aOutScheme,pluginData);
       
   308     mSrvConnContainer.insert(pairObj);
       
   309     return conn;
       
   310 }
       
   311 
       
   312 /**
       
   313  *
       
   314  */
       
   315 void PushServerConnPluginManager::createAndOpenConn(const PushRegData& aData,
       
   316         const std::wstring& aScheme)
       
   317 {
       
   318     JELOG2(EJavaPush);
       
   319 
       
   320     SrvConnContainerIter_t connIter;
       
   321     try
       
   322     {
       
   323         connIter = mSrvConnContainer.find(aScheme);
       
   324         if (mSrvConnContainer.end() == connIter)
       
   325             return;
       
   326 
       
   327         connIter->second.mServerConnFactory.createPushServerConn
       
   328         (aData.mUri,aData.mFilter,mConnListener,mPendingConnListener);
       
   329 
       
   330         ScopedLock lockObj(mMutex);
       
   331         mSuccessPushConnList.insert(std::pair<std::wstring,bool>(aData.mUri,true));
       
   332     }
       
   333     catch (...)
       
   334     {
       
   335         ELOG(EJavaPush,"ERROR!!! PushServerConnPluginManager::createAndOpenConn()");
       
   336         throw;
       
   337     }
       
   338 }
       
   339 
       
   340 /**
       
   341  *
       
   342  */
       
   343 std::wstring PushServerConnPluginManager::resolveScheme(const std::wstring& aUri) const
       
   344 {
       
   345     JELOG2(EJavaPush);
       
   346 
       
   347     std::wstring::size_type schemeIndex = aUri.find(L":");
       
   348     if (std::string::npos == schemeIndex)
       
   349     {
       
   350         std::string errTxt("URI does not contain scheme");
       
   351         ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str());
       
   352         throw PushException(INVALID_URI,errTxt,__FILE__,__FUNCTION__,__LINE__);
       
   353     }
       
   354     std::wstring schemeStr = aUri.substr(0,schemeIndex);
       
   355     if (L"secure-element" == schemeStr)
       
   356         return L"secureelement";
       
   357     return schemeStr;
       
   358 }
       
   359 
       
   360 /**
       
   361  *
       
   362  */
       
   363 std::string PushServerConnPluginManager::resolveDllName(const std::wstring& aScheme) const
       
   364 {
       
   365     JELOG2(EJavaPush);
       
   366     std::string schemeStr(aScheme.begin(),aScheme.end());
       
   367     std::string dllNameStr(PREFIX_OF_SRV_CONN_PLUGIN);
       
   368     dllNameStr.append(schemeStr);
       
   369     dllNameStr.append(SUFFIX_OF_SRV_CONN_PLUGIN);
       
   370     WLOG1(EJavaPush,"Name of the loaded dll: %s",dllNameStr.c_str());
       
   371     return dllNameStr;
       
   372 }
       
   373 
       
   374 /**
       
   375  *
       
   376  */
       
   377 int PushServerConnPluginManager::getNumOfSuccessfulPushConns()
       
   378 {
       
   379     JELOG2(EJavaPush);
       
   380     ScopedLock lockObj(mMutex);
       
   381 
       
   382     int successConnections = 0;
       
   383     for (SuccessPushConnListIter_t iter = mSuccessPushConnList.begin();
       
   384             iter != mSuccessPushConnList.end(); ++iter)
       
   385     {
       
   386         if (true == iter->second)
       
   387             successConnections++;
       
   388     }
       
   389     return successConnections;
       
   390 }
       
   391 
       
   392 /**
       
   393  *
       
   394  */
       
   395 void PushServerConnPluginManager::findAndDeleteUnregPushConns
       
   396 (std::list<std::wstring>& aExistingUriList,UriList_t& aNewUriListFromStorage,
       
   397  PushControllerErrorHandlerInterface& aErrorHandler)
       
   398 {
       
   399     JELOG2(EJavaPush);
       
   400 
       
   401     //First is removed all valid push connections(=not push regs which will be unregistered)
       
   402     //from the 'existingUriList' list.
       
   403     //After the loop 'aExistingUriList' list contains connections which will be removed.
       
   404     for (UriListIter_t iter = aNewUriListFromStorage.begin();
       
   405             iter != aNewUriListFromStorage.end(); ++iter)
       
   406     {
       
   407         aExistingUriList.remove(iter->mUri);
       
   408     }//end for
       
   409 
       
   410     //Unregistering connections. Actually this list should contains only one item because
       
   411     //dynamic push regs are unregistered one by one from PushRegstry class.
       
   412     for (std::list<std::wstring>::iterator iter2 = aExistingUriList.begin();
       
   413             iter2 != aExistingUriList.end(); ++iter2)
       
   414     {
       
   415         unregisterDynamicPushConn((*iter2));
       
   416         mConnManagedInterface->connCompleted((*iter2));
       
   417     }//end for
       
   418 
       
   419     //Next is checked whether this MIDlet has any push connections. Below
       
   420     //is also checked whether listening of all push connections are failed.
       
   421     std::list<std::wstring> existingPushConns;
       
   422     listConnections(false,existingPushConns);
       
   423     if (0 < existingPushConns.size())
       
   424     {
       
   425         //MIDlet has push connections. Next is checked whether opening
       
   426         //of all MIDlets has been done successfully.
       
   427         if (0 == getNumOfSuccessfulPushConns())
       
   428         {
       
   429             //Initialization of all connections has been failed.
       
   430             aErrorHandler.sendAllConnsFailedMsg();
       
   431             //No active connections so we can inform runtime to close a process.
       
   432             aErrorHandler.closeRuntime();
       
   433         }
       
   434     }
       
   435     else if (0 == existingPushConns.size())
       
   436     {
       
   437         //No connections so runtime can be informed to close an application.
       
   438         aErrorHandler.closeRuntime();
       
   439     }
       
   440 }
       
   441 
       
   442 /**
       
   443  *
       
   444  */
       
   445 void PushServerConnPluginManager::findAndAddNewPushConns
       
   446 (std::list<std::wstring>& aExistingUriList,UriList_t& aNewUriListFromStorage)
       
   447 {
       
   448     JELOG2(EJavaPush);
       
   449 
       
   450     //First is removed all push connections from 'aNewUriListFromStorage' list which
       
   451     //already exists in the push plugins.
       
   452     for (std::list<std::wstring>::iterator iter = aExistingUriList.begin();
       
   453             iter != aExistingUriList.end(); ++iter)
       
   454     {
       
   455         PushRegData tmpObj((*iter),L"*");
       
   456         aNewUriListFromStorage.remove(tmpObj);
       
   457     }//end for
       
   458 
       
   459     //Now 'aNewUriListFromStorage' list contains only new dynamic push regs.
       
   460     startListen(aNewUriListFromStorage,false,true);
       
   461 }
       
   462