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

Generated by: LCOV version 1.10