LCOV - code coverage report
Current view: top level - framework/source/fwi/classes - protocolhandlercache.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 81 103 78.6 %
Date: 2014-11-03 Functions: 9 13 69.2 %
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             : 
      29             : #include <tools/wldcrd.hxx>
      30             : #include <unotools/configpaths.hxx>
      31             : #include <rtl/ustrbuf.hxx>
      32             : #include <vcl/svapp.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       51693 : PatternHash::iterator PatternHash::findPatternKey( const OUString& sURL )
      51             : {
      52       51693 :     PatternHash::iterator pItem = this->begin();
      53       51693 :     while( pItem!=this->end() )
      54             :     {
      55      498476 :         WildCard aPattern(pItem->first);
      56      498476 :         if (aPattern.Matches(sURL))
      57       51691 :             break;
      58      446785 :         ++pItem;
      59      446785 :     }
      60       51693 :     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 automatically
      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        5883 : HandlerCache::HandlerCache()
      82             : {
      83        5883 :     SolarMutexGuard aGuard;
      84             : 
      85        5883 :     if (m_nRefCount==0)
      86             :     {
      87         309 :         m_pHandler = new HandlerHash();
      88         309 :         m_pPattern = new PatternHash();
      89         309 :         m_pConfig  = new HandlerCFGAccess(PACKAGENAME_PROTOCOLHANDLER);
      90         309 :         m_pConfig->read(&m_pHandler,&m_pPattern);
      91         309 :         m_pConfig->setCache(this);
      92             :     }
      93             : 
      94        5883 :     ++m_nRefCount;
      95        5883 : }
      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        5873 : HandlerCache::~HandlerCache()
     103             : {
     104        5873 :     SolarMutexGuard aGuard;
     105             : 
     106        5873 :     if( m_nRefCount==1)
     107             :     {
     108         301 :         m_pConfig->setCache(NULL);
     109         301 :         m_pHandler->free();
     110         301 :         m_pPattern->free();
     111             : 
     112         301 :         delete m_pConfig;
     113         301 :         delete m_pHandler;
     114         301 :         delete m_pPattern;
     115         301 :         m_pConfig = NULL;
     116         301 :         m_pHandler= NULL;
     117         301 :         m_pPattern= NULL;
     118             :     }
     119             : 
     120        5873 :     --m_nRefCount;
     121        5873 : }
     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       51693 : bool HandlerCache::search( const OUString& sURL, ProtocolHandler* pReturn ) const
     129             : {
     130       51693 :     bool bFound = false;
     131             : 
     132       51693 :     SolarMutexGuard aGuard;
     133             : 
     134       51693 :     PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL);
     135       51693 :     if (pItem!=m_pPattern->end())
     136             :     {
     137       51691 :         *pReturn = (*m_pHandler)[pItem->second];
     138       51691 :         bFound = true;
     139             :     }
     140             : 
     141       51693 :     return bFound;
     142             : }
     143             : 
     144             : /**
     145             :     @short      search for a registered handler by using an URL struct
     146             :     @descr      We combine necessary parts of this struct to a valid URL string
     147             :                 and call our other search method ...
     148             :                 It's a helper for outside code.
     149             :  */
     150       51693 : bool HandlerCache::search( const css::util::URL& aURL, ProtocolHandler* pReturn ) const
     151             : {
     152       51693 :     return search( aURL.Complete, pReturn );
     153             : }
     154             : 
     155           0 : void HandlerCache::takeOver(HandlerHash* pHandler, PatternHash* pPattern)
     156             : {
     157           0 :     SolarMutexGuard aGuard;
     158             : 
     159           0 :     HandlerHash* pOldHandler = m_pHandler;
     160           0 :     PatternHash* pOldPattern = m_pPattern;
     161             : 
     162           0 :     m_pHandler = pHandler;
     163           0 :     m_pPattern = pPattern;
     164             : 
     165           0 :     pOldHandler->free();
     166           0 :     pOldPattern->free();
     167           0 :     delete pOldHandler;
     168           0 :     delete pOldPattern;
     169           0 : }
     170             : 
     171             : /**
     172             :     @short      dtor of the config access class
     173             :     @descr      It opens the configuration package automatically by using base class mechanism.
     174             :                 After that "read()" method of this class should be called to use it.
     175             : 
     176             :     @param      sPackage
     177             :                 specifies the package name of the configuration data which should be used
     178             :  */
     179         309 : HandlerCFGAccess::HandlerCFGAccess( const OUString& sPackage )
     180             :     : ConfigItem(sPackage)
     181         309 :     , m_pCache(0)
     182             : {
     183         309 :     css::uno::Sequence< OUString > lListenPaths(1);
     184         309 :     lListenPaths[0] = SETNAME_HANDLER;
     185         309 :     EnableNotification(lListenPaths);
     186         309 : }
     187             : 
     188             : /**
     189             :     @short      use base class mechanism to fill given structures
     190             :     @descr      User use us as a wrapper between configuration api and his internal structures.
     191             :                 He give us some pointer to his member and we fill it.
     192             : 
     193             :     @param      pHandler
     194             :                 pointer to a list of protocol handler infos
     195             : 
     196             :     @param      pPattern
     197             :                 reverse map of handler pattern to her uno names
     198             :  */
     199         309 : void HandlerCFGAccess::read( HandlerHash** ppHandler ,
     200             :                              PatternHash** ppPattern )
     201             : {
     202             :     // list of all uno implementation names without encoding
     203         309 :     css::uno::Sequence< OUString > lNames = GetNodeNames( SETNAME_HANDLER, ::utl::CONFIG_NAME_LOCAL_PATH );
     204         309 :     sal_Int32 nSourceCount = lNames.getLength();
     205         309 :     sal_Int32 nTargetCount = nSourceCount;
     206             :     // list of all full qualified path names of configuration entries
     207         618 :     css::uno::Sequence< OUString > lFullNames ( nTargetCount );
     208             : 
     209             :     // expand names to full path names
     210         309 :     sal_Int32 nSource=0;
     211         309 :     sal_Int32 nTarget=0;
     212        3399 :     for( nSource=0; nSource<nSourceCount; ++nSource )
     213             :     {
     214        3090 :         OUStringBuffer sPath( SETNAME_HANDLER );
     215        3090 :         sPath.append(CFG_PATH_SEPARATOR);
     216        3090 :         sPath.append(lNames[nSource]);
     217        3090 :         sPath.append(CFG_PATH_SEPARATOR);
     218        3090 :         sPath.append(PROPERTY_PROTOCOLS);
     219             : 
     220        3090 :         lFullNames[nTarget]  = sPath.makeStringAndClear();
     221        3090 :         ++nTarget;
     222        3090 :     }
     223             : 
     224             :     // get values at all
     225         618 :     css::uno::Sequence< css::uno::Any > lValues = GetProperties( lFullNames );
     226             :     SAL_WARN_IF( lFullNames.getLength()!=lValues.getLength(), "fwk", "HandlerCFGAccess::read(): Miss some configuration values of handler set!" );
     227             : 
     228             :     // fill structures
     229         309 :     nSource = 0;
     230        3399 :     for( nTarget=0; nTarget<nTargetCount; ++nTarget )
     231             :     {
     232             :         // create it new for every loop to guarantee a real empty object!
     233        3090 :         ProtocolHandler aHandler;
     234        3090 :         aHandler.m_sUNOName = ::utl::extractFirstFromConfigurationPath(lNames[nSource]);
     235             : 
     236             :         // unpack all values of this handler
     237        6180 :         css::uno::Sequence< OUString > lTemp;
     238        3090 :         lValues[nTarget] >>= lTemp;
     239        3090 :         aHandler.m_lProtocols = Converter::convert_seqOUString2OUStringList(lTemp);
     240             : 
     241             :         // register his pattern into the performance search hash
     242       19467 :         for (OUStringList::iterator pItem =aHandler.m_lProtocols.begin();
     243       12978 :                                     pItem!=aHandler.m_lProtocols.end();
     244             :                                     ++pItem                             )
     245             :         {
     246        3399 :             (**ppPattern)[*pItem] = lNames[nSource];
     247             :         }
     248             : 
     249             :         // insert the handler info into the normal handler cache
     250        3090 :         (**ppHandler)[lNames[nSource]] = aHandler;
     251        3090 :         ++nSource;
     252        3399 :     }
     253         309 : }
     254             : 
     255           0 : void HandlerCFGAccess::Notify(const css::uno::Sequence< OUString >& /*lPropertyNames*/)
     256             : {
     257           0 :     HandlerHash* pHandler = new HandlerHash;
     258           0 :     PatternHash* pPattern = new PatternHash;
     259             : 
     260           0 :     read(&pHandler, &pPattern);
     261           0 :     if (m_pCache)
     262           0 :         m_pCache->takeOver(pHandler, pPattern);
     263             :     else
     264             :     {
     265           0 :         delete pHandler;
     266           0 :         delete pPattern;
     267             :     }
     268           0 : }
     269             : 
     270           0 : void HandlerCFGAccess::Commit()
     271             : {
     272           0 : }
     273             : 
     274         969 : } // namespace framework
     275             : 
     276             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10