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