LCOV - code coverage report
Current view: top level - framework/source/fwi/classes - protocolhandlercache.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 81 103 78.6 %
Date: 2014-04-11 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 it's 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/lockhelper.hxx>
      29             : 
      30             : #include <tools/wldcrd.hxx>
      31             : #include <unotools/configpaths.hxx>
      32             : #include <rtl/ustrbuf.hxx>
      33             : 
      34             : namespace framework{
      35             : 
      36             : /**
      37             :     @short      overloaded index operator of hash map to support pattern key search
      38             :     @descr      All keys inside this hash map are URL pattern which points to an uno
      39             :                 implementation name of a protocol handler service which is registered
      40             :                 for this pattern. This operator makes it easy to find such registered
      41             :                 handler by using a full qualified URL and compare it with all pattern
      42             :                 keys.
      43             : 
      44             :     @param      sURL
      45             :                 the full qualified URL which should match to a registered pattern
      46             : 
      47             :     @return     An iterator which points to the found item inside the hash or PatternHash::end()
      48             :                 if no pattern match this given <var>sURL</var>.
      49             :  */
      50       19558 : PatternHash::iterator PatternHash::findPatternKey( const OUString& sURL )
      51             : {
      52       19558 :     PatternHash::iterator pItem = this->begin();
      53       19558 :     while( pItem!=this->end() )
      54             :     {
      55      191083 :         WildCard aPattern(pItem->first);
      56      191083 :         if (aPattern.Matches(sURL))
      57       19557 :             break;
      58      171526 :         ++pItem;
      59      171526 :     }
      60       19558 :     return pItem;
      61             : }
      62             : 
      63             : /**
      64             :     @short      initialize static member of class HandlerCache
      65             :     @descr      We use a singleton pattern to implement this handler cache.
      66             :                 That means it use two static member list to hold all necessary information
      67             :                 and a ref count mechanism to create/destroy it on demand.
      68             :  */
      69             : HandlerHash* HandlerCache::m_pHandler  = NULL;
      70             : PatternHash* HandlerCache::m_pPattern  = NULL;
      71             : sal_Int32    HandlerCache::m_nRefCount = 0;
      72             : HandlerCFGAccess* HandlerCache::m_pConfig = NULL;
      73             : 
      74             : /**
      75             :     @short      ctor of the cache of all registered protoco handler
      76             :     @descr      It tries to open the right configuration package automaticly
      77             :                 and fill the internal structures. After that the cache can be
      78             :                 used for read access on this data and perform some search
      79             :                 operations on it.
      80             :  */
      81        2224 : HandlerCache::HandlerCache()
      82             : {
      83        2224 :     osl::MutexGuard g(LockHelper::getGlobalLock());
      84             : 
      85        2224 :     if (m_nRefCount==0)
      86             :     {
      87         146 :         m_pHandler = new HandlerHash();
      88         146 :         m_pPattern = new PatternHash();
      89         146 :         m_pConfig  = new HandlerCFGAccess(PACKAGENAME_PROTOCOLHANDLER);
      90         146 :         m_pConfig->read(&m_pHandler,&m_pPattern);
      91         146 :         m_pConfig->setCache(this);
      92             :     }
      93             : 
      94        2224 :     ++m_nRefCount;
      95        2224 : }
      96             : 
      97             : /**
      98             :     @short      dtor of the cache
      99             :     @descr      It frees all used memory. In further implementations (may if we support write access too)
     100             :                 it's a good place to flush changes back to the configuration - but not needed yet.
     101             :  */
     102        2210 : HandlerCache::~HandlerCache()
     103             : {
     104        2210 :     osl::MutexGuard g(LockHelper::getGlobalLock());
     105             : 
     106        2210 :     if( m_nRefCount==1)
     107             :     {
     108         138 :         m_pConfig->setCache(NULL);
     109         138 :         m_pHandler->free();
     110         138 :         m_pPattern->free();
     111             : 
     112         138 :         delete m_pConfig;
     113         138 :         delete m_pHandler;
     114         138 :         delete m_pPattern;
     115         138 :         m_pConfig = NULL;
     116         138 :         m_pHandler= NULL;
     117         138 :         m_pPattern= NULL;
     118             :     }
     119             : 
     120        2210 :     --m_nRefCount;
     121        2210 : }
     122             : 
     123             : /**
     124             :     @short      dtor of the cache
     125             :     @descr      It frees all used memory. In further implementations (may if we support write access too)
     126             :                 it's a good place to flush changes back to the configuration - but not needed yet.
     127             :  */
     128       19558 : bool HandlerCache::search( const OUString& sURL, ProtocolHandler* pReturn ) const
     129             : {
     130       19558 :     bool bFound = false;
     131             :     /* SAFE */{
     132       19558 :         osl::MutexGuard g(LockHelper::getGlobalLock());
     133       19558 :         PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL);
     134       19558 :         if (pItem!=m_pPattern->end())
     135             :         {
     136       19557 :             *pReturn = (*m_pHandler)[pItem->second];
     137       19557 :             bFound = true;
     138       19558 :         }
     139             :     /* SAFE */}
     140       19558 :     return bFound;
     141             : }
     142             : 
     143             : /**
     144             :     @short      search for a registered handler by using an URL struct
     145             :     @descr      We combine necessary parts of this struct to a valid URL string
     146             :                 and call our other search method ...
     147             :                 It's a helper for outside code.
     148             :  */
     149       19558 : bool HandlerCache::search( const css::util::URL& aURL, ProtocolHandler* pReturn ) const
     150             : {
     151       19558 :     return search( aURL.Complete, pReturn );
     152             : }
     153             : 
     154           0 : void HandlerCache::takeOver(HandlerHash* pHandler, PatternHash* pPattern)
     155             : {
     156           0 :     osl::MutexGuard g(LockHelper::getGlobalLock());
     157             : 
     158           0 :     HandlerHash* pOldHandler = m_pHandler;
     159           0 :     PatternHash* pOldPattern = m_pPattern;
     160             : 
     161           0 :     m_pHandler = pHandler;
     162           0 :     m_pPattern = pPattern;
     163             : 
     164           0 :     pOldHandler->free();
     165           0 :     pOldPattern->free();
     166           0 :     delete pOldHandler;
     167           0 :     delete pOldPattern;
     168           0 : }
     169             : 
     170             : /**
     171             :     @short      dtor of the config access class
     172             :     @descr      It opens the configuration package automaticly by using base class mechanism.
     173             :                 After that "read()" method of this class should be called to use it.
     174             : 
     175             :     @param      sPackage
     176             :                 specifies the package name of the configuration data which should be used
     177             :  */
     178         146 : HandlerCFGAccess::HandlerCFGAccess( const OUString& sPackage )
     179             :     : ConfigItem(sPackage)
     180         146 :     , m_pCache(0)
     181             : {
     182         146 :     css::uno::Sequence< OUString > lListenPaths(1);
     183         146 :     lListenPaths[0] = SETNAME_HANDLER;
     184         146 :     EnableNotification(lListenPaths);
     185         146 : }
     186             : 
     187             : /**
     188             :     @short      use base class mechanism to fill given structures
     189             :     @descr      User use us as a wrapper between configuration api and his internal structures.
     190             :                 He give us some pointer to his member and we fill it.
     191             : 
     192             :     @param      pHandler
     193             :                 pointer to a list of protocol handler infos
     194             : 
     195             :     @param      pPattern
     196             :                 reverse map of handler pattern to her uno names
     197             :  */
     198         146 : void HandlerCFGAccess::read( HandlerHash** ppHandler ,
     199             :                              PatternHash** ppPattern )
     200             : {
     201             :     // list of all uno implementation names without encoding
     202         146 :     css::uno::Sequence< OUString > lNames = GetNodeNames( SETNAME_HANDLER, ::utl::CONFIG_NAME_LOCAL_PATH );
     203         146 :     sal_Int32 nSourceCount = lNames.getLength();
     204         146 :     sal_Int32 nTargetCount = nSourceCount;
     205             :     // list of all full qualified path names of configuration entries
     206         292 :     css::uno::Sequence< OUString > lFullNames ( nTargetCount );
     207             : 
     208             :     // expand names to full path names
     209         146 :     sal_Int32 nSource=0;
     210         146 :     sal_Int32 nTarget=0;
     211        1606 :     for( nSource=0; nSource<nSourceCount; ++nSource )
     212             :     {
     213        1460 :         OUStringBuffer sPath( SETNAME_HANDLER );
     214        1460 :         sPath.append(CFG_PATH_SEPARATOR);
     215        1460 :         sPath.append(lNames[nSource]);
     216        1460 :         sPath.append(CFG_PATH_SEPARATOR);
     217        1460 :         sPath.append(PROPERTY_PROTOCOLS);
     218             : 
     219        1460 :         lFullNames[nTarget]  = sPath.makeStringAndClear();
     220        1460 :         ++nTarget;
     221        1460 :     }
     222             : 
     223             :     // get values at all
     224         292 :     css::uno::Sequence< css::uno::Any > lValues = GetProperties( lFullNames );
     225             :     SAL_WARN_IF( lFullNames.getLength()!=lValues.getLength(), "fwk", "HandlerCFGAccess::read(): Miss some configuration values of handler set!" );
     226             : 
     227             :     // fill structures
     228         146 :     nSource = 0;
     229        1606 :     for( nTarget=0; nTarget<nTargetCount; ++nTarget )
     230             :     {
     231             :         // create it new for every loop to guarantee a real empty object!
     232        1460 :         ProtocolHandler aHandler;
     233        1460 :         aHandler.m_sUNOName = ::utl::extractFirstFromConfigurationPath(lNames[nSource]);
     234             : 
     235             :         // unpack all values of this handler
     236        2920 :         css::uno::Sequence< OUString > lTemp;
     237        1460 :         lValues[nTarget] >>= lTemp;
     238        1460 :         aHandler.m_lProtocols = Converter::convert_seqOUString2OUStringList(lTemp);
     239             : 
     240             :         // register his pattern into the performance search hash
     241        9198 :         for (OUStringList::iterator pItem =aHandler.m_lProtocols.begin();
     242        6132 :                                     pItem!=aHandler.m_lProtocols.end();
     243             :                                     ++pItem                             )
     244             :         {
     245        1606 :             (**ppPattern)[*pItem] = lNames[nSource];
     246             :         }
     247             : 
     248             :         // insert the handler info into the normal handler cache
     249        1460 :         (**ppHandler)[lNames[nSource]] = aHandler;
     250        1460 :         ++nSource;
     251        1606 :     }
     252         146 : }
     253             : 
     254           0 : void HandlerCFGAccess::Notify(const css::uno::Sequence< OUString >& /*lPropertyNames*/)
     255             : {
     256           0 :     HandlerHash* pHandler = new HandlerHash;
     257           0 :     PatternHash* pPattern = new PatternHash;
     258             : 
     259           0 :     read(&pHandler, &pPattern);
     260           0 :     if (m_pCache)
     261           0 :         m_pCache->takeOver(pHandler, pPattern);
     262             :     else
     263             :     {
     264           0 :         delete pHandler;
     265           0 :         delete pPattern;
     266             :     }
     267           0 : }
     268             : 
     269           0 : void HandlerCFGAccess::Commit()
     270             : {
     271           0 : }
     272             : 
     273             : } // namespace framework
     274             : 
     275             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10