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 <ucbhelper/content.hxx>
53 #include "fsstorage.hxx"
54 #include "oinputstreamcontainer.hxx"
55 #include "ostreamcontainer.hxx"
57 using namespace ::com::sun::star
;
59 FSStorage::FSStorage( const ::ucbhelper::Content
& aContent
,
61 uno::Reference
< uno::XComponentContext
> const & xContext
)
62 : m_aURL( aContent
.getURL() )
63 , m_aContent( aContent
)
65 , m_xContext( xContext
)
67 OSL_ENSURE( !m_aURL
.isEmpty(), "The URL must not be empty" );
68 // TODO: use properties
70 throw uno::RuntimeException();
75 FSStorage::~FSStorage()
77 ::osl::MutexGuard
aGuard( m_aMutex
);
78 osl_atomic_increment(&m_refCount
); // to call dispose
82 catch( uno::RuntimeException
& )
86 bool FSStorage::MakeFolderNoUI( const OUString
& rFolder
)
88 INetURLObject
aURL( rFolder
);
89 OUString aTitle
= aURL
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DecodeMechanism::WithCharset
);
91 ::ucbhelper::Content aParent
;
92 ::ucbhelper::Content aResultContent
;
94 if ( ::ucbhelper::Content::create( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
95 uno::Reference
< ucb::XCommandEnvironment
>(),
96 comphelper::getProcessComponentContext(),
98 return ::utl::UCBContentHelper::MakeFolder( aParent
, aTitle
, aResultContent
);
103 ucbhelper::Content
& FSStorage::GetContent()
105 ::osl::MutexGuard
aGuard( m_aMutex
);
109 void FSStorage::CopyStreamToSubStream( const OUString
& aSourceURL
,
110 const uno::Reference
< embed::XStorage
>& xDest
,
111 const OUString
& aNewEntryName
)
114 throw uno::RuntimeException();
116 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
117 ::ucbhelper::Content
aSourceContent( aSourceURL
, xDummyEnv
, comphelper::getProcessComponentContext() );
118 uno::Reference
< io::XInputStream
> xSourceInput
= aSourceContent
.openStream();
120 if ( !xSourceInput
.is() )
121 throw io::IOException(); // TODO: error handling
123 uno::Reference
< io::XStream
> xSubStream
= xDest
->openStreamElement(
125 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
126 if ( !xSubStream
.is() )
127 throw uno::RuntimeException();
129 uno::Reference
< io::XOutputStream
> xDestOutput
= xSubStream
->getOutputStream();
130 if ( !xDestOutput
.is() )
131 throw uno::RuntimeException();
133 ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInput
, xDestOutput
);
134 xDestOutput
->closeOutput();
137 void FSStorage::CopyContentToStorage_Impl(ucbhelper::Content
& rContent
,
138 const uno::Reference
<embed::XStorage
>& xDest
)
140 // get list of contents of the Content
141 // create cursor for access to children
142 uno::Sequence
< OUString
> aProps( 2 );
143 OUString
* pProps
= aProps
.getArray();
144 pProps
[0] = "TargetURL";
145 pProps
[1] = "IsFolder";
149 uno::Reference
<sdbc::XResultSet
> xResultSet
150 = rContent
.createCursor(aProps
, ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
);
151 uno::Reference
< sdbc::XRow
> xRow( xResultSet
, uno::UNO_QUERY
);
152 if ( xResultSet
.is() )
154 // go through the list: insert files as streams, insert folders as substorages using recursion
155 while ( xResultSet
->next() )
157 OUString
aSourceURL( xRow
->getString( 1 ) );
158 bool bIsFolder( xRow
->getBoolean(2) );
160 // TODO/LATER: not sure whether the entry name must be encoded
161 OUString
aNewEntryName( INetURLObject( aSourceURL
).getName( INetURLObject::LAST_SEGMENT
,
163 INetURLObject::DecodeMechanism::NONE
) );
166 uno::Reference
< embed::XStorage
> xSubStorage
= xDest
->openStorageElement( aNewEntryName
,
167 embed::ElementModes::READWRITE
);
168 if ( !xSubStorage
.is() )
169 throw uno::RuntimeException();
171 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
172 ::ucbhelper::Content
aSourceContent( aSourceURL
, xDummyEnv
, comphelper::getProcessComponentContext() );
173 CopyContentToStorage_Impl( aSourceContent
, xSubStorage
);
177 CopyStreamToSubStream( aSourceURL
, xDest
, aNewEntryName
);
182 uno::Reference
< embed::XTransactedObject
> xTransact( xDest
, uno::UNO_QUERY
);
183 if ( xTransact
.is() )
186 catch( ucb::InteractiveIOException
& r
)
188 if ( r
.Code
== ucb::IOErrorCode_NOT_EXISTING
)
189 OSL_FAIL( "The folder does not exist!" );
197 uno::Any SAL_CALL
FSStorage::queryInterface( const uno::Type
& rType
)
199 uno::Any aReturn
= ::cppu::queryInterface
201 , static_cast<lang::XTypeProvider
*> ( this )
202 , static_cast<embed::XStorage
*> ( this )
203 , static_cast<embed::XHierarchicalStorageAccess
*> ( this )
204 , static_cast<container::XNameAccess
*> ( this )
205 , static_cast<container::XElementAccess
*> ( this )
206 , static_cast<lang::XComponent
*> ( this )
207 , static_cast<beans::XPropertySet
*> ( this ) );
209 if ( aReturn
.hasValue() )
212 return OWeakObject::queryInterface( rType
);
215 void SAL_CALL
FSStorage::acquire() noexcept
217 OWeakObject::acquire();
220 void SAL_CALL
FSStorage::release() noexcept
222 OWeakObject::release();
227 uno::Sequence
< uno::Type
> SAL_CALL
FSStorage::getTypes()
229 static const uno::Sequence
<uno::Type
> aTypes
{
230 cppu::UnoType
<lang::XTypeProvider
>::get(),
231 cppu::UnoType
<embed::XStorage
>::get(),
232 cppu::UnoType
<embed::XHierarchicalStorageAccess
>::get(),
233 cppu::UnoType
<beans::XPropertySet
>::get() };
237 uno::Sequence
< sal_Int8
> SAL_CALL
FSStorage::getImplementationId()
239 return css::uno::Sequence
<sal_Int8
>();
244 void SAL_CALL
FSStorage::copyToStorage( const uno::Reference
< embed::XStorage
>& xDest
)
246 ::osl::MutexGuard
aGuard( m_aMutex
);
248 if ( !xDest
.is() || xDest
== uno::Reference
< uno::XInterface
>( static_cast< OWeakObject
*> ( this ), uno::UNO_QUERY
) )
249 throw lang::IllegalArgumentException(); // TODO:
253 CopyContentToStorage_Impl( GetContent(), xDest
);
255 catch( embed::InvalidStorageException
& )
259 catch( lang::IllegalArgumentException
& )
263 catch( embed::StorageWrappedTargetException
& )
267 catch( io::IOException
& )
271 catch( uno::RuntimeException
& )
275 catch( uno::Exception
& )
277 uno::Any
aCaught( ::cppu::getCaughtException() );
278 throw embed::StorageWrappedTargetException("Can't copy raw stream",
279 uno::Reference
< io::XInputStream
>(),
284 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::openStreamElement(
285 const OUString
& aStreamName
, sal_Int32 nOpenMode
)
287 ::osl::MutexGuard
aGuard( m_aMutex
);
289 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
290 INetURLObject
aFileURL( m_aURL
);
291 aFileURL
.Append( aStreamName
);
293 if ( ::utl::UCBContentHelper::IsFolder( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
294 throw io::IOException();
296 if ( ( nOpenMode
& embed::ElementModes::NOCREATE
)
297 && !::utl::UCBContentHelper::IsDocument( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
298 throw io::IOException(); // TODO:
300 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
; // TODO: provide InteractionHandler if any
301 uno::Reference
< io::XStream
> xResult
;
304 if ( nOpenMode
& embed::ElementModes::WRITE
)
306 if ( aFileURL
.GetProtocol() == INetProtocol::File
)
308 uno::Reference
<ucb::XSimpleFileAccess3
> xSimpleFileAccess(
309 ucb::SimpleFileAccess::create( m_xContext
) );
310 xResult
= xSimpleFileAccess
->openFileReadWrite( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
314 // TODO: test whether it really works for http and fwp
315 std::unique_ptr
<SvStream
> pStream
= ::utl::UcbStreamHelper::CreateStream( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
316 StreamMode::STD_WRITE
);
317 if ( pStream
&& !pStream
->GetError() )
318 xResult
.set( new ::utl::OStreamWrapper( std::move(pStream
) ) );
322 throw io::IOException();
324 if ( nOpenMode
& embed::ElementModes::TRUNCATE
)
326 uno::Reference
< io::XTruncate
> xTrunc( xResult
->getOutputStream(), uno::UNO_QUERY_THROW
);
332 if ( ( nOpenMode
& embed::ElementModes::TRUNCATE
)
333 || !::utl::UCBContentHelper::IsDocument( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
334 throw io::IOException(); // TODO: access denied
336 ::ucbhelper::Content
aResultContent( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
337 uno::Reference
< io::XInputStream
> xInStream
= aResultContent
.openStream();
338 xResult
= new OFSInputStreamContainer(xInStream
);
341 catch( embed::InvalidStorageException
& )
345 catch( lang::IllegalArgumentException
& )
349 catch( packages::WrongPasswordException
& )
353 catch( embed::StorageWrappedTargetException
& )
357 catch( io::IOException
& )
361 catch( uno::RuntimeException
& )
365 catch( uno::Exception
& )
367 uno::Any
aCaught( ::cppu::getCaughtException() );
368 throw embed::StorageWrappedTargetException("Can't copy raw stream",
369 uno::Reference
< io::XInputStream
>(),
376 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::openEncryptedStreamElement(
377 const OUString
&, sal_Int32
, const OUString
& )
379 throw packages::NoEncryptionException();
382 uno::Reference
< embed::XStorage
> SAL_CALL
FSStorage::openStorageElement(
383 const OUString
& aStorName
, sal_Int32 nStorageMode
)
385 ::osl::MutexGuard
aGuard( m_aMutex
);
387 if ( ( nStorageMode
& embed::ElementModes::WRITE
)
388 && !( m_nMode
& embed::ElementModes::WRITE
) )
389 throw io::IOException(); // TODO: error handling
391 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
392 INetURLObject
aFolderURL( m_aURL
);
393 aFolderURL
.Append( aStorName
);
395 bool bFolderExists
= ::utl::UCBContentHelper::IsFolder( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
396 if ( !bFolderExists
&& ::utl::UCBContentHelper::IsDocument( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
397 throw io::IOException(); // TODO:
399 if ( ( nStorageMode
& embed::ElementModes::NOCREATE
) && !bFolderExists
)
400 throw io::IOException(); // TODO:
402 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
; // TODO: provide InteractionHandler if any
403 uno::Reference
< embed::XStorage
> xResult
;
406 if ( nStorageMode
& embed::ElementModes::WRITE
)
408 if ( ( nStorageMode
& embed::ElementModes::TRUNCATE
) && bFolderExists
)
410 ::utl::UCBContentHelper::Kill( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
412 MakeFolderNoUI( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ); // TODO: not atomic :(
414 else if ( !bFolderExists
)
417 MakeFolderNoUI( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ); // TODO: not atomic :(
420 else if ( nStorageMode
& embed::ElementModes::TRUNCATE
)
421 throw io::IOException(); // TODO: access denied
423 if ( !bFolderExists
)
424 throw io::IOException(); // there is no such folder
426 ::ucbhelper::Content
aResultContent( aFolderURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
427 xResult
= new FSStorage( aResultContent
, nStorageMode
, m_xContext
);
429 catch( embed::InvalidStorageException
& )
433 catch( lang::IllegalArgumentException
& )
437 catch( embed::StorageWrappedTargetException
& )
441 catch( io::IOException
& )
445 catch( uno::RuntimeException
& )
449 catch( uno::Exception
& )
451 uno::Any
aCaught( ::cppu::getCaughtException() );
452 throw embed::StorageWrappedTargetException("Can't copy raw stream",
453 uno::Reference
< io::XInputStream
>(),
460 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::cloneStreamElement( const OUString
& aStreamName
)
462 ::osl::MutexGuard
aGuard( m_aMutex
);
464 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
465 INetURLObject
aFileURL( m_aURL
);
466 aFileURL
.Append( aStreamName
);
468 uno::Reference
< io::XStream
> xTempResult
;
471 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
472 ::ucbhelper::Content
aResultContent( aFileURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
473 uno::Reference
< io::XInputStream
> xInStream
= aResultContent
.openStream();
475 xTempResult
= io::TempFile::create(m_xContext
);
476 uno::Reference
< io::XOutputStream
> xTempOut
= xTempResult
->getOutputStream();
477 uno::Reference
< io::XInputStream
> xTempIn
= xTempResult
->getInputStream();
479 if ( !xTempOut
.is() || !xTempIn
.is() )
480 throw io::IOException();
482 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream
, xTempOut
);
483 xTempOut
->closeOutput();
485 catch( embed::InvalidStorageException
& )
489 catch( lang::IllegalArgumentException
& )
493 catch( packages::WrongPasswordException
& )
497 catch( io::IOException
& )
501 catch( embed::StorageWrappedTargetException
& )
505 catch( uno::RuntimeException
& )
509 catch( uno::Exception
& )
511 uno::Any
aCaught( ::cppu::getCaughtException() );
512 throw embed::StorageWrappedTargetException("Can't copy raw stream",
513 uno::Reference
< io::XInputStream
>(),
520 uno::Reference
< io::XStream
> SAL_CALL
FSStorage::cloneEncryptedStreamElement(
524 throw packages::NoEncryptionException();
527 void SAL_CALL
FSStorage::copyLastCommitTo(
528 const uno::Reference
< embed::XStorage
>& xTargetStorage
)
530 copyToStorage( xTargetStorage
);
533 void SAL_CALL
FSStorage::copyStorageElementLastCommitTo(
534 const OUString
& aStorName
,
535 const uno::Reference
< embed::XStorage
>& xTargetStorage
)
537 ::osl::MutexGuard
aGuard( m_aMutex
);
539 uno::Reference
< embed::XStorage
> xSourceStor( openStorageElement( aStorName
, embed::ElementModes::READ
),
540 uno::UNO_SET_THROW
);
541 xSourceStor
->copyToStorage( xTargetStorage
);
544 sal_Bool SAL_CALL
FSStorage::isStreamElement( const OUString
& aElementName
)
546 ::osl::MutexGuard
aGuard( m_aMutex
);
548 INetURLObject
aURL( m_aURL
);
549 aURL
.Append( aElementName
);
551 return !::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
554 sal_Bool SAL_CALL
FSStorage::isStorageElement( const OUString
& aElementName
)
556 ::osl::MutexGuard
aGuard( m_aMutex
);
558 INetURLObject
aURL( m_aURL
);
559 aURL
.Append( aElementName
);
561 return ::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
564 void SAL_CALL
FSStorage::removeElement( const OUString
& aElementName
)
566 ::osl::MutexGuard
aGuard( m_aMutex
);
568 INetURLObject
aURL( m_aURL
);
569 aURL
.Append( aElementName
);
571 if ( !::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) )
572 && !::utl::UCBContentHelper::IsDocument( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
573 throw container::NoSuchElementException(); // TODO:
575 ::utl::UCBContentHelper::Kill( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) );
578 void SAL_CALL
FSStorage::renameElement( const OUString
& aElementName
, const OUString
& aNewName
)
580 ::osl::MutexGuard
aGuard( m_aMutex
);
582 INetURLObject
aOldURL( m_aURL
);
583 aOldURL
.Append( aElementName
);
585 INetURLObject
aNewURL( m_aURL
);
586 aNewURL
.Append( aNewName
);
588 if ( !::utl::UCBContentHelper::IsFolder( aOldURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) )
589 && !::utl::UCBContentHelper::IsDocument( aOldURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
590 throw container::NoSuchElementException(); // TODO:
592 if ( ::utl::UCBContentHelper::IsFolder( aNewURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) )
593 || ::utl::UCBContentHelper::IsDocument( aNewURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
594 throw container::ElementExistException(); // TODO:
598 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
599 ::ucbhelper::Content
aSourceContent( aOldURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
601 GetContent().transferContent(aSourceContent
, ::ucbhelper::InsertOperation::Move
, aNewName
,
602 ucb::NameClash::ERROR
);
604 catch( embed::InvalidStorageException
& )
608 catch( lang::IllegalArgumentException
& )
612 catch( container::NoSuchElementException
& )
616 catch( container::ElementExistException
& )
620 catch( io::IOException
& )
624 catch( embed::StorageWrappedTargetException
& )
628 catch( uno::RuntimeException
& )
632 catch( uno::Exception
& )
634 uno::Any
aCaught( ::cppu::getCaughtException() );
635 throw embed::StorageWrappedTargetException("Can't copy raw stream",
636 uno::Reference
< io::XInputStream
>(),
641 void SAL_CALL
FSStorage::copyElementTo( const OUString
& aElementName
,
642 const uno::Reference
< embed::XStorage
>& xDest
,
643 const OUString
& aNewName
)
645 ::osl::MutexGuard
aGuard( m_aMutex
);
648 throw uno::RuntimeException();
650 INetURLObject
aOwnURL( m_aURL
);
651 aOwnURL
.Append( aElementName
);
653 if ( xDest
->hasByName( aNewName
) )
654 throw container::ElementExistException(); // TODO:
658 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
;
659 if ( ::utl::UCBContentHelper::IsFolder( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
661 ::ucbhelper::Content
aSourceContent( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDummyEnv
, comphelper::getProcessComponentContext() );
662 uno::Reference
< embed::XStorage
> xDestSubStor(
663 xDest
->openStorageElement( aNewName
, embed::ElementModes::READWRITE
),
664 uno::UNO_SET_THROW
);
666 CopyContentToStorage_Impl( aSourceContent
, xDestSubStor
);
668 else if ( ::utl::UCBContentHelper::IsDocument( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
670 CopyStreamToSubStream( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), xDest
, aNewName
);
673 throw container::NoSuchElementException(); // TODO:
675 catch( embed::InvalidStorageException
& )
679 catch( lang::IllegalArgumentException
& )
683 catch( container::NoSuchElementException
& )
687 catch( container::ElementExistException
& )
691 catch( embed::StorageWrappedTargetException
& )
695 catch( io::IOException
& )
699 catch( uno::RuntimeException
& )
703 catch( uno::Exception
& )
705 uno::Any
aCaught( ::cppu::getCaughtException() );
706 throw embed::StorageWrappedTargetException("Can't copy raw stream",
707 uno::Reference
< io::XInputStream
>(),
712 void SAL_CALL
FSStorage::moveElementTo( const OUString
& aElementName
,
713 const uno::Reference
< embed::XStorage
>& xDest
,
714 const OUString
& aNewName
)
716 ::osl::MutexGuard
aGuard( m_aMutex
);
717 copyElementTo( aElementName
, xDest
, aNewName
);
719 INetURLObject
aOwnURL( m_aURL
);
720 aOwnURL
.Append( aElementName
);
721 if ( !::utl::UCBContentHelper::Kill( aOwnURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
722 throw io::IOException(); // TODO: error handling
727 uno::Any SAL_CALL
FSStorage::getByName( const OUString
& aName
)
729 ::osl::MutexGuard
aGuard( m_aMutex
);
731 if ( aName
.isEmpty() )
732 throw lang::IllegalArgumentException();
737 INetURLObject
aURL( m_aURL
);
738 aURL
.Append( aName
);
741 if ( ::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
743 aResult
<<= openStorageElement( aName
, embed::ElementModes::READ
);
745 else if ( ::utl::UCBContentHelper::IsDocument( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) )
747 aResult
<<= openStreamElement( aName
, embed::ElementModes::READ
);
750 throw container::NoSuchElementException(); // TODO:
752 catch (const container::NoSuchElementException
&)
756 catch (const lang::WrappedTargetException
&)
760 catch (const uno::RuntimeException
&)
764 catch (const uno::Exception
&)
766 uno::Any
aCaught( ::cppu::getCaughtException() );
767 throw lang::WrappedTargetException( "Can not open element!",
768 static_cast< OWeakObject
* >( this ),
776 uno::Sequence
< OUString
> SAL_CALL
FSStorage::getElementNames()
778 ::osl::MutexGuard
aGuard( m_aMutex
);
780 uno::Sequence
< OUString
> aResult
;
784 uno::Sequence
<OUString
> aProps
{ "Title" };
787 uno::Reference
<sdbc::XResultSet
> xResultSet
788 = GetContent().createCursor(aProps
, ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
);
789 uno::Reference
< sdbc::XRow
> xRow( xResultSet
, uno::UNO_QUERY
);
790 if ( xResultSet
.is() )
792 // go through the list
793 while ( xResultSet
->next() )
795 OUString
aName( xRow
->getString( 1 ) );
796 aResult
.realloc( ++nSize
);
797 aResult
.getArray()[nSize
-1] = aName
;
801 catch( const ucb::InteractiveIOException
& r
)
803 if ( r
.Code
== ucb::IOErrorCode_NOT_EXISTING
)
804 OSL_FAIL( "The folder does not exist!" );
807 uno::Any
aCaught( ::cppu::getCaughtException() );
808 throw lang::WrappedTargetRuntimeException( "Can not open storage!",
809 static_cast< OWeakObject
* >( this ),
813 catch (const uno::RuntimeException
&)
817 catch (const uno::Exception
&)
819 uno::Any
aCaught( ::cppu::getCaughtException() );
820 throw lang::WrappedTargetRuntimeException( "Can not open storage!",
821 static_cast< OWeakObject
* >( this ),
828 sal_Bool SAL_CALL
FSStorage::hasByName( const OUString
& aName
)
830 ::osl::MutexGuard
aGuard( m_aMutex
);
832 if ( aName
.isEmpty() )
833 throw lang::IllegalArgumentException();
835 INetURLObject
aURL( m_aURL
);
836 aURL
.Append( aName
);
838 return ( ::utl::UCBContentHelper::IsFolder( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) )
839 || ::utl::UCBContentHelper::IsDocument( aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) );
842 uno::Type SAL_CALL
FSStorage::getElementType()
844 // it is a multitype container
848 sal_Bool SAL_CALL
FSStorage::hasElements()
850 ::osl::MutexGuard
aGuard( m_aMutex
);
854 uno::Sequence
<OUString
> aProps
{ "TargetURL" };
856 uno::Reference
<sdbc::XResultSet
> xResultSet
857 = GetContent().createCursor(aProps
, ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS
);
858 return ( xResultSet
.is() && xResultSet
->next() );
860 catch (const uno::RuntimeException
&)
864 catch (const uno::Exception
& ex
)
866 css::uno::Any anyEx
= cppu::getCaughtException();
867 throw lang::WrappedTargetRuntimeException( ex
.Message
,
873 void SAL_CALL
FSStorage::dispose()
875 ::osl::MutexGuard
aGuard( m_aMutex
);
877 if ( m_pListenersContainer
)
879 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
880 m_pListenersContainer
->disposeAndClear( aSource
);
884 void SAL_CALL
FSStorage::addEventListener(
885 const uno::Reference
< lang::XEventListener
>& xListener
)
887 ::osl::MutexGuard
aGuard( m_aMutex
);
889 if ( !m_pListenersContainer
)
890 m_pListenersContainer
.reset(new ::comphelper::OInterfaceContainerHelper2( m_aMutex
));
892 m_pListenersContainer
->addInterface( xListener
);
895 void SAL_CALL
FSStorage::removeEventListener(
896 const uno::Reference
< lang::XEventListener
>& xListener
)
898 ::osl::MutexGuard
aGuard( m_aMutex
);
900 if ( m_pListenersContainer
)
901 m_pListenersContainer
->removeInterface( xListener
);
906 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
FSStorage::getPropertySetInfo()
909 return uno::Reference
< beans::XPropertySetInfo
>();
913 void SAL_CALL
FSStorage::setPropertyValue( const OUString
& aPropertyName
, const uno::Any
& )
915 if ( aPropertyName
== "URL" || aPropertyName
== "OpenMode" )
916 throw beans::PropertyVetoException(); // TODO
918 throw beans::UnknownPropertyException(aPropertyName
); // TODO
922 uno::Any SAL_CALL
FSStorage::getPropertyValue( const OUString
& aPropertyName
)
924 ::osl::MutexGuard
aGuard( m_aMutex
);
926 if ( aPropertyName
== "URL" )
927 return uno::makeAny( m_aURL
);
928 else if ( aPropertyName
== "OpenMode" )
929 return uno::makeAny( m_nMode
);
931 throw beans::UnknownPropertyException(aPropertyName
); // TODO
935 void SAL_CALL
FSStorage::addPropertyChangeListener(
936 const OUString
& /*aPropertyName*/,
937 const uno::Reference
< beans::XPropertyChangeListener
>& /*xListener*/ )
943 void SAL_CALL
FSStorage::removePropertyChangeListener(
944 const OUString
& /*aPropertyName*/,
945 const uno::Reference
< beans::XPropertyChangeListener
>& /*aListener*/ )
951 void SAL_CALL
FSStorage::addVetoableChangeListener(
952 const OUString
& /*PropertyName*/,
953 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
959 void SAL_CALL
FSStorage::removeVetoableChangeListener(
960 const OUString
& /*PropertyName*/,
961 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
966 // XHierarchicalStorageAccess
967 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
FSStorage::openStreamElementByHierarchicalName( const OUString
& sStreamPath
, ::sal_Int32 nOpenMode
)
969 ::osl::MutexGuard
aGuard( m_aMutex
);
971 if ( sStreamPath
.toChar() == '/' )
972 throw lang::IllegalArgumentException();
974 INetURLObject
aBaseURL( m_aURL
);
975 if ( !aBaseURL
.setFinalSlash() )
976 throw uno::RuntimeException();
978 OUString aFileURL
= INetURLObject::GetAbsURL(
979 aBaseURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
982 if ( ::utl::UCBContentHelper::IsFolder( aFileURL
) )
983 throw io::IOException();
985 if ( ( nOpenMode
& embed::ElementModes::NOCREATE
)
986 && !::utl::UCBContentHelper::IsDocument( aFileURL
) )
987 throw io::IOException(); // TODO:
989 uno::Reference
< ucb::XCommandEnvironment
> xDummyEnv
; // TODO: provide InteractionHandler if any
990 uno::Reference
< io::XStream
> xResult
;
993 if ( nOpenMode
& embed::ElementModes::WRITE
)
995 if ( comphelper::isFileUrl( aFileURL
) )
997 uno::Reference
<ucb::XSimpleFileAccess3
> xSimpleFileAccess(
998 ucb::SimpleFileAccess::create( m_xContext
) );
999 uno::Reference
< io::XStream
> xStream
=
1000 xSimpleFileAccess
->openFileReadWrite( aFileURL
);
1002 xResult
= new OFSStreamContainer(xStream
);
1006 // TODO: test whether it really works for http and fwp
1007 std::unique_ptr
<SvStream
> pStream
= ::utl::UcbStreamHelper::CreateStream( aFileURL
,
1008 StreamMode::STD_WRITE
);
1009 if ( pStream
&& !pStream
->GetError() )
1011 uno::Reference
< io::XStream
> xStream( new ::utl::OStreamWrapper( std::move(pStream
) ) );
1012 xResult
= new OFSStreamContainer(xStream
);
1016 if ( !xResult
.is() )
1017 throw io::IOException();
1019 if ( nOpenMode
& embed::ElementModes::TRUNCATE
)
1021 uno::Reference
< io::XTruncate
> xTrunc( xResult
->getOutputStream(), uno::UNO_QUERY_THROW
);
1027 if ( ( nOpenMode
& embed::ElementModes::TRUNCATE
)
1028 || !::utl::UCBContentHelper::IsDocument( aFileURL
) )
1029 throw io::IOException(); // TODO: access denied
1031 ::ucbhelper::Content
aResultContent( aFileURL
, xDummyEnv
, comphelper::getProcessComponentContext() );
1032 uno::Reference
< io::XInputStream
> xInStream
= aResultContent
.openStream();
1033 xResult
= new OFSInputStreamContainer(xInStream
);
1036 catch( embed::InvalidStorageException
& )
1040 catch( lang::IllegalArgumentException
& )
1044 catch( packages::WrongPasswordException
& )
1048 catch( embed::StorageWrappedTargetException
& )
1052 catch( io::IOException
& )
1056 catch( uno::RuntimeException
& )
1060 catch( uno::Exception
& )
1062 uno::Any
aCaught( ::cppu::getCaughtException() );
1063 throw embed::StorageWrappedTargetException("Can't copy raw stream",
1064 uno::Reference
< io::XInputStream
>(),
1068 return uno::Reference
< embed::XExtendedStorageStream
>( xResult
, uno::UNO_QUERY_THROW
);
1071 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
FSStorage::openEncryptedStreamElementByHierarchicalName( const OUString
& /*sStreamName*/, ::sal_Int32
/*nOpenMode*/, const OUString
& /*sPassword*/ )
1073 throw packages::NoEncryptionException();
1076 void SAL_CALL
FSStorage::removeStreamElementByHierarchicalName( const OUString
& sStreamPath
)
1078 ::osl::MutexGuard
aGuard( m_aMutex
);
1080 // TODO/LATER: may need possibility to create folder if it was removed, since the folder can not be locked
1081 INetURLObject
aBaseURL( m_aURL
);
1082 if ( !aBaseURL
.setFinalSlash() )
1083 throw uno::RuntimeException();
1085 OUString aFileURL
= INetURLObject::GetAbsURL(
1086 aBaseURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
1089 if ( !::utl::UCBContentHelper::IsDocument( aFileURL
) )
1091 if ( ::utl::UCBContentHelper::IsFolder( aFileURL
) )
1092 throw lang::IllegalArgumentException();
1094 throw container::NoSuchElementException(); // TODO:
1097 if ( !::utl::UCBContentHelper::Kill( aFileURL
) )
1098 throw io::IOException(); // TODO: error handling
1102 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */