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
StorageElementFactory(const uno::Reference<lang::XMultiServiceFactory> & xSMgr,const rtl::Reference<OfficeDocumentsManager> & xDocsMgr)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 //=========================================================================
~StorageElementFactory()70cdf0e10cSrcweir StorageElementFactory::~StorageElementFactory()
71cdf0e10cSrcweir {
72cdf0e10cSrcweir OSL_ENSURE( m_aMap.size() == 0,
73cdf0e10cSrcweir "StorageElementFactory::~StorageElementFactory - Dangling storages!" );
74cdf0e10cSrcweir }
75cdf0e10cSrcweir
76cdf0e10cSrcweir //=========================================================================
77cdf0e10cSrcweir uno::Reference< embed::XStorage >
createTemporaryStorage()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 >
createStorage(const rtl::OUString & rUri,StorageAccessMode eMode)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 >
createInputStream(const rtl::OUString & rUri,const rtl::OUString & rPassword)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 >
createOutputStream(const rtl::OUString & rUri,const rtl::OUString & rPassword,bool bTruncate)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 >
createStream(const rtl::OUString & rUri,const rtl::OUString & rPassword,bool bTruncate)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 //=========================================================================
releaseElement(Storage * pElement)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
queryParentStorage(const rtl::OUString & rUri,StorageAccessMode eMode)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 //=========================================================================
queryStorage(const uno::Reference<embed::XStorage> & xParentStorage,const rtl::OUString & rUri,StorageAccessMode eMode)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 >
queryStream(const uno::Reference<embed::XStorage> & xParentStorage,const rtl::OUString & rUri,const rtl::OUString & rPassword,StorageAccessMode eMode,bool bTruncate)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