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: */
|