LCOV - code coverage report
Current view: top level - framework/source/accelerators - storageholder.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 168 258 65.1 %
Date: 2012-08-25 Functions: 15 22 68.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 144 399 36.1 %

           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                 :            : #include <accelerators/storageholder.hxx>
      30                 :            : 
      31                 :            : #include <threadhelp/readguard.hxx>
      32                 :            : #include <threadhelp/writeguard.hxx>
      33                 :            : #include <services.h>
      34                 :            : 
      35                 :            : #include <com/sun/star/container/NoSuchElementException.hpp>
      36                 :            : 
      37                 :            : #include <com/sun/star/container/XNameAccess.hpp>
      38                 :            : 
      39                 :            : #include <com/sun/star/beans/XPropertySet.hpp>
      40                 :            : 
      41                 :            : #include <com/sun/star/embed/ElementModes.hpp>
      42                 :            : 
      43                 :            : #include <com/sun/star/embed/XTransactedObject.hpp>
      44                 :            : 
      45                 :            : #include <com/sun/star/embed/XPackageStructureCreator.hpp>
      46                 :            : 
      47                 :            : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
      48                 :            : 
      49                 :            : #include <com/sun/star/io/XSeekable.hpp>
      50                 :            : 
      51                 :            : #include <comphelper/processfactory.hxx>
      52                 :            : 
      53                 :            : 
      54                 :            : #define PATH_SEPERATOR_ASCII        "/"
      55                 :            : #define PATH_SEPERATOR_UNICODE      ((sal_Unicode)'/')
      56                 :            : #define PATH_SEPERATOR              ::rtl::OUString(PATH_SEPERATOR_ASCII)
      57                 :            : 
      58                 :            : 
      59                 :            : namespace framework
      60                 :            : {
      61                 :            : 
      62                 :            : namespace css = ::com::sun::star;
      63                 :            : 
      64                 :            : //-----------------------------------------------
      65                 :          0 : StorageHolder::StorageHolder()
      66                 :            :     : ThreadHelpBase(                                        )
      67 [ #  # ][ #  # ]:          0 :     , m_xSMGR       (::comphelper::getProcessServiceFactory())
      68                 :            : {
      69                 :          0 : }
      70                 :            : 
      71                 :            : //-----------------------------------------------
      72                 :       1798 : StorageHolder::StorageHolder(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
      73                 :            :     : ThreadHelpBase(     )
      74         [ +  - ]:       1798 :     , m_xSMGR       (xSMGR)
      75                 :            : {
      76                 :       1798 : }
      77                 :            : 
      78                 :            : //-----------------------------------------------
      79         [ +  - ]:       1748 : StorageHolder::~StorageHolder()
      80                 :            : {
      81                 :            :     // TODO implement me
      82                 :            :     // dispose/clear etcpp.
      83         [ -  + ]:       1748 : }
      84                 :            : 
      85                 :            : //-----------------------------------------------
      86                 :       1558 : void StorageHolder::forgetCachedStorages()
      87                 :            : {
      88                 :            :     // SAFE -> ----------------------------------
      89         [ +  - ]:       1558 :     WriteGuard aWriteLock(m_aLock);
      90                 :            : 
      91                 :       1558 :     TPath2StorageInfo::iterator pIt;
      92 [ +  + ][ +  - ]:       5398 :     for (  pIt  = m_lStorages.begin();
      93                 :       2699 :            pIt != m_lStorages.end()  ;
      94                 :            :          ++pIt                       )
      95                 :            :     {
      96         [ +  - ]:       1141 :         TStorageInfo& rInfo = pIt->second;
      97                 :            :         // TODO think about listener !
      98                 :       1141 :         rInfo.Storage.clear();
      99                 :            :     }
     100         [ +  - ]:       1558 :     m_lStorages.clear();
     101                 :            : 
     102 [ +  - ][ +  - ]:       1558 :     aWriteLock.unlock();
     103                 :            :     // <- SAFE ----------------------------------
     104                 :       1558 : }
     105                 :            : 
     106                 :            : //-----------------------------------------------
     107                 :       1367 : void StorageHolder::setRootStorage(const css::uno::Reference< css::embed::XStorage >& xRoot)
     108                 :            : {
     109                 :            :     // SAFE -> ----------------------------------
     110         [ +  - ]:       1367 :     WriteGuard aWriteLock(m_aLock);
     111         [ +  - ]:       1367 :     m_xRoot = xRoot;
     112 [ +  - ][ +  - ]:       1367 :     aWriteLock.unlock();
     113                 :            :     // <- SAFE ----------------------------------
     114                 :       1367 : }
     115                 :            : 
     116                 :            : //-----------------------------------------------
     117                 :       1043 : css::uno::Reference< css::embed::XStorage > StorageHolder::getRootStorage() const
     118                 :            : {
     119                 :            :     // SAFE -> ----------------------------------
     120         [ +  - ]:       1043 :     ReadGuard aReadLock(m_aLock);
     121         [ +  - ]:       1043 :     return m_xRoot;
     122                 :            :     // <- SAFE ----------------------------------
     123                 :            : }
     124                 :            : 
     125                 :            : //-----------------------------------------------
     126                 :       2035 : css::uno::Reference< css::embed::XStorage > StorageHolder::openPath(const ::rtl::OUString& sPath    ,
     127                 :            :                                                                           sal_Int32        nOpenMode)
     128                 :            : {
     129         [ +  - ]:       2035 :     ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
     130         [ +  - ]:       2035 :     OUStringList    lFolders    = StorageHolder::impl_st_parsePath(sNormedPath);
     131                 :            : 
     132                 :            :     // SAFE -> ----------------------------------
     133         [ +  - ]:       2035 :     ReadGuard aReadLock(m_aLock);
     134                 :       2035 :     css::uno::Reference< css::embed::XStorage > xParent = m_xRoot;
     135         [ +  - ]:       2035 :     aReadLock.unlock();
     136                 :            :     // <- SAFE ----------------------------------
     137                 :            : 
     138                 :       2035 :     css::uno::Reference< css::embed::XStorage > xChild  ;
     139                 :       2035 :     ::rtl::OUString                             sRelPath;
     140                 :       2035 :     OUStringList::const_iterator                pIt     ;
     141                 :            : 
     142 [ +  - ][ +  + ]:      11704 :     for (  pIt  = lFolders.begin();
                 [ +  - ]
     143                 :       5852 :            pIt != lFolders.end()  ;
     144                 :            :          ++pIt                    )
     145                 :            :     {
     146                 :       3822 :         const ::rtl::OUString& sChild     = *pIt;
     147                 :       3822 :               ::rtl::OUString  sCheckPath (sRelPath);
     148                 :       3822 :                                sCheckPath += sChild;
     149                 :       3822 :                                sCheckPath += PATH_SEPERATOR;
     150                 :            : 
     151                 :            :         // SAFE -> ------------------------------
     152         [ +  - ]:       3822 :         aReadLock.lock();
     153                 :            : 
     154                 :            :         // If we found an already open storage ... we must increase
     155                 :            :         // its use count. Otherwhise it will may be closed to early :-)
     156         [ +  - ]:       3822 :         TPath2StorageInfo::iterator pCheck = m_lStorages.find(sCheckPath);
     157                 :       3822 :         TStorageInfo*               pInfo  = 0;
     158         [ +  + ]:       3822 :         if (pCheck != m_lStorages.end())
     159                 :            :         {
     160         [ +  - ]:       1263 :             pInfo = &(pCheck->second);
     161                 :       1263 :             ++(pInfo->UseCount);
     162         [ +  - ]:       1263 :             xChild = pInfo->Storage;
     163                 :            :         }
     164                 :            :         else
     165                 :            :         {
     166         [ +  - ]:       2559 :             aReadLock.unlock();
     167                 :            :             // <- SAFE ------------------------------
     168                 :            : 
     169                 :            :             try
     170                 :            :             {
     171 [ +  + ][ +  - ]:       2559 :                 xChild = StorageHolder::openSubStorageWithFallback(xParent, sChild, nOpenMode, sal_True); // TODO think about delegating fallback decision to our own calli!
     172                 :            :             }
     173                 :          0 :             catch(const css::uno::RuntimeException&)
     174                 :          0 :                 { throw; }
     175      [ -  -  + ]:         10 :             catch(const css::uno::Exception&)
     176                 :            :                 {
     177                 :            :                     /* TODO URGENT!
     178                 :            :                         in case we found some "already existing storages" on the path before and increased its UseCount ...
     179                 :            :                         and now we will get an exception on creating a new sub storage ...
     180                 :            :                         we must decrease all UseCounts, which was touched before. Otherwise these storages cant be closed!
     181                 :            : 
     182                 :            :                         Idea: Using of another structure member "PossibleUseCount" as vector of unique numbers.
     183                 :            :                         Every thread use another unique number to identify all "owned candidates".
     184                 :            :                         A flush method with the same unique number force increasing of the "UseCount" variable then
     185                 :            :                         inside a synchronized block ...
     186                 :            :                     */
     187                 :          5 :                     throw;
     188                 :            :                 }
     189                 :            : 
     190                 :            :             // SAFE -> ------------------------------
     191         [ +  - ]:       2554 :             WriteGuard aWriteLock(m_aLock);
     192         [ +  - ]:       2554 :             pInfo = &(m_lStorages[sCheckPath]);
     193         [ +  - ]:       2554 :             pInfo->Storage  = xChild;
     194                 :       2554 :             pInfo->UseCount = 1;
     195 [ +  - ][ +  - ]:       2559 :             aWriteLock.unlock();
     196                 :            :             // <- SAFE ------------------------------
     197                 :            :         }
     198                 :            : 
     199         [ +  - ]:       3817 :         xParent   = xChild;
     200                 :       3817 :         sRelPath += sChild;
     201                 :       3817 :         sRelPath += PATH_SEPERATOR;
     202                 :       3822 :     }
     203                 :            : 
     204                 :            :     // TODO think about return last storage as working storage ... but dont caching it inside this holder!
     205                 :            :     // => otherwhise the same storage is may be commit more then once.
     206                 :            : 
     207 [ +  - ][ +  - ]:       2035 :     return xChild;
     208                 :            : }
     209                 :            : 
     210                 :            : //-----------------------------------------------
     211                 :          0 : StorageHolder::TStorageList StorageHolder::getAllPathStorages(const ::rtl::OUString& sPath)
     212                 :            : {
     213         [ #  # ]:          0 :     ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
     214         [ #  # ]:          0 :     OUStringList    lFolders    = StorageHolder::impl_st_parsePath(sNormedPath);
     215                 :            : 
     216         [ #  # ]:          0 :     StorageHolder::TStorageList  lStoragesOfPath;
     217                 :          0 :     ::rtl::OUString              sRelPath       ;
     218                 :          0 :     OUStringList::const_iterator pIt            ;
     219                 :            : 
     220                 :            :     // SAFE -> ----------------------------------
     221         [ #  # ]:          0 :     ReadGuard aReadLock(m_aLock);
     222                 :            : 
     223 [ #  # ][ #  # ]:          0 :     for (  pIt  = lFolders.begin();
                 [ #  # ]
     224                 :          0 :            pIt != lFolders.end()  ;
     225                 :            :          ++pIt                    )
     226                 :            :     {
     227                 :          0 :         const ::rtl::OUString& sChild     = *pIt;
     228                 :          0 :               ::rtl::OUString  sCheckPath (sRelPath);
     229                 :          0 :                                sCheckPath += sChild;
     230                 :          0 :                                sCheckPath += PATH_SEPERATOR;
     231                 :            : 
     232         [ #  # ]:          0 :         TPath2StorageInfo::iterator pCheck = m_lStorages.find(sCheckPath);
     233         [ #  # ]:          0 :         if (pCheck == m_lStorages.end())
     234                 :            :         {
     235                 :            :             // at least one path element was not found
     236                 :            :             // Seems that this path isnt open ...
     237                 :          0 :             lStoragesOfPath.clear();
     238                 :            :             return lStoragesOfPath;
     239                 :            :         }
     240                 :            : 
     241         [ #  # ]:          0 :         TStorageInfo& rInfo = pCheck->second;
     242         [ #  # ]:          0 :         lStoragesOfPath.push_back(rInfo.Storage);
     243                 :            : 
     244                 :          0 :         sRelPath += sChild;
     245         [ #  # ]:          0 :         sRelPath += PATH_SEPERATOR;
     246                 :          0 :     }
     247                 :            : 
     248         [ #  # ]:          0 :     aReadLock.unlock();
     249                 :            :     // <- SAFE ----------------------------------
     250                 :            : 
     251 [ #  # ][ #  # ]:          0 :     return lStoragesOfPath;
     252                 :            : }
     253                 :            : 
     254                 :            : //-----------------------------------------------
     255                 :          0 : void StorageHolder::commitPath(const ::rtl::OUString& sPath)
     256                 :            : {
     257         [ #  # ]:          0 :     StorageHolder::TStorageList lStorages = getAllPathStorages(sPath);
     258                 :            : 
     259                 :          0 :     css::uno::Reference< css::embed::XTransactedObject > xCommit;
     260                 :          0 :     StorageHolder::TStorageList::reverse_iterator pIt;
     261   [ #  #  #  # ]:          0 :     for (  pIt  = lStorages.rbegin(); // order of commit is important ... otherwhise changes are not recognized!
                 [ #  # ]
     262                 :          0 :            pIt != lStorages.rend()  ;
     263                 :            :          ++pIt                      )
     264                 :            :     {
     265 [ #  # ][ #  # ]:          0 :         xCommit = css::uno::Reference< css::embed::XTransactedObject >(*pIt, css::uno::UNO_QUERY);
                 [ #  # ]
     266         [ #  # ]:          0 :         if (!xCommit.is())
     267                 :          0 :             continue;
     268 [ #  # ][ #  # ]:          0 :         xCommit->commit();
     269                 :            :     }
     270                 :            : 
     271                 :            :     // SAFE -> ------------------------------
     272         [ #  # ]:          0 :     ReadGuard aReadLock(m_aLock);
     273 [ #  # ][ #  # ]:          0 :     xCommit = css::uno::Reference< css::embed::XTransactedObject >(m_xRoot, css::uno::UNO_QUERY);
     274         [ #  # ]:          0 :     aReadLock.unlock();
     275                 :            :     // <- SAFE ------------------------------
     276                 :            : 
     277         [ #  # ]:          0 :     if (xCommit.is())
     278 [ #  # ][ #  # ]:          0 :         xCommit->commit();
                 [ #  # ]
     279                 :          0 : }
     280                 :            : 
     281                 :            : //-----------------------------------------------
     282                 :       3084 : void StorageHolder::closePath(const ::rtl::OUString& rPath)
     283                 :            : {
     284         [ +  - ]:       3084 :     ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(rPath);
     285         [ +  - ]:       3084 :     OUStringList    lFolders    = StorageHolder::impl_st_parsePath(sNormedPath);
     286                 :            : 
     287                 :            :     /* convert list of paths in the following way:
     288                 :            :         [0] = "path_1" => "path_1
     289                 :            :         [1] = "path_2" => "path_1/path_2"
     290                 :            :         [2] = "path_3" => "path_1/path_2/path_3"
     291                 :            :     */
     292                 :       3084 :     OUStringList::iterator pIt1       ;
     293                 :       3084 :     ::rtl::OUString        sParentPath;
     294 [ +  + ][ +  - ]:      15672 :     for (  pIt1  = lFolders.begin();
     295                 :       7836 :            pIt1 != lFolders.end()  ;
     296                 :            :          ++pIt1                    )
     297                 :            :     {
     298                 :       4752 :         ::rtl::OUString sCurrentRelPath  = sParentPath;
     299                 :       4752 :                         sCurrentRelPath += *pIt1;
     300                 :       4752 :                         sCurrentRelPath += PATH_SEPERATOR;
     301                 :       4752 :         *pIt1       = sCurrentRelPath;
     302                 :       4752 :         sParentPath = sCurrentRelPath;
     303                 :       4752 :     }
     304                 :            : 
     305                 :            :     // SAFE -> ------------------------------
     306         [ +  - ]:       3084 :     ReadGuard aReadLock(m_aLock);
     307                 :            : 
     308                 :       3084 :     OUStringList::reverse_iterator pIt2;
     309   [ +  -  +  - ]:      15672 :     for (  pIt2  = lFolders.rbegin();
                 [ +  + ]
     310                 :       7836 :            pIt2 != lFolders.rend()  ;
     311                 :            :          ++pIt2                     )
     312                 :            :     {
     313         [ +  - ]:       4752 :         ::rtl::OUString             sPath = *pIt2;
     314         [ +  - ]:       4752 :         TPath2StorageInfo::iterator pPath = m_lStorages.find(sPath);
     315         [ +  + ]:       4752 :         if (pPath == m_lStorages.end())
     316                 :       2256 :             continue; // ???
     317                 :            : 
     318         [ +  - ]:       2496 :         TStorageInfo& rInfo = pPath->second;
     319                 :       2496 :         --rInfo.UseCount;
     320         [ +  + ]:       2496 :         if (rInfo.UseCount < 1)
     321                 :            :         {
     322                 :       1313 :             rInfo.Storage.clear();
     323         [ +  - ]:       2496 :             m_lStorages.erase(pPath);
     324                 :            :         }
     325         [ +  + ]:       4752 :     }
     326                 :            : 
     327 [ +  - ][ +  - ]:       3084 :     aReadLock.unlock();
                 [ +  - ]
     328                 :            :     // <- SAFE ------------------------------
     329                 :       3084 : }
     330                 :            : 
     331                 :            : //-----------------------------------------------
     332                 :          0 : void StorageHolder::notifyPath(const ::rtl::OUString& sPath)
     333                 :            : {
     334         [ #  # ]:          0 :     ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
     335                 :            : 
     336                 :            :     // SAFE -> ------------------------------
     337         [ #  # ]:          0 :     ReadGuard aReadLock(m_aLock);
     338                 :            : 
     339         [ #  # ]:          0 :     TPath2StorageInfo::iterator pIt1 = m_lStorages.find(sNormedPath);
     340         [ #  # ]:          0 :     if (pIt1 == m_lStorages.end())
     341                 :          0 :         return;
     342                 :            : 
     343         [ #  # ]:          0 :     TStorageInfo& rInfo = pIt1->second;
     344                 :          0 :     TStorageListenerList::iterator pIt2;
     345 [ #  # ][ #  # ]:          0 :     for (  pIt2  = rInfo.Listener.begin();
     346                 :          0 :            pIt2 != rInfo.Listener.end()  ;
     347                 :            :          ++pIt2                          )
     348                 :            :     {
     349                 :          0 :         IStorageListener* pListener = *pIt2;
     350         [ #  # ]:          0 :         if (pListener)
     351         [ #  # ]:          0 :             pListener->changesOccurred(sNormedPath);
     352                 :            :     }
     353                 :            : 
     354 [ #  # ][ #  # ]:          0 :     aReadLock.unlock();
         [ #  # ][ #  # ]
     355                 :            :     // <- SAFE ------------------------------
     356                 :            : }
     357                 :            : 
     358                 :            : //-----------------------------------------------
     359                 :       1141 : void StorageHolder::addStorageListener(      IStorageListener* pListener,
     360                 :            :                                        const ::rtl::OUString&  sPath    )
     361                 :            : {
     362         [ +  - ]:       1141 :     ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
     363                 :            : 
     364                 :            :     // SAFE -> ------------------------------
     365         [ +  - ]:       1141 :     ReadGuard aReadLock(m_aLock);
     366                 :            : 
     367         [ +  - ]:       1141 :     TPath2StorageInfo::iterator pIt1 = m_lStorages.find(sNormedPath);
     368         [ -  + ]:       1141 :     if (pIt1 == m_lStorages.end())
     369                 :       1141 :         return;
     370                 :            : 
     371         [ +  - ]:       1141 :     TStorageInfo& rInfo = pIt1->second;
     372         [ +  - ]:       1141 :     TStorageListenerList::iterator pIt2 = ::std::find(rInfo.Listener.begin(), rInfo.Listener.end(), pListener);
     373 [ +  - ][ +  - ]:       1141 :     if (pIt2 == rInfo.Listener.end())
     374         [ +  - ]:       1141 :         rInfo.Listener.push_back(pListener);
     375                 :            : 
     376 [ +  - ][ +  - ]:       1141 :     aReadLock.unlock();
         [ -  + ][ +  - ]
     377                 :            :     // <- SAFE ------------------------------
     378                 :            : }
     379                 :            : 
     380                 :            : //-----------------------------------------------
     381                 :       1125 : void StorageHolder::removeStorageListener(      IStorageListener* pListener,
     382                 :            :                                           const ::rtl::OUString&  sPath    )
     383                 :            : {
     384         [ +  - ]:       1125 :     ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sPath);
     385                 :            : 
     386                 :            :     // SAFE -> ------------------------------
     387         [ +  - ]:       1125 :     ReadGuard aReadLock(m_aLock);
     388                 :            : 
     389         [ +  - ]:       1125 :     TPath2StorageInfo::iterator pIt1 = m_lStorages.find(sNormedPath);
     390         [ -  + ]:       1125 :     if (pIt1 == m_lStorages.end())
     391                 :       1125 :         return;
     392                 :            : 
     393         [ +  - ]:       1125 :     TStorageInfo& rInfo = pIt1->second;
     394         [ +  - ]:       1125 :     TStorageListenerList::iterator pIt2 = ::std::find(rInfo.Listener.begin(), rInfo.Listener.end(), pListener);
     395 [ +  - ][ +  - ]:       1125 :     if (pIt2 != rInfo.Listener.end())
     396         [ +  - ]:       1125 :         rInfo.Listener.erase(pIt2);
     397                 :            : 
     398 [ +  - ][ +  - ]:       1125 :     aReadLock.unlock();
         [ -  + ][ +  - ]
     399                 :            :     // <- SAFE ------------------------------
     400                 :            : }
     401                 :            : 
     402                 :            : //-----------------------------------------------
     403                 :        298 : ::rtl::OUString StorageHolder::getPathOfStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
     404                 :            : {
     405                 :            :     // SAFE -> ------------------------------
     406         [ +  - ]:        298 :     ReadGuard aReadLock(m_aLock);
     407                 :            : 
     408                 :        298 :     TPath2StorageInfo::const_iterator pIt;
     409 [ +  + ][ +  - ]:       1954 :     for (  pIt  = m_lStorages.begin();
     410                 :        977 :            pIt != m_lStorages.end()  ;
     411                 :            :          ++pIt                       )
     412                 :            :     {
     413         [ +  - ]:        976 :         const TStorageInfo& rInfo = pIt->second;
     414 [ +  - ][ +  + ]:        976 :         if (rInfo.Storage == xStorage)
     415                 :        297 :             break;
     416                 :            :     }
     417                 :            : 
     418         [ +  + ]:        298 :     if (pIt == m_lStorages.end())
     419                 :          1 :         return ::rtl::OUString();
     420                 :            : 
     421 [ +  - ][ +  - ]:        298 :     return pIt->first;
     422                 :            : 
     423                 :            :     // <- SAFE ------------------------------
     424                 :            : }
     425                 :            : 
     426                 :            : //-----------------------------------------------
     427                 :        298 : css::uno::Reference< css::embed::XStorage > StorageHolder::getParentStorage(const css::uno::Reference< css::embed::XStorage >& xChild)
     428                 :            : {
     429         [ +  - ]:        298 :     ::rtl::OUString sChildPath = getPathOfStorage(xChild);
     430         [ +  - ]:        298 :     return getParentStorage(sChildPath);
     431                 :            : }
     432                 :            : 
     433                 :            : //-----------------------------------------------
     434                 :        298 : css::uno::Reference< css::embed::XStorage > StorageHolder::getParentStorage(const ::rtl::OUString& sChildPath)
     435                 :            : {
     436                 :            :     // normed path = "a/b/c/" ... we search for "a/b/"
     437         [ +  - ]:        298 :     ::rtl::OUString sNormedPath = StorageHolder::impl_st_normPath(sChildPath);
     438         [ +  - ]:        298 :     OUStringList    lFolders    = StorageHolder::impl_st_parsePath(sNormedPath);
     439                 :        298 :     sal_Int32       c           = lFolders.size();
     440                 :            : 
     441                 :            :     // a) ""       => -       => no parent
     442                 :            :     // b) "a/b/c/" => "a/b/"  => return storage "a/b/"
     443                 :            :     // c) "a/"     => ""      => return root !
     444                 :            : 
     445                 :            :     // a)
     446         [ +  + ]:        298 :     if (c < 1)
     447                 :          1 :         return css::uno::Reference< css::embed::XStorage >();
     448                 :            : 
     449                 :            :     // SAFE -> ----------------------------------
     450         [ +  - ]:        297 :     ReadGuard aReadLock(m_aLock);
     451                 :            : 
     452                 :            :     // b)
     453         [ -  + ]:        297 :     if (c < 2)
     454                 :          0 :         return m_xRoot;
     455                 :            : 
     456                 :            :     // c)
     457                 :        297 :     ::rtl::OUString sParentPath;
     458                 :        297 :     sal_Int32       i = 0;
     459         [ +  + ]:        891 :     for (i=0; i<c-1; ++i)
     460                 :            :     {
     461                 :        594 :         sParentPath += lFolders[i];
     462                 :        594 :         sParentPath += PATH_SEPERATOR;
     463                 :            :     }
     464                 :            : 
     465         [ +  - ]:        297 :     TPath2StorageInfo::const_iterator pParent = m_lStorages.find(sParentPath);
     466         [ +  - ]:        297 :     if (pParent != m_lStorages.end())
     467         [ +  - ]:        297 :         return pParent->second.Storage;
     468                 :            : 
     469         [ #  # ]:          0 :     aReadLock.unlock();
     470                 :            :     // <- SAFE ----------------------------------
     471                 :            : 
     472                 :            :     // ?
     473                 :            :     LOG_WARNING("StorageHolder::getParentStorage()", "Unexpected situation. Cached storage item seems to be wrong.")
     474 [ +  - ][ +  - ]:        298 :     return css::uno::Reference< css::embed::XStorage >();
     475                 :            : }
     476                 :            : 
     477                 :            : //-----------------------------------------------
     478                 :          0 : void StorageHolder::operator=(const StorageHolder& rCopy)
     479                 :            : {
     480                 :            :     // SAFE -> ----------------------------------
     481         [ #  # ]:          0 :     WriteGuard aWriteLock(m_aLock);
     482                 :            : 
     483         [ #  # ]:          0 :     m_xSMGR     = rCopy.m_xSMGR; // ???
     484         [ #  # ]:          0 :     m_xRoot     = rCopy.m_xRoot;
     485         [ #  # ]:          0 :     m_lStorages = rCopy.m_lStorages;
     486                 :            : 
     487 [ #  # ][ #  # ]:          0 :     aWriteLock.unlock();
     488                 :            :     // <- SAFE ----------------------------------
     489                 :          0 : }
     490                 :            : 
     491                 :            : //-----------------------------------------------
     492                 :       2559 : css::uno::Reference< css::embed::XStorage > StorageHolder::openSubStorageWithFallback(const css::uno::Reference< css::embed::XStorage >& xBaseStorage  ,
     493                 :            :                                                                                       const ::rtl::OUString&                             sSubStorage   ,
     494                 :            :                                                                                             sal_Int32                                    eOpenMode     ,
     495                 :            :                                                                                             sal_Bool                                     bAllowFallback)
     496                 :            : {
     497                 :            :     // a) try it first with user specified open mode
     498                 :            :     //    ignore errors ... but save it for later use!
     499         [ +  - ]:       2559 :     css::uno::Exception exResult;
     500                 :            :     try
     501                 :            :     {
     502 [ +  - ][ +  + ]:       2559 :         css::uno::Reference< css::embed::XStorage > xSubStorage = xBaseStorage->openStorageElement(sSubStorage, eOpenMode);
     503         [ +  - ]:       2554 :         if (xSubStorage.is())
     504         [ -  + ]:       2554 :             return xSubStorage;
     505                 :            :     }
     506                 :          0 :     catch(const css::uno::RuntimeException&)
     507                 :          0 :         { throw; }
     508      [ -  -  + ]:         10 :     catch(const css::uno::Exception& ex)
                 [ +  - ]
     509         [ -  + ]:          5 :         { exResult = ex; }
     510                 :            : 
     511                 :            :     // b) readonly already tried? => forward last error!
     512 [ +  - ][ +  - ]:          5 :     if (
     513                 :            :         (!bAllowFallback                                                                 ) ||   // fallback allowed  ?
     514                 :            :         ((eOpenMode & css::embed::ElementModes::WRITE) != css::embed::ElementModes::WRITE)      // fallback possible ?
     515                 :            :        )
     516         [ +  - ]:          5 :         throw exResult;
     517                 :            : 
     518                 :            :     // c) try it readonly
     519                 :            :     //    dont catch exception here! Outside code whish to know, if operation failed or not.
     520                 :            :     //    Otherwhise they work on NULL references ...
     521                 :          0 :     sal_Int32 eNewMode = (eOpenMode & ~css::embed::ElementModes::WRITE);
     522 [ #  # ][ #  # ]:          0 :     css::uno::Reference< css::embed::XStorage > xSubStorage = xBaseStorage->openStorageElement(sSubStorage, eNewMode);
     523         [ #  # ]:          0 :     if (xSubStorage.is())
     524                 :          0 :         return xSubStorage;
     525                 :            : 
     526                 :            :     // d) no chance!
     527                 :            :     LOG_WARNING("openSubStorageWithFallback()", "Unexpected situation! Got no exception for missing storage ...")
     528         [ +  - ]:       2564 :     return css::uno::Reference< css::embed::XStorage >();
     529                 :            : }
     530                 :            : 
     531                 :            : //-----------------------------------------------
     532                 :          0 : css::uno::Reference< css::io::XStream > StorageHolder::openSubStreamWithFallback(const css::uno::Reference< css::embed::XStorage >& xBaseStorage  ,
     533                 :            :                                                                                  const ::rtl::OUString&                             sSubStream    ,
     534                 :            :                                                                                        sal_Int32                                    eOpenMode     ,
     535                 :            :                                                                                        sal_Bool                                     bAllowFallback)
     536                 :            : {
     537                 :            :     // a) try it first with user specified open mode
     538                 :            :     //    ignore errors ... but save it for later use!
     539         [ #  # ]:          0 :     css::uno::Exception exResult;
     540                 :            :     try
     541                 :            :     {
     542 [ #  # ][ #  # ]:          0 :         css::uno::Reference< css::io::XStream > xSubStream = xBaseStorage->openStreamElement(sSubStream, eOpenMode);
     543         [ #  # ]:          0 :         if (xSubStream.is())
     544         [ #  # ]:          0 :             return xSubStream;
     545                 :            :     }
     546                 :          0 :     catch(const css::uno::RuntimeException&)
     547                 :          0 :         { throw; }
     548   [ #  #  #  #  :          0 :     catch(const css::uno::Exception& ex)
                      # ]
     549         [ #  # ]:          0 :         { exResult = ex; }
     550                 :            : 
     551                 :            :     // b) readonly already tried? => forward last error!
     552 [ #  # ][ #  # ]:          0 :     if (
     553                 :            :         (!bAllowFallback                                                                 ) ||   // fallback allowed  ?
     554                 :            :         ((eOpenMode & css::embed::ElementModes::WRITE) != css::embed::ElementModes::WRITE)      // fallback possible ?
     555                 :            :        )
     556         [ #  # ]:          0 :         throw exResult;
     557                 :            : 
     558                 :            :     // c) try it readonly
     559                 :            :     //    dont catch exception here! Outside code whish to know, if operation failed or not.
     560                 :            :     //    Otherwhise they work on NULL references ...
     561                 :          0 :     sal_Int32 eNewMode = (eOpenMode & ~css::embed::ElementModes::WRITE);
     562 [ #  # ][ #  # ]:          0 :     css::uno::Reference< css::io::XStream > xSubStream = xBaseStorage->openStreamElement(sSubStream, eNewMode);
     563         [ #  # ]:          0 :     if (xSubStream.is())
     564                 :          0 :         return xSubStream;
     565                 :            : 
     566                 :            :     // d) no chance!
     567                 :            :     LOG_WARNING("openSubStreamWithFallbacks()", "Unexpected situation! Got no exception for missing stream ...")
     568         [ #  # ]:          0 :     return css::uno::Reference< css::io::XStream >();
     569                 :            : }
     570                 :            : 
     571                 :            : //-----------------------------------------------
     572                 :       7683 : ::rtl::OUString StorageHolder::impl_st_normPath(const ::rtl::OUString& sPath)
     573                 :            : {
     574                 :            :     // path must start without "/" but end with "/"!
     575                 :            : 
     576                 :       7683 :     ::rtl::OUString sNormedPath = sPath;
     577                 :            : 
     578                 :            :     // "/bla" => "bla" && "/" => "" (!)
     579         [ -  + ]:       7683 :     if (sNormedPath.indexOf(PATH_SEPERATOR) == 0)
     580                 :          0 :         sNormedPath += sNormedPath.copy(1);
     581                 :            : 
     582                 :            :     // "/" => "" || "" => "" ?
     583         [ +  + ]:       7683 :     if (sNormedPath.isEmpty())
     584                 :          1 :         return ::rtl::OUString();
     585                 :            : 
     586                 :            :     // "bla" => "bla/"
     587         [ +  + ]:       7682 :     if (sNormedPath.lastIndexOf(PATH_SEPERATOR) != (sNormedPath.getLength()-1))
     588                 :       7385 :         sNormedPath += PATH_SEPERATOR;
     589                 :            : 
     590                 :       7683 :     return sNormedPath;
     591                 :            : }
     592                 :            : 
     593                 :            : //-----------------------------------------------
     594                 :       5417 : OUStringList StorageHolder::impl_st_parsePath(const ::rtl::OUString& sPath)
     595                 :            : {
     596         [ +  - ]:       5417 :     OUStringList lToken;
     597                 :       5417 :     sal_Int32    i  = 0;
     598                 :      14883 :     while (sal_True)
     599                 :            :     {
     600                 :      14883 :         ::rtl::OUString sToken = sPath.getToken(0, PATH_SEPERATOR_UNICODE, i);
     601         [ +  + ]:      14883 :         if (i < 0)
     602                 :            :             break;
     603 [ +  - ][ +  + ]:      24349 :         lToken.push_back(sToken);
     604                 :      14883 :     }
     605                 :       5417 :     return lToken;
     606                 :            : }
     607                 :            : 
     608                 :            : //===============================================
     609                 :            : } // namespace framework
     610                 :            : 
     611                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10