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/embed/ElementModes.hpp>
21 #include <com/sun/star/embed/InvalidStorageException.hpp>
22 #include <com/sun/star/embed/StorageWrappedTargetException.hpp>
23 #include <com/sun/star/embed/XTransactedObject.hpp>
24 #include <com/sun/star/packages/NoEncryptionException.hpp>
25 #include <com/sun/star/packages/WrongPasswordException.hpp>
26 #include <com/sun/star/ucb/NameClash.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/ElementExistException.hpp>
32 #include <com/sun/star/lang/XComponent.hpp>
33 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
34 #include <com/sun/star/io/IOException.hpp>
35 #include <com/sun/star/io/XTruncate.hpp>
36 #include <com/sun/star/io/TempFile.hpp>
37 #include <com/sun/star/sdbc/XResultSet.hpp>
38 #include <com/sun/star/sdbc/XRow.hpp>
40 #include <comphelper/fileurl.hxx>
41 #include <comphelper/processfactory.hxx>
42 #include <comphelper/storagehelper.hxx>
43 #include <cppuhelper/queryinterface.hxx>
44 #include <cppuhelper/exc_hlp.hxx>
46 #include <osl/diagnose.h>
47 #include <tools/urlobj.hxx>
48 #include <unotools/ucbhelper.hxx>
49 #include <unotools/ucbstreamhelper.hxx>
50 #include <unotools/streamwrap.hxx>
51 #include <unotools/tempfile.hxx>
52 #include <ucbhelper/content.hxx>
54 #include "fsstorage.hxx"
55 #include "oinputstreamcontainer.hxx"
56 #include "ostreamcontainer.hxx"
58 using namespace ::com::sun::star
;
60 FSStorage::FSStorage( const ::ucbhelper::Content
& aContent
,
62 uno::Reference
< uno::XComponentContext
> const & xContext
)
63 : m_aURL( aContent
.getURL() )
64 , m_aContent( aContent
)
66 , m_xContext( xContext
)
68 OSL_ENSURE( !m_aURL
.isEmpty(), "The URL must not be empty" );
69 // TODO: use properties
71 throw uno::RuntimeException();
76 FSStorage::~FSStorage()
78 std::unique_lock
aGuard( m_aMutex
);
79 osl_atomic_increment(&m_refCount
); // to call dispose
83 catch( uno::RuntimeException
& )
87 bool FSStorage::MakeFolderNoUI( std::u16string_view rFolder
)
89 INetURLObject
aURL( rFolder
);
90 OUString aTitle
= aURL
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
);
92 ::ucbhelper::Content aParent
;
93 ::ucbhelper::Content aResultContent
;
95 if ( ::ucbhelper::Content::create( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
96 uno::Reference
< ucb::XCommandEnvironment
>(),
97 comphelper::getProcessComponentContext(),
99 return ::utl::UCBContentHelper::MakeFolder( aParent
, aTitle
, aResultContent
);
104 ucbhelper::Content
& FSStorage::GetContent()
106 std::unique_lock
aGuard( m_aMutex
);
110 void FSStorage::CopyStreamToSubStream( const OUString
& aSourceURL
,
111 const uno::Reference
< embed::XStorage
>& xDest
,
112 const OUString
& aNewEntryName
)
115 throw uno::RuntimeException();
117 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
118 ::ucbhelper::Content
aSourceContent( aSourceURL
, xDummyEnv
, comphelper::getProcessComponentContext() );
119 uno::Reference
< io::XInputStream
> xSourceInput
= aSourceContent
.openStream();
121 if ( !xSourceInput
.is() )
122 throw io::IOException(); // TODO: error handling
124 uno::Reference
< io::XStream
> xSubStream
= xDest
->openStreamElement(
126 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
127 if ( !xSubStream
.is() )
128 throw uno::RuntimeException();
130 uno::Reference
< io::XOutputStream
> xDestOutput
= xSubStream
->getOutputStream();
131 if ( !xDestOutput
.is() )
132 throw uno::RuntimeException();
134 ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInput
, xDestOutput
);
135 xDestOutput
->closeOutput();
138 void FSStorage::CopyContentToStorage_Impl(ucbhelper::Content
& rContent
,
139 const uno::Reference
<embed::XStorage
>& xDest
)
141 // get list of contents of the Content
142 // create cursor for access to children
143 uno::Sequence
< OUString
> aProps( 2 );
144 OUString
* pProps
= aProps
.getArray();
145 pProps
[0] = "TargetURL";
146 pProps
[1] = "IsFolder";
150 uno::Reference
<sdbc::XResultSet
> xResultSet
151 = rContent
.createCursor(aProps
, ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
);
152 uno::Reference
< sdbc::XRow
> xRow( xResultSet
, uno::UNO_QUERY
);
153 if ( xResultSet
.is() )
155 // go through the list: insert files as streams, insert folders as substorages using recursion
156 while ( xResultSet
->next() )
158 OUString
aSourceURL( xRow
->getString( 1 ) );
159 bool bIsFolder( xRow
->getBoolean(2) );
161 // TODO/LATER: not sure whether the entry name must be encoded
162 OUString
aNewEntryName( INetURLObject( aSourceURL
).getName( INetURLObject::LAST_SEGMENT
,
164 INetURLObject::DecodeMechanism::NONE
) );
167 uno::Reference
< embed::XStorage
> xSubStorage
= xDest
->openStorageElement( aNewEntryName
,
168 embed::ElementModes::READWRITE
);
169 if ( !xSubStorage
.is() )
170 throw uno::RuntimeException();
172 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
173 ::ucbhelper::Content
aSourceContent( aSourceURL
, xDummyEnv
, comphelper::getProcessComponentContext() );
174 CopyContentToStorage_Impl( aSourceContent
, xSubStorage
);
178 CopyStreamToSubStream( aSourceURL
, xDest
, aNewEntryName
);
183 uno::Reference
< embed::XTransactedObject
> xTransact( xDest
, uno::UNO_QUERY
);
184 if ( xTransact
.is() )
187 catch( ucb::InteractiveIOException
& r
)
189 if ( r
.Code
== ucb::IOErrorCode_NOT_EXISTING
)
190 OSL_FAIL( "The folder does not exist!" );
198 uno::Any SAL_CALL
FSStorage::queryInterface( const uno::Type
& rType
)
200 uno::Any aReturn
= ::cppu::queryInterface
202 , static_cast<lang::XTypeProvider
*> ( this )
203 , static_cast<embed::XStorage
*> ( this )
204 , static_cast<embed::XHierarchicalStorageAccess
*> ( this )
205 , static_cast<container::XNameAccess
*> ( this )
206 , static_cast<container::XElementAccess
*> ( this )
207 , static_cast<lang::XComponent
*> ( this )
208 , static_cast<beans::XPropertySet
*> ( this ) );
210 if ( aReturn
.hasValue() )
213 return OWeakObject::queryInterface( rType
);
216 void SAL_CALL
FSStorage::acquire() noexcept
218 OWeakObject::acquire();
221 void SAL_CALL
FSStorage::release() noexcept
223 OWeakObject::release();
228 uno::Sequence
< uno::Type
> SAL_CALL
FSStorage::getTypes()
230 static const uno::Sequence
<uno::Type
> aTypes
{
231 cppu::UnoType
<lang::XTypeProvider
>::get(),
232 cppu::UnoType
<embed::XStorage
>::get(),
233 cppu::UnoType
<embed::XHierarchicalStorageAccess
>::get(),
234 cppu::UnoType
<beans::XPropertySet
>::get() };
238 uno::Sequence
< sal_Int8
> SAL_CALL
FSStorage::getImplementationId()
240 return css::uno::Sequence
<sal_Int8
>();
245 void SAL_CALL
FSStorage::copyToStorage( const uno::Reference
< embed::XStorage
>& xDest
)
247 std::unique_lock
aGuard( m_aMutex
);
249 if ( !xDest
.is() || xDest
== uno::Reference
< uno::XInterface
>( static_cast< OWeakObject
*> ( this ), uno::UNO_QUERY
) )
250 throw lang::IllegalArgumentException(); // TODO:
254 CopyContentToStorage_Impl( m_aContent
, xDest
);
256 catch( embed::InvalidStorageException
& )
260 catch( lang::IllegalArgumentException
& )
264 catch( embed::StorageWrappedTargetException
& )
268 catch( io::IOException
& )
272 catch( uno::RuntimeException
& )
276 catch( uno::Exception
& )
278 uno::Any
aCaught( ::cppu::getCaughtException() );
279 throw embed::StorageWrappedTargetException("Can't copy raw stream",
280 uno::Reference
< io::XInputStream
>(),
285 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::openStreamElement(
286 const OUString
& aStreamName
, sal_Int32 nOpenMode
)
288 std::unique_lock
aGuard( m_aMutex
);
289 return openStreamElementImpl(aGuard
, aStreamName
, nOpenMode
);
292 uno::Reference
< io::XStream
> FSStorage::openStreamElementImpl(
293 std::unique_lock
<std::mutex
>& /*rGuard*/,
294 std::u16string_view aStreamName
, sal_Int32 nOpenMode
)
296 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
297 INetURLObject
aFileURL( m_aURL
);
298 aFileURL
.Append( aStreamName
);
300 if ( ::utl::UCBContentHelper::IsFolder( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
301 throw io::IOException();
303 if ( ( nOpenMode
& embed::ElementModes::NOCREATE
)
304 && !::utl::UCBContentHelper::IsDocument( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
305 throw io::IOException(); // TODO:
307 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
; // TODO: provide InteractionHandler if any
308 uno::Reference
< io::XStream
> xResult
;
311 if ( nOpenMode
& embed::ElementModes::WRITE
)
313 if ( aFileURL
.GetProtocol() == INetProtocol::File
)
315 uno::Reference
<ucb::XSimpleFileAccess3
> xSimpleFileAccess(
316 ucb::SimpleFileAccess::create( m_xContext
) );
317 xResult
= xSimpleFileAccess
->openFileReadWrite( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
321 // TODO: test whether it really works for http and fwp
322 std::unique_ptr
<SvStream
> pStream
= ::utl::UcbStreamHelper::CreateStream( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
323 StreamMode::STD_WRITE
);
324 if ( pStream
&& !pStream
->GetError() )
325 xResult
.set( new ::utl::OStreamWrapper( std::move(pStream
) ) );
329 throw io::IOException();
331 if ( nOpenMode
& embed::ElementModes::TRUNCATE
)
333 uno::Reference
< io::XTruncate
> xTrunc( xResult
->getOutputStream(), uno::UNO_QUERY_THROW
);
339 if ( ( nOpenMode
& embed::ElementModes::TRUNCATE
)
340 || !::utl::UCBContentHelper::IsDocument( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
341 throw io::IOException(); // TODO: access denied
343 ::ucbhelper::Content
aResultContent( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
344 uno::Reference
< io::XInputStream
> xInStream
= aResultContent
.openStream();
345 xResult
= new OFSInputStreamContainer(xInStream
);
348 catch( embed::InvalidStorageException
& )
352 catch( lang::IllegalArgumentException
& )
356 catch( packages::WrongPasswordException
& )
360 catch( embed::StorageWrappedTargetException
& )
364 catch( io::IOException
& )
368 catch( uno::RuntimeException
& )
372 catch( uno::Exception
& )
374 uno::Any
aCaught( ::cppu::getCaughtException() );
375 throw embed::StorageWrappedTargetException("Can't copy raw stream",
376 uno::Reference
< io::XInputStream
>(),
383 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::openEncryptedStreamElement(
384 const OUString
&, sal_Int32
, const OUString
& )
386 throw packages::NoEncryptionException();
389 uno::Reference
< embed::XStorage
> SAL_CALL
FSStorage::openStorageElement(
390 const OUString
& aStorName
, sal_Int32 nStorageMode
)
392 std::unique_lock
aGuard( m_aMutex
);
393 return openStorageElementImpl(aGuard
, aStorName
, nStorageMode
);
396 uno::Reference
< embed::XStorage
> FSStorage::openStorageElementImpl(
397 std::unique_lock
<std::mutex
>& /*rGuard*/,
398 std::u16string_view aStorName
, sal_Int32 nStorageMode
)
400 if ( ( nStorageMode
& embed::ElementModes::WRITE
)
401 && !( m_nMode
& embed::ElementModes::WRITE
) )
402 throw io::IOException(); // TODO: error handling
404 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
405 INetURLObject
aFolderURL( m_aURL
);
406 aFolderURL
.Append( aStorName
);
408 bool bFolderExists
= ::utl::UCBContentHelper::IsFolder( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
409 if ( !bFolderExists
&& ::utl::UCBContentHelper::IsDocument( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
410 throw io::IOException(); // TODO:
412 if ( ( nStorageMode
& embed::ElementModes::NOCREATE
) && !bFolderExists
)
413 throw io::IOException(); // TODO:
415 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
; // TODO: provide InteractionHandler if any
416 uno::Reference
< embed::XStorage
> xResult
;
419 if ( nStorageMode
& embed::ElementModes::WRITE
)
421 if ( ( nStorageMode
& embed::ElementModes::TRUNCATE
) && bFolderExists
)
423 ::utl::UCBContentHelper::Kill( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
425 MakeFolderNoUI( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ); // TODO: not atomic :(
427 else if ( !bFolderExists
)
430 MakeFolderNoUI( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ); // TODO: not atomic :(
433 else if ( nStorageMode
& embed::ElementModes::TRUNCATE
)
434 throw io::IOException(); // TODO: access denied
436 if ( !bFolderExists
)
437 throw io::IOException(); // there is no such folder
439 ::ucbhelper::Content
aResultContent( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
440 xResult
= new FSStorage( aResultContent
, nStorageMode
, m_xContext
);
442 catch( embed::InvalidStorageException
& )
446 catch( lang::IllegalArgumentException
& )
450 catch( embed::StorageWrappedTargetException
& )
454 catch( io::IOException
& )
458 catch( uno::RuntimeException
& )
462 catch( uno::Exception
& )
464 uno::Any
aCaught( ::cppu::getCaughtException() );
465 throw embed::StorageWrappedTargetException("Can't copy raw stream",
466 uno::Reference
< io::XInputStream
>(),
473 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::cloneStreamElement( const OUString
& aStreamName
)
475 std::unique_lock
aGuard( m_aMutex
);
477 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
478 INetURLObject
aFileURL( m_aURL
);
479 aFileURL
.Append( aStreamName
);
481 uno::Reference
< io::XStream
> xTempResult
;
484 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
485 ::ucbhelper::Content
aResultContent( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
486 uno::Reference
< io::XInputStream
> xInStream
= aResultContent
.openStream();
488 xTempResult
= new utl::TempFileFastService
;
489 uno::Reference
< io::XOutputStream
> xTempOut
= xTempResult
->getOutputStream();
490 uno::Reference
< io::XInputStream
> xTempIn
= xTempResult
->getInputStream();
492 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream
, xTempOut
);
493 xTempOut
->closeOutput();
495 catch( embed::InvalidStorageException
& )
499 catch( lang::IllegalArgumentException
& )
503 catch( packages::WrongPasswordException
& )
507 catch( io::IOException
& )
511 catch( embed::StorageWrappedTargetException
& )
515 catch( uno::RuntimeException
& )
519 catch( uno::Exception
& )
521 uno::Any
aCaught( ::cppu::getCaughtException() );
522 throw embed::StorageWrappedTargetException("Can't copy raw stream",
523 uno::Reference
< io::XInputStream
>(),
530 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::cloneEncryptedStreamElement(
534 throw packages::NoEncryptionException();
537 void SAL_CALL
FSStorage::copyLastCommitTo(
538 const uno::Reference
< embed::XStorage
>& xTargetStorage
)
540 copyToStorage( xTargetStorage
);
543 void SAL_CALL
FSStorage::copyStorageElementLastCommitTo(
544 const OUString
& aStorName
,
545 const uno::Reference
< embed::XStorage
>& xTargetStorage
)
547 std::unique_lock
aGuard( m_aMutex
);
549 uno::Reference
< embed::XStorage
> xSourceStor( openStorageElement( aStorName
, embed::ElementModes::READ
),
550 uno::UNO_SET_THROW
);
551 xSourceStor
->copyToStorage( xTargetStorage
);
554 sal_Bool SAL_CALL
FSStorage::isStreamElement( const OUString
& aElementName
)
556 std::unique_lock
aGuard( m_aMutex
);
558 INetURLObject
aURL( m_aURL
);
559 aURL
.Append( aElementName
);
561 return !::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
564 sal_Bool SAL_CALL
FSStorage::isStorageElement( const OUString
& aElementName
)
566 std::unique_lock
aGuard( m_aMutex
);
568 INetURLObject
aURL( m_aURL
);
569 aURL
.Append( aElementName
);
571 return ::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
574 void SAL_CALL
FSStorage::removeElement( const OUString
& aElementName
)
576 std::unique_lock
aGuard( m_aMutex
);
578 INetURLObject
aURL( m_aURL
);
579 aURL
.Append( aElementName
);
581 if ( !::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) )
582 && !::utl::UCBContentHelper::IsDocument( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
583 throw container::NoSuchElementException(); // TODO:
585 ::utl::UCBContentHelper::Kill( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
588 void SAL_CALL
FSStorage::renameElement( const OUString
& aElementName
, const OUString
& aNewName
)
590 std::unique_lock
aGuard( m_aMutex
);
592 INetURLObject
aOldURL( m_aURL
);
593 aOldURL
.Append( aElementName
);
595 INetURLObject
aNewURL( m_aURL
);
596 aNewURL
.Append( aNewName
);
598 if ( !::utl::UCBContentHelper::IsFolder( aOldURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) )
599 && !::utl::UCBContentHelper::IsDocument( aOldURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
600 throw container::NoSuchElementException(); // TODO:
602 if ( ::utl::UCBContentHelper::IsFolder( aNewURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) )
603 || ::utl::UCBContentHelper::IsDocument( aNewURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
604 throw container::ElementExistException(); // TODO:
608 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
609 ::ucbhelper::Content
aSourceContent( aOldURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
611 m_aContent
.transferContent(aSourceContent
, ::ucbhelper::InsertOperation::Move
, aNewName
,
612 ucb::NameClash::ERROR
);
614 catch( embed::InvalidStorageException
& )
618 catch( lang::IllegalArgumentException
& )
622 catch( container::NoSuchElementException
& )
626 catch( container::ElementExistException
& )
630 catch( io::IOException
& )
634 catch( embed::StorageWrappedTargetException
& )
638 catch( uno::RuntimeException
& )
642 catch( uno::Exception
& )
644 uno::Any
aCaught( ::cppu::getCaughtException() );
645 throw embed::StorageWrappedTargetException("Can't copy raw stream",
646 uno::Reference
< io::XInputStream
>(),
651 void SAL_CALL
FSStorage::copyElementTo( const OUString
& aElementName
,
652 const uno::Reference
< embed::XStorage
>& xDest
,
653 const OUString
& aNewName
)
655 std::unique_lock
aGuard( m_aMutex
);
658 throw uno::RuntimeException();
660 INetURLObject
aOwnURL( m_aURL
);
661 aOwnURL
.Append( aElementName
);
663 if ( xDest
->hasByName( aNewName
) )
664 throw container::ElementExistException(); // TODO:
668 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
669 if ( ::utl::UCBContentHelper::IsFolder( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
671 ::ucbhelper::Content
aSourceContent( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
672 uno::Reference
< embed::XStorage
> xDestSubStor(
673 xDest
->openStorageElement( aNewName
, embed::ElementModes::READWRITE
),
674 uno::UNO_SET_THROW
);
676 CopyContentToStorage_Impl( aSourceContent
, xDestSubStor
);
678 else if ( ::utl::UCBContentHelper::IsDocument( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
680 CopyStreamToSubStream( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDest
, aNewName
);
683 throw container::NoSuchElementException(); // TODO:
685 catch( embed::InvalidStorageException
& )
689 catch( lang::IllegalArgumentException
& )
693 catch( container::NoSuchElementException
& )
697 catch( container::ElementExistException
& )
701 catch( embed::StorageWrappedTargetException
& )
705 catch( io::IOException
& )
709 catch( uno::RuntimeException
& )
713 catch( uno::Exception
& )
715 uno::Any
aCaught( ::cppu::getCaughtException() );
716 throw embed::StorageWrappedTargetException("Can't copy raw stream",
717 uno::Reference
< io::XInputStream
>(),
722 void SAL_CALL
FSStorage::moveElementTo( const OUString
& aElementName
,
723 const uno::Reference
< embed::XStorage
>& xDest
,
724 const OUString
& aNewName
)
726 std::unique_lock
aGuard( m_aMutex
);
727 copyElementTo( aElementName
, xDest
, aNewName
);
729 INetURLObject
aOwnURL( m_aURL
);
730 aOwnURL
.Append( aElementName
);
731 if ( !::utl::UCBContentHelper::Kill( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
732 throw io::IOException(); // TODO: error handling
737 uno::Any SAL_CALL
FSStorage::getByName( const OUString
& aName
)
739 std::unique_lock
aGuard( m_aMutex
);
741 if ( aName
.isEmpty() )
742 throw lang::IllegalArgumentException();
747 INetURLObject
aURL( m_aURL
);
748 aURL
.Append( aName
);
751 if ( ::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
753 aResult
<<= openStorageElementImpl( aGuard
, aName
, embed::ElementModes::READ
);
755 else if ( ::utl::UCBContentHelper::IsDocument( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
757 aResult
<<= openStreamElementImpl( aGuard
, aName
, embed::ElementModes::READ
);
760 throw container::NoSuchElementException(); // TODO:
762 catch (const container::NoSuchElementException
&)
766 catch (const lang::WrappedTargetException
&)
770 catch (const uno::RuntimeException
&)
774 catch (const uno::Exception
&)
776 uno::Any
aCaught( ::cppu::getCaughtException() );
777 throw lang::WrappedTargetException( "Can not open element!",
778 static_cast< OWeakObject
* >( this ),
786 uno::Sequence
< OUString
> SAL_CALL
FSStorage::getElementNames()
788 std::unique_lock
aGuard( m_aMutex
);
790 uno::Sequence
< OUString
> aResult
;
794 uno::Sequence
<OUString
> aProps
{ "Title" };
797 uno::Reference
<sdbc::XResultSet
> xResultSet
798 = m_aContent
.createCursor(aProps
, ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
);
799 uno::Reference
< sdbc::XRow
> xRow( xResultSet
, uno::UNO_QUERY
);
800 if ( xResultSet
.is() )
802 // go through the list
803 while ( xResultSet
->next() )
805 OUString
aName( xRow
->getString( 1 ) );
806 aResult
.realloc( ++nSize
);
807 aResult
.getArray()[nSize
-1] = aName
;
811 catch( const ucb::InteractiveIOException
& r
)
813 if ( r
.Code
== ucb::IOErrorCode_NOT_EXISTING
)
814 OSL_FAIL( "The folder does not exist!" );
817 uno::Any
aCaught( ::cppu::getCaughtException() );
818 throw lang::WrappedTargetRuntimeException( "Can not open storage!",
819 static_cast< OWeakObject
* >( this ),
823 catch (const uno::RuntimeException
&)
827 catch (const uno::Exception
&)
829 uno::Any
aCaught( ::cppu::getCaughtException() );
830 throw lang::WrappedTargetRuntimeException( "Can not open storage!",
831 static_cast< OWeakObject
* >( this ),
838 sal_Bool SAL_CALL
FSStorage::hasByName( const OUString
& aName
)
840 std::unique_lock
aGuard( m_aMutex
);
842 if ( aName
.isEmpty() )
843 throw lang::IllegalArgumentException();
845 INetURLObject
aURL( m_aURL
);
846 aURL
.Append( aName
);
848 return ( ::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) )
849 || ::utl::UCBContentHelper::IsDocument( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) );
852 uno::Type SAL_CALL
FSStorage::getElementType()
854 // it is a multitype container
858 sal_Bool SAL_CALL
FSStorage::hasElements()
860 std::unique_lock
aGuard( m_aMutex
);
864 uno::Sequence
<OUString
> aProps
{ "TargetURL" };
866 uno::Reference
<sdbc::XResultSet
> xResultSet
867 = m_aContent
.createCursor(aProps
, ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
);
868 return ( xResultSet
.is() && xResultSet
->next() );
870 catch (const uno::RuntimeException
&)
874 catch (const uno::Exception
& ex
)
876 css::uno::Any anyEx
= cppu::getCaughtException();
877 throw lang::WrappedTargetRuntimeException( ex
.Message
,
883 void SAL_CALL
FSStorage::dispose()
885 std::unique_lock
aGuard( m_aMutex
);
889 void FSStorage::disposeImpl(std::unique_lock
<std::mutex
>& rGuard
)
891 if ( m_aListenersContainer
.getLength(rGuard
) )
893 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
894 m_aListenersContainer
.disposeAndClear( rGuard
, aSource
);
898 void SAL_CALL
FSStorage::addEventListener(
899 const uno::Reference
< lang::XEventListener
>& xListener
)
901 std::unique_lock
aGuard( m_aMutex
);
903 m_aListenersContainer
.addInterface( aGuard
, xListener
);
906 void SAL_CALL
FSStorage::removeEventListener(
907 const uno::Reference
< lang::XEventListener
>& xListener
)
909 std::unique_lock
aGuard( m_aMutex
);
911 m_aListenersContainer
.removeInterface( aGuard
, xListener
);
916 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
FSStorage::getPropertySetInfo()
919 return uno::Reference
< beans::XPropertySetInfo
>();
923 void SAL_CALL
FSStorage::setPropertyValue( const OUString
& aPropertyName
, const uno::Any
& )
925 if ( aPropertyName
== "URL" || aPropertyName
== "OpenMode" )
926 throw beans::PropertyVetoException(); // TODO
928 throw beans::UnknownPropertyException(aPropertyName
); // TODO
932 uno::Any SAL_CALL
FSStorage::getPropertyValue( const OUString
& aPropertyName
)
934 std::unique_lock
aGuard( m_aMutex
);
936 if ( aPropertyName
== "URL" )
937 return uno::Any( m_aURL
);
938 else if ( aPropertyName
== "OpenMode" )
939 return uno::Any( m_nMode
);
941 throw beans::UnknownPropertyException(aPropertyName
); // TODO
945 void SAL_CALL
FSStorage::addPropertyChangeListener(
946 const OUString
& /*aPropertyName*/,
947 const uno::Reference
< beans::XPropertyChangeListener
>& /*xListener*/ )
953 void SAL_CALL
FSStorage::removePropertyChangeListener(
954 const OUString
& /*aPropertyName*/,
955 const uno::Reference
< beans::XPropertyChangeListener
>& /*aListener*/ )
961 void SAL_CALL
FSStorage::addVetoableChangeListener(
962 const OUString
& /*PropertyName*/,
963 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
969 void SAL_CALL
FSStorage::removeVetoableChangeListener(
970 const OUString
& /*PropertyName*/,
971 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
976 // XHierarchicalStorageAccess
977 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
FSStorage::openStreamElementByHierarchicalName( const OUString
& sStreamPath
, ::sal_Int32 nOpenMode
)
979 std::unique_lock
aGuard( m_aMutex
);
981 if ( sStreamPath
.toChar() == '/' )
982 throw lang::IllegalArgumentException();
984 INetURLObject
aBaseURL( m_aURL
);
985 if ( !aBaseURL
.setFinalSlash() )
986 throw uno::RuntimeException();
988 OUString aFileURL
= INetURLObject::GetAbsURL(
989 aBaseURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
992 if ( ::utl::UCBContentHelper::IsFolder( aFileURL
) )
993 throw io::IOException();
995 if ( ( nOpenMode
& embed::ElementModes::NOCREATE
)
996 && !::utl::UCBContentHelper::IsDocument( aFileURL
) )
997 throw io::IOException(); // TODO:
999 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
; // TODO: provide InteractionHandler if any
1000 uno::Reference
< io::XStream
> xResult
;
1003 if ( nOpenMode
& embed::ElementModes::WRITE
)
1005 if ( comphelper::isFileUrl( aFileURL
) )
1007 uno::Reference
<ucb::XSimpleFileAccess3
> xSimpleFileAccess(
1008 ucb::SimpleFileAccess::create( m_xContext
) );
1009 uno::Reference
< io::XStream
> xStream
=
1010 xSimpleFileAccess
->openFileReadWrite( aFileURL
);
1012 xResult
= new OFSStreamContainer(xStream
);
1016 // TODO: test whether it really works for http and fwp
1017 std::unique_ptr
<SvStream
> pStream
= ::utl::UcbStreamHelper::CreateStream( aFileURL
,
1018 StreamMode::STD_WRITE
);
1019 if ( pStream
&& !pStream
->GetError() )
1021 uno::Reference
< io::XStream
> xStream( new ::utl::OStreamWrapper( std::move(pStream
) ) );
1022 xResult
= new OFSStreamContainer(xStream
);
1026 if ( !xResult
.is() )
1027 throw io::IOException();
1029 if ( nOpenMode
& embed::ElementModes::TRUNCATE
)
1031 uno::Reference
< io::XTruncate
> xTrunc( xResult
->getOutputStream(), uno::UNO_QUERY_THROW
);
1037 if ( ( nOpenMode
& embed::ElementModes::TRUNCATE
)
1038 || !::utl::UCBContentHelper::IsDocument( aFileURL
) )
1039 throw io::IOException(); // TODO: access denied
1041 ::ucbhelper::Content
aResultContent( aFileURL
, xDummyEnv
, comphelper::getProcessComponentContext() );
1042 uno::Reference
< io::XInputStream
> xInStream
= aResultContent
.openStream();
1043 xResult
= new OFSInputStreamContainer(xInStream
);
1046 catch( embed::InvalidStorageException
& )
1050 catch( lang::IllegalArgumentException
& )
1054 catch( packages::WrongPasswordException
& )
1058 catch( embed::StorageWrappedTargetException
& )
1062 catch( io::IOException
& )
1066 catch( uno::RuntimeException
& )
1070 catch( uno::Exception
& )
1072 uno::Any
aCaught( ::cppu::getCaughtException() );
1073 throw embed::StorageWrappedTargetException("Can't copy raw stream",
1074 uno::Reference
< io::XInputStream
>(),
1078 return uno::Reference
< embed::XExtendedStorageStream
>( xResult
, uno::UNO_QUERY_THROW
);
1081 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
FSStorage::openEncryptedStreamElementByHierarchicalName( const OUString
& /*sStreamName*/, ::sal_Int32
/*nOpenMode*/, const OUString
& /*sPassword*/ )
1083 throw packages::NoEncryptionException();
1086 void SAL_CALL
FSStorage::removeStreamElementByHierarchicalName( const OUString
& sStreamPath
)
1088 std::unique_lock
aGuard( m_aMutex
);
1090 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
1091 INetURLObject
aBaseURL( m_aURL
);
1092 if ( !aBaseURL
.setFinalSlash() )
1093 throw uno::RuntimeException();
1095 OUString aFileURL
= INetURLObject::GetAbsURL(
1096 aBaseURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
1099 if ( !::utl::UCBContentHelper::IsDocument( aFileURL
) )
1101 if ( ::utl::UCBContentHelper::IsFolder( aFileURL
) )
1102 throw lang::IllegalArgumentException();
1104 throw container::NoSuchElementException(); // TODO:
1107 if ( !::utl::UCBContentHelper::Kill( aFileURL
) )
1108 throw io::IOException(); // TODO: error handling
1112 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */