LCOV - code coverage report
Current view: top level - libreoffice/framework/source/fwi/classes - protocolhandlercache.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 80 103 77.7 %
Date: 2012-12-17 Functions: 7 11 63.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10