xref: /trunk/main/svl/source/fsstor/fsstorage.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 {
316     uno::Any aReturn;
317     aReturn <<= ::cppu::queryInterface
318                 (   rType
319                 ,   static_cast<lang::XTypeProvider*> ( this )
320                 ,   static_cast<embed::XStorage*> ( this )
321                 ,   static_cast<embed::XHierarchicalStorageAccess*> ( this )
322                 ,   static_cast<container::XNameAccess*> ( this )
323                 ,   static_cast<container::XElementAccess*> ( this )
324                 ,   static_cast<lang::XComponent*> ( this )
325                 ,   static_cast<beans::XPropertySet*> ( this ) );
326 
327     if ( aReturn.hasValue() == sal_True )
328         return aReturn ;
329 
330     return OWeakObject::queryInterface( rType );
331 }
332 
333 //-----------------------------------------------
acquire()334 void SAL_CALL FSStorage::acquire() throw()
335 {
336     OWeakObject::acquire();
337 }
338 
339 //-----------------------------------------------
release()340 void SAL_CALL FSStorage::release() throw()
341 {
342     OWeakObject::release();
343 }
344 
345 //____________________________________________________________________________________________________
346 //  XTypeProvider
347 //____________________________________________________________________________________________________
348 
349 //-----------------------------------------------
getTypes()350 uno::Sequence< uno::Type > SAL_CALL FSStorage::getTypes()
351 {
352     if ( m_pImpl->m_pTypeCollection == NULL )
353     {
354         ::osl::MutexGuard aGuard( m_aMutex );
355 
356         if ( m_pImpl->m_pTypeCollection == NULL )
357         {
358             m_pImpl->m_pTypeCollection = new ::cppu::OTypeCollection
359                                 (   ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
360                                 ,   ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
361                                 ,   ::getCppuType( ( const uno::Reference< embed::XHierarchicalStorageAccess >* )NULL )
362                                 ,   ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
363         }
364     }
365 
366     return m_pImpl->m_pTypeCollection->getTypes() ;
367 }
368 
369 //-----------------------------------------------
getImplementationId()370 uno::Sequence< sal_Int8 > SAL_CALL FSStorage::getImplementationId()
371 {
372     static ::cppu::OImplementationId* pID = NULL ;
373 
374     if ( pID == NULL )
375     {
376         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ;
377 
378         if ( pID == NULL )
379         {
380             static ::cppu::OImplementationId aID( sal_False ) ;
381             pID = &aID ;
382         }
383     }
384 
385     return pID->getImplementationId() ;
386 
387 }
388 
389 //____________________________________________________________________________________________________
390 //  XStorage
391 //____________________________________________________________________________________________________
392 
393 //-----------------------------------------------
copyToStorage(const uno::Reference<embed::XStorage> & xDest)394 void SAL_CALL FSStorage::copyToStorage( const uno::Reference< embed::XStorage >& xDest )
395 {
396     ::osl::MutexGuard aGuard( m_aMutex );
397 
398     if ( !m_pImpl )
399         throw lang::DisposedException();
400 
401     if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject*> ( this ), uno::UNO_QUERY ) )
402         throw lang::IllegalArgumentException(); // TODO:
403 
404     if ( !GetContent() )
405         throw io::IOException(); // TODO: error handling
406 
407     try
408     {
409         CopyContentToStorage_Impl( GetContent(), xDest );
410     }
411     catch( embed::InvalidStorageException& )
412     {
413         throw;
414     }
415     catch( lang::IllegalArgumentException& )
416     {
417         throw;
418     }
419     catch( embed::StorageWrappedTargetException& )
420     {
421         throw;
422     }
423     catch( io::IOException& )
424     {
425         throw;
426     }
427     catch( uno::RuntimeException& )
428     {
429         throw;
430     }
431     catch( uno::Exception& )
432     {
433         uno::Any aCaught( ::cppu::getCaughtException() );
434         throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
435                                                  uno::Reference< io::XInputStream >(),
436                                                  aCaught );
437     }
438 }
439 
440 //-----------------------------------------------
openStreamElement(const::rtl::OUString & aStreamName,sal_Int32 nOpenMode)441 uno::Reference< io::XStream > SAL_CALL FSStorage::openStreamElement(
442     const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode )
443 {
444     ::osl::MutexGuard aGuard( m_aMutex );
445 
446     if ( !m_pImpl )
447         throw lang::DisposedException();
448 
449     if ( !GetContent() )
450         throw io::IOException(); // TODO: error handling
451 
452     // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
453     INetURLObject aFileURL( m_pImpl->m_aURL );
454     aFileURL.Append( aStreamName );
455 
456     if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
457         throw io::IOException();
458 
459     if ( ( nOpenMode & embed::ElementModes::NOCREATE )
460       && !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
461         throw io::IOException(); // TODO:
462 
463     uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
464     uno::Reference< io::XStream > xResult;
465     try
466     {
467         if ( nOpenMode & embed::ElementModes::WRITE )
468         {
469             if ( isLocalFile_Impl( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
470             {
471                 uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess(
472                     m_pImpl->m_xFactory->createInstance(
473                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ),
474                     uno::UNO_QUERY_THROW );
475                 xResult = xSimpleFileAccess->openFileReadWrite( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) );
476             }
477             else
478             {
479                 // TODO: test whether it really works for http and fwp
480                 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ),
481                                                                         STREAM_STD_WRITE );
482                 if ( pStream )
483                 {
484                     if ( !pStream->GetError() )
485                         xResult = uno::Reference < io::XStream >( new ::utl::OStreamWrapper( *pStream ) );
486                     else
487                         delete pStream;
488                 }
489             }
490 
491             if ( !xResult.is() )
492                 throw io::IOException();
493 
494             if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) )
495             {
496                 uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW );
497                 xTrunc->truncate();
498             }
499         }
500         else
501         {
502             if ( ( nOpenMode & embed::ElementModes::TRUNCATE )
503             || !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
504                 throw io::IOException(); // TODO: access denied
505 
506             ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
507             uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
508             xResult = static_cast< io::XStream* >( new OFSInputStreamContainer( xInStream ) );
509         }
510     }
511     catch( embed::InvalidStorageException& )
512     {
513         throw;
514     }
515     catch( lang::IllegalArgumentException& )
516     {
517         throw;
518     }
519     catch( packages::WrongPasswordException& )
520     {
521         throw;
522     }
523     catch( embed::StorageWrappedTargetException& )
524     {
525         throw;
526     }
527     catch( io::IOException& )
528     {
529         throw;
530     }
531     catch( uno::RuntimeException& )
532     {
533         throw;
534     }
535     catch( uno::Exception& )
536     {
537         uno::Any aCaught( ::cppu::getCaughtException() );
538         throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
539                                                  uno::Reference< io::XInputStream >(),
540                                                  aCaught );
541     }
542 
543     return xResult;
544 }
545 
546 //-----------------------------------------------
openEncryptedStreamElement(const::rtl::OUString &,sal_Int32,const::rtl::OUString &)547 uno::Reference< io::XStream > SAL_CALL FSStorage::openEncryptedStreamElement(
548     const ::rtl::OUString&, sal_Int32, const ::rtl::OUString& )
549 {
550     throw packages::NoEncryptionException();
551 }
552 
553 //-----------------------------------------------
openStorageElement(const::rtl::OUString & aStorName,sal_Int32 nStorageMode)554 uno::Reference< embed::XStorage > SAL_CALL FSStorage::openStorageElement(
555             const ::rtl::OUString& aStorName, sal_Int32 nStorageMode )
556 {
557     ::osl::MutexGuard aGuard( m_aMutex );
558 
559     if ( !m_pImpl )
560         throw lang::DisposedException();
561 
562     if ( !GetContent() )
563         throw io::IOException(); // TODO: error handling
564 
565     if ( ( nStorageMode & embed::ElementModes::WRITE )
566       && !( m_pImpl->m_nMode & embed::ElementModes::WRITE ) )
567         throw io::IOException(); // TODO: error handling
568 
569     // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
570     INetURLObject aFolderURL( m_pImpl->m_aURL );
571     aFolderURL.Append( aStorName );
572 
573     sal_Bool bFolderExists = ::utl::UCBContentHelper::IsFolder( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) );
574     if ( !bFolderExists && ::utl::UCBContentHelper::IsDocument( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
575         throw io::IOException(); // TODO:
576 
577     if ( ( nStorageMode & embed::ElementModes::NOCREATE ) && !bFolderExists )
578         throw io::IOException(); // TODO:
579 
580     uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
581     uno::Reference< embed::XStorage > xResult;
582     try
583     {
584         if ( nStorageMode & embed::ElementModes::WRITE )
585         {
586             if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) && bFolderExists )
587             {
588                 ::utl::UCBContentHelper::Kill( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ) );
589                 bFolderExists =
590                     MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), sal_True ); // TODO: not atomar :(
591             }
592             else if ( !bFolderExists )
593             {
594                 bFolderExists =
595                     MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), sal_True ); // TODO: not atomar :(
596             }
597         }
598         else if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) )
599             throw io::IOException(); // TODO: access denied
600 
601         if ( !bFolderExists )
602             throw io::IOException(); // there is no such folder
603 
604         ::ucbhelper::Content aResultContent( aFolderURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
605         xResult = uno::Reference< embed::XStorage >(
606                             static_cast< OWeakObject* >( new FSStorage( aResultContent,
607                                                                         nStorageMode,
608                                                                         uno::Sequence< beans::PropertyValue >(),
609                                                                         m_pImpl->m_xFactory ) ),
610                             uno::UNO_QUERY );
611     }
612     catch( embed::InvalidStorageException& )
613     {
614         throw;
615     }
616     catch( lang::IllegalArgumentException& )
617     {
618         throw;
619     }
620     catch( embed::StorageWrappedTargetException& )
621     {
622         throw;
623     }
624     catch( io::IOException& )
625     {
626         throw;
627     }
628     catch( uno::RuntimeException& )
629     {
630         throw;
631     }
632     catch( uno::Exception& )
633     {
634         uno::Any aCaught( ::cppu::getCaughtException() );
635         throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
636                                                  uno::Reference< io::XInputStream >(),
637                                                  aCaught );
638     }
639 
640     return xResult;
641 }
642 
643 //-----------------------------------------------
cloneStreamElement(const::rtl::OUString & aStreamName)644 uno::Reference< io::XStream > SAL_CALL FSStorage::cloneStreamElement( const ::rtl::OUString& aStreamName )
645 {
646     ::osl::MutexGuard aGuard( m_aMutex );
647 
648     if ( !m_pImpl )
649         throw lang::DisposedException();
650 
651     if ( !GetContent() )
652         throw io::IOException(); // TODO: error handling
653 
654     // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
655     INetURLObject aFileURL( m_pImpl->m_aURL );
656     aFileURL.Append( aStreamName );
657 
658     uno::Reference < io::XStream > xTempResult;
659     try
660     {
661         uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
662         ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
663         uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
664 
665         xTempResult = uno::Reference < io::XStream >(
666                     m_pImpl->m_xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
667                     uno::UNO_QUERY_THROW );
668         uno::Reference < io::XOutputStream > xTempOut = xTempResult->getOutputStream();
669         uno::Reference < io::XInputStream > xTempIn = xTempResult->getInputStream();
670 
671         if ( !xTempOut.is() || !xTempIn.is() )
672             throw io::IOException();
673 
674         ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOut );
675         xTempOut->closeOutput();
676     }
677     catch( embed::InvalidStorageException& )
678     {
679         throw;
680     }
681     catch( lang::IllegalArgumentException& )
682     {
683         throw;
684     }
685     catch( packages::WrongPasswordException& )
686     {
687         throw;
688     }
689     catch( io::IOException& )
690     {
691         throw;
692     }
693     catch( embed::StorageWrappedTargetException& )
694     {
695         throw;
696     }
697     catch( uno::RuntimeException& )
698     {
699         throw;
700     }
701     catch( uno::Exception& )
702     {
703         uno::Any aCaught( ::cppu::getCaughtException() );
704         throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
705                                                  uno::Reference< io::XInputStream >(),
706                                                  aCaught );
707     }
708 
709     return xTempResult;
710 }
711 
712 //-----------------------------------------------
cloneEncryptedStreamElement(const::rtl::OUString &,const::rtl::OUString &)713 uno::Reference< io::XStream > SAL_CALL FSStorage::cloneEncryptedStreamElement(
714     const ::rtl::OUString&,
715     const ::rtl::OUString& )
716 {
717     throw packages::NoEncryptionException();
718 }
719 
720 //-----------------------------------------------
copyLastCommitTo(const uno::Reference<embed::XStorage> & xTargetStorage)721 void SAL_CALL FSStorage::copyLastCommitTo(
722             const uno::Reference< embed::XStorage >& xTargetStorage )
723 {
724     copyToStorage( xTargetStorage );
725 }
726 
727 //-----------------------------------------------
copyStorageElementLastCommitTo(const::rtl::OUString & aStorName,const uno::Reference<embed::XStorage> & xTargetStorage)728 void SAL_CALL FSStorage::copyStorageElementLastCommitTo(
729             const ::rtl::OUString& aStorName,
730             const uno::Reference< embed::XStorage >& xTargetStorage )
731 {
732     ::osl::MutexGuard aGuard( m_aMutex );
733 
734     if ( !m_pImpl )
735         throw lang::DisposedException();
736 
737     uno::Reference< embed::XStorage > xSourceStor( openStorageElement( aStorName, embed::ElementModes::READ ),
738                                                     uno::UNO_QUERY_THROW );
739     xSourceStor->copyToStorage( xTargetStorage );
740 }
741 
742 //-----------------------------------------------
isStreamElement(const::rtl::OUString & aElementName)743 sal_Bool SAL_CALL FSStorage::isStreamElement( const ::rtl::OUString& aElementName )
744 {
745     ::osl::MutexGuard aGuard( m_aMutex );
746 
747     if ( !m_pImpl )
748         throw lang::DisposedException();
749 
750     if ( !GetContent() )
751         throw embed::InvalidStorageException(); // TODO: error handling
752 
753     INetURLObject aURL( m_pImpl->m_aURL );
754     aURL.Append( aElementName );
755 
756     return !::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
757 }
758 
759 //-----------------------------------------------
isStorageElement(const::rtl::OUString & aElementName)760 sal_Bool SAL_CALL FSStorage::isStorageElement( const ::rtl::OUString& aElementName )
761 {
762     ::osl::MutexGuard aGuard( m_aMutex );
763 
764     if ( !m_pImpl )
765         throw lang::DisposedException();
766 
767     if ( !GetContent() )
768         throw embed::InvalidStorageException(); // TODO: error handling
769 
770     INetURLObject aURL( m_pImpl->m_aURL );
771     aURL.Append( aElementName );
772 
773     return ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
774 }
775 
776 //-----------------------------------------------
removeElement(const::rtl::OUString & aElementName)777 void SAL_CALL FSStorage::removeElement( const ::rtl::OUString& aElementName )
778 {
779     ::osl::MutexGuard aGuard( m_aMutex );
780 
781     if ( !m_pImpl )
782         throw lang::DisposedException();
783 
784     if ( !GetContent() )
785         throw io::IOException(); // TODO: error handling
786 
787     INetURLObject aURL( m_pImpl->m_aURL );
788     aURL.Append( aElementName );
789 
790     if ( !::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) )
791       && !::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
792         throw container::NoSuchElementException(); // TODO:
793 
794     ::utl::UCBContentHelper::Kill( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
795 }
796 
797 //-----------------------------------------------
renameElement(const::rtl::OUString & aElementName,const::rtl::OUString & aNewName)798 void SAL_CALL FSStorage::renameElement( const ::rtl::OUString& aElementName, const ::rtl::OUString& aNewName )
799 {
800     ::osl::MutexGuard aGuard( m_aMutex );
801 
802     if ( !m_pImpl )
803         throw lang::DisposedException();
804 
805     if ( !GetContent() )
806         throw io::IOException(); // TODO: error handling
807 
808     INetURLObject aOldURL( m_pImpl->m_aURL );
809     aOldURL.Append( aElementName );
810 
811     INetURLObject aNewURL( m_pImpl->m_aURL );
812     aNewURL.Append( aNewName );
813 
814     if ( !::utl::UCBContentHelper::IsFolder( aOldURL.GetMainURL( INetURLObject::NO_DECODE ) )
815       && !::utl::UCBContentHelper::IsDocument( aOldURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
816         throw container::NoSuchElementException(); // TODO:
817 
818     if ( ::utl::UCBContentHelper::IsFolder( aNewURL.GetMainURL( INetURLObject::NO_DECODE ) )
819       || ::utl::UCBContentHelper::IsDocument( aNewURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
820         throw container::ElementExistException(); // TODO:
821 
822     try
823     {
824         uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
825         ::ucbhelper::Content aSourceContent( aOldURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
826 
827         if ( !GetContent()->transferContent( aSourceContent,
828                                             ::ucbhelper::InsertOperation_MOVE,
829                                             aNewName,
830                                             ucb::NameClash::ERROR ) )
831             throw io::IOException(); // TODO: error handling
832     }
833     catch( embed::InvalidStorageException& )
834     {
835         throw;
836     }
837     catch( lang::IllegalArgumentException& )
838     {
839         throw;
840     }
841     catch( container::NoSuchElementException& )
842     {
843         throw;
844     }
845     catch( container::ElementExistException& )
846     {
847         throw;
848     }
849     catch( io::IOException& )
850     {
851         throw;
852     }
853     catch( embed::StorageWrappedTargetException& )
854     {
855         throw;
856     }
857     catch( uno::RuntimeException& )
858     {
859         throw;
860     }
861     catch( uno::Exception& )
862     {
863         uno::Any aCaught( ::cppu::getCaughtException() );
864         throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
865                                                  uno::Reference< io::XInputStream >(),
866                                                  aCaught );
867     }
868 }
869 
870 //-----------------------------------------------
copyElementTo(const::rtl::OUString & aElementName,const uno::Reference<embed::XStorage> & xDest,const::rtl::OUString & aNewName)871 void SAL_CALL FSStorage::copyElementTo( const ::rtl::OUString& aElementName,
872                                         const uno::Reference< embed::XStorage >& xDest,
873                                         const ::rtl::OUString& aNewName )
874 {
875     ::osl::MutexGuard aGuard( m_aMutex );
876 
877     if ( !m_pImpl )
878         throw lang::DisposedException();
879 
880     if ( !xDest.is() )
881         throw uno::RuntimeException();
882 
883     if ( !GetContent() )
884         throw io::IOException(); // TODO: error handling
885 
886     INetURLObject aOwnURL( m_pImpl->m_aURL );
887     aOwnURL.Append( aElementName );
888 
889     if ( xDest->hasByName( aNewName ) )
890         throw container::ElementExistException(); // TODO:
891 
892     try
893     {
894         uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
895         if ( ::utl::UCBContentHelper::IsFolder( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
896         {
897             ::ucbhelper::Content aSourceContent( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
898             uno::Reference< embed::XStorage > xDestSubStor(
899                                     xDest->openStorageElement( aNewName, embed::ElementModes::READWRITE ),
900                                     uno::UNO_QUERY_THROW );
901 
902             CopyContentToStorage_Impl( &aSourceContent, xDestSubStor );
903         }
904         else if ( ::utl::UCBContentHelper::IsDocument( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
905         {
906             CopyStreamToSubStream( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ), xDest, aNewName );
907         }
908         else
909             throw container::NoSuchElementException(); // TODO:
910     }
911     catch( embed::InvalidStorageException& )
912     {
913         throw;
914     }
915     catch( lang::IllegalArgumentException& )
916     {
917         throw;
918     }
919     catch( container::NoSuchElementException& )
920     {
921         throw;
922     }
923     catch( container::ElementExistException& )
924     {
925         throw;
926     }
927     catch( embed::StorageWrappedTargetException& )
928     {
929         throw;
930     }
931     catch( io::IOException& )
932     {
933         throw;
934     }
935     catch( uno::RuntimeException& )
936     {
937         throw;
938     }
939     catch( uno::Exception& )
940     {
941         uno::Any aCaught( ::cppu::getCaughtException() );
942         throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
943                                                  uno::Reference< io::XInputStream >(),
944                                                  aCaught );
945     }
946 }
947 
948 //-----------------------------------------------
moveElementTo(const::rtl::OUString & aElementName,const uno::Reference<embed::XStorage> & xDest,const::rtl::OUString & aNewName)949 void SAL_CALL FSStorage::moveElementTo( const ::rtl::OUString& aElementName,
950                                         const uno::Reference< embed::XStorage >& xDest,
951                                         const ::rtl::OUString& aNewName )
952 {
953     ::osl::MutexGuard aGuard( m_aMutex );
954     copyElementTo( aElementName, xDest, aNewName );
955 
956     INetURLObject aOwnURL( m_pImpl->m_aURL );
957     aOwnURL.Append( aElementName );
958     if ( !::utl::UCBContentHelper::Kill( aOwnURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
959         throw io::IOException(); // TODO: error handling
960 }
961 
962 //____________________________________________________________________________________________________
963 //  XNameAccess
964 //____________________________________________________________________________________________________
965 
966 //-----------------------------------------------
getByName(const::rtl::OUString & aName)967 uno::Any SAL_CALL FSStorage::getByName( const ::rtl::OUString& aName )
968 {
969     ::osl::MutexGuard aGuard( m_aMutex );
970 
971     if ( !m_pImpl )
972         throw lang::DisposedException();
973 
974     if ( !GetContent() )
975         throw io::IOException(); // TODO: error handling
976 
977     if ( !aName.getLength() )
978         throw lang::IllegalArgumentException();
979 
980     INetURLObject aURL( m_pImpl->m_aURL );
981     aURL.Append( aName );
982 
983     uno::Any aResult;
984     try
985     {
986         if ( ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
987         {
988             aResult <<= openStorageElement( aName, embed::ElementModes::READ );
989         }
990         else if ( ::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
991         {
992             aResult <<= openStreamElement( aName, embed::ElementModes::READ );
993         }
994         else
995             throw container::NoSuchElementException(); // TODO:
996     }
997     catch( container::NoSuchElementException& )
998     {
999         throw;
1000     }
1001     catch( lang::WrappedTargetException& )
1002     {
1003         throw;
1004     }
1005     catch( uno::RuntimeException& )
1006     {
1007         throw;
1008     }
1009     catch ( uno::Exception& )
1010     {
1011         uno::Any aCaught( ::cppu::getCaughtException() );
1012         throw lang::WrappedTargetException( ::rtl::OUString::createFromAscii( "Can not open element!\n" ),
1013                                             uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
1014                                                                                 uno::UNO_QUERY ),
1015                                             aCaught );
1016     }
1017 
1018     return aResult;
1019 }
1020 
1021 
1022 //-----------------------------------------------
getElementNames()1023 uno::Sequence< ::rtl::OUString > SAL_CALL FSStorage::getElementNames()
1024 {
1025     ::osl::MutexGuard aGuard( m_aMutex );
1026 
1027     if ( !m_pImpl )
1028         throw lang::DisposedException();
1029 
1030     if ( !GetContent() )
1031         throw io::IOException(); // TODO: error handling
1032 
1033     uno::Sequence< ::rtl::OUString > aProps( 1 );
1034     ::rtl::OUString* pProps = aProps.getArray();
1035     pProps[0] = ::rtl::OUString::createFromAscii( "Title" );
1036     ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
1037 
1038     uno::Sequence< ::rtl::OUString > aResult;
1039     sal_Int32 nSize = 0;
1040 
1041     try
1042     {
1043         uno::Reference< sdbc::XResultSet > xResultSet = GetContent()->createCursor( aProps, eInclude );
1044         uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY );
1045         uno::Reference< sdbc::XRow > xRow( xResultSet, uno::UNO_QUERY );
1046         if ( xResultSet.is() )
1047         {
1048             // go through the list
1049             while ( xResultSet->next() )
1050             {
1051                 ::rtl::OUString aName( xRow->getString( 1 ) );
1052                 aResult.realloc( ++nSize );
1053                 aResult[nSize-1] = aName;
1054             }
1055         }
1056     }
1057     catch( ucb::InteractiveIOException& r )
1058     {
1059         if ( r.Code == ucb::IOErrorCode_NOT_EXISTING )
1060             OSL_ENSURE( sal_False, "The folder does not exist!\n" );
1061         else
1062         {
1063             uno::Any aCaught( ::cppu::getCaughtException() );
1064             throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
1065                                             uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
1066                                                                                 uno::UNO_QUERY ),
1067                                             aCaught );
1068         }
1069     }
1070     catch( uno::RuntimeException& )
1071     {
1072         throw;
1073     }
1074     catch ( uno::Exception& )
1075     {
1076         uno::Any aCaught( ::cppu::getCaughtException() );
1077         throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
1078                                             uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
1079                                                                                 uno::UNO_QUERY ),
1080                                             aCaught );
1081     }
1082 
1083     return aResult;
1084 }
1085 
1086 
1087 //-----------------------------------------------
hasByName(const::rtl::OUString & aName)1088 sal_Bool SAL_CALL FSStorage::hasByName( const ::rtl::OUString& aName )
1089 {
1090     ::osl::MutexGuard aGuard( m_aMutex );
1091 
1092     if ( !m_pImpl )
1093         throw lang::DisposedException();
1094 
1095     try
1096     {
1097         if ( !GetContent() )
1098             throw io::IOException(); // TODO: error handling
1099 
1100         if ( !aName.getLength() )
1101             throw lang::IllegalArgumentException();
1102     }
1103     catch( uno::RuntimeException& )
1104     {
1105         throw;
1106     }
1107     catch ( uno::Exception& )
1108     {
1109         uno::Any aCaught( ::cppu::getCaughtException() );
1110         throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
1111                                             uno::Reference< uno::XInterface >(  static_cast< OWeakObject* >( this ),
1112                                                                                 uno::UNO_QUERY ),
1113                                             aCaught );
1114     }
1115 
1116     INetURLObject aURL( m_pImpl->m_aURL );
1117     aURL.Append( aName );
1118 
1119     return ( ::utl::UCBContentHelper::IsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) )
1120       || ::utl::UCBContentHelper::IsDocument( aURL.GetMainURL( INetURLObject::NO_DECODE ) ) );
1121 }
1122 
1123 //-----------------------------------------------
getElementType()1124 uno::Type SAL_CALL FSStorage::getElementType()
1125 {
1126     ::osl::MutexGuard aGuard( m_aMutex );
1127 
1128     if ( !m_pImpl )
1129         throw lang::DisposedException();
1130 
1131     // it is a multitype container
1132     return uno::Type();
1133 }
1134 
1135 //-----------------------------------------------
hasElements()1136 sal_Bool SAL_CALL FSStorage::hasElements()
1137 {
1138     ::osl::MutexGuard aGuard( m_aMutex );
1139 
1140     if ( !m_pImpl )
1141         throw lang::DisposedException();
1142 
1143     if ( !GetContent() )
1144         throw io::IOException(); // TODO: error handling
1145 
1146     uno::Sequence< ::rtl::OUString > aProps( 1 );
1147     aProps[0] = ::rtl::OUString::createFromAscii( "TargetURL" );
1148     ::ucbhelper::ResultSetInclude eInclude = ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
1149 
1150     try
1151     {
1152         uno::Reference< sdbc::XResultSet > xResultSet = GetContent()->createCursor( aProps, eInclude );
1153         return ( xResultSet.is() && xResultSet->next() );
1154     }
1155     catch( uno::Exception& )
1156     {
1157         throw uno::RuntimeException();
1158     }
1159 }
1160 
1161 
1162 //____________________________________________________________________________________________________
1163 //  XDisposable
1164 //____________________________________________________________________________________________________
1165 
1166 //-----------------------------------------------
dispose()1167 void SAL_CALL FSStorage::dispose()
1168 {
1169     ::osl::MutexGuard aGuard( m_aMutex );
1170 
1171     if ( !m_pImpl )
1172         throw lang::DisposedException();
1173 
1174     if ( m_pImpl->m_pListenersContainer )
1175     {
1176         lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
1177         m_pImpl->m_pListenersContainer->disposeAndClear( aSource );
1178     }
1179 
1180     delete m_pImpl;
1181     m_pImpl = NULL;
1182 }
1183 
1184 //-----------------------------------------------
addEventListener(const uno::Reference<lang::XEventListener> & xListener)1185 void SAL_CALL FSStorage::addEventListener(
1186             const uno::Reference< lang::XEventListener >& xListener )
1187 {
1188     ::osl::MutexGuard aGuard( m_aMutex );
1189 
1190     if ( !m_pImpl )
1191         throw lang::DisposedException();
1192 
1193     if ( !m_pImpl->m_pListenersContainer )
1194         m_pImpl->m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex );
1195 
1196     m_pImpl->m_pListenersContainer->addInterface( xListener );
1197 }
1198 
1199 //-----------------------------------------------
removeEventListener(const uno::Reference<lang::XEventListener> & xListener)1200 void SAL_CALL FSStorage::removeEventListener(
1201             const uno::Reference< lang::XEventListener >& xListener )
1202 {
1203     ::osl::MutexGuard aGuard( m_aMutex );
1204 
1205     if ( !m_pImpl )
1206         throw lang::DisposedException();
1207 
1208     if ( m_pImpl->m_pListenersContainer )
1209         m_pImpl->m_pListenersContainer->removeInterface( xListener );
1210 }
1211 
1212 //____________________________________________________________________________________________________
1213 //  XPropertySet
1214 //____________________________________________________________________________________________________
1215 
1216 //-----------------------------------------------
getPropertySetInfo()1217 uno::Reference< beans::XPropertySetInfo > SAL_CALL FSStorage::getPropertySetInfo()
1218 {
1219     ::osl::MutexGuard aGuard( m_aMutex );
1220 
1221     if ( !m_pImpl )
1222         throw lang::DisposedException();
1223 
1224     //TODO:
1225     return uno::Reference< beans::XPropertySetInfo >();
1226 }
1227 
1228 
1229 //-----------------------------------------------
setPropertyValue(const::rtl::OUString & aPropertyName,const uno::Any &)1230 void SAL_CALL FSStorage::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& )
1231 {
1232     ::osl::MutexGuard aGuard( m_aMutex );
1233 
1234     if ( !m_pImpl )
1235         throw lang::DisposedException();
1236 
1237     if ( aPropertyName.equalsAscii( "URL" ) || aPropertyName.equalsAscii( "OpenMode" ) )
1238         throw beans::PropertyVetoException(); // TODO
1239     else
1240         throw beans::UnknownPropertyException(); // TODO
1241 }
1242 
1243 
1244 //-----------------------------------------------
getPropertyValue(const::rtl::OUString & aPropertyName)1245 uno::Any SAL_CALL FSStorage::getPropertyValue( const ::rtl::OUString& aPropertyName )
1246 {
1247     ::osl::MutexGuard aGuard( m_aMutex );
1248 
1249     if ( !m_pImpl )
1250         throw lang::DisposedException();
1251 
1252     if ( aPropertyName.equalsAscii( "URL" ) )
1253         return uno::makeAny( m_pImpl->m_aURL );
1254     else if ( aPropertyName.equalsAscii( "OpenMode" ) )
1255         return uno::makeAny( m_pImpl->m_nMode );
1256 
1257     throw beans::UnknownPropertyException(); // TODO
1258 }
1259 
1260 
1261 //-----------------------------------------------
addPropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1262 void SAL_CALL FSStorage::addPropertyChangeListener(
1263             const ::rtl::OUString& /*aPropertyName*/,
1264             const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
1265 {
1266     ::osl::MutexGuard aGuard( m_aMutex );
1267 
1268     if ( !m_pImpl )
1269         throw lang::DisposedException();
1270 
1271     //TODO:
1272 }
1273 
1274 
1275 //-----------------------------------------------
removePropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1276 void SAL_CALL FSStorage::removePropertyChangeListener(
1277             const ::rtl::OUString& /*aPropertyName*/,
1278             const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
1279 {
1280     ::osl::MutexGuard aGuard( m_aMutex );
1281 
1282     if ( !m_pImpl )
1283         throw lang::DisposedException();
1284 
1285     //TODO:
1286 }
1287 
1288 
1289 //-----------------------------------------------
addVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1290 void SAL_CALL FSStorage::addVetoableChangeListener(
1291             const ::rtl::OUString& /*PropertyName*/,
1292             const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
1293 {
1294     ::osl::MutexGuard aGuard( m_aMutex );
1295 
1296     if ( !m_pImpl )
1297         throw lang::DisposedException();
1298 
1299     //TODO:
1300 }
1301 
1302 
1303 //-----------------------------------------------
removeVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1304 void SAL_CALL FSStorage::removeVetoableChangeListener(
1305             const ::rtl::OUString& /*PropertyName*/,
1306             const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
1307 {
1308     ::osl::MutexGuard aGuard( m_aMutex );
1309 
1310     if ( !m_pImpl )
1311         throw lang::DisposedException();
1312 
1313     //TODO:
1314 }
1315 
1316 //____________________________________________________________________________________________________
1317 //  XHierarchicalStorageAccess
1318 //____________________________________________________________________________________________________
1319 //-----------------------------------------------
openStreamElementByHierarchicalName(const::rtl::OUString & sStreamPath,::sal_Int32 nOpenMode)1320 uno::Reference< embed::XExtendedStorageStream > SAL_CALL FSStorage::openStreamElementByHierarchicalName( const ::rtl::OUString& sStreamPath, ::sal_Int32 nOpenMode )
1321 {
1322     ::osl::MutexGuard aGuard( m_aMutex );
1323 
1324     if ( !m_pImpl )
1325         throw lang::DisposedException();
1326 
1327     if ( sStreamPath.toChar() == '/' )
1328         throw lang::IllegalArgumentException();
1329 
1330     if ( !GetContent() )
1331         throw io::IOException(); // TODO: error handling
1332 
1333     INetURLObject aBaseURL( m_pImpl->m_aURL );
1334     if ( !aBaseURL.setFinalSlash() )
1335         throw uno::RuntimeException();
1336 
1337     INetURLObject aFileURL = INetURLObject::GetAbsURL(
1338                 aBaseURL.GetMainURL( INetURLObject::NO_DECODE ),
1339                 sStreamPath );
1340 
1341     if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1342         throw io::IOException();
1343 
1344     if ( ( nOpenMode & embed::ElementModes::NOCREATE )
1345       && !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1346         throw io::IOException(); // TODO:
1347 
1348     uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
1349     uno::Reference< io::XStream > xResult;
1350     try
1351     {
1352         if ( nOpenMode & embed::ElementModes::WRITE )
1353         {
1354             if ( isLocalFile_Impl( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1355             {
1356                 uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess(
1357                     m_pImpl->m_xFactory->createInstance(
1358                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.SimpleFileAccess" ) ) ),
1359                     uno::UNO_QUERY_THROW );
1360                 uno::Reference< io::XStream > xStream =
1361                     xSimpleFileAccess->openFileReadWrite( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) );
1362 
1363                 xResult = static_cast< io::XStream* >( new OFSStreamContainer( xStream ) );
1364             }
1365             else
1366             {
1367                 // TODO: test whether it really works for http and fwp
1368                 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ),
1369                                                                         STREAM_STD_WRITE );
1370                 if ( pStream )
1371                 {
1372                     if ( !pStream->GetError() )
1373                     {
1374                         uno::Reference< io::XStream > xStream =
1375                             uno::Reference < io::XStream >( new ::utl::OStreamWrapper( *pStream ) );
1376                         xResult = static_cast< io::XStream* >( new OFSStreamContainer( xStream ) );
1377                     }
1378                     else
1379                         delete pStream;
1380                 }
1381             }
1382 
1383             if ( !xResult.is() )
1384                 throw io::IOException();
1385 
1386             if ( ( nOpenMode & embed::ElementModes::TRUNCATE ) )
1387             {
1388                 uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW );
1389                 xTrunc->truncate();
1390             }
1391         }
1392         else
1393         {
1394             if ( ( nOpenMode & embed::ElementModes::TRUNCATE )
1395             || !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1396                 throw io::IOException(); // TODO: access denied
1397 
1398             ::ucbhelper::Content aResultContent( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), xDummyEnv );
1399             uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
1400             xResult = static_cast< io::XStream* >( new OFSInputStreamContainer( xInStream ) );
1401         }
1402     }
1403     catch( embed::InvalidStorageException& )
1404     {
1405         throw;
1406     }
1407     catch( lang::IllegalArgumentException& )
1408     {
1409         throw;
1410     }
1411     catch( packages::WrongPasswordException& )
1412     {
1413         throw;
1414     }
1415     catch( embed::StorageWrappedTargetException& )
1416     {
1417         throw;
1418     }
1419     catch( io::IOException& )
1420     {
1421         throw;
1422     }
1423     catch( uno::RuntimeException& )
1424     {
1425         throw;
1426     }
1427     catch( uno::Exception& )
1428     {
1429         uno::Any aCaught( ::cppu::getCaughtException() );
1430         throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy raw stream" ),
1431                                                  uno::Reference< io::XInputStream >(),
1432                                                  aCaught );
1433     }
1434 
1435     return uno::Reference< embed::XExtendedStorageStream >( xResult, uno::UNO_QUERY_THROW );
1436 }
1437 
1438 //-----------------------------------------------
openEncryptedStreamElementByHierarchicalName(const::rtl::OUString &,::sal_Int32,const::rtl::OUString &)1439 uno::Reference< embed::XExtendedStorageStream > SAL_CALL FSStorage::openEncryptedStreamElementByHierarchicalName( const ::rtl::OUString& /*sStreamName*/, ::sal_Int32 /*nOpenMode*/, const ::rtl::OUString& /*sPassword*/ )
1440 {
1441     throw packages::NoEncryptionException();
1442 }
1443 
1444 //-----------------------------------------------
removeStreamElementByHierarchicalName(const::rtl::OUString & sStreamPath)1445 void SAL_CALL FSStorage::removeStreamElementByHierarchicalName( const ::rtl::OUString& sStreamPath )
1446 {
1447     ::osl::MutexGuard aGuard( m_aMutex );
1448 
1449     if ( !m_pImpl )
1450         throw lang::DisposedException();
1451 
1452     if ( !GetContent() )
1453         throw io::IOException(); // TODO: error handling
1454 
1455     // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
1456     INetURLObject aBaseURL( m_pImpl->m_aURL );
1457     if ( !aBaseURL.setFinalSlash() )
1458         throw uno::RuntimeException();
1459 
1460     INetURLObject aFileURL = INetURLObject::GetAbsURL(
1461                 aBaseURL.GetMainURL( INetURLObject::NO_DECODE ),
1462                 sStreamPath );
1463 
1464     if ( !::utl::UCBContentHelper::IsDocument( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1465     {
1466         if ( ::utl::UCBContentHelper::IsFolder( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1467             throw lang::IllegalArgumentException();
1468         else
1469             throw container::NoSuchElementException(); // TODO:
1470     }
1471 
1472     if ( !::utl::UCBContentHelper::Kill( aFileURL.GetMainURL( INetURLObject::NO_DECODE ) ) )
1473         throw io::IOException(); // TODO: error handling
1474 }
1475