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