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