1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svl.hxx"
26 #include <com/sun/star/beans/PropertyValue.hpp>
27 #include <com/sun/star/embed/ElementModes.hpp>
28 #include <com/sun/star/embed/XTransactedObject.hpp>
29 #include <com/sun/star/ucb/XProgressHandler.hpp>
30 #include <com/sun/star/ucb/XContentAccess.hpp>
31 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
32
33 #ifndef _COM_SUN_STAR_UCB_INTERACTIVEIODEXCEPTION_HPP_
34 #include <com/sun/star/ucb/InteractiveIOException.hpp>
35 #endif
36 #include <com/sun/star/ucb/IOErrorCode.hpp>
37 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
38 #include <com/sun/star/container/XEnumerationAccess.hpp>
39 #include <com/sun/star/container/XNamed.hpp>
40 #include <com/sun/star/util/XChangesBatch.hpp>
41 #include <com/sun/star/util/XCloneable.hpp>
42 #include <com/sun/star/lang/XUnoTunnel.hpp>
43 #include <com/sun/star/lang/XComponent.hpp>
44 #include <com/sun/star/lang/DisposedException.hpp>
45 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
46 #include <com/sun/star/io/IOException.hpp>
47 #include <com/sun/star/io/XTruncate.hpp>
48 #include <com/sun/star/sdbc/XResultSet.hpp>
49 #include <com/sun/star/sdbc/XRow.hpp>
50
51
52 #ifndef _COMPHELPER_PROCESSFACTORY_HXX
53 #include <comphelper/processfactory.hxx>
54 #endif
55 #include <comphelper/storagehelper.hxx>
56 #include <cppuhelper/typeprovider.hxx>
57 #include <cppuhelper/exc_hlp.hxx>
58
59 #include <tools/urlobj.hxx>
60 #include <unotools/ucbhelper.hxx>
61 #include <unotools/ucbstreamhelper.hxx>
62 #include <unotools/streamwrap.hxx>
63 #include <ucbhelper/fileidentifierconverter.hxx>
64 #include <ucbhelper/contentbroker.hxx>
65 #include <ucbhelper/content.hxx>
66
67 #include "fsstorage.hxx"
68 #include "oinputstreamcontainer.hxx"
69 #include "ostreamcontainer.hxx"
70
71 using namespace ::com::sun::star;
72
73 //=========================================================
74
75 // TODO: move to a standard helper
isLocalFile_Impl(::rtl::OUString aURL)76 sal_Bool isLocalFile_Impl( ::rtl::OUString aURL )
77 {
78 ::rtl::OUString aSystemPath;
79 ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
80 if ( !pBroker )
81 throw uno::RuntimeException();
82
83 uno::Reference< ucb::XContentProviderManager > xManager =
84 pBroker->getContentProviderManagerInterface();
85 try
86 {
87 aSystemPath = ::ucbhelper::getSystemPathFromFileURL( xManager, aURL );
88 }
89 catch ( uno::Exception& )
90 {
91 }
92
93 return ( aSystemPath.getLength() != 0 );
94 }
95
96
97 //=========================================================
98
99 struct FSStorage_Impl
100 {
101 ::rtl::OUString m_aURL;
102
103 ::ucbhelper::Content* m_pContent;
104 sal_Int32 m_nMode;
105
106 ::cppu::OInterfaceContainerHelper* m_pListenersContainer; // list of listeners
107 ::cppu::OTypeCollection* m_pTypeCollection;
108
109 uno::Reference< lang::XMultiServiceFactory > m_xFactory;
110
111
FSStorage_ImplFSStorage_Impl112 FSStorage_Impl( const ::rtl::OUString& aURL, sal_Int32 nMode, uno::Reference< lang::XMultiServiceFactory > xFactory )
113 : m_aURL( aURL )
114 , m_pContent( NULL )
115 , m_nMode( nMode )
116 , m_pListenersContainer( NULL )
117 , m_pTypeCollection( NULL )
118 , m_xFactory( xFactory )
119 {
120 OSL_ENSURE( m_aURL.getLength(), "The URL must not be empty" );
121 }
122
FSStorage_ImplFSStorage_Impl123 FSStorage_Impl( const ::ucbhelper::Content& aContent, sal_Int32 nMode, uno::Reference< lang::XMultiServiceFactory > xFactory )
124 : m_aURL( aContent.getURL() )
125 , m_pContent( new ::ucbhelper::Content( aContent ) )
126 , m_nMode( nMode )
127 , m_pListenersContainer( NULL )
128 , m_pTypeCollection( NULL )
129 , m_xFactory( xFactory )
130 {
131 OSL_ENSURE( m_aURL.getLength(), "The URL must not be empty" );
132 }
133
134 ~FSStorage_Impl();
135 };
136
137 //=========================================================
138
~FSStorage_Impl()139 FSStorage_Impl::~FSStorage_Impl()
140 {
141 if ( m_pListenersContainer )
142 delete m_pListenersContainer;
143 if ( m_pTypeCollection )
144 delete m_pTypeCollection;
145 if ( m_pContent )
146 delete m_pContent;
147 }
148
149 //=====================================================
150 // FSStorage implementation
151 //=====================================================
152
153 //-----------------------------------------------
FSStorage(const::ucbhelper::Content & aContent,sal_Int32 nMode,uno::Sequence<beans::PropertyValue>,uno::Reference<lang::XMultiServiceFactory> xFactory)154 FSStorage::FSStorage( const ::ucbhelper::Content& aContent,
155 sal_Int32 nMode,
156 uno::Sequence< beans::PropertyValue >,
157 uno::Reference< lang::XMultiServiceFactory > xFactory )
158 : m_pImpl( new FSStorage_Impl( aContent, nMode, xFactory ) )
159 {
160 // TODO: use properties
161 if ( !xFactory.is() )
162 throw uno::RuntimeException();
163
164 GetContent();
165 }
166
167 //-----------------------------------------------
~FSStorage()168 FSStorage::~FSStorage()
169 {
170 {
171 ::osl::MutexGuard aGuard( m_aMutex );
172 m_refCount++; // to call dispose
173 try {
174 dispose();
175 }
176 catch( uno::RuntimeException& )
177 {}
178 }
179 }
180
181 //-----------------------------------------------
MakeFolderNoUI(const String & rFolder,sal_Bool)182 sal_Bool FSStorage::MakeFolderNoUI( const String& rFolder, sal_Bool )
183 {
184 INetURLObject aURL( rFolder );
185 ::rtl::OUString aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
186 aURL.removeSegment();
187 ::ucbhelper::Content aParent;
188 ::ucbhelper::Content aResultContent;
189
190 if ( ::ucbhelper::Content::create( aURL.GetMainURL( INetURLObject::NO_DECODE ),
191 uno::Reference< ucb::XCommandEnvironment >(),
192 aParent ) )
193 return ::utl::UCBContentHelper::MakeFolder( aParent, aTitle, aResultContent, sal_False );
194
195 return sal_False;
196 }
197
198 //-----------------------------------------------
GetContent()199 ::ucbhelper::Content* FSStorage::GetContent()
200 {
201 ::osl::MutexGuard aGuard( m_aMutex );
202 if ( !m_pImpl->m_pContent )
203 {
204 uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
205
206 try
207 {
208 m_pImpl->m_pContent = new ::ucbhelper::Content( m_pImpl->m_aURL, xDummyEnv );
209 }
210 catch( uno::Exception& )
211 {
212 }
213 }
214
215 return m_pImpl->m_pContent;
216 }
217
218 //-----------------------------------------------
CopyStreamToSubStream(const::rtl::OUString & aSourceURL,const uno::Reference<embed::XStorage> & xDest,const::rtl::OUString & aNewEntryName)219 void FSStorage::CopyStreamToSubStream( const ::rtl::OUString& aSourceURL,
220 const uno::Reference< embed::XStorage >& xDest,
221 const ::rtl::OUString& aNewEntryName )
222 {
223 if ( !xDest.is() )
224 throw uno::RuntimeException();
225
226 uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
227 ::ucbhelper::Content aSourceContent( aSourceURL, xDummyEnv );
228 uno::Reference< io::XInputStream > xSourceInput = aSourceContent.openStream();
229
230 if ( !xSourceInput.is() )
231 throw io::IOException(); // TODO: error handling
232
233 uno::Reference< io::XStream > xSubStream = xDest->openStreamElement(
234 aNewEntryName,
235 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
236 if ( !xSubStream.is() )
237 throw uno::RuntimeException();
238
239 uno::Reference< io::XOutputStream > xDestOutput = xSubStream->getOutputStream();
240 if ( !xDestOutput.is() )
241 throw uno::RuntimeException();
242
243 ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInput, xDestOutput );
244 xDestOutput->closeOutput();
245 }
246
247 //-----------------------------------------------
CopyContentToStorage_Impl(::ucbhelper::Content * pContent,const uno::Reference<embed::XStorage> & xDest)248 void FSStorage::CopyContentToStorage_Impl( ::ucbhelper::Content* pContent, const uno::Reference< embed::XStorage >& xDest )
249 {
250 if ( !pContent )
251 throw uno::RuntimeException();
252
253 // get list of contents of the Content
254 // create cursor for access to children
255 uno::Sequence< ::rtl::OUString > aProps( 2 );
256 ::rtl::OUString* pProps = aProps.getArray();
257 pProps[0] = ::rtl::OUString::createFromAscii( "TargetURL" );
258 pProps[1] = ::rtl::OUString::createFromAscii( "IsFolder" );
259 ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
260
261 try
262 {
263 uno::Reference< sdbc::XResultSet > xResultSet = pContent->createCursor( aProps, eInclude );
264 uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY );
265 uno::Reference< sdbc::XRow > xRow( xResultSet, uno::UNO_QUERY );
266 if ( xResultSet.is() )
267 {
268 // go through the list: insert files as streams, insert folders as substorages using recursion
269 while ( xResultSet->next() )
270 {
271 ::rtl::OUString aSourceURL( xRow->getString( 1 ) );
272 sal_Bool bIsFolder( xRow->getBoolean(2) );
273
274 // TODO/LATER: not sure whether the entry name must be encoded
275 ::rtl::OUString aNewEntryName( INetURLObject( aSourceURL ).getName( INetURLObject::LAST_SEGMENT,
276 true,
277 INetURLObject::NO_DECODE ) );
278 if ( bIsFolder )
279 {
280 uno::Reference< embed::XStorage > xSubStorage = xDest->openStorageElement( aNewEntryName,
281 embed::ElementModes::READWRITE );
282 if ( !xSubStorage.is() )
283 throw uno::RuntimeException();
284
285 uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
286 ::ucbhelper::Content aSourceContent( aSourceURL, xDummyEnv );
287 CopyContentToStorage_Impl( &aSourceContent, xSubStorage );
288 }
289 else
290 {
291 CopyStreamToSubStream( aSourceURL, xDest, aNewEntryName );
292 }
293 }
294 }
295
296 uno::Reference< embed::XTransactedObject > xTransact( xDest, uno::UNO_QUERY );
297 if ( xTransact.is() )
298 xTransact->commit();
299 }
300 catch( ucb::InteractiveIOException& r )
301 {
302 if ( r.Code == ucb::IOErrorCode_NOT_EXISTING )
303 OSL_ENSURE( sal_False, "The folder does not exist!\n" );
304 else
305 throw;
306 }
307 }
308
309 //____________________________________________________________________________________________________
310 // XInterface
311 //____________________________________________________________________________________________________
312
313 //-----------------------------------------------
queryInterface(const uno::Type & rType)314 uno::Any SAL_CALL FSStorage::queryInterface( const uno::Type& rType )
315 throw( uno::RuntimeException )
316 {
317 uno::Any aReturn;
318 aReturn <<= ::cppu::queryInterface
319 ( rType
320 , static_cast<lang::XTypeProvider*> ( this )
321 , static_cast<embed::XStorage*> ( this )
322 , static_cast<embed::XHierarchicalStorageAccess*> ( this )
323 , static_cast<container::XNameAccess*> ( this )
324 , static_cast<container::XElementAccess*> ( this )
325 , static_cast<lang::XComponent*> ( this )
326 , static_cast<beans::XPropertySet*> ( this ) );
327
328 if ( aReturn.hasValue() == sal_True )
329 return aReturn ;
330
331 return OWeakObject::queryInterface( rType );
332 }
333
334 //-----------------------------------------------
acquire()335 void SAL_CALL FSStorage::acquire() throw()
336 {
337 OWeakObject::acquire();
338 }
339
340 //-----------------------------------------------
release()341 void SAL_CALL FSStorage::release() throw()
342 {
343 OWeakObject::release();
344 }
345
346 //____________________________________________________________________________________________________
347 // XTypeProvider
348 //____________________________________________________________________________________________________
349
350 //-----------------------------------------------
getTypes()351 uno::Sequence< uno::Type > SAL_CALL FSStorage::getTypes()
352 throw( uno::RuntimeException )
353 {
354 if ( m_pImpl->m_pTypeCollection == NULL )
355 {
356 ::osl::MutexGuard aGuard( m_aMutex );
357
358 if ( m_pImpl->m_pTypeCollection == NULL )
359 {
360 m_pImpl->m_pTypeCollection = new ::cppu::OTypeCollection
361 ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
362 , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
363 , ::getCppuType( ( const uno::Reference< embed::XHierarchicalStorageAccess >* )NULL )
364 , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
365 }
366 }
367
368 return m_pImpl->m_pTypeCollection->getTypes() ;
369 }
370
371 //-----------------------------------------------
getImplementationId()372 uno::Sequence< sal_Int8 > SAL_CALL FSStorage::getImplementationId()
373 throw( uno::RuntimeException )
374 {
375 static ::cppu::OImplementationId* pID = NULL ;
376
377 if ( pID == NULL )
378 {
379 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ;
380
381 if ( pID == NULL )
382 {
383 static ::cppu::OImplementationId aID( sal_False ) ;
384 pID = &aID ;
385 }
386 }
387
388 return pID->getImplementationId() ;
389
390 }
391
392 //____________________________________________________________________________________________________
393 // XStorage
394 //____________________________________________________________________________________________________
395
396 //-----------------------------------------------
copyToStorage(const uno::Reference<embed::XStorage> & xDest)397 void SAL_CALL FSStorage::copyToStorage( const uno::Reference< embed::XStorage >& xDest )
398 throw ( embed::InvalidStorageException,
399 io::IOException,
400 lang::IllegalArgumentException,
401 embed::StorageWrappedTargetException,
402 uno::RuntimeException )
403 {
404 ::osl::MutexGuard aGuard( m_aMutex );
405
406 if ( !m_pImpl )
407 throw lang::DisposedException();
408
409 if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject*> ( this ), uno::UNO_QUERY ) )
410 throw lang::IllegalArgumentException(); // TODO:
411
412 if ( !GetContent() )
413 throw io::IOException(); // TODO: error handling
414
415 try
416 {
417 CopyContentToStorage_Impl( GetContent(), xDest );
418 }
419 catch( embed::InvalidStorageException& )
420 {
421 throw;
422 }
423 catch( lang::IllegalArgumentException& )
424 {
425 throw;
426 }
427 catch( embed::StorageWrappedTargetException& )
428 {
429 throw;
430 }
431 catch( io::IOException& )
432 {
433 throw;
434 }
435 catch( uno::RuntimeException& )
436 {
437 throw;
438 }
439 catch( uno::Exception& )
440 {
441 uno::Any aCaught( ::cppu::getCaughtException() );
442 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
443 uno::Reference< io::XInputStream >(),
444 aCaught );
445 }
446 }
447
448 //-----------------------------------------------
openStreamElement(const::rtl::OUString & aStreamName,sal_Int32 nOpenMode)449 uno::Reference< io::XStream > SAL_CALL FSStorage::openStreamElement(
450 const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode )
451 throw ( embed::InvalidStorageException,
452 lang::IllegalArgumentException,
453 packages::WrongPasswordException,
454 io::IOException,
455 embed::StorageWrappedTargetException,
456 uno::RuntimeException )
457 {
458 ::osl::MutexGuard aGuard( m_aMutex );
459
460 if ( !m_pImpl )
461 throw lang::DisposedException();
462
463 if ( !GetContent() )
464 throw io::IOException(); // TODO: error handling
465
466 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
467 INetURLObject aFileURL( m_pImpl->m_aURL );
468 aFileURL.Append( aStreamName );
469
470 if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
471 throw io::IOException();
472
473 if ( ( nOpenMode & embed::ElementModes::NOCREATE )
474 && !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
475 throw io::IOException(); // TODO:
476
477 uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
478 uno::Reference< io::XStream > xResult;
479 try
480 {
481 if ( nOpenMode & embed::ElementModes::WRITE )
482 {
483 if ( isLocalFile_Impl( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
484 {
485 uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess(
486 m_pImpl->m_xFactory->createInstance(
487 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ),
488 uno::UNO_QUERY_THROW );
489 xResult = xSimpleFileAccess->openFileReadWrite( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) );
490 }
491 else
492 {
493 // TODO: test whether it really works for http and fwp
494 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ),
495 STREAM_STD_WRITE );
496 if ( pStream )
497 {
498 if ( !pStream->GetError() )
499 xResult = uno::Reference < io::XStream >( new ::utl::OStreamWrapper( *pStream ) );
500 else
501 delete pStream;
502 }
503 }
504
505 if ( !xResult.is() )
506 throw io::IOException();
507
508 if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) )
509 {
510 uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW );
511 xTrunc->truncate();
512 }
513 }
514 else
515 {
516 if ( ( nOpenMode & embed::ElementModes::TRUNCATE )
517 || !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
518 throw io::IOException(); // TODO: access denied
519
520 ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
521 uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
522 xResult = static_cast< io::XStream* >( new OFSInputStreamContainer( xInStream ) );
523 }
524 }
525 catch( embed::InvalidStorageException& )
526 {
527 throw;
528 }
529 catch( lang::IllegalArgumentException& )
530 {
531 throw;
532 }
533 catch( packages::WrongPasswordException& )
534 {
535 throw;
536 }
537 catch( embed::StorageWrappedTargetException& )
538 {
539 throw;
540 }
541 catch( io::IOException& )
542 {
543 throw;
544 }
545 catch( uno::RuntimeException& )
546 {
547 throw;
548 }
549 catch( uno::Exception& )
550 {
551 uno::Any aCaught( ::cppu::getCaughtException() );
552 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
553 uno::Reference< io::XInputStream >(),
554 aCaught );
555 }
556
557 return xResult;
558 }
559
560 //-----------------------------------------------
openEncryptedStreamElement(const::rtl::OUString &,sal_Int32,const::rtl::OUString &)561 uno::Reference< io::XStream > SAL_CALL FSStorage::openEncryptedStreamElement(
562 const ::rtl::OUString&, sal_Int32, const ::rtl::OUString& )
563 throw ( embed::InvalidStorageException,
564 lang::IllegalArgumentException,
565 packages::NoEncryptionException,
566 packages::WrongPasswordException,
567 io::IOException,
568 embed::StorageWrappedTargetException,
569 uno::RuntimeException )
570 {
571 throw packages::NoEncryptionException();
572 }
573
574 //-----------------------------------------------
openStorageElement(const::rtl::OUString & aStorName,sal_Int32 nStorageMode)575 uno::Reference< embed::XStorage > SAL_CALL FSStorage::openStorageElement(
576 const ::rtl::OUString& aStorName, sal_Int32 nStorageMode )
577 throw ( embed::InvalidStorageException,
578 lang::IllegalArgumentException,
579 io::IOException,
580 embed::StorageWrappedTargetException,
581 uno::RuntimeException )
582 {
583 ::osl::MutexGuard aGuard( m_aMutex );
584
585 if ( !m_pImpl )
586 throw lang::DisposedException();
587
588 if ( !GetContent() )
589 throw io::IOException(); // TODO: error handling
590
591 if ( ( nStorageMode & embed::ElementModes::WRITE )
592 && !( m_pImpl->m_nMode & embed::ElementModes::WRITE ) )
593 throw io::IOException(); // TODO: error handling
594
595 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
596 INetURLObject aFolderURL( m_pImpl->m_aURL );
597 aFolderURL.Append( aStorName );
598
599 sal_Bool bFolderExists = ::utl::UCBContentHelper::IsFolder( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) );
600 if ( !bFolderExists && ::utl::UCBContentHelper::IsDocument( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
601 throw io::IOException(); // TODO:
602
603 if ( ( nStorageMode & embed::ElementModes::NOCREATE ) && !bFolderExists )
604 throw io::IOException(); // TODO:
605
606 uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
607 uno::Reference< embed::XStorage > xResult;
608 try
609 {
610 if ( nStorageMode & embed::ElementModes::WRITE )
611 {
612 if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) && bFolderExists )
613 {
614 ::utl::UCBContentHelper::Kill( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) );
615 bFolderExists =
616 MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), sal_True ); // TODO: not atomar :(
617 }
618 else if ( !bFolderExists )
619 {
620 bFolderExists =
621 MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), sal_True ); // TODO: not atomar :(
622 }
623 }
624 else if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) )
625 throw io::IOException(); // TODO: access denied
626
627 if ( !bFolderExists )
628 throw io::IOException(); // there is no such folder
629
630 ::ucbhelper::Content aResultContent( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
631 xResult = uno::Reference< embed::XStorage >(
632 static_cast< OWeakObject* >( new FSStorage( aResultContent,
633 nStorageMode,
634 uno::Sequence< beans::PropertyValue >(),
635 m_pImpl->m_xFactory ) ),
636 uno::UNO_QUERY );
637 }
638 catch( embed::InvalidStorageException& )
639 {
640 throw;
641 }
642 catch( lang::IllegalArgumentException& )
643 {
644 throw;
645 }
646 catch( embed::StorageWrappedTargetException& )
647 {
648 throw;
649 }
650 catch( io::IOException& )
651 {
652 throw;
653 }
654 catch( uno::RuntimeException& )
655 {
656 throw;
657 }
658 catch( uno::Exception& )
659 {
660 uno::Any aCaught( ::cppu::getCaughtException() );
661 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
662 uno::Reference< io::XInputStream >(),
663 aCaught );
664 }
665
666 return xResult;
667 }
668
669 //-----------------------------------------------
cloneStreamElement(const::rtl::OUString & aStreamName)670 uno::Reference< io::XStream > SAL_CALL FSStorage::cloneStreamElement( const ::rtl::OUString& aStreamName )
671 throw ( embed::InvalidStorageException,
672 lang::IllegalArgumentException,
673 packages::WrongPasswordException,
674 io::IOException,
675 embed::StorageWrappedTargetException,
676 uno::RuntimeException )
677 {
678 ::osl::MutexGuard aGuard( m_aMutex );
679
680 if ( !m_pImpl )
681 throw lang::DisposedException();
682
683 if ( !GetContent() )
684 throw io::IOException(); // TODO: error handling
685
686 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
687 INetURLObject aFileURL( m_pImpl->m_aURL );
688 aFileURL.Append( aStreamName );
689
690 uno::Reference < io::XStream > xTempResult;
691 try
692 {
693 uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
694 ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
695 uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
696
697 xTempResult = uno::Reference < io::XStream >(
698 m_pImpl->m_xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
699 uno::UNO_QUERY_THROW );
700 uno::Reference < io::XOutputStream > xTempOut = xTempResult->getOutputStream();
701 uno::Reference < io::XInputStream > xTempIn = xTempResult->getInputStream();
702
703 if ( !xTempOut.is() || !xTempIn.is() )
704 throw io::IOException();
705
706 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOut );
707 xTempOut->closeOutput();
708 }
709 catch( embed::InvalidStorageException& )
710 {
711 throw;
712 }
713 catch( lang::IllegalArgumentException& )
714 {
715 throw;
716 }
717 catch( packages::WrongPasswordException& )
718 {
719 throw;
720 }
721 catch( io::IOException& )
722 {
723 throw;
724 }
725 catch( embed::StorageWrappedTargetException& )
726 {
727 throw;
728 }
729 catch( uno::RuntimeException& )
730 {
731 throw;
732 }
733 catch( uno::Exception& )
734 {
735 uno::Any aCaught( ::cppu::getCaughtException() );
736 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
737 uno::Reference< io::XInputStream >(),
738 aCaught );
739 }
740
741 return xTempResult;
742 }
743
744 //-----------------------------------------------
cloneEncryptedStreamElement(const::rtl::OUString &,const::rtl::OUString &)745 uno::Reference< io::XStream > SAL_CALL FSStorage::cloneEncryptedStreamElement(
746 const ::rtl::OUString&,
747 const ::rtl::OUString& )
748 throw ( embed::InvalidStorageException,
749 lang::IllegalArgumentException,
750 packages::NoEncryptionException,
751 packages::WrongPasswordException,
752 io::IOException,
753 embed::StorageWrappedTargetException,
754 uno::RuntimeException )
755 {
756 throw packages::NoEncryptionException();
757 }
758
759 //-----------------------------------------------
copyLastCommitTo(const uno::Reference<embed::XStorage> & xTargetStorage)760 void SAL_CALL FSStorage::copyLastCommitTo(
761 const uno::Reference< embed::XStorage >& xTargetStorage )
762 throw ( embed::InvalidStorageException,
763 lang::IllegalArgumentException,
764 io::IOException,
765 embed::StorageWrappedTargetException,
766 uno::RuntimeException )
767 {
768 copyToStorage( xTargetStorage );
769 }
770
771 //-----------------------------------------------
copyStorageElementLastCommitTo(const::rtl::OUString & aStorName,const uno::Reference<embed::XStorage> & xTargetStorage)772 void SAL_CALL FSStorage::copyStorageElementLastCommitTo(
773 const ::rtl::OUString& aStorName,
774 const uno::Reference< embed::XStorage >& xTargetStorage )
775 throw ( embed::InvalidStorageException,
776 lang::IllegalArgumentException,
777 io::IOException,
778 embed::StorageWrappedTargetException,
779 uno::RuntimeException )
780 {
781 ::osl::MutexGuard aGuard( m_aMutex );
782
783 if ( !m_pImpl )
784 throw lang::DisposedException();
785
786 uno::Reference< embed::XStorage > xSourceStor( openStorageElement( aStorName, embed::ElementModes::READ ),
787 uno::UNO_QUERY_THROW );
788 xSourceStor->copyToStorage( xTargetStorage );
789 }
790
791 //-----------------------------------------------
isStreamElement(const::rtl::OUString & aElementName)792 sal_Bool SAL_CALL FSStorage::isStreamElement( const ::rtl::OUString& aElementName )
793 throw ( embed::InvalidStorageException,
794 lang::IllegalArgumentException,
795 container::NoSuchElementException,
796 uno::RuntimeException )
797 {
798 ::osl::MutexGuard aGuard( m_aMutex );
799
800 if ( !m_pImpl )
801 throw lang::DisposedException();
802
803 if ( !GetContent() )
804 throw embed::InvalidStorageException(); // TODO: error handling
805
806 INetURLObject aURL( m_pImpl->m_aURL );
807 aURL.Append( aElementName );
808
809 return !::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
810 }
811
812 //-----------------------------------------------
isStorageElement(const::rtl::OUString & aElementName)813 sal_Bool SAL_CALL FSStorage::isStorageElement( const ::rtl::OUString& aElementName )
814 throw ( embed::InvalidStorageException,
815 lang::IllegalArgumentException,
816 container::NoSuchElementException,
817 uno::RuntimeException )
818 {
819 ::osl::MutexGuard aGuard( m_aMutex );
820
821 if ( !m_pImpl )
822 throw lang::DisposedException();
823
824 if ( !GetContent() )
825 throw embed::InvalidStorageException(); // TODO: error handling
826
827 INetURLObject aURL( m_pImpl->m_aURL );
828 aURL.Append( aElementName );
829
830 return ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
831 }
832
833 //-----------------------------------------------
removeElement(const::rtl::OUString & aElementName)834 void SAL_CALL FSStorage::removeElement( const ::rtl::OUString& aElementName )
835 throw ( embed::InvalidStorageException,
836 lang::IllegalArgumentException,
837 container::NoSuchElementException,
838 io::IOException,
839 embed::StorageWrappedTargetException,
840 uno::RuntimeException )
841 {
842 ::osl::MutexGuard aGuard( m_aMutex );
843
844 if ( !m_pImpl )
845 throw lang::DisposedException();
846
847 if ( !GetContent() )
848 throw io::IOException(); // TODO: error handling
849
850 INetURLObject aURL( m_pImpl->m_aURL );
851 aURL.Append( aElementName );
852
853 if ( !::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) )
854 && !::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
855 throw container::NoSuchElementException(); // TODO:
856
857 ::utl::UCBContentHelper::Kill( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
858 }
859
860 //-----------------------------------------------
renameElement(const::rtl::OUString & aElementName,const::rtl::OUString & aNewName)861 void SAL_CALL FSStorage::renameElement( const ::rtl::OUString& aElementName, const ::rtl::OUString& aNewName )
862 throw ( embed::InvalidStorageException,
863 lang::IllegalArgumentException,
864 container::NoSuchElementException,
865 container::ElementExistException,
866 io::IOException,
867 embed::StorageWrappedTargetException,
868 uno::RuntimeException )
869 {
870 ::osl::MutexGuard aGuard( m_aMutex );
871
872 if ( !m_pImpl )
873 throw lang::DisposedException();
874
875 if ( !GetContent() )
876 throw io::IOException(); // TODO: error handling
877
878 INetURLObject aOldURL( m_pImpl->m_aURL );
879 aOldURL.Append( aElementName );
880
881 INetURLObject aNewURL( m_pImpl->m_aURL );
882 aNewURL.Append( aNewName );
883
884 if ( !::utl::UCBContentHelper::IsFolder( aOldURL.GetMainURL( INetURLObject::NO_DECODE ) )
885 && !::utl::UCBContentHelper::IsDocument( aOldURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
886 throw container::NoSuchElementException(); // TODO:
887
888 if ( ::utl::UCBContentHelper::IsFolder( aNewURL.GetMainURL( INetURLObject::NO_DECODE ) )
889 || ::utl::UCBContentHelper::IsDocument( aNewURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
890 throw container::ElementExistException(); // TODO:
891
892 try
893 {
894 uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
895 ::ucbhelper::Content aSourceContent( aOldURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
896
897 if ( !GetContent()->transferContent( aSourceContent,
898 ::ucbhelper::InsertOperation_MOVE,
899 aNewName,
900 ucb::NameClash::ERROR ) )
901 throw io::IOException(); // TODO: error handling
902 }
903 catch( embed::InvalidStorageException& )
904 {
905 throw;
906 }
907 catch( lang::IllegalArgumentException& )
908 {
909 throw;
910 }
911 catch( container::NoSuchElementException& )
912 {
913 throw;
914 }
915 catch( container::ElementExistException& )
916 {
917 throw;
918 }
919 catch( io::IOException& )
920 {
921 throw;
922 }
923 catch( embed::StorageWrappedTargetException& )
924 {
925 throw;
926 }
927 catch( uno::RuntimeException& )
928 {
929 throw;
930 }
931 catch( uno::Exception& )
932 {
933 uno::Any aCaught( ::cppu::getCaughtException() );
934 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
935 uno::Reference< io::XInputStream >(),
936 aCaught );
937 }
938 }
939
940 //-----------------------------------------------
copyElementTo(const::rtl::OUString & aElementName,const uno::Reference<embed::XStorage> & xDest,const::rtl::OUString & aNewName)941 void SAL_CALL FSStorage::copyElementTo( const ::rtl::OUString& aElementName,
942 const uno::Reference< embed::XStorage >& xDest,
943 const ::rtl::OUString& aNewName )
944 throw ( embed::InvalidStorageException,
945 lang::IllegalArgumentException,
946 container::NoSuchElementException,
947 container::ElementExistException,
948 io::IOException,
949 embed::StorageWrappedTargetException,
950 uno::RuntimeException )
951 {
952 ::osl::MutexGuard aGuard( m_aMutex );
953
954 if ( !m_pImpl )
955 throw lang::DisposedException();
956
957 if ( !xDest.is() )
958 throw uno::RuntimeException();
959
960 if ( !GetContent() )
961 throw io::IOException(); // TODO: error handling
962
963 INetURLObject aOwnURL( m_pImpl->m_aURL );
964 aOwnURL.Append( aElementName );
965
966 if ( xDest->hasByName( aNewName ) )
967 throw container::ElementExistException(); // TODO:
968
969 try
970 {
971 uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
972 if ( ::utl::UCBContentHelper::IsFolder( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
973 {
974 ::ucbhelper::Content aSourceContent( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
975 uno::Reference< embed::XStorage > xDestSubStor(
976 xDest->openStorageElement( aNewName, embed::ElementModes::READWRITE ),
977 uno::UNO_QUERY_THROW );
978
979 CopyContentToStorage_Impl( &aSourceContent, xDestSubStor );
980 }
981 else if ( ::utl::UCBContentHelper::IsDocument( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
982 {
983 CopyStreamToSubStream( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ), xDest, aNewName );
984 }
985 else
986 throw container::NoSuchElementException(); // TODO:
987 }
988 catch( embed::InvalidStorageException& )
989 {
990 throw;
991 }
992 catch( lang::IllegalArgumentException& )
993 {
994 throw;
995 }
996 catch( container::NoSuchElementException& )
997 {
998 throw;
999 }
1000 catch( container::ElementExistException& )
1001 {
1002 throw;
1003 }
1004 catch( embed::StorageWrappedTargetException& )
1005 {
1006 throw;
1007 }
1008 catch( io::IOException& )
1009 {
1010 throw;
1011 }
1012 catch( uno::RuntimeException& )
1013 {
1014 throw;
1015 }
1016 catch( uno::Exception& )
1017 {
1018 uno::Any aCaught( ::cppu::getCaughtException() );
1019 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
1020 uno::Reference< io::XInputStream >(),
1021 aCaught );
1022 }
1023 }
1024
1025 //-----------------------------------------------
moveElementTo(const::rtl::OUString & aElementName,const uno::Reference<embed::XStorage> & xDest,const::rtl::OUString & aNewName)1026 void SAL_CALL FSStorage::moveElementTo( const ::rtl::OUString& aElementName,
1027 const uno::Reference< embed::XStorage >& xDest,
1028 const ::rtl::OUString& aNewName )
1029 throw ( embed::InvalidStorageException,
1030 lang::IllegalArgumentException,
1031 container::NoSuchElementException,
1032 container::ElementExistException,
1033 io::IOException,
1034 embed::StorageWrappedTargetException,
1035 uno::RuntimeException )
1036 {
1037 ::osl::MutexGuard aGuard( m_aMutex );
1038 copyElementTo( aElementName, xDest, aNewName );
1039
1040 INetURLObject aOwnURL( m_pImpl->m_aURL );
1041 aOwnURL.Append( aElementName );
1042 if ( !::utl::UCBContentHelper::Kill( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1043 throw io::IOException(); // TODO: error handling
1044 }
1045
1046 //____________________________________________________________________________________________________
1047 // XNameAccess
1048 //____________________________________________________________________________________________________
1049
1050 //-----------------------------------------------
getByName(const::rtl::OUString & aName)1051 uno::Any SAL_CALL FSStorage::getByName( const ::rtl::OUString& aName )
1052 throw ( container::NoSuchElementException,
1053 lang::WrappedTargetException,
1054 uno::RuntimeException )
1055 {
1056 ::osl::MutexGuard aGuard( m_aMutex );
1057
1058 if ( !m_pImpl )
1059 throw lang::DisposedException();
1060
1061 if ( !GetContent() )
1062 throw io::IOException(); // TODO: error handling
1063
1064 if ( !aName.getLength() )
1065 throw lang::IllegalArgumentException();
1066
1067 INetURLObject aURL( m_pImpl->m_aURL );
1068 aURL.Append( aName );
1069
1070 uno::Any aResult;
1071 try
1072 {
1073 if ( ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1074 {
1075 aResult <<= openStorageElement( aName, embed::ElementModes::READ );
1076 }
1077 else if ( ::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1078 {
1079 aResult <<= openStreamElement( aName, embed::ElementModes::READ );
1080 }
1081 else
1082 throw container::NoSuchElementException(); // TODO:
1083 }
1084 catch( container::NoSuchElementException& )
1085 {
1086 throw;
1087 }
1088 catch( lang::WrappedTargetException& )
1089 {
1090 throw;
1091 }
1092 catch( uno::RuntimeException& )
1093 {
1094 throw;
1095 }
1096 catch ( uno::Exception& )
1097 {
1098 uno::Any aCaught( ::cppu::getCaughtException() );
1099 throw lang::WrappedTargetException( ::rtl::OUString::createFromAscii( "Can not open element!\n" ),
1100 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
1101 uno::UNO_QUERY ),
1102 aCaught );
1103 }
1104
1105 return aResult;
1106 }
1107
1108
1109 //-----------------------------------------------
getElementNames()1110 uno::Sequence< ::rtl::OUString > SAL_CALL FSStorage::getElementNames()
1111 throw ( uno::RuntimeException )
1112 {
1113 ::osl::MutexGuard aGuard( m_aMutex );
1114
1115 if ( !m_pImpl )
1116 throw lang::DisposedException();
1117
1118 if ( !GetContent() )
1119 throw io::IOException(); // TODO: error handling
1120
1121 uno::Sequence< ::rtl::OUString > aProps( 1 );
1122 ::rtl::OUString* pProps = aProps.getArray();
1123 pProps[0] = ::rtl::OUString::createFromAscii( "Title" );
1124 ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
1125
1126 uno::Sequence< ::rtl::OUString > aResult;
1127 sal_Int32 nSize = 0;
1128
1129 try
1130 {
1131 uno::Reference< sdbc::XResultSet > xResultSet = GetContent()->createCursor( aProps, eInclude );
1132 uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY );
1133 uno::Reference< sdbc::XRow > xRow( xResultSet, uno::UNO_QUERY );
1134 if ( xResultSet.is() )
1135 {
1136 // go through the list
1137 while ( xResultSet->next() )
1138 {
1139 ::rtl::OUString aName( xRow->getString( 1 ) );
1140 aResult.realloc( ++nSize );
1141 aResult[nSize-1] = aName;
1142 }
1143 }
1144 }
1145 catch( ucb::InteractiveIOException& r )
1146 {
1147 if ( r.Code == ucb::IOErrorCode_NOT_EXISTING )
1148 OSL_ENSURE( sal_False, "The folder does not exist!\n" );
1149 else
1150 {
1151 uno::Any aCaught( ::cppu::getCaughtException() );
1152 throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
1153 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
1154 uno::UNO_QUERY ),
1155 aCaught );
1156 }
1157 }
1158 catch( uno::RuntimeException& )
1159 {
1160 throw;
1161 }
1162 catch ( uno::Exception& )
1163 {
1164 uno::Any aCaught( ::cppu::getCaughtException() );
1165 throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
1166 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
1167 uno::UNO_QUERY ),
1168 aCaught );
1169 }
1170
1171 return aResult;
1172 }
1173
1174
1175 //-----------------------------------------------
hasByName(const::rtl::OUString & aName)1176 sal_Bool SAL_CALL FSStorage::hasByName( const ::rtl::OUString& aName )
1177 throw ( uno::RuntimeException )
1178 {
1179 ::osl::MutexGuard aGuard( m_aMutex );
1180
1181 if ( !m_pImpl )
1182 throw lang::DisposedException();
1183
1184 try
1185 {
1186 if ( !GetContent() )
1187 throw io::IOException(); // TODO: error handling
1188
1189 if ( !aName.getLength() )
1190 throw lang::IllegalArgumentException();
1191 }
1192 catch( uno::RuntimeException& )
1193 {
1194 throw;
1195 }
1196 catch ( uno::Exception& )
1197 {
1198 uno::Any aCaught( ::cppu::getCaughtException() );
1199 throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
1200 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
1201 uno::UNO_QUERY ),
1202 aCaught );
1203 }
1204
1205 INetURLObject aURL( m_pImpl->m_aURL );
1206 aURL.Append( aName );
1207
1208 return ( ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) )
1209 || ::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) );
1210 }
1211
1212 //-----------------------------------------------
getElementType()1213 uno::Type SAL_CALL FSStorage::getElementType()
1214 throw ( uno::RuntimeException )
1215 {
1216 ::osl::MutexGuard aGuard( m_aMutex );
1217
1218 if ( !m_pImpl )
1219 throw lang::DisposedException();
1220
1221 // it is a multitype container
1222 return uno::Type();
1223 }
1224
1225 //-----------------------------------------------
hasElements()1226 sal_Bool SAL_CALL FSStorage::hasElements()
1227 throw ( uno::RuntimeException )
1228 {
1229 ::osl::MutexGuard aGuard( m_aMutex );
1230
1231 if ( !m_pImpl )
1232 throw lang::DisposedException();
1233
1234 if ( !GetContent() )
1235 throw io::IOException(); // TODO: error handling
1236
1237 uno::Sequence< ::rtl::OUString > aProps( 1 );
1238 aProps[0] = ::rtl::OUString::createFromAscii( "TargetURL" );
1239 ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
1240
1241 try
1242 {
1243 uno::Reference< sdbc::XResultSet > xResultSet = GetContent()->createCursor( aProps, eInclude );
1244 return ( xResultSet.is() && xResultSet->next() );
1245 }
1246 catch( uno::Exception& )
1247 {
1248 throw uno::RuntimeException();
1249 }
1250 }
1251
1252
1253 //____________________________________________________________________________________________________
1254 // XDisposable
1255 //____________________________________________________________________________________________________
1256
1257 //-----------------------------------------------
dispose()1258 void SAL_CALL FSStorage::dispose()
1259 throw ( uno::RuntimeException )
1260 {
1261 ::osl::MutexGuard aGuard( m_aMutex );
1262
1263 if ( !m_pImpl )
1264 throw lang::DisposedException();
1265
1266 if ( m_pImpl->m_pListenersContainer )
1267 {
1268 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
1269 m_pImpl->m_pListenersContainer->disposeAndClear( aSource );
1270 }
1271
1272 delete m_pImpl;
1273 m_pImpl = NULL;
1274 }
1275
1276 //-----------------------------------------------
addEventListener(const uno::Reference<lang::XEventListener> & xListener)1277 void SAL_CALL FSStorage::addEventListener(
1278 const uno::Reference< lang::XEventListener >& xListener )
1279 throw ( uno::RuntimeException )
1280 {
1281 ::osl::MutexGuard aGuard( m_aMutex );
1282
1283 if ( !m_pImpl )
1284 throw lang::DisposedException();
1285
1286 if ( !m_pImpl->m_pListenersContainer )
1287 m_pImpl->m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex );
1288
1289 m_pImpl->m_pListenersContainer->addInterface( xListener );
1290 }
1291
1292 //-----------------------------------------------
removeEventListener(const uno::Reference<lang::XEventListener> & xListener)1293 void SAL_CALL FSStorage::removeEventListener(
1294 const uno::Reference< lang::XEventListener >& xListener )
1295 throw ( uno::RuntimeException )
1296 {
1297 ::osl::MutexGuard aGuard( m_aMutex );
1298
1299 if ( !m_pImpl )
1300 throw lang::DisposedException();
1301
1302 if ( m_pImpl->m_pListenersContainer )
1303 m_pImpl->m_pListenersContainer->removeInterface( xListener );
1304 }
1305
1306 //____________________________________________________________________________________________________
1307 // XPropertySet
1308 //____________________________________________________________________________________________________
1309
1310 //-----------------------------------------------
getPropertySetInfo()1311 uno::Reference< beans::XPropertySetInfo > SAL_CALL FSStorage::getPropertySetInfo()
1312 throw ( uno::RuntimeException )
1313 {
1314 ::osl::MutexGuard aGuard( m_aMutex );
1315
1316 if ( !m_pImpl )
1317 throw lang::DisposedException();
1318
1319 //TODO:
1320 return uno::Reference< beans::XPropertySetInfo >();
1321 }
1322
1323
1324 //-----------------------------------------------
setPropertyValue(const::rtl::OUString & aPropertyName,const uno::Any &)1325 void SAL_CALL FSStorage::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& )
1326 throw ( beans::UnknownPropertyException,
1327 beans::PropertyVetoException,
1328 lang::IllegalArgumentException,
1329 lang::WrappedTargetException,
1330 uno::RuntimeException )
1331 {
1332 ::osl::MutexGuard aGuard( m_aMutex );
1333
1334 if ( !m_pImpl )
1335 throw lang::DisposedException();
1336
1337 if ( aPropertyName.equalsAscii( "URL" ) || aPropertyName.equalsAscii( "OpenMode" ) )
1338 throw beans::PropertyVetoException(); // TODO
1339 else
1340 throw beans::UnknownPropertyException(); // TODO
1341 }
1342
1343
1344 //-----------------------------------------------
getPropertyValue(const::rtl::OUString & aPropertyName)1345 uno::Any SAL_CALL FSStorage::getPropertyValue( const ::rtl::OUString& aPropertyName )
1346 throw ( beans::UnknownPropertyException,
1347 lang::WrappedTargetException,
1348 uno::RuntimeException )
1349 {
1350 ::osl::MutexGuard aGuard( m_aMutex );
1351
1352 if ( !m_pImpl )
1353 throw lang::DisposedException();
1354
1355 if ( aPropertyName.equalsAscii( "URL" ) )
1356 return uno::makeAny( m_pImpl->m_aURL );
1357 else if ( aPropertyName.equalsAscii( "OpenMode" ) )
1358 return uno::makeAny( m_pImpl->m_nMode );
1359
1360 throw beans::UnknownPropertyException(); // TODO
1361 }
1362
1363
1364 //-----------------------------------------------
addPropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1365 void SAL_CALL FSStorage::addPropertyChangeListener(
1366 const ::rtl::OUString& /*aPropertyName*/,
1367 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
1368 throw ( beans::UnknownPropertyException,
1369 lang::WrappedTargetException,
1370 uno::RuntimeException )
1371 {
1372 ::osl::MutexGuard aGuard( m_aMutex );
1373
1374 if ( !m_pImpl )
1375 throw lang::DisposedException();
1376
1377 //TODO:
1378 }
1379
1380
1381 //-----------------------------------------------
removePropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1382 void SAL_CALL FSStorage::removePropertyChangeListener(
1383 const ::rtl::OUString& /*aPropertyName*/,
1384 const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
1385 throw ( beans::UnknownPropertyException,
1386 lang::WrappedTargetException,
1387 uno::RuntimeException )
1388 {
1389 ::osl::MutexGuard aGuard( m_aMutex );
1390
1391 if ( !m_pImpl )
1392 throw lang::DisposedException();
1393
1394 //TODO:
1395 }
1396
1397
1398 //-----------------------------------------------
addVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1399 void SAL_CALL FSStorage::addVetoableChangeListener(
1400 const ::rtl::OUString& /*PropertyName*/,
1401 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
1402 throw ( beans::UnknownPropertyException,
1403 lang::WrappedTargetException,
1404 uno::RuntimeException )
1405 {
1406 ::osl::MutexGuard aGuard( m_aMutex );
1407
1408 if ( !m_pImpl )
1409 throw lang::DisposedException();
1410
1411 //TODO:
1412 }
1413
1414
1415 //-----------------------------------------------
removeVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1416 void SAL_CALL FSStorage::removeVetoableChangeListener(
1417 const ::rtl::OUString& /*PropertyName*/,
1418 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
1419 throw ( beans::UnknownPropertyException,
1420 lang::WrappedTargetException,
1421 uno::RuntimeException )
1422 {
1423 ::osl::MutexGuard aGuard( m_aMutex );
1424
1425 if ( !m_pImpl )
1426 throw lang::DisposedException();
1427
1428 //TODO:
1429 }
1430
1431 //____________________________________________________________________________________________________
1432 // XHierarchicalStorageAccess
1433 //____________________________________________________________________________________________________
1434 //-----------------------------------------------
openStreamElementByHierarchicalName(const::rtl::OUString & sStreamPath,::sal_Int32 nOpenMode)1435 uno::Reference< embed::XExtendedStorageStream > SAL_CALL FSStorage::openStreamElementByHierarchicalName( const ::rtl::OUString& sStreamPath, ::sal_Int32 nOpenMode )
1436 throw ( embed::InvalidStorageException,
1437 lang::IllegalArgumentException,
1438 packages::WrongPasswordException,
1439 io::IOException,
1440 embed::StorageWrappedTargetException,
1441 uno::RuntimeException )
1442 {
1443 ::osl::MutexGuard aGuard( m_aMutex );
1444
1445 if ( !m_pImpl )
1446 throw lang::DisposedException();
1447
1448 if ( sStreamPath.toChar() == '/' )
1449 throw lang::IllegalArgumentException();
1450
1451 if ( !GetContent() )
1452 throw io::IOException(); // TODO: error handling
1453
1454 INetURLObject aBaseURL( m_pImpl->m_aURL );
1455 if ( !aBaseURL.setFinalSlash() )
1456 throw uno::RuntimeException();
1457
1458 INetURLObject aFileURL = INetURLObject::GetAbsURL(
1459 aBaseURL.GetMainURL( INetURLObject::NO_DECODE ),
1460 sStreamPath );
1461
1462 if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1463 throw io::IOException();
1464
1465 if ( ( nOpenMode & embed::ElementModes::NOCREATE )
1466 && !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1467 throw io::IOException(); // TODO:
1468
1469 uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
1470 uno::Reference< io::XStream > xResult;
1471 try
1472 {
1473 if ( nOpenMode & embed::ElementModes::WRITE )
1474 {
1475 if ( isLocalFile_Impl( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1476 {
1477 uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess(
1478 m_pImpl->m_xFactory->createInstance(
1479 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ),
1480 uno::UNO_QUERY_THROW );
1481 uno::Reference< io::XStream > xStream =
1482 xSimpleFileAccess->openFileReadWrite( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) );
1483
1484 xResult = static_cast< io::XStream* >( new OFSStreamContainer( xStream ) );
1485 }
1486 else
1487 {
1488 // TODO: test whether it really works for http and fwp
1489 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ),
1490 STREAM_STD_WRITE );
1491 if ( pStream )
1492 {
1493 if ( !pStream->GetError() )
1494 {
1495 uno::Reference< io::XStream > xStream =
1496 uno::Reference < io::XStream >( new ::utl::OStreamWrapper( *pStream ) );
1497 xResult = static_cast< io::XStream* >( new OFSStreamContainer( xStream ) );
1498 }
1499 else
1500 delete pStream;
1501 }
1502 }
1503
1504 if ( !xResult.is() )
1505 throw io::IOException();
1506
1507 if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) )
1508 {
1509 uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW );
1510 xTrunc->truncate();
1511 }
1512 }
1513 else
1514 {
1515 if ( ( nOpenMode & embed::ElementModes::TRUNCATE )
1516 || !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1517 throw io::IOException(); // TODO: access denied
1518
1519 ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
1520 uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
1521 xResult = static_cast< io::XStream* >( new OFSInputStreamContainer( xInStream ) );
1522 }
1523 }
1524 catch( embed::InvalidStorageException& )
1525 {
1526 throw;
1527 }
1528 catch( lang::IllegalArgumentException& )
1529 {
1530 throw;
1531 }
1532 catch( packages::WrongPasswordException& )
1533 {
1534 throw;
1535 }
1536 catch( embed::StorageWrappedTargetException& )
1537 {
1538 throw;
1539 }
1540 catch( io::IOException& )
1541 {
1542 throw;
1543 }
1544 catch( uno::RuntimeException& )
1545 {
1546 throw;
1547 }
1548 catch( uno::Exception& )
1549 {
1550 uno::Any aCaught( ::cppu::getCaughtException() );
1551 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
1552 uno::Reference< io::XInputStream >(),
1553 aCaught );
1554 }
1555
1556 return uno::Reference< embed::XExtendedStorageStream >( xResult, uno::UNO_QUERY_THROW );
1557 }
1558
1559 //-----------------------------------------------
openEncryptedStreamElementByHierarchicalName(const::rtl::OUString &,::sal_Int32,const::rtl::OUString &)1560 uno::Reference< embed::XExtendedStorageStream > SAL_CALL FSStorage::openEncryptedStreamElementByHierarchicalName( const ::rtl::OUString& /*sStreamName*/, ::sal_Int32 /*nOpenMode*/, const ::rtl::OUString& /*sPassword*/ )
1561 throw ( embed::InvalidStorageException,
1562 lang::IllegalArgumentException,
1563 packages::NoEncryptionException,
1564 packages::WrongPasswordException,
1565 io::IOException,
1566 embed::StorageWrappedTargetException,
1567 uno::RuntimeException )
1568 {
1569 throw packages::NoEncryptionException();
1570 }
1571
1572 //-----------------------------------------------
removeStreamElementByHierarchicalName(const::rtl::OUString & sStreamPath)1573 void SAL_CALL FSStorage::removeStreamElementByHierarchicalName( const ::rtl::OUString& sStreamPath )
1574 throw ( embed::InvalidStorageException,
1575 lang::IllegalArgumentException,
1576 container::NoSuchElementException,
1577 io::IOException,
1578 embed::StorageWrappedTargetException,
1579 uno::RuntimeException )
1580 {
1581 ::osl::MutexGuard aGuard( m_aMutex );
1582
1583 if ( !m_pImpl )
1584 throw lang::DisposedException();
1585
1586 if ( !GetContent() )
1587 throw io::IOException(); // TODO: error handling
1588
1589 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
1590 INetURLObject aBaseURL( m_pImpl->m_aURL );
1591 if ( !aBaseURL.setFinalSlash() )
1592 throw uno::RuntimeException();
1593
1594 INetURLObject aFileURL = INetURLObject::GetAbsURL(
1595 aBaseURL.GetMainURL( INetURLObject::NO_DECODE ),
1596 sStreamPath );
1597
1598 if ( !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1599 {
1600 if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1601 throw lang::IllegalArgumentException();
1602 else
1603 throw container::NoSuchElementException(); // TODO:
1604 }
1605
1606 if ( !::utl::UCBContentHelper::Kill( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1607 throw io::IOException(); // TODO: error handling
1608 }
1609
1610
1611