LCOV - code coverage report
Current view: top level - ucb/source/ucp/tdoc - tdoc_storage.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 49 197 24.9 %
Date: 2012-08-25 Functions: 6 12 50.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 42 415 10.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 <memory>
      30                 :            : 
      31                 :            : #include "com/sun/star/beans/XPropertySet.hpp"
      32                 :            : #include "com/sun/star/embed/ElementModes.hpp"
      33                 :            : #include "com/sun/star/lang/XSingleServiceFactory.hpp"
      34                 :            : 
      35                 :            : #include "tdoc_uri.hxx"
      36                 :            : #include "tdoc_docmgr.hxx"
      37                 :            : #include "tdoc_stgelems.hxx"
      38                 :            : 
      39                 :            : #include "tdoc_storage.hxx"
      40                 :            : 
      41                 :            : using namespace com::sun::star;
      42                 :            : using namespace tdoc_ucp;
      43                 :            : 
      44                 :            : 
      45                 :            : //=========================================================================
      46                 :            : //=========================================================================
      47                 :            : //
      48                 :            : // StorageElementFactory Implementation.
      49                 :            : //
      50                 :            : //=========================================================================
      51                 :            : //=========================================================================
      52                 :            : 
      53                 :         17 : StorageElementFactory::StorageElementFactory(
      54                 :            :     const uno::Reference< lang::XMultiServiceFactory > & xSMgr,
      55                 :            :     const rtl::Reference< OfficeDocumentsManager > & xDocsMgr )
      56                 :            : : m_xDocsMgr( xDocsMgr ),
      57 [ +  - ][ +  - ]:         17 :   m_xSMgr( xSMgr )
      58                 :            : {
      59                 :         17 : }
      60                 :            : 
      61                 :            : //=========================================================================
      62         [ +  - ]:         17 : StorageElementFactory::~StorageElementFactory()
      63                 :            : {
      64                 :            :     OSL_ENSURE( m_aMap.empty(),
      65                 :            :         "StorageElementFactory::~StorageElementFactory - Dangling storages!" );
      66         [ -  + ]:         34 : }
      67                 :            : 
      68                 :            : //=========================================================================
      69                 :            : uno::Reference< embed::XStorage >
      70                 :          0 : StorageElementFactory::createTemporaryStorage()
      71                 :            :     throw ( uno::Exception,
      72                 :            :             uno::RuntimeException )
      73                 :            : {
      74                 :          0 :     uno::Reference< embed::XStorage > xStorage;
      75                 :          0 :     uno::Reference< lang::XSingleServiceFactory > xStorageFac;
      76         [ #  # ]:          0 :     if ( m_xSMgr.is() )
      77                 :            :     {
      78                 :            :         xStorageFac = uno::Reference< lang::XSingleServiceFactory >(
      79         [ #  # ]:          0 :                m_xSMgr->createInstance(
      80                 :            :                    rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
      81                 :          0 :                        "com.sun.star.embed.StorageFactory" ) ) ),
      82 [ #  # ][ #  # ]:          0 :                uno::UNO_QUERY );
         [ #  # ][ #  # ]
      83                 :            :     }
      84                 :            : 
      85                 :            :     OSL_ENSURE( xStorageFac.is(), "Can't create storage factory!" );
      86         [ #  # ]:          0 :     if ( xStorageFac.is() )
      87                 :            :         xStorage = uno::Reference< embed::XStorage >(
      88         [ #  # ]:          0 :                             xStorageFac->createInstance(),
      89 [ #  # ][ #  # ]:          0 :                             uno::UNO_QUERY );
                 [ #  # ]
      90                 :            : 
      91         [ #  # ]:          0 :     if ( !xStorage.is() )
      92         [ #  # ]:          0 :         throw uno::RuntimeException();
      93                 :            : 
      94                 :          0 :     return xStorage;
      95                 :            : }
      96                 :            : 
      97                 :            : //=========================================================================
      98                 :            : uno::Reference< embed::XStorage >
      99                 :         95 : StorageElementFactory::createStorage( const rtl::OUString & rUri,
     100                 :            :                                       StorageAccessMode eMode )
     101                 :            :     throw ( embed::InvalidStorageException,
     102                 :            :             lang::IllegalArgumentException,
     103                 :            :             io::IOException,
     104                 :            :             embed::StorageWrappedTargetException,
     105                 :            :             uno::RuntimeException )
     106                 :            : {
     107         [ +  - ]:         95 :     osl::MutexGuard aGuard( m_aMutex );
     108                 :            : 
     109 [ -  + ][ #  # ]:         95 :     if ( ( eMode != READ ) &&
                 [ #  # ]
     110                 :            :          ( eMode != READ_WRITE_NOCREATE ) &&
     111                 :            :          ( eMode != READ_WRITE_CREATE ) )
     112                 :            :         throw lang::IllegalArgumentException(
     113                 :            :             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
     114                 :            :                 "Invalid open mode!" ) ),
     115                 :            :             uno::Reference< uno::XInterface >(),
     116 [ #  # ][ #  # ]:          0 :             sal_Int16( 2 ) );
     117                 :            : 
     118                 :         95 :     Uri aUri( rUri );
     119 [ -  + ][ +  - ]:         95 :     if ( aUri.isRoot() )
     120                 :            :     {
     121                 :            :         throw lang::IllegalArgumentException(
     122                 :            :             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
     123                 :            :                 "Root never has a storage!" ) ),
     124                 :            :             uno::Reference< uno::XInterface >(),
     125 [ #  # ][ #  # ]:          0 :             sal_Int16( 1 ) );
     126                 :            :     }
     127                 :            : 
     128                 :            :     rtl::OUString aUriKey
     129                 :         95 :         ( ( rUri.getStr()[ rUri.getLength() - 1 ] == sal_Unicode( '/' ) )
     130                 :          0 :           ? rUri.copy( 0, rUri.getLength() - 1 )
     131         [ -  + ]:         95 :           : rUri );
     132                 :            : 
     133                 :         95 :     StorageMap::iterator aIt ( m_aMap.begin() );
     134                 :         95 :     StorageMap::iterator aEnd( m_aMap.end() );
     135                 :            : 
     136         [ -  + ]:         95 :     while ( aIt != aEnd )
     137                 :            :     {
     138         [ #  # ]:          0 :         if ( (*aIt).first.first == aUriKey )
     139                 :            :         {
     140                 :            :             // URI matches. Now, check open mode.
     141                 :          0 :             bool bMatch = true;
     142      [ #  #  # ]:          0 :             switch ( eMode )
     143                 :            :             {
     144                 :            :                 case READ:
     145                 :            :                     // No need to check; storage is at least readable.
     146                 :          0 :                     bMatch = true;
     147                 :          0 :                     break;
     148                 :            : 
     149                 :            :                 case READ_WRITE_NOCREATE:
     150                 :            :                 case READ_WRITE_CREATE:
     151                 :            :                     // If found storage is writable, it can be used.
     152                 :            :                     // If not, a new one must be created.
     153                 :          0 :                     bMatch = (*aIt).first.second;
     154                 :          0 :                     break;
     155                 :            :             }
     156                 :            : 
     157         [ #  # ]:          0 :             if ( bMatch )
     158                 :          0 :                 break;
     159                 :            :         }
     160                 :          0 :         ++aIt;
     161                 :            :     }
     162                 :            : 
     163         [ +  - ]:         95 :     if ( aIt == aEnd )
     164                 :            :     {
     165                 :         95 :         uno::Reference< embed::XStorage > xParentStorage;
     166                 :            : 
     167                 :            :         // documents never have a parent storage.
     168 [ -  + ][ +  - ]:         95 :         if ( !aUri.isDocument() )
     169                 :            :         {
     170 [ #  # ][ #  # ]:          0 :             xParentStorage = queryParentStorage( aUriKey, eMode );
     171                 :            : 
     172         [ #  # ]:          0 :             if ( !xParentStorage.is() )
     173                 :            :             {
     174                 :            :                 // requested to create new storage, but failed?
     175                 :            :                 OSL_ENSURE( eMode != READ_WRITE_CREATE,
     176                 :            :                             "Unable to create parent storage!" );
     177                 :          0 :                 return xParentStorage;
     178                 :            :             }
     179                 :            :         }
     180                 :            : 
     181                 :            :         uno::Reference< embed::XStorage > xStorage
     182         [ +  - ]:         95 :             = queryStorage( xParentStorage, aUriKey, eMode );
     183                 :            : 
     184         [ -  + ]:         95 :         if ( !xStorage.is() )
     185                 :            :         {
     186                 :            :             // requested to create new storage, but failed?
     187                 :            :             OSL_ENSURE( eMode != READ_WRITE_CREATE,
     188                 :            :                         "Unable to create storage!" );
     189                 :          0 :             return xStorage;
     190                 :            :         }
     191                 :            : 
     192                 :            :         bool bWritable = ( ( eMode == READ_WRITE_NOCREATE )
     193 [ +  - ][ -  + ]:         95 :                             || ( eMode == READ_WRITE_CREATE ) );
     194                 :            : 
     195                 :            :         std::auto_ptr< Storage > xElement(
     196 [ +  - ][ +  - ]:         95 :             new Storage( m_xSMgr, this, aUriKey, xParentStorage, xStorage ) );
                 [ +  - ]
     197                 :            : 
     198                 :            :         aIt = m_aMap.insert(
     199                 :            :             StorageMap::value_type(
     200                 :            :                 std::pair< rtl::OUString, bool >( aUriKey, bWritable ),
     201 [ +  - ][ +  - ]:         95 :                 xElement.get() ) ).first;
     202                 :            : 
     203                 :         95 :         aIt->second->m_aContainerIt = aIt;
     204                 :         95 :         xElement.release();
     205 [ +  - ][ +  - ]:         95 :         return aIt->second;
                 [ +  - ]
     206                 :            :     }
     207 [ #  # ][ #  # ]:          0 :     else if ( osl_incrementInterlockedCount( &aIt->second->m_refCount ) > 1 )
     208                 :            :     {
     209                 :          0 :         rtl::Reference< Storage > xElement( aIt->second );
     210         [ #  # ]:          0 :         osl_decrementInterlockedCount( &aIt->second->m_refCount );
     211 [ #  # ][ #  # ]:          0 :         return aIt->second;
     212                 :            :     }
     213                 :            :     else
     214                 :            :     {
     215         [ #  # ]:          0 :         osl_decrementInterlockedCount( &aIt->second->m_refCount );
     216                 :          0 :         aIt->second->m_aContainerIt = m_aMap.end();
     217                 :            : 
     218                 :          0 :         uno::Reference< embed::XStorage > xParentStorage;
     219                 :            : 
     220                 :            :         // documents never have a parent storage.
     221 [ #  # ][ #  # ]:          0 :         if ( !aUri.isDocument() )
     222                 :            :         {
     223 [ #  # ][ #  # ]:          0 :             xParentStorage = queryParentStorage( aUriKey, eMode );
     224                 :            : 
     225         [ #  # ]:          0 :             if ( !xParentStorage.is() )
     226                 :            :             {
     227                 :            :                 // requested to create new storage, but failed?
     228                 :            :                 OSL_ENSURE( eMode != READ_WRITE_CREATE,
     229                 :            :                             "Unable to create parent storage!" );
     230                 :          0 :                 return xParentStorage;
     231                 :            :             }
     232                 :            :         }
     233                 :            : 
     234                 :            :         uno::Reference< embed::XStorage > xStorage
     235         [ #  # ]:          0 :             = queryStorage( xParentStorage, aUriKey, eMode );
     236                 :            : 
     237         [ #  # ]:          0 :         if ( !xStorage.is() )
     238                 :            :         {
     239                 :            :             // requested to create new storage, but failed?
     240                 :            :             OSL_ENSURE( eMode != READ_WRITE_CREATE,
     241                 :            :                         "Unable to create storage!" );
     242                 :          0 :             return xStorage;
     243                 :            :         }
     244                 :            : 
     245                 :          0 :         aIt->second
     246         [ #  # ]:          0 :             = new Storage( m_xSMgr, this, aUriKey, xParentStorage, xStorage );
           [ #  #  #  # ]
     247                 :          0 :         aIt->second->m_aContainerIt = aIt;
     248 [ #  # ][ #  # ]:          0 :         return aIt->second;
     249         [ +  - ]:         95 :     }
     250                 :            : }
     251                 :            : 
     252                 :            : //=========================================================================
     253                 :            : uno::Reference< io::XInputStream >
     254                 :          0 : StorageElementFactory::createInputStream( const rtl::OUString & rUri,
     255                 :            :                                           const rtl::OUString & rPassword )
     256                 :            :     throw ( embed::InvalidStorageException,
     257                 :            :             lang::IllegalArgumentException,
     258                 :            :             io::IOException,
     259                 :            :             embed::StorageWrappedTargetException,
     260                 :            :             packages::WrongPasswordException,
     261                 :            :             uno::RuntimeException )
     262                 :            : {
     263         [ #  # ]:          0 :     osl::MutexGuard aGuard( m_aMutex );
     264                 :            : 
     265                 :            :     uno::Reference< embed::XStorage > xParentStorage
     266         [ #  # ]:          0 :         = queryParentStorage( rUri, READ );
     267                 :            : 
     268                 :            :     // Each stream must have a parent storage.
     269         [ #  # ]:          0 :     if ( !xParentStorage.is() )
     270                 :          0 :         return uno::Reference< io::XInputStream >();
     271                 :            : 
     272                 :            :     uno::Reference< io::XStream > xStream
     273         [ #  # ]:          0 :         = queryStream( xParentStorage, rUri, rPassword, READ, false );
     274                 :            : 
     275         [ #  # ]:          0 :     if ( !xStream.is() )
     276                 :          0 :         return uno::Reference< io::XInputStream >();
     277                 :            : 
     278 [ #  # ][ #  # ]:          0 :     return xStream->getInputStream();
                 [ #  # ]
     279                 :            : }
     280                 :            : 
     281                 :            : //=========================================================================
     282                 :            : uno::Reference< io::XOutputStream >
     283                 :          0 : StorageElementFactory::createOutputStream( const rtl::OUString & rUri,
     284                 :            :                                            const rtl::OUString & rPassword,
     285                 :            :                                            bool bTruncate )
     286                 :            :     throw ( embed::InvalidStorageException,
     287                 :            :             lang::IllegalArgumentException,
     288                 :            :             io::IOException,
     289                 :            :             embed::StorageWrappedTargetException,
     290                 :            :             packages::WrongPasswordException,
     291                 :            :             uno::RuntimeException )
     292                 :            : {
     293         [ #  # ]:          0 :     osl::MutexGuard aGuard( m_aMutex );
     294                 :            : 
     295                 :            :     uno::Reference< embed::XStorage > xParentStorage
     296         [ #  # ]:          0 :         = queryParentStorage( rUri, READ_WRITE_CREATE );
     297                 :            : 
     298                 :            :     // Each stream must have a parent storage.
     299         [ #  # ]:          0 :     if ( !xParentStorage.is() )
     300                 :            :     {
     301                 :            :         OSL_FAIL( "StorageElementFactory::createOutputStream - "
     302                 :            :                     "Unable to create parent storage!" );
     303                 :          0 :         return uno::Reference< io::XOutputStream >();
     304                 :            :     }
     305                 :            : 
     306                 :            :     uno::Reference< io::XStream > xStream
     307                 :            :         = queryStream(
     308         [ #  # ]:          0 :             xParentStorage, rUri, rPassword, READ_WRITE_CREATE, bTruncate );
     309                 :            : 
     310         [ #  # ]:          0 :     if ( !xStream.is() )
     311                 :            :     {
     312                 :            :         OSL_FAIL( "StorageElementFactory::createOutputStream - "
     313                 :            :                     "Unable to create stream!" );
     314                 :          0 :         return uno::Reference< io::XOutputStream >();
     315                 :            :     }
     316                 :            : 
     317                 :            :     // Note: We need a wrapper to hold a reference to the parent storage to
     318                 :            :     //       ensure that nobody else owns it at the moment we want to commit
     319                 :            :     //       our changes. (There can be only one writable instance at a time
     320                 :            :     //       and even no writable instance if there is  already another
     321                 :            :     //       read-only instance!)
     322                 :            :     return uno::Reference< io::XOutputStream >(
     323                 :            :         new OutputStream(
     324 [ #  # ][ #  # ]:          0 :             m_xSMgr, rUri, xParentStorage, xStream->getOutputStream() ) );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     325                 :            : }
     326                 :            : 
     327                 :            : //=========================================================================
     328                 :            : uno::Reference< io::XStream >
     329                 :          0 : StorageElementFactory::createStream( const rtl::OUString & rUri,
     330                 :            :                                      const rtl::OUString & rPassword,
     331                 :            :                                      bool bTruncate )
     332                 :            :     throw ( embed::InvalidStorageException,
     333                 :            :             lang::IllegalArgumentException,
     334                 :            :             io::IOException,
     335                 :            :             embed::StorageWrappedTargetException,
     336                 :            :             packages::WrongPasswordException,
     337                 :            :             uno::RuntimeException )
     338                 :            : {
     339         [ #  # ]:          0 :     osl::MutexGuard aGuard( m_aMutex );
     340                 :            : 
     341                 :            :     uno::Reference< embed::XStorage > xParentStorage
     342         [ #  # ]:          0 :         = queryParentStorage( rUri, READ_WRITE_CREATE );
     343                 :            : 
     344                 :            :     // Each stream must have a parent storage.
     345         [ #  # ]:          0 :     if ( !xParentStorage.is() )
     346                 :            :     {
     347                 :            :         OSL_FAIL( "StorageElementFactory::createStream - "
     348                 :            :                     "Unable to create parent storage!" );
     349                 :          0 :         return uno::Reference< io::XStream >();
     350                 :            :     }
     351                 :            : 
     352                 :            :     uno::Reference< io::XStream > xStream
     353                 :            :         = queryStream(
     354         [ #  # ]:          0 :             xParentStorage, rUri, rPassword, READ_WRITE_NOCREATE, bTruncate );
     355                 :            : 
     356         [ #  # ]:          0 :     if ( !xStream.is() )
     357                 :            :     {
     358                 :            :         OSL_FAIL( "StorageElementFactory::createStream - "
     359                 :            :                     "Unable to create stream!" );
     360                 :          0 :         return uno::Reference< io::XStream >();
     361                 :            :     }
     362                 :            : 
     363                 :            :     return uno::Reference< io::XStream >(
     364 [ #  # ][ #  # ]:          0 :         new Stream( m_xSMgr, rUri, xParentStorage, xStream ) );
         [ #  # ][ #  # ]
     365                 :            : }
     366                 :            : 
     367                 :            : //=========================================================================
     368                 :         95 : void StorageElementFactory::releaseElement( Storage * pElement ) SAL_THROW(())
     369                 :            : {
     370                 :            :     OSL_ASSERT( pElement );
     371         [ +  - ]:         95 :     osl::MutexGuard aGuard( m_aMutex );
     372         [ +  - ]:         95 :     if ( pElement->m_aContainerIt != m_aMap.end() )
     373 [ +  - ][ +  - ]:         95 :         m_aMap.erase( pElement->m_aContainerIt );
     374                 :         95 : }
     375                 :            : 
     376                 :            : //=========================================================================
     377                 :            : //
     378                 :            : // Non-UNO interface
     379                 :            : //
     380                 :            : //=========================================================================
     381                 :            : 
     382                 :          0 : uno::Reference< embed::XStorage > StorageElementFactory::queryParentStorage(
     383                 :            :         const rtl::OUString & rUri, StorageAccessMode eMode )
     384                 :            :     throw ( embed::InvalidStorageException,
     385                 :            :             lang::IllegalArgumentException,
     386                 :            :             io::IOException,
     387                 :            :             embed::StorageWrappedTargetException,
     388                 :            :             uno::RuntimeException )
     389                 :            : {
     390                 :          0 :     uno::Reference< embed::XStorage > xParentStorage;
     391                 :            : 
     392                 :          0 :     Uri aUri( rUri );
     393         [ #  # ]:          0 :     Uri aParentUri( aUri.getParentUri() );
     394 [ #  # ][ #  # ]:          0 :     if ( !aParentUri.isRoot() )
     395                 :            :     {
     396 [ #  # ][ #  # ]:          0 :         xParentStorage = createStorage( aUri.getParentUri(), eMode );
                 [ #  # ]
     397                 :            :         OSL_ENSURE( xParentStorage.is()
     398                 :            :                     // requested to create new storage, but failed?
     399                 :            :                     || ( eMode != READ_WRITE_CREATE ),
     400                 :            :                     "StorageElementFactory::queryParentStorage - No storage!" );
     401                 :            :     }
     402                 :          0 :     return xParentStorage;
     403                 :            : }
     404                 :            : 
     405                 :            : //=========================================================================
     406                 :         95 : uno::Reference< embed::XStorage > StorageElementFactory::queryStorage(
     407                 :            :         const uno::Reference< embed::XStorage > & xParentStorage,
     408                 :            :         const rtl::OUString & rUri,
     409                 :            :         StorageAccessMode eMode )
     410                 :            :     throw ( embed::InvalidStorageException,
     411                 :            :             lang::IllegalArgumentException,
     412                 :            :             io::IOException,
     413                 :            :             embed::StorageWrappedTargetException,
     414                 :            :             uno::RuntimeException )
     415                 :            : {
     416                 :         95 :     uno::Reference< embed::XStorage > xStorage;
     417                 :            : 
     418                 :         95 :     Uri aUri( rUri );
     419                 :            : 
     420         [ +  - ]:         95 :     if ( !xParentStorage.is() )
     421                 :            :     {
     422                 :            :         // document storage
     423                 :            : 
     424 [ +  - ][ +  - ]:         95 :         xStorage = m_xDocsMgr->queryStorage( aUri.getDocumentId() );
                 [ +  - ]
     425                 :            : 
     426         [ -  + ]:         95 :         if ( !xStorage.is() )
     427                 :            :         {
     428         [ #  # ]:          0 :             if ( eMode == READ_WRITE_CREATE )
     429                 :            :                 throw lang::IllegalArgumentException(
     430                 :            :                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
     431                 :            :                         "Invalid open mode: document storages cannot be "
     432                 :            :                         "created!" ) ),
     433                 :            :                     uno::Reference< uno::XInterface >(),
     434 [ #  # ][ #  # ]:          0 :                     sal_Int16( 2 ) );
     435                 :            :             else
     436                 :            :                 throw embed::InvalidStorageException(
     437                 :            :                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
     438                 :            :                         "Invalid document id!" ) ),
     439 [ #  # ][ #  # ]:          0 :                     uno::Reference< uno::XInterface >() );
     440                 :            :         }
     441                 :            : 
     442                 :            :         // match xStorage's open mode against requested open mode
     443                 :            : 
     444                 :            :         uno::Reference< beans::XPropertySet > xPropSet(
     445         [ +  - ]:         95 :             xStorage, uno::UNO_QUERY );
     446                 :            :         OSL_ENSURE( xPropSet.is(),
     447                 :            :                     "StorageElementFactory::queryStorage - "
     448                 :            :                     "No XPropertySet interface!" );
     449                 :            :         try
     450                 :            :         {
     451         [ +  - ]:         95 :             uno::Any aPropValue = xPropSet->getPropertyValue(
     452                 :            :                 rtl::OUString(
     453 [ +  - ][ +  - ]:         95 :                     RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ) ) );
     454                 :            : 
     455                 :         95 :             sal_Int32 nOpenMode = 0;
     456         [ +  - ]:         95 :             if ( aPropValue >>= nOpenMode )
     457                 :            :             {
     458      [ +  -  - ]:         95 :                 switch ( eMode )
     459                 :            :                 {
     460                 :            :                     case READ:
     461         [ -  + ]:         95 :                         if ( !( nOpenMode & embed::ElementModes::READ ) )
     462                 :            :                         {
     463                 :            :                             // document opened, but not readable.
     464                 :            :                             throw embed::InvalidStorageException(
     465                 :            :                                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
     466                 :            :                                     "Storage is open, but not readable!" ) ),
     467 [ #  # ][ #  # ]:          0 :                                 uno::Reference< uno::XInterface >() );
     468                 :            :                         }
     469                 :            :                         // storage okay
     470                 :         95 :                         break;
     471                 :            : 
     472                 :            :                     case READ_WRITE_NOCREATE:
     473                 :            :                     case READ_WRITE_CREATE:
     474         [ #  # ]:          0 :                         if ( !( nOpenMode & embed::ElementModes::WRITE ) )
     475                 :            :                         {
     476                 :            :                             // document opened, but not writable.
     477                 :            :                             throw embed::InvalidStorageException(
     478                 :            :                                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
     479                 :            :                                     "Storage is open, but not writable!" ) ),
     480 [ #  # ][ #  # ]:          0 :                                 uno::Reference< uno::XInterface >() );
     481                 :            :                         }
     482                 :            :                         // storage okay
     483                 :          0 :                         break;
     484                 :            :                 }
     485                 :            :             }
     486                 :            :             else
     487                 :            :             {
     488                 :            :                 OSL_FAIL(
     489                 :            :                     "Bug! Value of property OpenMode has wrong type!" );
     490                 :            : 
     491                 :            :                 throw uno::RuntimeException(
     492                 :            :                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
     493                 :            :                         "Bug! Value of property OpenMode has wrong type!" ) ),
     494 [ #  # ][ #  # ]:          0 :                     uno::Reference< uno::XInterface >() );
     495                 :         95 :             }
     496                 :            :         }
     497                 :          0 :         catch ( beans::UnknownPropertyException const & e )
     498                 :            :         {
     499                 :            :             OSL_FAIL( "Property OpenMode not supported!" );
     500                 :            : 
     501                 :            :             throw embed::StorageWrappedTargetException(
     502                 :            :                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
     503                 :            :                         "Bug! Value of property OpenMode has wrong type!" ) ),
     504                 :            :                     uno::Reference< uno::XInterface >(),
     505   [ #  #  #  #  :          0 :                     uno::makeAny( e ) );
                   #  # ]
     506                 :            :         }
     507      [ #  #  # ]:          0 :         catch ( lang::WrappedTargetException const & e )
     508                 :            :         {
     509                 :            :             OSL_FAIL( "Caught WrappedTargetException!" );
     510                 :            : 
     511                 :            :             throw embed::StorageWrappedTargetException(
     512                 :            :                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
     513                 :            :                         "WrappedTargetException during getPropertyValue!" ) ),
     514                 :            :                     uno::Reference< uno::XInterface >(),
     515   [ #  #  #  #  :          0 :                     uno::makeAny( e ) );
                   #  # ]
     516                 :         95 :         }
     517                 :            :     }
     518                 :            :     else
     519                 :            :     {
     520                 :            :         // sub storage
     521                 :            : 
     522         [ #  # ]:          0 :         const rtl::OUString & rName = aUri.getDecodedName();
     523                 :            : 
     524         [ #  # ]:          0 :         if ( eMode == READ )
     525                 :            :         {
     526                 :            :             try
     527                 :            :             {
     528                 :            :                 sal_Int32 nOpenMode = embed::ElementModes::READ
     529                 :          0 :                                       | embed::ElementModes::NOCREATE;
     530                 :            :                 xStorage
     531 [ #  # ][ #  # ]:          0 :                     = xParentStorage->openStorageElement( rName, nOpenMode );
                 [ #  # ]
     532                 :            :             }
     533   [ #  #  #  # ]:          0 :             catch ( io::IOException const & )
     534                 :            :             {
     535                 :            :                 // Another chance: Try to clone storage.
     536   [ #  #  #  # ]:          0 :                 xStorage = createTemporaryStorage();
     537         [ #  # ]:          0 :                 xParentStorage->copyStorageElementLastCommitTo( rName,
     538         [ #  # ]:          0 :                                                                 xStorage );
     539                 :            :             }
     540                 :            :         }
     541                 :            :         else
     542                 :            :         {
     543                 :          0 :             sal_Int32 nOpenMode = embed::ElementModes::READWRITE;
     544         [ #  # ]:          0 :             if ( eMode == READ_WRITE_NOCREATE )
     545                 :          0 :                 nOpenMode |= embed::ElementModes::NOCREATE;
     546                 :            : 
     547 [ #  # ][ #  # ]:          0 :             xStorage = xParentStorage->openStorageElement( rName, nOpenMode );
                 [ #  # ]
     548                 :            :         }
     549                 :            :     }
     550                 :            : 
     551                 :            :     OSL_ENSURE( xStorage.is() || ( eMode != READ_WRITE_CREATE ),
     552                 :            :                 "StorageElementFactory::queryStorage - No storage!" );
     553                 :         95 :     return xStorage;
     554                 :            : }
     555                 :            : 
     556                 :            : //=========================================================================
     557                 :            : uno::Reference< io::XStream >
     558                 :          0 : StorageElementFactory::queryStream(
     559                 :            :                 const uno::Reference< embed::XStorage > & xParentStorage,
     560                 :            :                 const rtl::OUString & rUri,
     561                 :            :                 const rtl::OUString & rPassword,
     562                 :            :                 StorageAccessMode eMode,
     563                 :            :                 bool bTruncate )
     564                 :            :     throw ( embed::InvalidStorageException,
     565                 :            :             lang::IllegalArgumentException,
     566                 :            :             io::IOException,
     567                 :            :             embed::StorageWrappedTargetException,
     568                 :            :             packages::WrongPasswordException,
     569                 :            :             uno::RuntimeException )
     570                 :            : {
     571         [ #  # ]:          0 :     osl::MutexGuard aGuard( m_aMutex );
     572                 :            : 
     573         [ #  # ]:          0 :     if ( !xParentStorage.is() )
     574                 :            :     {
     575                 :            :         throw lang::IllegalArgumentException(
     576                 :            :             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
     577                 :            :                 "No parent storage!" ) ),
     578                 :            :             uno::Reference< uno::XInterface >(),
     579 [ #  # ][ #  # ]:          0 :             sal_Int16( 2 ) );
     580                 :            :     }
     581                 :            : 
     582                 :          0 :     Uri aUri( rUri );
     583 [ #  # ][ #  # ]:          0 :     if ( aUri.isRoot() )
     584                 :            :     {
     585                 :            :         throw lang::IllegalArgumentException(
     586                 :            :             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
     587                 :            :                 "Root never is a stream!" ) ),
     588                 :            :             uno::Reference< uno::XInterface >(),
     589 [ #  # ][ #  # ]:          0 :             sal_Int16( 2 ) );
     590                 :            :     }
     591 [ #  # ][ #  # ]:          0 :     else if ( aUri.isDocument() )
     592                 :            :     {
     593                 :            :         throw lang::IllegalArgumentException(
     594                 :            :             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
     595                 :            :                 "A document never is a stream!" ) ),
     596                 :            :             uno::Reference< uno::XInterface >(),
     597 [ #  # ][ #  # ]:          0 :             sal_Int16( 2 ) );
     598                 :            :     }
     599                 :            : 
     600                 :            :     sal_Int32 nOpenMode;
     601   [ #  #  #  # ]:          0 :     switch ( eMode )
     602                 :            :     {
     603                 :            :         case READ:
     604                 :            :             nOpenMode = embed::ElementModes::READ
     605                 :            :                         | embed::ElementModes::NOCREATE
     606                 :          0 :                         | embed::ElementModes::SEEKABLE;
     607                 :          0 :             break;
     608                 :            : 
     609                 :            :         case READ_WRITE_NOCREATE:
     610                 :            :             nOpenMode = embed::ElementModes::READWRITE
     611                 :            :                         | embed::ElementModes::NOCREATE
     612                 :          0 :                         | embed::ElementModes::SEEKABLE;
     613                 :            : 
     614         [ #  # ]:          0 :             if ( bTruncate )
     615                 :          0 :                 nOpenMode |= embed::ElementModes::TRUNCATE;
     616                 :            : 
     617                 :          0 :             break;
     618                 :            : 
     619                 :            :         case READ_WRITE_CREATE:
     620                 :            :             nOpenMode = embed::ElementModes::READWRITE
     621                 :          0 :                         | embed::ElementModes::SEEKABLE;
     622                 :            : 
     623         [ #  # ]:          0 :             if ( bTruncate )
     624                 :          0 :                 nOpenMode |= embed::ElementModes::TRUNCATE;
     625                 :            : 
     626                 :          0 :             break;
     627                 :            : 
     628                 :            :         default:
     629                 :            :             OSL_FAIL( "StorageElementFactory::queryStream : Unknown open mode!" );
     630                 :            : 
     631                 :            :             throw embed::InvalidStorageException(
     632                 :            :                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
     633                 :            :                     "Unknown open mode!" ) ),
     634 [ #  # ][ #  # ]:          0 :                 uno::Reference< uno::XInterface >() );
     635                 :            :     }
     636                 :            : 
     637                 :            :     // No object re-usage mechanism; streams are seekable => not stateless.
     638                 :            : 
     639                 :          0 :     uno::Reference< io::XStream > xStream;
     640         [ #  # ]:          0 :     if ( !rPassword.isEmpty() )
     641                 :            :     {
     642         [ #  # ]:          0 :         if ( eMode == READ )
     643                 :            :         {
     644                 :            :             try
     645                 :            :             {
     646         [ #  # ]:          0 :                 xStream = xParentStorage->cloneEncryptedStreamElement(
     647         [ #  # ]:          0 :                                                          aUri.getDecodedName(),
     648 [ #  # ][ #  # ]:          0 :                                                          rPassword );
     649                 :            :             }
     650   [ #  #  #  # ]:          0 :             catch ( packages::NoEncryptionException const & )
     651                 :            :             {
     652                 :            :                 xStream
     653   [ #  #  #  #  :          0 :                     = xParentStorage->cloneStreamElement( aUri.getDecodedName() );
             #  #  #  # ]
     654                 :            :             }
     655                 :            :         }
     656                 :            :         else
     657                 :            :         {
     658                 :            :             try
     659                 :            :             {
     660         [ #  # ]:          0 :                 xStream = xParentStorage->openEncryptedStreamElement(
     661         [ #  # ]:          0 :                                                          aUri.getDecodedName(),
     662                 :            :                                                          nOpenMode,
     663 [ #  # ][ #  # ]:          0 :                                                          rPassword );
     664                 :            :             }
     665   [ #  #  #  # ]:          0 :             catch ( packages::NoEncryptionException const & )
     666                 :            :             {
     667                 :            :                 xStream
     668   [ #  #  #  # ]:          0 :                     = xParentStorage->openStreamElement( aUri.getDecodedName(),
     669   [ #  #  #  # ]:          0 :                                                          nOpenMode );
     670                 :            :             }
     671                 :            :         }
     672                 :            :     }
     673                 :            :     else
     674                 :            :     {
     675         [ #  # ]:          0 :         if ( eMode == READ )
     676                 :            :         {
     677 [ #  # ][ #  # ]:          0 :             xStream = xParentStorage->cloneStreamElement( aUri.getDecodedName() );
         [ #  # ][ #  # ]
     678                 :            :         }
     679                 :            :         else
     680                 :            :         {
     681 [ #  # ][ #  # ]:          0 :             xStream = xParentStorage->openStreamElement( aUri.getDecodedName(),
     682 [ #  # ][ #  # ]:          0 :                                                          nOpenMode );
     683                 :            :         }
     684                 :            :     }
     685                 :            : 
     686         [ #  # ]:          0 :     if ( !xStream.is() )
     687                 :            :     {
     688                 :            :         throw embed::InvalidStorageException(
     689                 :            :             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
     690                 :            :                 "No stream!" ) ),
     691 [ #  # ][ #  # ]:          0 :             uno::Reference< uno::XInterface >() );
     692                 :            :     }
     693                 :            : 
     694         [ #  # ]:          0 :     return xStream;
     695                 :            : }
     696                 :            : 
     697                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10