LCOV - code coverage report
Current view: top level - framework/source/fwi/classes - protocolhandlercache.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 80 103 77.7 %
Date: 2012-08-25 Functions: 7 11 63.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 96 216 44.4 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : /*TODO
      30                 :            :     - change "singleton" behaviour by using new helper ::comhelper::SingletonRef
      31                 :            :     - rename method exist() to existHandlerForURL() or similar one
      32                 :            :     - may its a good idea to replace struct ProtocolHandler by css::beans::NamedValue type?!
      33                 :            : */
      34                 :            : 
      35                 :            : #include <classes/protocolhandlercache.hxx>
      36                 :            : #include <classes/converter.hxx>
      37                 :            : #include <threadhelp/readguard.hxx>
      38                 :            : #include <threadhelp/writeguard.hxx>
      39                 :            : #include <threadhelp/lockhelper.hxx>
      40                 :            : 
      41                 :            : #include <tools/wldcrd.hxx>
      42                 :            : #include <unotools/configpaths.hxx>
      43                 :            : #include <rtl/ustrbuf.hxx>
      44                 :            : 
      45                 :            : namespace framework{
      46                 :            : 
      47                 :            : /**
      48                 :            :     @short      overloaded index operator of hash map to support pattern key search
      49                 :            :     @descr      All keys inside this hash map are URL pattern which points to an uno
      50                 :            :                 implementation name of a protocol handler service which is registered
      51                 :            :                 for this pattern. This operator makes it easy to find such registered
      52                 :            :                 handler by using a full qualified URL and compare it with all pattern
      53                 :            :                 keys.
      54                 :            : 
      55                 :            :     @param      sURL
      56                 :            :                 the full qualified URL which should match to a registered pattern
      57                 :            : 
      58                 :            :     @return     An iterator which points to the found item inside the hash or PatternHash::end()
      59                 :            :                 if no pattern match this given <var>sURL</var>.
      60                 :            :  */
      61                 :       3782 : PatternHash::iterator PatternHash::findPatternKey( const ::rtl::OUString& sURL )
      62                 :            : {
      63                 :       3782 :     PatternHash::iterator pItem = this->begin();
      64         [ +  + ]:      34048 :     while( pItem!=this->end() )
      65                 :            :     {
      66 [ +  - ][ +  - ]:      34046 :         WildCard aPattern(pItem->first);
      67 [ +  - ][ +  - ]:      34046 :         if (aPattern.Matches(sURL))
         [ +  - ][ +  + ]
      68                 :            :             break;
      69         [ +  + ]:      64312 :         ++pItem;
      70         [ +  - ]:      34046 :     }
      71                 :       3782 :     return pItem;
      72                 :            : }
      73                 :            : 
      74                 :            : //_________________________________________________________________________________________________________________
      75                 :            : 
      76                 :            : /**
      77                 :            :     @short      initialize static member of class HandlerCache
      78                 :            :     @descr      We use a singleton pattern to implement this handler cache.
      79                 :            :                 That means it use two static member list to hold all neccessary informations
      80                 :            :                 and a ref count mechanism to create/destroy it on demand.
      81                 :            :  */
      82                 :            : HandlerHash* HandlerCache::m_pHandler  = NULL;
      83                 :            : PatternHash* HandlerCache::m_pPattern  = NULL;
      84                 :            : sal_Int32    HandlerCache::m_nRefCount = 0   ;
      85                 :            : HandlerCFGAccess* HandlerCache::m_pConfig = NULL;
      86                 :            : 
      87                 :            : //_________________________________________________________________________________________________________________
      88                 :            : 
      89                 :            : /**
      90                 :            :     @short      ctor of the cache of all registered protoco handler
      91                 :            :     @descr      It tries to open the right configuration package automaticly
      92                 :            :                 and fill the internal structures. After that the cache can be
      93                 :            :                 used for read access on this data and perform some search
      94                 :            :                 operations on it.
      95                 :            :  */
      96                 :       2317 : HandlerCache::HandlerCache()
      97                 :            : {
      98                 :            :     /* SAFE */{
      99 [ +  - ][ +  - ]:       2317 :         WriteGuard aGlobalLock( LockHelper::getGlobalLock() );
     100                 :            : 
     101         [ +  + ]:       2317 :         if (m_nRefCount==0)
     102                 :            :         {
     103 [ +  - ][ +  - ]:        267 :             m_pHandler = new HandlerHash();
     104 [ +  - ][ +  - ]:        267 :             m_pPattern = new PatternHash();
     105 [ +  - ][ +  - ]:        267 :             m_pConfig  = new HandlerCFGAccess(PACKAGENAME_PROTOCOLHANDLER);
                 [ +  - ]
     106         [ +  - ]:        267 :             m_pConfig->read(&m_pHandler,&m_pPattern);
     107                 :        267 :             m_pConfig->setCache(this);
     108                 :            :         }
     109                 :            : 
     110         [ +  - ]:       2317 :         ++m_nRefCount;
     111                 :            :     /* SAFE */}
     112                 :       2317 : }
     113                 :            : 
     114                 :            : //_________________________________________________________________________________________________________________
     115                 :            : 
     116                 :            : /**
     117                 :            :     @short      dtor of the cache
     118                 :            :     @descr      It frees all used memory. In further implementations (may if we support write access too)
     119                 :            :                 it's a good place to flush changes back to the configuration - but not needed yet.
     120                 :            :  */
     121                 :       2168 : HandlerCache::~HandlerCache()
     122                 :            : {
     123                 :            :     /* SAFE */{
     124 [ +  - ][ +  - ]:       2168 :         WriteGuard aGlobalLock( LockHelper::getGlobalLock() );
     125                 :            : 
     126         [ +  + ]:       2168 :         if( m_nRefCount==1)
     127                 :            :         {
     128                 :        253 :             m_pConfig->setCache(NULL);
     129         [ +  - ]:        253 :             m_pHandler->free();
     130         [ +  - ]:        253 :             m_pPattern->free();
     131                 :            : 
     132 [ +  - ][ +  - ]:        253 :             delete m_pConfig;
     133 [ +  - ][ +  - ]:        253 :             delete m_pHandler;
     134 [ +  - ][ +  - ]:        253 :             delete m_pPattern;
     135                 :        253 :             m_pConfig = NULL;
     136                 :        253 :             m_pHandler= NULL;
     137                 :        253 :             m_pPattern= NULL;
     138                 :            :         }
     139                 :            : 
     140         [ +  - ]:       2168 :         --m_nRefCount;
     141                 :            :     /* SAFE */}
     142         [ -  + ]:       2168 : }
     143                 :            : 
     144                 :            : //_________________________________________________________________________________________________________________
     145                 :            : 
     146                 :            : /**
     147                 :            :     @short      dtor of the cache
     148                 :            :     @descr      It frees all used memory. In further implementations (may if we support write access too)
     149                 :            :                 it's a good place to flush changes back to the configuration - but not needed yet.
     150                 :            :  */
     151                 :       3782 : sal_Bool HandlerCache::search( const ::rtl::OUString& sURL, ProtocolHandler* pReturn ) const
     152                 :            : {
     153                 :       3782 :     sal_Bool bFound = sal_False;
     154                 :            :     /* SAFE */{
     155 [ +  - ][ +  - ]:       3782 :         ReadGuard aReadLock( LockHelper::getGlobalLock() );
     156         [ +  - ]:       3782 :         PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL);
     157 [ +  + ][ +  - ]:       3782 :         if (pItem!=m_pPattern->end())
     158                 :            :         {
     159 [ +  - ][ +  - ]:       3780 :             *pReturn = (*m_pHandler)[pItem->second];
                 [ +  - ]
     160                 :       3780 :             bFound = sal_True;
     161         [ +  - ]:       3782 :         }
     162                 :            :     /* SAFE */}
     163                 :       3782 :     return bFound;
     164                 :            : }
     165                 :            : 
     166                 :            : //_________________________________________________________________________________________________________________
     167                 :            : 
     168                 :            : /**
     169                 :            :     @short      search for a registered handler by using an URL struct
     170                 :            :     @descr      We combine neccessary parts of this struct to a valid URL string
     171                 :            :                 and call our other search method ...
     172                 :            :                 It's a helper for outside code.
     173                 :            :  */
     174                 :       3782 : sal_Bool HandlerCache::search( const css::util::URL& aURL, ProtocolHandler* pReturn ) const
     175                 :            : {
     176                 :       3782 :     return search( aURL.Complete, pReturn );
     177                 :            : }
     178                 :            : 
     179                 :            : //_________________________________________________________________________________________________________________
     180                 :          0 : void HandlerCache::takeOver(HandlerHash* pHandler, PatternHash* pPattern)
     181                 :            : {
     182                 :            :     // SAFE ->
     183 [ #  # ][ #  # ]:          0 :     WriteGuard aWriteLock( LockHelper::getGlobalLock() );
     184                 :            : 
     185                 :          0 :     HandlerHash* pOldHandler = m_pHandler;
     186                 :          0 :     PatternHash* pOldPattern = m_pPattern;
     187                 :            : 
     188                 :          0 :     m_pHandler = pHandler;
     189                 :          0 :     m_pPattern = pPattern;
     190                 :            : 
     191         [ #  # ]:          0 :     pOldHandler->free();
     192         [ #  # ]:          0 :     pOldPattern->free();
     193 [ #  # ][ #  # ]:          0 :     delete pOldHandler;
     194 [ #  # ][ #  # ]:          0 :     delete pOldPattern;
     195                 :            : 
     196 [ #  # ][ #  # ]:          0 :     aWriteLock.unlock();
     197                 :            :     // <- SAFE
     198                 :          0 : }
     199                 :            : 
     200                 :            : //_________________________________________________________________________________________________________________
     201                 :            : 
     202                 :            : /**
     203                 :            :     @short      dtor of the config access class
     204                 :            :     @descr      It opens the configuration package automaticly by using base class mechanism.
     205                 :            :                 After that "read()" method of this class should be called to use it.
     206                 :            : 
     207                 :            :     @param      sPackage
     208                 :            :                 specifies the package name of the configuration data which should be used
     209                 :            :  */
     210                 :        267 : HandlerCFGAccess::HandlerCFGAccess( const ::rtl::OUString& sPackage )
     211                 :        267 :     : ConfigItem( sPackage )
     212                 :            : {
     213         [ +  - ]:        267 :     css::uno::Sequence< ::rtl::OUString > lListenPaths(1);
     214 [ +  - ][ +  - ]:        267 :     lListenPaths[0] = SETNAME_HANDLER;
     215 [ +  - ][ +  - ]:        267 :     EnableNotification(lListenPaths);
     216                 :        267 : }
     217                 :            : 
     218                 :            : //_________________________________________________________________________________________________________________
     219                 :            : 
     220                 :            : /**
     221                 :            :     @short      use base class mechanism to fill given structures
     222                 :            :     @descr      User use us as a wrapper between configuration api and his internal structures.
     223                 :            :                 He give us some pointer to his member and we fill it.
     224                 :            : 
     225                 :            :     @param      pHandler
     226                 :            :                 pointer to a list of protocol handler infos
     227                 :            : 
     228                 :            :     @param      pPattern
     229                 :            :                 reverse map of handler pattern to her uno names
     230                 :            :  */
     231                 :        267 : void HandlerCFGAccess::read( HandlerHash** ppHandler ,
     232                 :            :                              PatternHash** ppPattern )
     233                 :            : {
     234                 :            :     // list of all uno implementation names without encoding
     235 [ +  - ][ +  - ]:        267 :     css::uno::Sequence< ::rtl::OUString > lNames = GetNodeNames( SETNAME_HANDLER, ::utl::CONFIG_NAME_LOCAL_PATH );
     236                 :        267 :     sal_Int32 nSourceCount = lNames.getLength();
     237                 :        267 :     sal_Int32 nTargetCount = nSourceCount;
     238                 :            :     // list of all full qualified path names of configuration entries
     239         [ +  - ]:        267 :     css::uno::Sequence< ::rtl::OUString > lFullNames ( nTargetCount );
     240                 :            : 
     241                 :            :     // expand names to full path names
     242                 :        267 :     sal_Int32 nSource=0;
     243                 :        267 :     sal_Int32 nTarget=0;
     244         [ +  + ]:       2595 :     for( nSource=0; nSource<nSourceCount; ++nSource )
     245                 :            :     {
     246 [ +  - ][ +  - ]:       2328 :         ::rtl::OUStringBuffer sPath( SETNAME_HANDLER );
     247 [ +  - ][ +  - ]:       2328 :         sPath.append(CFG_PATH_SEPERATOR);
     248 [ +  - ][ +  - ]:       2328 :         sPath.append(lNames[nSource]);
     249 [ +  - ][ +  - ]:       2328 :         sPath.append(CFG_PATH_SEPERATOR);
     250 [ +  - ][ +  - ]:       2328 :         sPath.append(PROPERTY_PROTOCOLS);
     251                 :            : 
     252 [ +  - ][ +  - ]:       2328 :         lFullNames[nTarget]  = sPath.makeStringAndClear();
     253                 :       2328 :         ++nTarget;
     254                 :       2328 :     }
     255                 :            : 
     256                 :            :     // get values at all
     257         [ +  - ]:        267 :     css::uno::Sequence< css::uno::Any > lValues = GetProperties( lFullNames );
     258                 :            :     LOG_ASSERT2( lFullNames.getLength()!=lValues.getLength(), "HandlerCFGAccess::read()", "Miss some configuration values of handler set!" )
     259                 :            : 
     260                 :            :     // fill structures
     261                 :        267 :     nSource = 0;
     262         [ +  + ]:       2595 :     for( nTarget=0; nTarget<nTargetCount; ++nTarget )
     263                 :            :     {
     264                 :            :         // create it new for every loop to guarantee a real empty object!
     265         [ +  - ]:       2328 :         ProtocolHandler aHandler;
     266 [ +  - ][ +  - ]:       2328 :         aHandler.m_sUNOName = ::utl::extractFirstFromConfigurationPath(lNames[nSource]);
     267                 :            : 
     268                 :            :         // unpack all values of this handler
     269         [ +  - ]:       2328 :         css::uno::Sequence< ::rtl::OUString > lTemp;
     270 [ +  - ][ +  - ]:       2328 :         lValues[nTarget] >>= lTemp;
     271 [ +  - ][ +  - ]:       2328 :         aHandler.m_lProtocols = Converter::convert_seqOUString2OUStringList(lTemp);
                 [ +  - ]
     272                 :            : 
     273                 :            :         // register his pattern into the performance search hash
     274 [ +  - ][ +  + ]:       9846 :         for (OUStringList::iterator pItem =aHandler.m_lProtocols.begin();
     275                 :       4923 :                                     pItem!=aHandler.m_lProtocols.end()  ;
     276                 :            :                                     ++pItem                             )
     277                 :            :         {
     278 [ +  - ][ +  - ]:       2595 :             (**ppPattern)[*pItem] = lNames[nSource];
     279                 :            :         }
     280                 :            : 
     281                 :            :         // ï¿œnsert the handler info into the normal handler cache
     282 [ +  - ][ +  - ]:       2328 :         (**ppHandler)[lNames[nSource]] = aHandler;
                 [ +  - ]
     283                 :       2328 :         ++nSource;
     284 [ +  - ][ +  - ]:       2595 :     }
         [ +  - ][ +  - ]
                 [ +  - ]
     285                 :        267 : }
     286                 :            : 
     287                 :            : //_________________________________________________________________________________________________________________
     288                 :          0 : void HandlerCFGAccess::Notify(const css::uno::Sequence< rtl::OUString >& /*lPropertyNames*/)
     289                 :            : {
     290 [ #  # ][ #  # ]:          0 :     HandlerHash* pHandler = new HandlerHash;
     291 [ #  # ][ #  # ]:          0 :     PatternHash* pPattern = new PatternHash;
     292                 :            : 
     293         [ #  # ]:          0 :     read(&pHandler, &pPattern);
     294         [ #  # ]:          0 :     if (m_pCache)
     295         [ #  # ]:          0 :         m_pCache->takeOver(pHandler, pPattern);
     296                 :            :     else
     297                 :            :     {
     298 [ #  # ][ #  # ]:          0 :         delete pHandler;
     299 [ #  # ][ #  # ]:          0 :         delete pPattern;
     300                 :            :     }
     301                 :          0 : }
     302                 :            : 
     303                 :          0 : void HandlerCFGAccess::Commit()
     304                 :            : {
     305                 :          0 : }
     306                 :            : 
     307                 :            : } // namespace framework
     308                 :            : 
     309                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10