1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/beans/PropertyValue.hpp>
21 #include <com/sun/star/embed/ElementModes.hpp>
22 #include <com/sun/star/embed/XTransactedObject.hpp>
23 #include <com/sun/star/ucb/NameClash.hpp>
24 #include <com/sun/star/ucb/UniversalContentBroker.hpp>
25 #include <com/sun/star/ucb/XProgressHandler.hpp>
26 #include <com/sun/star/ucb/XContentAccess.hpp>
27 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
29 #include <com/sun/star/ucb/InteractiveIOException.hpp>
30 #include <com/sun/star/ucb/IOErrorCode.hpp>
31 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
32 #include <com/sun/star/container/XEnumerationAccess.hpp>
33 #include <com/sun/star/container/XNamed.hpp>
34 #include <com/sun/star/util/XChangesBatch.hpp>
35 #include <com/sun/star/util/XCloneable.hpp>
36 #include <com/sun/star/lang/XUnoTunnel.hpp>
37 #include <com/sun/star/lang/XComponent.hpp>
38 #include <com/sun/star/lang/DisposedException.hpp>
39 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
40 #include <com/sun/star/io/IOException.hpp>
41 #include <com/sun/star/io/XTruncate.hpp>
42 #include <com/sun/star/io/TempFile.hpp>
43 #include <com/sun/star/sdbc/XResultSet.hpp>
44 #include <com/sun/star/sdbc/XRow.hpp>
47 #include <comphelper/processfactory.hxx>
48 #include <comphelper/storagehelper.hxx>
49 #include <cppuhelper/queryinterface.hxx>
50 #include <cppuhelper/typeprovider.hxx>
51 #include <cppuhelper/exc_hlp.hxx>
53 #include <tools/urlobj.hxx>
54 #include <unotools/ucbhelper.hxx>
55 #include <unotools/ucbstreamhelper.hxx>
56 #include <unotools/streamwrap.hxx>
57 #include <ucbhelper/fileidentifierconverter.hxx>
58 #include <ucbhelper/content.hxx>
60 #include "fsstorage.hxx"
61 #include "oinputstreamcontainer.hxx"
62 #include "ostreamcontainer.hxx"
64 using namespace ::com::sun::star
;
67 // TODO: move to a standard helper
68 bool isLocalFile_Impl( const OUString
& aURL
)
74 aSystemPath
= ::ucbhelper::getSystemPathFromFileURL(
75 ucb::UniversalContentBroker::create(
76 comphelper::getProcessComponentContext() ),
79 catch ( uno::Exception
& )
83 return ( !aSystemPath
.isEmpty() );
92 ::ucbhelper::Content
* m_pContent
;
95 ::cppu::OInterfaceContainerHelper
* m_pListenersContainer
; // list of listeners
96 ::cppu::OTypeCollection
* m_pTypeCollection
;
98 uno::Reference
< uno::XComponentContext
> m_xContext
;
101 FSStorage_Impl( const ::ucbhelper::Content
& aContent
, sal_Int32 nMode
, uno::Reference
< uno::XComponentContext
> xContext
)
102 : m_aURL( aContent
.getURL() )
103 , m_pContent( new ::ucbhelper::Content( aContent
) )
105 , m_pListenersContainer( NULL
)
106 , m_pTypeCollection( NULL
)
107 , m_xContext( xContext
)
109 OSL_ENSURE( !m_aURL
.isEmpty(), "The URL must not be empty" );
116 FSStorage_Impl::~FSStorage_Impl()
118 if ( m_pListenersContainer
)
119 delete m_pListenersContainer
;
120 if ( m_pTypeCollection
)
121 delete m_pTypeCollection
;
126 FSStorage::FSStorage( const ::ucbhelper::Content
& aContent
,
128 uno::Reference
< uno::XComponentContext
> xContext
)
129 : m_pImpl( new FSStorage_Impl( aContent
, nMode
, xContext
) )
131 // TODO: use properties
132 if ( !xContext
.is() )
133 throw uno::RuntimeException();
138 FSStorage::~FSStorage()
141 ::osl::MutexGuard
aGuard( m_aMutex
);
142 m_refCount
++; // to call dispose
146 catch( uno::RuntimeException
& )
151 bool FSStorage::MakeFolderNoUI( const OUString
& rFolder
)
153 INetURLObject
aURL( rFolder
);
154 OUString aTitle
= aURL
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DECODE_WITH_CHARSET
);
155 aURL
.removeSegment();
156 ::ucbhelper::Content aParent
;
157 ::ucbhelper::Content aResultContent
;
159 if ( ::ucbhelper::Content::create( aURL
.GetMainURL( INetURLObject::NO_DECODE
),
160 uno::Reference
< ucb::XCommandEnvironment
>(),
161 comphelper::getProcessComponentContext(),
163 return ::utl::UCBContentHelper::MakeFolder( aParent
, aTitle
, aResultContent
, false );
168 ::ucbhelper::Content
* FSStorage::GetContent()
170 ::osl::MutexGuard
aGuard( m_aMutex
);
171 if ( !m_pImpl
->m_pContent
)
173 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
177 m_pImpl
->m_pContent
= new ::ucbhelper::Content( m_pImpl
->m_aURL
, xDummyEnv
, comphelper::getProcessComponentContext() );
179 catch( uno::Exception
& )
184 return m_pImpl
->m_pContent
;
187 void FSStorage::CopyStreamToSubStream( const OUString
& aSourceURL
,
188 const uno::Reference
< embed::XStorage
>& xDest
,
189 const OUString
& aNewEntryName
)
192 throw uno::RuntimeException();
194 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
195 ::ucbhelper::Content
aSourceContent( aSourceURL
, xDummyEnv
, comphelper::getProcessComponentContext() );
196 uno::Reference
< io::XInputStream
> xSourceInput
= aSourceContent
.openStream();
198 if ( !xSourceInput
.is() )
199 throw io::IOException(); // TODO: error handling
201 uno::Reference
< io::XStream
> xSubStream
= xDest
->openStreamElement(
203 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
204 if ( !xSubStream
.is() )
205 throw uno::RuntimeException();
207 uno::Reference
< io::XOutputStream
> xDestOutput
= xSubStream
->getOutputStream();
208 if ( !xDestOutput
.is() )
209 throw uno::RuntimeException();
211 ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInput
, xDestOutput
);
212 xDestOutput
->closeOutput();
215 void FSStorage::CopyContentToStorage_Impl( ::ucbhelper::Content
* pContent
, const uno::Reference
< embed::XStorage
>& xDest
)
218 throw uno::RuntimeException();
220 // get list of contents of the Content
221 // create cursor for access to children
222 uno::Sequence
< OUString
> aProps( 2 );
223 OUString
* pProps
= aProps
.getArray();
224 pProps
[0] = "TargetURL";
225 pProps
[1] = "IsFolder";
226 ::ucbhelper::ResultSetInclude eInclude
= ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
;
230 uno::Reference
< sdbc::XResultSet
> xResultSet
= pContent
->createCursor( aProps
, eInclude
);
231 uno::Reference
< ucb::XContentAccess
> xContentAccess( xResultSet
, uno::UNO_QUERY
);
232 uno::Reference
< sdbc::XRow
> xRow( xResultSet
, uno::UNO_QUERY
);
233 if ( xResultSet
.is() )
235 // go through the list: insert files as streams, insert folders as substorages using recursion
236 while ( xResultSet
->next() )
238 OUString
aSourceURL( xRow
->getString( 1 ) );
239 bool bIsFolder( xRow
->getBoolean(2) );
241 // TODO/LATER: not sure whether the entry name must be encoded
242 OUString
aNewEntryName( INetURLObject( aSourceURL
).getName( INetURLObject::LAST_SEGMENT
,
244 INetURLObject::NO_DECODE
) );
247 uno::Reference
< embed::XStorage
> xSubStorage
= xDest
->openStorageElement( aNewEntryName
,
248 embed::ElementModes::READWRITE
);
249 if ( !xSubStorage
.is() )
250 throw uno::RuntimeException();
252 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
253 ::ucbhelper::Content
aSourceContent( aSourceURL
, xDummyEnv
, comphelper::getProcessComponentContext() );
254 CopyContentToStorage_Impl( &aSourceContent
, xSubStorage
);
258 CopyStreamToSubStream( aSourceURL
, xDest
, aNewEntryName
);
263 uno::Reference
< embed::XTransactedObject
> xTransact( xDest
, uno::UNO_QUERY
);
264 if ( xTransact
.is() )
267 catch( ucb::InteractiveIOException
& r
)
269 if ( r
.Code
== ucb::IOErrorCode_NOT_EXISTING
)
270 OSL_FAIL( "The folder does not exist!\n" );
278 uno::Any SAL_CALL
FSStorage::queryInterface( const uno::Type
& rType
)
279 throw( uno::RuntimeException
, std::exception
)
282 aReturn
<<= ::cppu::queryInterface
284 , static_cast<lang::XTypeProvider
*> ( this )
285 , static_cast<embed::XStorage
*> ( this )
286 , static_cast<embed::XHierarchicalStorageAccess
*> ( this )
287 , static_cast<container::XNameAccess
*> ( this )
288 , static_cast<container::XElementAccess
*> ( this )
289 , static_cast<lang::XComponent
*> ( this )
290 , static_cast<beans::XPropertySet
*> ( this ) );
292 if ( aReturn
.hasValue() )
295 return OWeakObject::queryInterface( rType
);
298 void SAL_CALL
FSStorage::acquire() throw()
300 OWeakObject::acquire();
303 void SAL_CALL
FSStorage::release() throw()
305 OWeakObject::release();
310 uno::Sequence
< uno::Type
> SAL_CALL
FSStorage::getTypes()
311 throw( uno::RuntimeException
, std::exception
)
313 if ( m_pImpl
->m_pTypeCollection
== NULL
)
315 ::osl::MutexGuard
aGuard( m_aMutex
);
317 if ( m_pImpl
->m_pTypeCollection
== NULL
)
319 m_pImpl
->m_pTypeCollection
= new ::cppu::OTypeCollection
320 ( cppu::UnoType
<lang::XTypeProvider
>::get()
321 , cppu::UnoType
<embed::XStorage
>::get()
322 , cppu::UnoType
<embed::XHierarchicalStorageAccess
>::get()
323 , cppu::UnoType
<beans::XPropertySet
>::get());
327 return m_pImpl
->m_pTypeCollection
->getTypes() ;
330 uno::Sequence
< sal_Int8
> SAL_CALL
FSStorage::getImplementationId()
331 throw( uno::RuntimeException
, std::exception
)
333 return css::uno::Sequence
<sal_Int8
>();
338 void SAL_CALL
FSStorage::copyToStorage( const uno::Reference
< embed::XStorage
>& xDest
)
339 throw ( embed::InvalidStorageException
,
341 lang::IllegalArgumentException
,
342 embed::StorageWrappedTargetException
,
343 uno::RuntimeException
, std::exception
)
345 ::osl::MutexGuard
aGuard( m_aMutex
);
348 throw lang::DisposedException();
350 if ( !xDest
.is() || xDest
== uno::Reference
< uno::XInterface
>( static_cast< OWeakObject
*> ( this ), uno::UNO_QUERY
) )
351 throw lang::IllegalArgumentException(); // TODO:
354 throw io::IOException(); // TODO: error handling
358 CopyContentToStorage_Impl( GetContent(), xDest
);
360 catch( embed::InvalidStorageException
& )
364 catch( lang::IllegalArgumentException
& )
368 catch( embed::StorageWrappedTargetException
& )
372 catch( io::IOException
& )
376 catch( uno::RuntimeException
& )
380 catch( uno::Exception
& )
382 uno::Any
aCaught( ::cppu::getCaughtException() );
383 throw embed::StorageWrappedTargetException("Can't copy raw stream",
384 uno::Reference
< io::XInputStream
>(),
389 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::openStreamElement(
390 const OUString
& aStreamName
, sal_Int32 nOpenMode
)
391 throw ( embed::InvalidStorageException
,
392 lang::IllegalArgumentException
,
393 packages::WrongPasswordException
,
395 embed::StorageWrappedTargetException
,
396 uno::RuntimeException
, std::exception
)
398 ::osl::MutexGuard
aGuard( m_aMutex
);
401 throw lang::DisposedException();
404 throw io::IOException(); // TODO: error handling
406 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
407 INetURLObject
aFileURL( m_pImpl
->m_aURL
);
408 aFileURL
.Append( aStreamName
);
410 if ( ::utl::UCBContentHelper::IsFolder( aFileURL
.GetMainURL( INetURLObject::NO_DECODE
) ) )
411 throw io::IOException();
413 if ( ( nOpenMode
& embed::ElementModes::NOCREATE
)
414 && !::utl::UCBContentHelper::IsDocument( aFileURL
.GetMainURL( INetURLObject::NO_DECODE
) ) )
415 throw io::IOException(); // TODO:
417 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
; // TODO: provide InteractionHandler if any
418 uno::Reference
< io::XStream
> xResult
;
421 if ( nOpenMode
& embed::ElementModes::WRITE
)
423 if ( isLocalFile_Impl( aFileURL
.GetMainURL( INetURLObject::NO_DECODE
) ) )
425 uno::Reference
<ucb::XSimpleFileAccess3
> xSimpleFileAccess(
426 ucb::SimpleFileAccess::create( m_pImpl
->m_xContext
) );
427 xResult
= xSimpleFileAccess
->openFileReadWrite( aFileURL
.GetMainURL( INetURLObject::NO_DECODE
) );
431 // TODO: test whether it really works for http and fwp
432 SvStream
* pStream
= ::utl::UcbStreamHelper::CreateStream( aFileURL
.GetMainURL( INetURLObject::NO_DECODE
),
436 if ( !pStream
->GetError() )
437 xResult
= uno::Reference
< io::XStream
>( new ::utl::OStreamWrapper( *pStream
) );
444 throw io::IOException();
446 if ( ( nOpenMode
& embed::ElementModes::TRUNCATE
) )
448 uno::Reference
< io::XTruncate
> xTrunc( xResult
->getOutputStream(), uno::UNO_QUERY_THROW
);
454 if ( ( nOpenMode
& embed::ElementModes::TRUNCATE
)
455 || !::utl::UCBContentHelper::IsDocument( aFileURL
.GetMainURL( INetURLObject::NO_DECODE
) ) )
456 throw io::IOException(); // TODO: access denied
458 ::ucbhelper::Content
aResultContent( aFileURL
.GetMainURL( INetURLObject::NO_DECODE
), xDummyEnv
, comphelper::getProcessComponentContext() );
459 uno::Reference
< io::XInputStream
> xInStream
= aResultContent
.openStream();
460 xResult
= static_cast< io::XStream
* >( new OFSInputStreamContainer( xInStream
) );
463 catch( embed::InvalidStorageException
& )
467 catch( lang::IllegalArgumentException
& )
471 catch( packages::WrongPasswordException
& )
475 catch( embed::StorageWrappedTargetException
& )
479 catch( io::IOException
& )
483 catch( uno::RuntimeException
& )
487 catch( uno::Exception
& )
489 uno::Any
aCaught( ::cppu::getCaughtException() );
490 throw embed::StorageWrappedTargetException("Can't copy raw stream",
491 uno::Reference
< io::XInputStream
>(),
498 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::openEncryptedStreamElement(
499 const OUString
&, sal_Int32
, const OUString
& )
500 throw ( embed::InvalidStorageException
,
501 lang::IllegalArgumentException
,
502 packages::NoEncryptionException
,
503 packages::WrongPasswordException
,
505 embed::StorageWrappedTargetException
,
506 uno::RuntimeException
, std::exception
)
508 throw packages::NoEncryptionException();
511 uno::Reference
< embed::XStorage
> SAL_CALL
FSStorage::openStorageElement(
512 const OUString
& aStorName
, sal_Int32 nStorageMode
)
513 throw ( embed::InvalidStorageException
,
514 lang::IllegalArgumentException
,
516 embed::StorageWrappedTargetException
,
517 uno::RuntimeException
, std::exception
)
519 ::osl::MutexGuard
aGuard( m_aMutex
);
522 throw lang::DisposedException();
525 throw io::IOException(); // TODO: error handling
527 if ( ( nStorageMode
& embed::ElementModes::WRITE
)
528 && !( m_pImpl
->m_nMode
& embed::ElementModes::WRITE
) )
529 throw io::IOException(); // TODO: error handling
531 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
532 INetURLObject
aFolderURL( m_pImpl
->m_aURL
);
533 aFolderURL
.Append( aStorName
);
535 bool bFolderExists
= ::utl::UCBContentHelper::IsFolder( aFolderURL
.GetMainURL( INetURLObject::NO_DECODE
) );
536 if ( !bFolderExists
&& ::utl::UCBContentHelper::IsDocument( aFolderURL
.GetMainURL( INetURLObject::NO_DECODE
) ) )
537 throw io::IOException(); // TODO:
539 if ( ( nStorageMode
& embed::ElementModes::NOCREATE
) && !bFolderExists
)
540 throw io::IOException(); // TODO:
542 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
; // TODO: provide InteractionHandler if any
543 uno::Reference
< embed::XStorage
> xResult
;
546 if ( nStorageMode
& embed::ElementModes::WRITE
)
548 if ( ( nStorageMode
& embed::ElementModes::TRUNCATE
) && bFolderExists
)
550 ::utl::UCBContentHelper::Kill( aFolderURL
.GetMainURL( INetURLObject::NO_DECODE
) );
552 MakeFolderNoUI( aFolderURL
.GetMainURL( INetURLObject::NO_DECODE
) ); // TODO: not atomic :(
554 else if ( !bFolderExists
)
557 MakeFolderNoUI( aFolderURL
.GetMainURL( INetURLObject::NO_DECODE
) ); // TODO: not atomic :(
560 else if ( ( nStorageMode
& embed::ElementModes::TRUNCATE
) )
561 throw io::IOException(); // TODO: access denied
563 if ( !bFolderExists
)
564 throw io::IOException(); // there is no such folder
566 ::ucbhelper::Content
aResultContent( aFolderURL
.GetMainURL( INetURLObject::NO_DECODE
), xDummyEnv
, comphelper::getProcessComponentContext() );
567 xResult
= uno::Reference
< embed::XStorage
>(
568 static_cast< OWeakObject
* >( new FSStorage( aResultContent
,
570 m_pImpl
->m_xContext
) ),
573 catch( embed::InvalidStorageException
& )
577 catch( lang::IllegalArgumentException
& )
581 catch( embed::StorageWrappedTargetException
& )
585 catch( io::IOException
& )
589 catch( uno::RuntimeException
& )
593 catch( uno::Exception
& )
595 uno::Any
aCaught( ::cppu::getCaughtException() );
596 throw embed::StorageWrappedTargetException("Can't copy raw stream",
597 uno::Reference
< io::XInputStream
>(),
604 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::cloneStreamElement( const OUString
& aStreamName
)
605 throw ( embed::InvalidStorageException
,
606 lang::IllegalArgumentException
,
607 packages::WrongPasswordException
,
609 embed::StorageWrappedTargetException
,
610 uno::RuntimeException
, std::exception
)
612 ::osl::MutexGuard
aGuard( m_aMutex
);
615 throw lang::DisposedException();
618 throw io::IOException(); // TODO: error handling
620 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
621 INetURLObject
aFileURL( m_pImpl
->m_aURL
);
622 aFileURL
.Append( aStreamName
);
624 uno::Reference
< io::XStream
> xTempResult
;
627 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
628 ::ucbhelper::Content
aResultContent( aFileURL
.GetMainURL( INetURLObject::NO_DECODE
), xDummyEnv
, comphelper::getProcessComponentContext() );
629 uno::Reference
< io::XInputStream
> xInStream
= aResultContent
.openStream();
631 xTempResult
= io::TempFile::create(m_pImpl
->m_xContext
);
632 uno::Reference
< io::XOutputStream
> xTempOut
= xTempResult
->getOutputStream();
633 uno::Reference
< io::XInputStream
> xTempIn
= xTempResult
->getInputStream();
635 if ( !xTempOut
.is() || !xTempIn
.is() )
636 throw io::IOException();
638 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream
, xTempOut
);
639 xTempOut
->closeOutput();
641 catch( embed::InvalidStorageException
& )
645 catch( lang::IllegalArgumentException
& )
649 catch( packages::WrongPasswordException
& )
653 catch( io::IOException
& )
657 catch( embed::StorageWrappedTargetException
& )
661 catch( uno::RuntimeException
& )
665 catch( uno::Exception
& )
667 uno::Any
aCaught( ::cppu::getCaughtException() );
668 throw embed::StorageWrappedTargetException("Can't copy raw stream",
669 uno::Reference
< io::XInputStream
>(),
676 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::cloneEncryptedStreamElement(
679 throw ( embed::InvalidStorageException
,
680 lang::IllegalArgumentException
,
681 packages::NoEncryptionException
,
682 packages::WrongPasswordException
,
684 embed::StorageWrappedTargetException
,
685 uno::RuntimeException
, std::exception
)
687 throw packages::NoEncryptionException();
690 void SAL_CALL
FSStorage::copyLastCommitTo(
691 const uno::Reference
< embed::XStorage
>& xTargetStorage
)
692 throw ( embed::InvalidStorageException
,
693 lang::IllegalArgumentException
,
695 embed::StorageWrappedTargetException
,
696 uno::RuntimeException
, std::exception
)
698 copyToStorage( xTargetStorage
);
701 void SAL_CALL
FSStorage::copyStorageElementLastCommitTo(
702 const OUString
& aStorName
,
703 const uno::Reference
< embed::XStorage
>& xTargetStorage
)
704 throw ( embed::InvalidStorageException
,
705 lang::IllegalArgumentException
,
707 embed::StorageWrappedTargetException
,
708 uno::RuntimeException
, std::exception
)
710 ::osl::MutexGuard
aGuard( m_aMutex
);
713 throw lang::DisposedException();
715 uno::Reference
< embed::XStorage
> xSourceStor( openStorageElement( aStorName
, embed::ElementModes::READ
),
716 uno::UNO_QUERY_THROW
);
717 xSourceStor
->copyToStorage( xTargetStorage
);
720 sal_Bool SAL_CALL
FSStorage::isStreamElement( const OUString
& aElementName
)
721 throw ( embed::InvalidStorageException
,
722 lang::IllegalArgumentException
,
723 container::NoSuchElementException
,
724 uno::RuntimeException
, std::exception
)
726 ::osl::MutexGuard
aGuard( m_aMutex
);
729 throw lang::DisposedException();
732 throw embed::InvalidStorageException(); // TODO: error handling
734 INetURLObject
aURL( m_pImpl
->m_aURL
);
735 aURL
.Append( aElementName
);
737 return !::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::NO_DECODE
) );
740 sal_Bool SAL_CALL
FSStorage::isStorageElement( const OUString
& aElementName
)
741 throw ( embed::InvalidStorageException
,
742 lang::IllegalArgumentException
,
743 container::NoSuchElementException
,
744 uno::RuntimeException
, std::exception
)
746 ::osl::MutexGuard
aGuard( m_aMutex
);
749 throw lang::DisposedException();
752 throw embed::InvalidStorageException(); // TODO: error handling
754 INetURLObject
aURL( m_pImpl
->m_aURL
);
755 aURL
.Append( aElementName
);
757 return ::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::NO_DECODE
) );
760 void SAL_CALL
FSStorage::removeElement( const OUString
& aElementName
)
761 throw ( embed::InvalidStorageException
,
762 lang::IllegalArgumentException
,
763 container::NoSuchElementException
,
765 embed::StorageWrappedTargetException
,
766 uno::RuntimeException
, std::exception
)
768 ::osl::MutexGuard
aGuard( m_aMutex
);
771 throw lang::DisposedException();
774 throw io::IOException(); // TODO: error handling
776 INetURLObject
aURL( m_pImpl
->m_aURL
);
777 aURL
.Append( aElementName
);
779 if ( !::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::NO_DECODE
) )
780 && !::utl::UCBContentHelper::IsDocument( aURL
.GetMainURL( INetURLObject::NO_DECODE
) ) )
781 throw container::NoSuchElementException(); // TODO:
783 ::utl::UCBContentHelper::Kill( aURL
.GetMainURL( INetURLObject::NO_DECODE
) );
786 void SAL_CALL
FSStorage::renameElement( const OUString
& aElementName
, const OUString
& aNewName
)
787 throw ( embed::InvalidStorageException
,
788 lang::IllegalArgumentException
,
789 container::NoSuchElementException
,
790 container::ElementExistException
,
792 embed::StorageWrappedTargetException
,
793 uno::RuntimeException
, std::exception
)
795 ::osl::MutexGuard
aGuard( m_aMutex
);
798 throw lang::DisposedException();
801 throw io::IOException(); // TODO: error handling
803 INetURLObject
aOldURL( m_pImpl
->m_aURL
);
804 aOldURL
.Append( aElementName
);
806 INetURLObject
aNewURL( m_pImpl
->m_aURL
);
807 aNewURL
.Append( aNewName
);
809 if ( !::utl::UCBContentHelper::IsFolder( aOldURL
.GetMainURL( INetURLObject::NO_DECODE
) )
810 && !::utl::UCBContentHelper::IsDocument( aOldURL
.GetMainURL( INetURLObject::NO_DECODE
) ) )
811 throw container::NoSuchElementException(); // TODO:
813 if ( ::utl::UCBContentHelper::IsFolder( aNewURL
.GetMainURL( INetURLObject::NO_DECODE
) )
814 || ::utl::UCBContentHelper::IsDocument( aNewURL
.GetMainURL( INetURLObject::NO_DECODE
) ) )
815 throw container::ElementExistException(); // TODO:
819 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
820 ::ucbhelper::Content
aSourceContent( aOldURL
.GetMainURL( INetURLObject::NO_DECODE
), xDummyEnv
, comphelper::getProcessComponentContext() );
822 if ( !GetContent()->transferContent( aSourceContent
,
823 ::ucbhelper::InsertOperation_MOVE
,
825 ucb::NameClash::ERROR
) )
826 throw io::IOException(); // TODO: error handling
828 catch( embed::InvalidStorageException
& )
832 catch( lang::IllegalArgumentException
& )
836 catch( container::NoSuchElementException
& )
840 catch( container::ElementExistException
& )
844 catch( io::IOException
& )
848 catch( embed::StorageWrappedTargetException
& )
852 catch( uno::RuntimeException
& )
856 catch( uno::Exception
& )
858 uno::Any
aCaught( ::cppu::getCaughtException() );
859 throw embed::StorageWrappedTargetException("Can't copy raw stream",
860 uno::Reference
< io::XInputStream
>(),
865 void SAL_CALL
FSStorage::copyElementTo( const OUString
& aElementName
,
866 const uno::Reference
< embed::XStorage
>& xDest
,
867 const OUString
& aNewName
)
868 throw ( embed::InvalidStorageException
,
869 lang::IllegalArgumentException
,
870 container::NoSuchElementException
,
871 container::ElementExistException
,
873 embed::StorageWrappedTargetException
,
874 uno::RuntimeException
, std::exception
)
876 ::osl::MutexGuard
aGuard( m_aMutex
);
879 throw lang::DisposedException();
882 throw uno::RuntimeException();
885 throw io::IOException(); // TODO: error handling
887 INetURLObject
aOwnURL( m_pImpl
->m_aURL
);
888 aOwnURL
.Append( aElementName
);
890 if ( xDest
->hasByName( aNewName
) )
891 throw container::ElementExistException(); // TODO:
895 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
896 if ( ::utl::UCBContentHelper::IsFolder( aOwnURL
.GetMainURL( INetURLObject::NO_DECODE
) ) )
898 ::ucbhelper::Content
aSourceContent( aOwnURL
.GetMainURL( INetURLObject::NO_DECODE
), xDummyEnv
, comphelper::getProcessComponentContext() );
899 uno::Reference
< embed::XStorage
> xDestSubStor(
900 xDest
->openStorageElement( aNewName
, embed::ElementModes::READWRITE
),
901 uno::UNO_QUERY_THROW
);
903 CopyContentToStorage_Impl( &aSourceContent
, xDestSubStor
);
905 else if ( ::utl::UCBContentHelper::IsDocument( aOwnURL
.GetMainURL( INetURLObject::NO_DECODE
) ) )
907 CopyStreamToSubStream( aOwnURL
.GetMainURL( INetURLObject::NO_DECODE
), xDest
, aNewName
);
910 throw container::NoSuchElementException(); // TODO:
912 catch( embed::InvalidStorageException
& )
916 catch( lang::IllegalArgumentException
& )
920 catch( container::NoSuchElementException
& )
924 catch( container::ElementExistException
& )
928 catch( embed::StorageWrappedTargetException
& )
932 catch( io::IOException
& )
936 catch( uno::RuntimeException
& )
940 catch( uno::Exception
& )
942 uno::Any
aCaught( ::cppu::getCaughtException() );
943 throw embed::StorageWrappedTargetException("Can't copy raw stream",
944 uno::Reference
< io::XInputStream
>(),
949 void SAL_CALL
FSStorage::moveElementTo( const OUString
& aElementName
,
950 const uno::Reference
< embed::XStorage
>& xDest
,
951 const OUString
& aNewName
)
952 throw ( embed::InvalidStorageException
,
953 lang::IllegalArgumentException
,
954 container::NoSuchElementException
,
955 container::ElementExistException
,
957 embed::StorageWrappedTargetException
,
958 uno::RuntimeException
, std::exception
)
960 ::osl::MutexGuard
aGuard( m_aMutex
);
961 copyElementTo( aElementName
, xDest
, aNewName
);
963 INetURLObject
aOwnURL( m_pImpl
->m_aURL
);
964 aOwnURL
.Append( aElementName
);
965 if ( !::utl::UCBContentHelper::Kill( aOwnURL
.GetMainURL( INetURLObject::NO_DECODE
) ) )
966 throw io::IOException(); // TODO: error handling
971 uno::Any SAL_CALL
FSStorage::getByName( const OUString
& aName
)
972 throw ( container::NoSuchElementException
,
973 lang::WrappedTargetException
,
974 uno::RuntimeException
, std::exception
)
976 ::osl::MutexGuard
aGuard( m_aMutex
);
979 throw lang::DisposedException();
981 if ( aName
.isEmpty() )
982 throw lang::IllegalArgumentException();
988 throw io::IOException(); // TODO: error handling
990 INetURLObject
aURL( m_pImpl
->m_aURL
);
991 aURL
.Append( aName
);
994 if ( ::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::NO_DECODE
) ) )
996 aResult
<<= openStorageElement( aName
, embed::ElementModes::READ
);
998 else if ( ::utl::UCBContentHelper::IsDocument( aURL
.GetMainURL( INetURLObject::NO_DECODE
) ) )
1000 aResult
<<= openStreamElement( aName
, embed::ElementModes::READ
);
1003 throw container::NoSuchElementException(); // TODO:
1005 catch (const container::NoSuchElementException
&)
1009 catch (const lang::WrappedTargetException
&)
1013 catch (const uno::RuntimeException
&)
1017 catch (const uno::Exception
&)
1019 uno::Any
aCaught( ::cppu::getCaughtException() );
1020 throw lang::WrappedTargetException( "Can not open element!",
1021 static_cast< OWeakObject
* >( this ),
1029 uno::Sequence
< OUString
> SAL_CALL
FSStorage::getElementNames()
1030 throw ( uno::RuntimeException
, std::exception
)
1032 ::osl::MutexGuard
aGuard( m_aMutex
);
1035 throw lang::DisposedException();
1037 uno::Sequence
< OUString
> aResult
;
1041 if ( !GetContent() )
1042 throw io::IOException(); // TODO: error handling
1044 uno::Sequence
< OUString
> aProps( 1 );
1045 aProps
[0] = "Title";
1046 ::ucbhelper::ResultSetInclude eInclude
= ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
;
1048 sal_Int32 nSize
= 0;
1049 uno::Reference
< sdbc::XResultSet
> xResultSet
= GetContent()->createCursor( aProps
, eInclude
);
1050 uno::Reference
< ucb::XContentAccess
> xContentAccess( xResultSet
, uno::UNO_QUERY
);
1051 uno::Reference
< sdbc::XRow
> xRow( xResultSet
, uno::UNO_QUERY
);
1052 if ( xResultSet
.is() )
1054 // go through the list
1055 while ( xResultSet
->next() )
1057 OUString
aName( xRow
->getString( 1 ) );
1058 aResult
.realloc( ++nSize
);
1059 aResult
[nSize
-1] = aName
;
1063 catch( const ucb::InteractiveIOException
& r
)
1065 if ( r
.Code
== ucb::IOErrorCode_NOT_EXISTING
)
1066 OSL_FAIL( "The folder does not exist!\n" );
1069 uno::Any
aCaught( ::cppu::getCaughtException() );
1070 throw lang::WrappedTargetRuntimeException( "Can not open storage!",
1071 static_cast< OWeakObject
* >( this ),
1075 catch (const uno::RuntimeException
&)
1079 catch (const uno::Exception
&)
1081 uno::Any
aCaught( ::cppu::getCaughtException() );
1082 throw lang::WrappedTargetRuntimeException( "Can not open storage!",
1083 static_cast< OWeakObject
* >( this ),
1090 sal_Bool SAL_CALL
FSStorage::hasByName( const OUString
& aName
)
1091 throw ( uno::RuntimeException
, std::exception
)
1093 ::osl::MutexGuard
aGuard( m_aMutex
);
1096 throw lang::DisposedException();
1100 if ( !GetContent() )
1101 throw io::IOException(); // TODO: error handling
1103 if ( aName
.isEmpty() )
1104 throw lang::IllegalArgumentException();
1106 catch( uno::RuntimeException
& )
1110 catch ( uno::Exception
& )
1112 uno::Any
aCaught( ::cppu::getCaughtException() );
1113 throw lang::WrappedTargetRuntimeException( "Can not open storage!",
1114 static_cast< OWeakObject
* >( this ),
1118 INetURLObject
aURL( m_pImpl
->m_aURL
);
1119 aURL
.Append( aName
);
1121 return ( ::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::NO_DECODE
) )
1122 || ::utl::UCBContentHelper::IsDocument( aURL
.GetMainURL( INetURLObject::NO_DECODE
) ) );
1125 uno::Type SAL_CALL
FSStorage::getElementType()
1126 throw ( uno::RuntimeException
, std::exception
)
1128 ::osl::MutexGuard
aGuard( m_aMutex
);
1131 throw lang::DisposedException();
1133 // it is a multitype container
1137 sal_Bool SAL_CALL
FSStorage::hasElements()
1138 throw ( uno::RuntimeException
, std::exception
)
1140 ::osl::MutexGuard
aGuard( m_aMutex
);
1143 throw lang::DisposedException();
1147 if ( !GetContent() )
1148 throw io::IOException(); // TODO: error handling
1150 uno::Sequence
< OUString
> aProps( 1 );
1151 aProps
[0] = "TargetURL";
1152 ::ucbhelper::ResultSetInclude eInclude
= ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
;
1154 uno::Reference
< sdbc::XResultSet
> xResultSet
= GetContent()->createCursor( aProps
, eInclude
);
1155 return ( xResultSet
.is() && xResultSet
->next() );
1157 catch (const uno::RuntimeException
&)
1161 catch (const uno::Exception
&)
1163 throw uno::RuntimeException();
1168 void SAL_CALL
FSStorage::dispose()
1169 throw ( uno::RuntimeException
, std::exception
)
1171 ::osl::MutexGuard
aGuard( m_aMutex
);
1174 throw lang::DisposedException();
1176 if ( m_pImpl
->m_pListenersContainer
)
1178 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
1179 m_pImpl
->m_pListenersContainer
->disposeAndClear( aSource
);
1186 void SAL_CALL
FSStorage::addEventListener(
1187 const uno::Reference
< lang::XEventListener
>& xListener
)
1188 throw ( uno::RuntimeException
, std::exception
)
1190 ::osl::MutexGuard
aGuard( m_aMutex
);
1193 throw lang::DisposedException();
1195 if ( !m_pImpl
->m_pListenersContainer
)
1196 m_pImpl
->m_pListenersContainer
= new ::cppu::OInterfaceContainerHelper( m_aMutex
);
1198 m_pImpl
->m_pListenersContainer
->addInterface( xListener
);
1201 void SAL_CALL
FSStorage::removeEventListener(
1202 const uno::Reference
< lang::XEventListener
>& xListener
)
1203 throw ( uno::RuntimeException
, std::exception
)
1205 ::osl::MutexGuard
aGuard( m_aMutex
);
1208 throw lang::DisposedException();
1210 if ( m_pImpl
->m_pListenersContainer
)
1211 m_pImpl
->m_pListenersContainer
->removeInterface( xListener
);
1216 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
FSStorage::getPropertySetInfo()
1217 throw ( uno::RuntimeException
, std::exception
)
1219 ::osl::MutexGuard
aGuard( m_aMutex
);
1222 throw lang::DisposedException();
1225 return uno::Reference
< beans::XPropertySetInfo
>();
1229 void SAL_CALL
FSStorage::setPropertyValue( const OUString
& aPropertyName
, const uno::Any
& )
1230 throw ( beans::UnknownPropertyException
,
1231 beans::PropertyVetoException
,
1232 lang::IllegalArgumentException
,
1233 lang::WrappedTargetException
,
1234 uno::RuntimeException
, std::exception
)
1236 ::osl::MutexGuard
aGuard( m_aMutex
);
1239 throw lang::DisposedException();
1241 if ( aPropertyName
== "URL" || aPropertyName
== "OpenMode" )
1242 throw beans::PropertyVetoException(); // TODO
1244 throw beans::UnknownPropertyException(); // TODO
1248 uno::Any SAL_CALL
FSStorage::getPropertyValue( const OUString
& aPropertyName
)
1249 throw ( beans::UnknownPropertyException
,
1250 lang::WrappedTargetException
,
1251 uno::RuntimeException
, std::exception
)
1253 ::osl::MutexGuard
aGuard( m_aMutex
);
1256 throw lang::DisposedException();
1258 if ( aPropertyName
== "URL" )
1259 return uno::makeAny( m_pImpl
->m_aURL
);
1260 else if ( aPropertyName
== "OpenMode" )
1261 return uno::makeAny( m_pImpl
->m_nMode
);
1263 throw beans::UnknownPropertyException(); // TODO
1267 void SAL_CALL
FSStorage::addPropertyChangeListener(
1268 const OUString
& /*aPropertyName*/,
1269 const uno::Reference
< beans::XPropertyChangeListener
>& /*xListener*/ )
1270 throw ( beans::UnknownPropertyException
,
1271 lang::WrappedTargetException
,
1272 uno::RuntimeException
, std::exception
)
1274 ::osl::MutexGuard
aGuard( m_aMutex
);
1277 throw lang::DisposedException();
1283 void SAL_CALL
FSStorage::removePropertyChangeListener(
1284 const OUString
& /*aPropertyName*/,
1285 const uno::Reference
< beans::XPropertyChangeListener
>& /*aListener*/ )
1286 throw ( beans::UnknownPropertyException
,
1287 lang::WrappedTargetException
,
1288 uno::RuntimeException
, std::exception
)
1290 ::osl::MutexGuard
aGuard( m_aMutex
);
1293 throw lang::DisposedException();
1299 void SAL_CALL
FSStorage::addVetoableChangeListener(
1300 const OUString
& /*PropertyName*/,
1301 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
1302 throw ( beans::UnknownPropertyException
,
1303 lang::WrappedTargetException
,
1304 uno::RuntimeException
, std::exception
)
1306 ::osl::MutexGuard
aGuard( m_aMutex
);
1309 throw lang::DisposedException();
1315 void SAL_CALL
FSStorage::removeVetoableChangeListener(
1316 const OUString
& /*PropertyName*/,
1317 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
1318 throw ( beans::UnknownPropertyException
,
1319 lang::WrappedTargetException
,
1320 uno::RuntimeException
, std::exception
)
1322 ::osl::MutexGuard
aGuard( m_aMutex
);
1325 throw lang::DisposedException();
1330 // XHierarchicalStorageAccess
1331 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
FSStorage::openStreamElementByHierarchicalName( const OUString
& sStreamPath
, ::sal_Int32 nOpenMode
)
1332 throw ( embed::InvalidStorageException
,
1333 lang::IllegalArgumentException
,
1334 packages::WrongPasswordException
,
1336 embed::StorageWrappedTargetException
,
1337 uno::RuntimeException
, std::exception
)
1339 ::osl::MutexGuard
aGuard( m_aMutex
);
1342 throw lang::DisposedException();
1344 if ( sStreamPath
.toChar() == '/' )
1345 throw lang::IllegalArgumentException();
1347 if ( !GetContent() )
1348 throw io::IOException(); // TODO: error handling
1350 INetURLObject
aBaseURL( m_pImpl
->m_aURL
);
1351 if ( !aBaseURL
.setFinalSlash() )
1352 throw uno::RuntimeException();
1354 OUString aFileURL
= INetURLObject::GetAbsURL(
1355 aBaseURL
.GetMainURL( INetURLObject::NO_DECODE
),
1358 if ( ::utl::UCBContentHelper::IsFolder( aFileURL
) )
1359 throw io::IOException();
1361 if ( ( nOpenMode
& embed::ElementModes::NOCREATE
)
1362 && !::utl::UCBContentHelper::IsDocument( aFileURL
) )
1363 throw io::IOException(); // TODO:
1365 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
; // TODO: provide InteractionHandler if any
1366 uno::Reference
< io::XStream
> xResult
;
1369 if ( nOpenMode
& embed::ElementModes::WRITE
)
1371 if ( isLocalFile_Impl( aFileURL
) )
1373 uno::Reference
<ucb::XSimpleFileAccess3
> xSimpleFileAccess(
1374 ucb::SimpleFileAccess::create( m_pImpl
->m_xContext
) );
1375 uno::Reference
< io::XStream
> xStream
=
1376 xSimpleFileAccess
->openFileReadWrite( aFileURL
);
1378 xResult
= static_cast< io::XStream
* >( new OFSStreamContainer( xStream
) );
1382 // TODO: test whether it really works for http and fwp
1383 SvStream
* pStream
= ::utl::UcbStreamHelper::CreateStream( aFileURL
,
1387 if ( !pStream
->GetError() )
1389 uno::Reference
< io::XStream
> xStream
=
1390 uno::Reference
< io::XStream
>( new ::utl::OStreamWrapper( *pStream
) );
1391 xResult
= static_cast< io::XStream
* >( new OFSStreamContainer( xStream
) );
1398 if ( !xResult
.is() )
1399 throw io::IOException();
1401 if ( ( nOpenMode
& embed::ElementModes::TRUNCATE
) )
1403 uno::Reference
< io::XTruncate
> xTrunc( xResult
->getOutputStream(), uno::UNO_QUERY_THROW
);
1409 if ( ( nOpenMode
& embed::ElementModes::TRUNCATE
)
1410 || !::utl::UCBContentHelper::IsDocument( aFileURL
) )
1411 throw io::IOException(); // TODO: access denied
1413 ::ucbhelper::Content
aResultContent( aFileURL
, xDummyEnv
, comphelper::getProcessComponentContext() );
1414 uno::Reference
< io::XInputStream
> xInStream
= aResultContent
.openStream();
1415 xResult
= static_cast< io::XStream
* >( new OFSInputStreamContainer( xInStream
) );
1418 catch( embed::InvalidStorageException
& )
1422 catch( lang::IllegalArgumentException
& )
1426 catch( packages::WrongPasswordException
& )
1430 catch( embed::StorageWrappedTargetException
& )
1434 catch( io::IOException
& )
1438 catch( uno::RuntimeException
& )
1442 catch( uno::Exception
& )
1444 uno::Any
aCaught( ::cppu::getCaughtException() );
1445 throw embed::StorageWrappedTargetException("Can't copy raw stream",
1446 uno::Reference
< io::XInputStream
>(),
1450 return uno::Reference
< embed::XExtendedStorageStream
>( xResult
, uno::UNO_QUERY_THROW
);
1453 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
FSStorage::openEncryptedStreamElementByHierarchicalName( const OUString
& /*sStreamName*/, ::sal_Int32
/*nOpenMode*/, const OUString
& /*sPassword*/ )
1454 throw ( embed::InvalidStorageException
,
1455 lang::IllegalArgumentException
,
1456 packages::NoEncryptionException
,
1457 packages::WrongPasswordException
,
1459 embed::StorageWrappedTargetException
,
1460 uno::RuntimeException
, std::exception
)
1462 throw packages::NoEncryptionException();
1465 void SAL_CALL
FSStorage::removeStreamElementByHierarchicalName( const OUString
& sStreamPath
)
1466 throw ( embed::InvalidStorageException
,
1467 lang::IllegalArgumentException
,
1468 container::NoSuchElementException
,
1470 embed::StorageWrappedTargetException
,
1471 uno::RuntimeException
, std::exception
)
1473 ::osl::MutexGuard
aGuard( m_aMutex
);
1476 throw lang::DisposedException();
1478 if ( !GetContent() )
1479 throw io::IOException(); // TODO: error handling
1481 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
1482 INetURLObject
aBaseURL( m_pImpl
->m_aURL
);
1483 if ( !aBaseURL
.setFinalSlash() )
1484 throw uno::RuntimeException();
1486 OUString aFileURL
= INetURLObject::GetAbsURL(
1487 aBaseURL
.GetMainURL( INetURLObject::NO_DECODE
),
1490 if ( !::utl::UCBContentHelper::IsDocument( aFileURL
) )
1492 if ( ::utl::UCBContentHelper::IsFolder( aFileURL
) )
1493 throw lang::IllegalArgumentException();
1495 throw container::NoSuchElementException(); // TODO:
1498 if ( !::utl::UCBContentHelper::Kill( aFileURL
) )
1499 throw io::IOException(); // TODO: error handling
1503 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */