Add 'reference' to the iterator_traits, needed by LegacyIterator reqs
[LibreOffice.git] / svl / source / fsstor / fsstorage.cxx
blob91e2e4c49ba243e4c433b2df039884b4d90d83ef
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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,
60 sal_Int32 nMode,
61 uno::Reference< uno::XComponentContext > const & xContext )
62 : m_aURL( aContent.getURL() )
63 , m_aContent( aContent )
64 , m_nMode( nMode )
65 , m_xContext( xContext )
67 OSL_ENSURE( !m_aURL.isEmpty(), "The URL must not be empty" );
68 // TODO: use properties
69 if ( !xContext.is() )
70 throw uno::RuntimeException();
72 GetContent();
75 FSStorage::~FSStorage()
77 ::osl::MutexGuard aGuard( m_aMutex );
78 osl_atomic_increment(&m_refCount); // to call dispose
79 try {
80 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 );
90 aURL.removeSegment();
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(),
97 aParent ) )
98 return ::utl::UCBContentHelper::MakeFolder( aParent, aTitle, aResultContent );
100 return false;
103 ucbhelper::Content& FSStorage::GetContent()
105 ::osl::MutexGuard aGuard( m_aMutex );
106 return m_aContent;
109 void FSStorage::CopyStreamToSubStream( const OUString& aSourceURL,
110 const uno::Reference< embed::XStorage >& xDest,
111 const OUString& aNewEntryName )
113 if ( !xDest.is() )
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(
124 aNewEntryName,
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,
162 true,
163 INetURLObject::DecodeMechanism::NONE ) );
164 if ( bIsFolder )
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 );
175 else
177 CopyStreamToSubStream( aSourceURL, xDest, aNewEntryName );
182 uno::Reference< embed::XTransactedObject > xTransact( xDest, uno::UNO_QUERY );
183 if ( xTransact.is() )
184 xTransact->commit();
186 catch( ucb::InteractiveIOException& r )
188 if ( r.Code == ucb::IOErrorCode_NOT_EXISTING )
189 OSL_FAIL( "The folder does not exist!" );
190 else
191 throw;
195 // XInterface
197 uno::Any SAL_CALL FSStorage::queryInterface( const uno::Type& rType )
199 uno::Any aReturn = ::cppu::queryInterface
200 ( rType
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() )
210 return aReturn ;
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();
225 // XTypeProvider
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() };
234 return aTypes;
237 uno::Sequence< sal_Int8 > SAL_CALL FSStorage::getImplementationId()
239 return css::uno::Sequence<sal_Int8>();
242 // XStorage
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& )
257 throw;
259 catch( lang::IllegalArgumentException& )
261 throw;
263 catch( embed::StorageWrappedTargetException& )
265 throw;
267 catch( io::IOException& )
269 throw;
271 catch( uno::RuntimeException& )
273 throw;
275 catch( uno::Exception& )
277 uno::Any aCaught( ::cppu::getCaughtException() );
278 throw embed::StorageWrappedTargetException("Can't copy raw stream",
279 uno::Reference< io::XInputStream >(),
280 aCaught );
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 ) );
312 else
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) ) );
321 if ( !xResult.is() )
322 throw io::IOException();
324 if ( nOpenMode & embed::ElementModes::TRUNCATE )
326 uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW );
327 xTrunc->truncate();
330 else
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& )
343 throw;
345 catch( lang::IllegalArgumentException& )
347 throw;
349 catch( packages::WrongPasswordException& )
351 throw;
353 catch( embed::StorageWrappedTargetException& )
355 throw;
357 catch( io::IOException& )
359 throw;
361 catch( uno::RuntimeException& )
363 throw;
365 catch( uno::Exception& )
367 uno::Any aCaught( ::cppu::getCaughtException() );
368 throw embed::StorageWrappedTargetException("Can't copy raw stream",
369 uno::Reference< io::XInputStream >(),
370 aCaught );
373 return xResult;
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 ) );
411 bFolderExists =
412 MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); // TODO: not atomic :(
414 else if ( !bFolderExists )
416 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& )
431 throw;
433 catch( lang::IllegalArgumentException& )
435 throw;
437 catch( embed::StorageWrappedTargetException& )
439 throw;
441 catch( io::IOException& )
443 throw;
445 catch( uno::RuntimeException& )
447 throw;
449 catch( uno::Exception& )
451 uno::Any aCaught( ::cppu::getCaughtException() );
452 throw embed::StorageWrappedTargetException("Can't copy raw stream",
453 uno::Reference< io::XInputStream >(),
454 aCaught );
457 return xResult;
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& )
487 throw;
489 catch( lang::IllegalArgumentException& )
491 throw;
493 catch( packages::WrongPasswordException& )
495 throw;
497 catch( io::IOException& )
499 throw;
501 catch( embed::StorageWrappedTargetException& )
503 throw;
505 catch( uno::RuntimeException& )
507 throw;
509 catch( uno::Exception& )
511 uno::Any aCaught( ::cppu::getCaughtException() );
512 throw embed::StorageWrappedTargetException("Can't copy raw stream",
513 uno::Reference< io::XInputStream >(),
514 aCaught );
517 return xTempResult;
520 uno::Reference< io::XStream > SAL_CALL FSStorage::cloneEncryptedStreamElement(
521 const OUString&,
522 const OUString& )
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& )
606 throw;
608 catch( lang::IllegalArgumentException& )
610 throw;
612 catch( container::NoSuchElementException& )
614 throw;
616 catch( container::ElementExistException& )
618 throw;
620 catch( io::IOException& )
622 throw;
624 catch( embed::StorageWrappedTargetException& )
626 throw;
628 catch( uno::RuntimeException& )
630 throw;
632 catch( uno::Exception& )
634 uno::Any aCaught( ::cppu::getCaughtException() );
635 throw embed::StorageWrappedTargetException("Can't copy raw stream",
636 uno::Reference< io::XInputStream >(),
637 aCaught );
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 );
647 if ( !xDest.is() )
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 );
672 else
673 throw container::NoSuchElementException(); // TODO:
675 catch( embed::InvalidStorageException& )
677 throw;
679 catch( lang::IllegalArgumentException& )
681 throw;
683 catch( container::NoSuchElementException& )
685 throw;
687 catch( container::ElementExistException& )
689 throw;
691 catch( embed::StorageWrappedTargetException& )
693 throw;
695 catch( io::IOException& )
697 throw;
699 catch( uno::RuntimeException& )
701 throw;
703 catch( uno::Exception& )
705 uno::Any aCaught( ::cppu::getCaughtException() );
706 throw embed::StorageWrappedTargetException("Can't copy raw stream",
707 uno::Reference< io::XInputStream >(),
708 aCaught );
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
725 // XNameAccess
727 uno::Any SAL_CALL FSStorage::getByName( const OUString& aName )
729 ::osl::MutexGuard aGuard( m_aMutex );
731 if ( aName.isEmpty() )
732 throw lang::IllegalArgumentException();
734 uno::Any aResult;
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 );
749 else
750 throw container::NoSuchElementException(); // TODO:
752 catch (const container::NoSuchElementException&)
754 throw;
756 catch (const lang::WrappedTargetException&)
758 throw;
760 catch (const uno::RuntimeException&)
762 throw;
764 catch (const uno::Exception&)
766 uno::Any aCaught( ::cppu::getCaughtException() );
767 throw lang::WrappedTargetException( "Can not open element!",
768 static_cast< OWeakObject* >( this ),
769 aCaught );
772 return aResult;
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" };
786 sal_Int32 nSize = 0;
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!" );
805 else
807 uno::Any aCaught( ::cppu::getCaughtException() );
808 throw lang::WrappedTargetRuntimeException( "Can not open storage!",
809 static_cast< OWeakObject* >( this ),
810 aCaught );
813 catch (const uno::RuntimeException&)
815 throw;
817 catch (const uno::Exception&)
819 uno::Any aCaught( ::cppu::getCaughtException() );
820 throw lang::WrappedTargetRuntimeException( "Can not open storage!",
821 static_cast< OWeakObject* >( this ),
822 aCaught );
825 return aResult;
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
845 return uno::Type();
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&)
862 throw;
864 catch (const uno::Exception& ex)
866 css::uno::Any anyEx = cppu::getCaughtException();
867 throw lang::WrappedTargetRuntimeException( ex.Message,
868 nullptr, anyEx );
872 // XDisposable
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 );
904 // XPropertySet
906 uno::Reference< beans::XPropertySetInfo > SAL_CALL FSStorage::getPropertySetInfo()
908 //TODO:
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
917 else
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*/ )
939 //TODO:
943 void SAL_CALL FSStorage::removePropertyChangeListener(
944 const OUString& /*aPropertyName*/,
945 const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
947 //TODO:
951 void SAL_CALL FSStorage::addVetoableChangeListener(
952 const OUString& /*PropertyName*/,
953 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
955 //TODO:
959 void SAL_CALL FSStorage::removeVetoableChangeListener(
960 const OUString& /*PropertyName*/,
961 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
963 //TODO:
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 ),
980 sStreamPath );
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);
1004 else
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 );
1022 xTrunc->truncate();
1025 else
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& )
1038 throw;
1040 catch( lang::IllegalArgumentException& )
1042 throw;
1044 catch( packages::WrongPasswordException& )
1046 throw;
1048 catch( embed::StorageWrappedTargetException& )
1050 throw;
1052 catch( io::IOException& )
1054 throw;
1056 catch( uno::RuntimeException& )
1058 throw;
1060 catch( uno::Exception& )
1062 uno::Any aCaught( ::cppu::getCaughtException() );
1063 throw embed::StorageWrappedTargetException("Can't copy raw stream",
1064 uno::Reference< io::XInputStream >(),
1065 aCaught );
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 ),
1087 sStreamPath );
1089 if ( !::utl::UCBContentHelper::IsDocument( aFileURL ) )
1091 if ( ::utl::UCBContentHelper::IsFolder( aFileURL ) )
1092 throw lang::IllegalArgumentException();
1093 else
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: */