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/InvalidStorageException.hpp>
23 #include <com/sun/star/embed/StorageWrappedTargetException.hpp>
24 #include <com/sun/star/embed/XTransactedObject.hpp>
25 #include <com/sun/star/packages/WrongPasswordException.hpp>
26 #include <com/sun/star/ucb/NameClash.hpp>
27 #include <com/sun/star/ucb/XProgressHandler.hpp>
28 #include <com/sun/star/ucb/XContentAccess.hpp>
29 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
31 #include <com/sun/star/ucb/InteractiveIOException.hpp>
32 #include <com/sun/star/ucb/IOErrorCode.hpp>
33 #include <com/sun/star/container/ElementExistException.hpp>
34 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
35 #include <com/sun/star/container/XEnumerationAccess.hpp>
36 #include <com/sun/star/container/XNamed.hpp>
37 #include <com/sun/star/util/XChangesBatch.hpp>
38 #include <com/sun/star/util/XCloneable.hpp>
39 #include <com/sun/star/lang/XUnoTunnel.hpp>
40 #include <com/sun/star/lang/XComponent.hpp>
41 #include <com/sun/star/lang/DisposedException.hpp>
42 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
43 #include <com/sun/star/io/IOException.hpp>
44 #include <com/sun/star/io/XTruncate.hpp>
45 #include <com/sun/star/io/TempFile.hpp>
46 #include <com/sun/star/sdbc/XResultSet.hpp>
47 #include <com/sun/star/sdbc/XRow.hpp>
49 #include <comphelper/fileurl.hxx>
50 #include <comphelper/processfactory.hxx>
51 #include <comphelper/storagehelper.hxx>
52 #include <cppuhelper/queryinterface.hxx>
53 #include <cppuhelper/typeprovider.hxx>
54 #include <cppuhelper/exc_hlp.hxx>
56 #include <tools/urlobj.hxx>
57 #include <unotools/ucbhelper.hxx>
58 #include <unotools/ucbstreamhelper.hxx>
59 #include <unotools/streamwrap.hxx>
60 #include <ucbhelper/content.hxx>
62 #include "fsstorage.hxx"
63 #include "oinputstreamcontainer.hxx"
64 #include "ostreamcontainer.hxx"
66 using namespace ::com::sun::star
;
70 OUString
const m_aURL
;
71 ::ucbhelper::Content m_aContent
;
72 sal_Int32
const m_nMode
;
73 std::unique_ptr
<::comphelper::OInterfaceContainerHelper2
> m_pListenersContainer
; // list of listeners
74 uno::Reference
< uno::XComponentContext
> m_xContext
;
76 FSStorage_Impl( const ::ucbhelper::Content
& aContent
, sal_Int32 nMode
, uno::Reference
< uno::XComponentContext
> const & xContext
)
77 : m_aURL( aContent
.getURL() )
78 , m_aContent( aContent
)
80 , m_xContext( xContext
)
82 OSL_ENSURE( !m_aURL
.isEmpty(), "The URL must not be empty" );
85 // Copy assignment is forbidden and not implemented.
86 FSStorage_Impl (const FSStorage_Impl
&) = delete;
87 FSStorage_Impl
& operator= (const FSStorage_Impl
&) = delete;
90 FSStorage::FSStorage( const ::ucbhelper::Content
& aContent
,
92 uno::Reference
< uno::XComponentContext
> const & xContext
)
93 : m_pImpl( new FSStorage_Impl( aContent
, nMode
, xContext
) )
95 // TODO: use properties
97 throw uno::RuntimeException();
102 FSStorage::~FSStorage()
104 ::osl::MutexGuard
aGuard( m_aMutex
);
105 osl_atomic_increment(&m_refCount
); // to call dispose
109 catch( uno::RuntimeException
& )
113 bool FSStorage::MakeFolderNoUI( const OUString
& rFolder
)
115 INetURLObject
aURL( rFolder
);
116 OUString aTitle
= aURL
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
);
117 aURL
.removeSegment();
118 ::ucbhelper::Content aParent
;
119 ::ucbhelper::Content aResultContent
;
121 if ( ::ucbhelper::Content::create( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
122 uno::Reference
< ucb::XCommandEnvironment
>(),
123 comphelper::getProcessComponentContext(),
125 return ::utl::UCBContentHelper::MakeFolder( aParent
, aTitle
, aResultContent
);
130 ucbhelper::Content
& FSStorage::GetContent()
132 ::osl::MutexGuard
aGuard( m_aMutex
);
133 return m_pImpl
->m_aContent
;
136 void FSStorage::CopyStreamToSubStream( const OUString
& aSourceURL
,
137 const uno::Reference
< embed::XStorage
>& xDest
,
138 const OUString
& aNewEntryName
)
141 throw uno::RuntimeException();
143 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
144 ::ucbhelper::Content
aSourceContent( aSourceURL
, xDummyEnv
, comphelper::getProcessComponentContext() );
145 uno::Reference
< io::XInputStream
> xSourceInput
= aSourceContent
.openStream();
147 if ( !xSourceInput
.is() )
148 throw io::IOException(); // TODO: error handling
150 uno::Reference
< io::XStream
> xSubStream
= xDest
->openStreamElement(
152 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
153 if ( !xSubStream
.is() )
154 throw uno::RuntimeException();
156 uno::Reference
< io::XOutputStream
> xDestOutput
= xSubStream
->getOutputStream();
157 if ( !xDestOutput
.is() )
158 throw uno::RuntimeException();
160 ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInput
, xDestOutput
);
161 xDestOutput
->closeOutput();
164 void FSStorage::CopyContentToStorage_Impl(ucbhelper::Content
& rContent
,
165 const uno::Reference
<embed::XStorage
>& xDest
)
167 // get list of contents of the Content
168 // create cursor for access to children
169 uno::Sequence
< OUString
> aProps( 2 );
170 OUString
* pProps
= aProps
.getArray();
171 pProps
[0] = "TargetURL";
172 pProps
[1] = "IsFolder";
176 uno::Reference
<sdbc::XResultSet
> xResultSet
177 = rContent
.createCursor(aProps
, ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
);
178 uno::Reference
< sdbc::XRow
> xRow( xResultSet
, uno::UNO_QUERY
);
179 if ( xResultSet
.is() )
181 // go through the list: insert files as streams, insert folders as substorages using recursion
182 while ( xResultSet
->next() )
184 OUString
aSourceURL( xRow
->getString( 1 ) );
185 bool bIsFolder( xRow
->getBoolean(2) );
187 // TODO/LATER: not sure whether the entry name must be encoded
188 OUString
aNewEntryName( INetURLObject( aSourceURL
).getName( INetURLObject::LAST_SEGMENT
,
190 INetURLObject::DecodeMechanism::NONE
) );
193 uno::Reference
< embed::XStorage
> xSubStorage
= xDest
->openStorageElement( aNewEntryName
,
194 embed::ElementModes::READWRITE
);
195 if ( !xSubStorage
.is() )
196 throw uno::RuntimeException();
198 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
199 ::ucbhelper::Content
aSourceContent( aSourceURL
, xDummyEnv
, comphelper::getProcessComponentContext() );
200 CopyContentToStorage_Impl( aSourceContent
, xSubStorage
);
204 CopyStreamToSubStream( aSourceURL
, xDest
, aNewEntryName
);
209 uno::Reference
< embed::XTransactedObject
> xTransact( xDest
, uno::UNO_QUERY
);
210 if ( xTransact
.is() )
213 catch( ucb::InteractiveIOException
& r
)
215 if ( r
.Code
== ucb::IOErrorCode_NOT_EXISTING
)
216 OSL_FAIL( "The folder does not exist!" );
224 uno::Any SAL_CALL
FSStorage::queryInterface( const uno::Type
& rType
)
226 uno::Any aReturn
= ::cppu::queryInterface
228 , static_cast<lang::XTypeProvider
*> ( this )
229 , static_cast<embed::XStorage
*> ( this )
230 , static_cast<embed::XHierarchicalStorageAccess
*> ( this )
231 , static_cast<container::XNameAccess
*> ( this )
232 , static_cast<container::XElementAccess
*> ( this )
233 , static_cast<lang::XComponent
*> ( this )
234 , static_cast<beans::XPropertySet
*> ( this ) );
236 if ( aReturn
.hasValue() )
239 return OWeakObject::queryInterface( rType
);
242 void SAL_CALL
FSStorage::acquire() throw()
244 OWeakObject::acquire();
247 void SAL_CALL
FSStorage::release() throw()
249 OWeakObject::release();
254 uno::Sequence
< uno::Type
> SAL_CALL
FSStorage::getTypes()
256 static const uno::Sequence
<uno::Type
> aTypes
{
257 cppu::UnoType
<lang::XTypeProvider
>::get(),
258 cppu::UnoType
<embed::XStorage
>::get(),
259 cppu::UnoType
<embed::XHierarchicalStorageAccess
>::get(),
260 cppu::UnoType
<beans::XPropertySet
>::get() };
264 uno::Sequence
< sal_Int8
> SAL_CALL
FSStorage::getImplementationId()
266 return css::uno::Sequence
<sal_Int8
>();
271 void SAL_CALL
FSStorage::copyToStorage( const uno::Reference
< embed::XStorage
>& xDest
)
273 ::osl::MutexGuard
aGuard( m_aMutex
);
276 throw lang::DisposedException();
278 if ( !xDest
.is() || xDest
== uno::Reference
< uno::XInterface
>( static_cast< OWeakObject
*> ( this ), uno::UNO_QUERY
) )
279 throw lang::IllegalArgumentException(); // TODO:
283 CopyContentToStorage_Impl( GetContent(), xDest
);
285 catch( embed::InvalidStorageException
& )
289 catch( lang::IllegalArgumentException
& )
293 catch( embed::StorageWrappedTargetException
& )
297 catch( io::IOException
& )
301 catch( uno::RuntimeException
& )
305 catch( uno::Exception
& )
307 uno::Any
aCaught( ::cppu::getCaughtException() );
308 throw embed::StorageWrappedTargetException("Can't copy raw stream",
309 uno::Reference
< io::XInputStream
>(),
314 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::openStreamElement(
315 const OUString
& aStreamName
, sal_Int32 nOpenMode
)
317 ::osl::MutexGuard
aGuard( m_aMutex
);
320 throw lang::DisposedException();
322 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
323 INetURLObject
aFileURL( m_pImpl
->m_aURL
);
324 aFileURL
.Append( aStreamName
);
326 if ( ::utl::UCBContentHelper::IsFolder( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
327 throw io::IOException();
329 if ( ( nOpenMode
& embed::ElementModes::NOCREATE
)
330 && !::utl::UCBContentHelper::IsDocument( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
331 throw io::IOException(); // TODO:
333 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
; // TODO: provide InteractionHandler if any
334 uno::Reference
< io::XStream
> xResult
;
337 if ( nOpenMode
& embed::ElementModes::WRITE
)
339 if ( aFileURL
.GetProtocol() == INetProtocol::File
)
341 uno::Reference
<ucb::XSimpleFileAccess3
> xSimpleFileAccess(
342 ucb::SimpleFileAccess::create( m_pImpl
->m_xContext
) );
343 xResult
= xSimpleFileAccess
->openFileReadWrite( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
347 // TODO: test whether it really works for http and fwp
348 std::unique_ptr
<SvStream
> pStream
= ::utl::UcbStreamHelper::CreateStream( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
349 StreamMode::STD_WRITE
);
350 if ( pStream
&& !pStream
->GetError() )
351 xResult
.set( new ::utl::OStreamWrapper( std::move(pStream
) ) );
355 throw io::IOException();
357 if ( nOpenMode
& embed::ElementModes::TRUNCATE
)
359 uno::Reference
< io::XTruncate
> xTrunc( xResult
->getOutputStream(), uno::UNO_QUERY_THROW
);
365 if ( ( nOpenMode
& embed::ElementModes::TRUNCATE
)
366 || !::utl::UCBContentHelper::IsDocument( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
367 throw io::IOException(); // TODO: access denied
369 ::ucbhelper::Content
aResultContent( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
370 uno::Reference
< io::XInputStream
> xInStream
= aResultContent
.openStream();
371 xResult
= new OFSInputStreamContainer(xInStream
);
374 catch( embed::InvalidStorageException
& )
378 catch( lang::IllegalArgumentException
& )
382 catch( packages::WrongPasswordException
& )
386 catch( embed::StorageWrappedTargetException
& )
390 catch( io::IOException
& )
394 catch( uno::RuntimeException
& )
398 catch( uno::Exception
& )
400 uno::Any
aCaught( ::cppu::getCaughtException() );
401 throw embed::StorageWrappedTargetException("Can't copy raw stream",
402 uno::Reference
< io::XInputStream
>(),
409 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::openEncryptedStreamElement(
410 const OUString
&, sal_Int32
, const OUString
& )
412 throw packages::NoEncryptionException();
415 uno::Reference
< embed::XStorage
> SAL_CALL
FSStorage::openStorageElement(
416 const OUString
& aStorName
, sal_Int32 nStorageMode
)
418 ::osl::MutexGuard
aGuard( m_aMutex
);
421 throw lang::DisposedException();
423 if ( ( nStorageMode
& embed::ElementModes::WRITE
)
424 && !( m_pImpl
->m_nMode
& embed::ElementModes::WRITE
) )
425 throw io::IOException(); // TODO: error handling
427 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
428 INetURLObject
aFolderURL( m_pImpl
->m_aURL
);
429 aFolderURL
.Append( aStorName
);
431 bool bFolderExists
= ::utl::UCBContentHelper::IsFolder( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
432 if ( !bFolderExists
&& ::utl::UCBContentHelper::IsDocument( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
433 throw io::IOException(); // TODO:
435 if ( ( nStorageMode
& embed::ElementModes::NOCREATE
) && !bFolderExists
)
436 throw io::IOException(); // TODO:
438 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
; // TODO: provide InteractionHandler if any
439 uno::Reference
< embed::XStorage
> xResult
;
442 if ( nStorageMode
& embed::ElementModes::WRITE
)
444 if ( ( nStorageMode
& embed::ElementModes::TRUNCATE
) && bFolderExists
)
446 ::utl::UCBContentHelper::Kill( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
448 MakeFolderNoUI( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ); // TODO: not atomic :(
450 else if ( !bFolderExists
)
453 MakeFolderNoUI( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ); // TODO: not atomic :(
456 else if ( nStorageMode
& embed::ElementModes::TRUNCATE
)
457 throw io::IOException(); // TODO: access denied
459 if ( !bFolderExists
)
460 throw io::IOException(); // there is no such folder
462 ::ucbhelper::Content
aResultContent( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
463 xResult
.set( static_cast< OWeakObject
* >( new FSStorage( aResultContent
,
465 m_pImpl
->m_xContext
) ),
468 catch( embed::InvalidStorageException
& )
472 catch( lang::IllegalArgumentException
& )
476 catch( embed::StorageWrappedTargetException
& )
480 catch( io::IOException
& )
484 catch( uno::RuntimeException
& )
488 catch( uno::Exception
& )
490 uno::Any
aCaught( ::cppu::getCaughtException() );
491 throw embed::StorageWrappedTargetException("Can't copy raw stream",
492 uno::Reference
< io::XInputStream
>(),
499 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::cloneStreamElement( const OUString
& aStreamName
)
501 ::osl::MutexGuard
aGuard( m_aMutex
);
504 throw lang::DisposedException();
506 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
507 INetURLObject
aFileURL( m_pImpl
->m_aURL
);
508 aFileURL
.Append( aStreamName
);
510 uno::Reference
< io::XStream
> xTempResult
;
513 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
514 ::ucbhelper::Content
aResultContent( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
515 uno::Reference
< io::XInputStream
> xInStream
= aResultContent
.openStream();
517 xTempResult
= io::TempFile::create(m_pImpl
->m_xContext
);
518 uno::Reference
< io::XOutputStream
> xTempOut
= xTempResult
->getOutputStream();
519 uno::Reference
< io::XInputStream
> xTempIn
= xTempResult
->getInputStream();
521 if ( !xTempOut
.is() || !xTempIn
.is() )
522 throw io::IOException();
524 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream
, xTempOut
);
525 xTempOut
->closeOutput();
527 catch( embed::InvalidStorageException
& )
531 catch( lang::IllegalArgumentException
& )
535 catch( packages::WrongPasswordException
& )
539 catch( io::IOException
& )
543 catch( embed::StorageWrappedTargetException
& )
547 catch( uno::RuntimeException
& )
551 catch( uno::Exception
& )
553 uno::Any
aCaught( ::cppu::getCaughtException() );
554 throw embed::StorageWrappedTargetException("Can't copy raw stream",
555 uno::Reference
< io::XInputStream
>(),
562 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::cloneEncryptedStreamElement(
566 throw packages::NoEncryptionException();
569 void SAL_CALL
FSStorage::copyLastCommitTo(
570 const uno::Reference
< embed::XStorage
>& xTargetStorage
)
572 copyToStorage( xTargetStorage
);
575 void SAL_CALL
FSStorage::copyStorageElementLastCommitTo(
576 const OUString
& aStorName
,
577 const uno::Reference
< embed::XStorage
>& xTargetStorage
)
579 ::osl::MutexGuard
aGuard( m_aMutex
);
582 throw lang::DisposedException();
584 uno::Reference
< embed::XStorage
> xSourceStor( openStorageElement( aStorName
, embed::ElementModes::READ
),
585 uno::UNO_SET_THROW
);
586 xSourceStor
->copyToStorage( xTargetStorage
);
589 sal_Bool SAL_CALL
FSStorage::isStreamElement( const OUString
& aElementName
)
591 ::osl::MutexGuard
aGuard( m_aMutex
);
594 throw lang::DisposedException();
596 INetURLObject
aURL( m_pImpl
->m_aURL
);
597 aURL
.Append( aElementName
);
599 return !::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
602 sal_Bool SAL_CALL
FSStorage::isStorageElement( const OUString
& aElementName
)
604 ::osl::MutexGuard
aGuard( m_aMutex
);
607 throw lang::DisposedException();
609 INetURLObject
aURL( m_pImpl
->m_aURL
);
610 aURL
.Append( aElementName
);
612 return ::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
615 void SAL_CALL
FSStorage::removeElement( const OUString
& aElementName
)
617 ::osl::MutexGuard
aGuard( m_aMutex
);
620 throw lang::DisposedException();
622 INetURLObject
aURL( m_pImpl
->m_aURL
);
623 aURL
.Append( aElementName
);
625 if ( !::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) )
626 && !::utl::UCBContentHelper::IsDocument( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
627 throw container::NoSuchElementException(); // TODO:
629 ::utl::UCBContentHelper::Kill( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
632 void SAL_CALL
FSStorage::renameElement( const OUString
& aElementName
, const OUString
& aNewName
)
634 ::osl::MutexGuard
aGuard( m_aMutex
);
637 throw lang::DisposedException();
639 INetURLObject
aOldURL( m_pImpl
->m_aURL
);
640 aOldURL
.Append( aElementName
);
642 INetURLObject
aNewURL( m_pImpl
->m_aURL
);
643 aNewURL
.Append( aNewName
);
645 if ( !::utl::UCBContentHelper::IsFolder( aOldURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) )
646 && !::utl::UCBContentHelper::IsDocument( aOldURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
647 throw container::NoSuchElementException(); // TODO:
649 if ( ::utl::UCBContentHelper::IsFolder( aNewURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) )
650 || ::utl::UCBContentHelper::IsDocument( aNewURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
651 throw container::ElementExistException(); // TODO:
655 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
656 ::ucbhelper::Content
aSourceContent( aOldURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
658 GetContent().transferContent(aSourceContent
, ::ucbhelper::InsertOperation::Move
, aNewName
,
659 ucb::NameClash::ERROR
);
661 catch( embed::InvalidStorageException
& )
665 catch( lang::IllegalArgumentException
& )
669 catch( container::NoSuchElementException
& )
673 catch( container::ElementExistException
& )
677 catch( io::IOException
& )
681 catch( embed::StorageWrappedTargetException
& )
685 catch( uno::RuntimeException
& )
689 catch( uno::Exception
& )
691 uno::Any
aCaught( ::cppu::getCaughtException() );
692 throw embed::StorageWrappedTargetException("Can't copy raw stream",
693 uno::Reference
< io::XInputStream
>(),
698 void SAL_CALL
FSStorage::copyElementTo( const OUString
& aElementName
,
699 const uno::Reference
< embed::XStorage
>& xDest
,
700 const OUString
& aNewName
)
702 ::osl::MutexGuard
aGuard( m_aMutex
);
705 throw lang::DisposedException();
708 throw uno::RuntimeException();
710 INetURLObject
aOwnURL( m_pImpl
->m_aURL
);
711 aOwnURL
.Append( aElementName
);
713 if ( xDest
->hasByName( aNewName
) )
714 throw container::ElementExistException(); // TODO:
718 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
719 if ( ::utl::UCBContentHelper::IsFolder( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
721 ::ucbhelper::Content
aSourceContent( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
722 uno::Reference
< embed::XStorage
> xDestSubStor(
723 xDest
->openStorageElement( aNewName
, embed::ElementModes::READWRITE
),
724 uno::UNO_SET_THROW
);
726 CopyContentToStorage_Impl( aSourceContent
, xDestSubStor
);
728 else if ( ::utl::UCBContentHelper::IsDocument( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
730 CopyStreamToSubStream( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDest
, aNewName
);
733 throw container::NoSuchElementException(); // TODO:
735 catch( embed::InvalidStorageException
& )
739 catch( lang::IllegalArgumentException
& )
743 catch( container::NoSuchElementException
& )
747 catch( container::ElementExistException
& )
751 catch( embed::StorageWrappedTargetException
& )
755 catch( io::IOException
& )
759 catch( uno::RuntimeException
& )
763 catch( uno::Exception
& )
765 uno::Any
aCaught( ::cppu::getCaughtException() );
766 throw embed::StorageWrappedTargetException("Can't copy raw stream",
767 uno::Reference
< io::XInputStream
>(),
772 void SAL_CALL
FSStorage::moveElementTo( const OUString
& aElementName
,
773 const uno::Reference
< embed::XStorage
>& xDest
,
774 const OUString
& aNewName
)
776 ::osl::MutexGuard
aGuard( m_aMutex
);
777 copyElementTo( aElementName
, xDest
, aNewName
);
779 INetURLObject
aOwnURL( m_pImpl
->m_aURL
);
780 aOwnURL
.Append( aElementName
);
781 if ( !::utl::UCBContentHelper::Kill( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
782 throw io::IOException(); // TODO: error handling
787 uno::Any SAL_CALL
FSStorage::getByName( const OUString
& aName
)
789 ::osl::MutexGuard
aGuard( m_aMutex
);
792 throw lang::DisposedException();
794 if ( aName
.isEmpty() )
795 throw lang::IllegalArgumentException();
800 INetURLObject
aURL( m_pImpl
->m_aURL
);
801 aURL
.Append( aName
);
804 if ( ::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
806 aResult
<<= openStorageElement( aName
, embed::ElementModes::READ
);
808 else if ( ::utl::UCBContentHelper::IsDocument( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
810 aResult
<<= openStreamElement( aName
, embed::ElementModes::READ
);
813 throw container::NoSuchElementException(); // TODO:
815 catch (const container::NoSuchElementException
&)
819 catch (const lang::WrappedTargetException
&)
823 catch (const uno::RuntimeException
&)
827 catch (const uno::Exception
&)
829 uno::Any
aCaught( ::cppu::getCaughtException() );
830 throw lang::WrappedTargetException( "Can not open element!",
831 static_cast< OWeakObject
* >( this ),
839 uno::Sequence
< OUString
> SAL_CALL
FSStorage::getElementNames()
841 ::osl::MutexGuard
aGuard( m_aMutex
);
844 throw lang::DisposedException();
846 uno::Sequence
< OUString
> aResult
;
850 uno::Sequence
<OUString
> aProps
{ "Title" };
853 uno::Reference
<sdbc::XResultSet
> xResultSet
854 = GetContent().createCursor(aProps
, ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
);
855 uno::Reference
< sdbc::XRow
> xRow( xResultSet
, uno::UNO_QUERY
);
856 if ( xResultSet
.is() )
858 // go through the list
859 while ( xResultSet
->next() )
861 OUString
aName( xRow
->getString( 1 ) );
862 aResult
.realloc( ++nSize
);
863 aResult
[nSize
-1] = aName
;
867 catch( const ucb::InteractiveIOException
& r
)
869 if ( r
.Code
== ucb::IOErrorCode_NOT_EXISTING
)
870 OSL_FAIL( "The folder does not exist!" );
873 uno::Any
aCaught( ::cppu::getCaughtException() );
874 throw lang::WrappedTargetRuntimeException( "Can not open storage!",
875 static_cast< OWeakObject
* >( this ),
879 catch (const uno::RuntimeException
&)
883 catch (const uno::Exception
&)
885 uno::Any
aCaught( ::cppu::getCaughtException() );
886 throw lang::WrappedTargetRuntimeException( "Can not open storage!",
887 static_cast< OWeakObject
* >( this ),
894 sal_Bool SAL_CALL
FSStorage::hasByName( const OUString
& aName
)
896 ::osl::MutexGuard
aGuard( m_aMutex
);
899 throw lang::DisposedException();
901 if ( aName
.isEmpty() )
902 throw lang::IllegalArgumentException();
904 INetURLObject
aURL( m_pImpl
->m_aURL
);
905 aURL
.Append( aName
);
907 return ( ::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) )
908 || ::utl::UCBContentHelper::IsDocument( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) );
911 uno::Type SAL_CALL
FSStorage::getElementType()
913 ::osl::MutexGuard
aGuard( m_aMutex
);
916 throw lang::DisposedException();
918 // it is a multitype container
922 sal_Bool SAL_CALL
FSStorage::hasElements()
924 ::osl::MutexGuard
aGuard( m_aMutex
);
927 throw lang::DisposedException();
931 uno::Sequence
<OUString
> aProps
{ "TargetURL" };
933 uno::Reference
<sdbc::XResultSet
> xResultSet
934 = GetContent().createCursor(aProps
, ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
);
935 return ( xResultSet
.is() && xResultSet
->next() );
937 catch (const uno::RuntimeException
&)
941 catch (const uno::Exception
& ex
)
943 css::uno::Any anyEx
= cppu::getCaughtException();
944 throw lang::WrappedTargetRuntimeException( ex
.Message
,
950 void SAL_CALL
FSStorage::dispose()
952 ::osl::MutexGuard
aGuard( m_aMutex
);
955 throw lang::DisposedException();
957 if ( m_pImpl
->m_pListenersContainer
)
959 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
960 m_pImpl
->m_pListenersContainer
->disposeAndClear( aSource
);
966 void SAL_CALL
FSStorage::addEventListener(
967 const uno::Reference
< lang::XEventListener
>& xListener
)
969 ::osl::MutexGuard
aGuard( m_aMutex
);
972 throw lang::DisposedException();
974 if ( !m_pImpl
->m_pListenersContainer
)
975 m_pImpl
->m_pListenersContainer
.reset(new ::comphelper::OInterfaceContainerHelper2( m_aMutex
));
977 m_pImpl
->m_pListenersContainer
->addInterface( xListener
);
980 void SAL_CALL
FSStorage::removeEventListener(
981 const uno::Reference
< lang::XEventListener
>& xListener
)
983 ::osl::MutexGuard
aGuard( m_aMutex
);
986 throw lang::DisposedException();
988 if ( m_pImpl
->m_pListenersContainer
)
989 m_pImpl
->m_pListenersContainer
->removeInterface( xListener
);
994 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
FSStorage::getPropertySetInfo()
996 ::osl::MutexGuard
aGuard( m_aMutex
);
999 throw lang::DisposedException();
1002 return uno::Reference
< beans::XPropertySetInfo
>();
1006 void SAL_CALL
FSStorage::setPropertyValue( const OUString
& aPropertyName
, const uno::Any
& )
1008 ::osl::MutexGuard
aGuard( m_aMutex
);
1011 throw lang::DisposedException();
1013 if ( aPropertyName
== "URL" || aPropertyName
== "OpenMode" )
1014 throw beans::PropertyVetoException(); // TODO
1016 throw beans::UnknownPropertyException(); // TODO
1020 uno::Any SAL_CALL
FSStorage::getPropertyValue( const OUString
& aPropertyName
)
1022 ::osl::MutexGuard
aGuard( m_aMutex
);
1025 throw lang::DisposedException();
1027 if ( aPropertyName
== "URL" )
1028 return uno::makeAny( m_pImpl
->m_aURL
);
1029 else if ( aPropertyName
== "OpenMode" )
1030 return uno::makeAny( m_pImpl
->m_nMode
);
1032 throw beans::UnknownPropertyException(); // TODO
1036 void SAL_CALL
FSStorage::addPropertyChangeListener(
1037 const OUString
& /*aPropertyName*/,
1038 const uno::Reference
< beans::XPropertyChangeListener
>& /*xListener*/ )
1040 ::osl::MutexGuard
aGuard( m_aMutex
);
1043 throw lang::DisposedException();
1049 void SAL_CALL
FSStorage::removePropertyChangeListener(
1050 const OUString
& /*aPropertyName*/,
1051 const uno::Reference
< beans::XPropertyChangeListener
>& /*aListener*/ )
1053 ::osl::MutexGuard
aGuard( m_aMutex
);
1056 throw lang::DisposedException();
1062 void SAL_CALL
FSStorage::addVetoableChangeListener(
1063 const OUString
& /*PropertyName*/,
1064 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
1066 ::osl::MutexGuard
aGuard( m_aMutex
);
1069 throw lang::DisposedException();
1075 void SAL_CALL
FSStorage::removeVetoableChangeListener(
1076 const OUString
& /*PropertyName*/,
1077 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
1079 ::osl::MutexGuard
aGuard( m_aMutex
);
1082 throw lang::DisposedException();
1087 // XHierarchicalStorageAccess
1088 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
FSStorage::openStreamElementByHierarchicalName( const OUString
& sStreamPath
, ::sal_Int32 nOpenMode
)
1090 ::osl::MutexGuard
aGuard( m_aMutex
);
1093 throw lang::DisposedException();
1095 if ( sStreamPath
.toChar() == '/' )
1096 throw lang::IllegalArgumentException();
1098 INetURLObject
aBaseURL( m_pImpl
->m_aURL
);
1099 if ( !aBaseURL
.setFinalSlash() )
1100 throw uno::RuntimeException();
1102 OUString aFileURL
= INetURLObject::GetAbsURL(
1103 aBaseURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
1106 if ( ::utl::UCBContentHelper::IsFolder( aFileURL
) )
1107 throw io::IOException();
1109 if ( ( nOpenMode
& embed::ElementModes::NOCREATE
)
1110 && !::utl::UCBContentHelper::IsDocument( aFileURL
) )
1111 throw io::IOException(); // TODO:
1113 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
; // TODO: provide InteractionHandler if any
1114 uno::Reference
< io::XStream
> xResult
;
1117 if ( nOpenMode
& embed::ElementModes::WRITE
)
1119 if ( comphelper::isFileUrl( aFileURL
) )
1121 uno::Reference
<ucb::XSimpleFileAccess3
> xSimpleFileAccess(
1122 ucb::SimpleFileAccess::create( m_pImpl
->m_xContext
) );
1123 uno::Reference
< io::XStream
> xStream
=
1124 xSimpleFileAccess
->openFileReadWrite( aFileURL
);
1126 xResult
= new OFSStreamContainer(xStream
);
1130 // TODO: test whether it really works for http and fwp
1131 std::unique_ptr
<SvStream
> pStream
= ::utl::UcbStreamHelper::CreateStream( aFileURL
,
1132 StreamMode::STD_WRITE
);
1133 if ( pStream
&& !pStream
->GetError() )
1135 uno::Reference
< io::XStream
> xStream( new ::utl::OStreamWrapper( std::move(pStream
) ) );
1136 xResult
= new OFSStreamContainer(xStream
);
1140 if ( !xResult
.is() )
1141 throw io::IOException();
1143 if ( nOpenMode
& embed::ElementModes::TRUNCATE
)
1145 uno::Reference
< io::XTruncate
> xTrunc( xResult
->getOutputStream(), uno::UNO_QUERY_THROW
);
1151 if ( ( nOpenMode
& embed::ElementModes::TRUNCATE
)
1152 || !::utl::UCBContentHelper::IsDocument( aFileURL
) )
1153 throw io::IOException(); // TODO: access denied
1155 ::ucbhelper::Content
aResultContent( aFileURL
, xDummyEnv
, comphelper::getProcessComponentContext() );
1156 uno::Reference
< io::XInputStream
> xInStream
= aResultContent
.openStream();
1157 xResult
= new OFSInputStreamContainer(xInStream
);
1160 catch( embed::InvalidStorageException
& )
1164 catch( lang::IllegalArgumentException
& )
1168 catch( packages::WrongPasswordException
& )
1172 catch( embed::StorageWrappedTargetException
& )
1176 catch( io::IOException
& )
1180 catch( uno::RuntimeException
& )
1184 catch( uno::Exception
& )
1186 uno::Any
aCaught( ::cppu::getCaughtException() );
1187 throw embed::StorageWrappedTargetException("Can't copy raw stream",
1188 uno::Reference
< io::XInputStream
>(),
1192 return uno::Reference
< embed::XExtendedStorageStream
>( xResult
, uno::UNO_QUERY_THROW
);
1195 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
FSStorage::openEncryptedStreamElementByHierarchicalName( const OUString
& /*sStreamName*/, ::sal_Int32
/*nOpenMode*/, const OUString
& /*sPassword*/ )
1197 throw packages::NoEncryptionException();
1200 void SAL_CALL
FSStorage::removeStreamElementByHierarchicalName( const OUString
& sStreamPath
)
1202 ::osl::MutexGuard
aGuard( m_aMutex
);
1205 throw lang::DisposedException();
1207 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
1208 INetURLObject
aBaseURL( m_pImpl
->m_aURL
);
1209 if ( !aBaseURL
.setFinalSlash() )
1210 throw uno::RuntimeException();
1212 OUString aFileURL
= INetURLObject::GetAbsURL(
1213 aBaseURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
1216 if ( !::utl::UCBContentHelper::IsDocument( aFileURL
) )
1218 if ( ::utl::UCBContentHelper::IsFolder( aFileURL
) )
1219 throw lang::IllegalArgumentException();
1221 throw container::NoSuchElementException(); // TODO:
1224 if ( !::utl::UCBContentHelper::Kill( aFileURL
) )
1225 throw io::IOException(); // TODO: error handling
1229 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */