LibreOffice Module svl (master) 1
fsstorage.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
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>
28
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>
39
45
46#include <osl/diagnose.h>
47#include <tools/urlobj.hxx>
51#include <unotools/tempfile.hxx>
52#include <ucbhelper/content.hxx>
53
54#include "fsstorage.hxx"
56#include "ostreamcontainer.hxx"
57
58using namespace ::com::sun::star;
59
60FSStorage::FSStorage( const ::ucbhelper::Content& aContent,
61 sal_Int32 nMode,
62 uno::Reference< uno::XComponentContext > const & xContext )
63: m_aURL( aContent.getURL() )
64, m_aContent( aContent )
65, m_nMode( nMode )
66, m_xContext( xContext )
67{
68 OSL_ENSURE( !m_aURL.isEmpty(), "The URL must not be empty" );
69 // TODO: use properties
70 if ( !xContext.is() )
71 throw uno::RuntimeException();
72
73 GetContent();
74}
75
77{
78 std::unique_lock aGuard( m_aMutex );
79 osl_atomic_increment(&m_refCount); // to call dispose
80 try {
81 disposeImpl(aGuard);
82 }
83 catch( uno::RuntimeException& )
84 {}
85}
86
87bool FSStorage::MakeFolderNoUI( std::u16string_view rFolder )
88{
89 INetURLObject aURL( rFolder );
91 aURL.removeSegment();
93 ::ucbhelper::Content aResultContent;
94
96 uno::Reference< ucb::XCommandEnvironment >(),
98 aParent ) )
99 return ::utl::UCBContentHelper::MakeFolder( aParent, aTitle, aResultContent );
100
101 return false;
102}
103
105{
106 std::unique_lock aGuard( m_aMutex );
107 return m_aContent;
108}
109
110void FSStorage::CopyStreamToSubStream( const OUString& aSourceURL,
111 const uno::Reference< embed::XStorage >& xDest,
112 const OUString& aNewEntryName )
113{
114 if ( !xDest.is() )
115 throw uno::RuntimeException();
116
117 uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
118 ::ucbhelper::Content aSourceContent( aSourceURL, xDummyEnv, comphelper::getProcessComponentContext() );
119 uno::Reference< io::XInputStream > xSourceInput = aSourceContent.openStream();
120
121 if ( !xSourceInput.is() )
122 throw io::IOException(); // TODO: error handling
123
124 uno::Reference< io::XStream > xSubStream = xDest->openStreamElement(
125 aNewEntryName,
126 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
127 if ( !xSubStream.is() )
128 throw uno::RuntimeException();
129
130 uno::Reference< io::XOutputStream > xDestOutput = xSubStream->getOutputStream();
131 if ( !xDestOutput.is() )
132 throw uno::RuntimeException();
133
134 ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInput, xDestOutput );
135 xDestOutput->closeOutput();
136}
137
139 const uno::Reference<embed::XStorage>& xDest)
140{
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";
147
148 try
149 {
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() )
154 {
155 // go through the list: insert files as streams, insert folders as substorages using recursion
156 while ( xResultSet->next() )
157 {
158 OUString aSourceURL( xRow->getString( 1 ) );
159 bool bIsFolder( xRow->getBoolean(2) );
160
161 // TODO/LATER: not sure whether the entry name must be encoded
162 OUString aNewEntryName( INetURLObject( aSourceURL ).getName( INetURLObject::LAST_SEGMENT,
163 true,
165 if ( bIsFolder )
166 {
167 uno::Reference< embed::XStorage > xSubStorage = xDest->openStorageElement( aNewEntryName,
168 embed::ElementModes::READWRITE );
169 if ( !xSubStorage.is() )
170 throw uno::RuntimeException();
171
172 uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
173 ::ucbhelper::Content aSourceContent( aSourceURL, xDummyEnv, comphelper::getProcessComponentContext() );
174 CopyContentToStorage_Impl( aSourceContent, xSubStorage );
175 }
176 else
177 {
178 CopyStreamToSubStream( aSourceURL, xDest, aNewEntryName );
179 }
180 }
181 }
182
183 uno::Reference< embed::XTransactedObject > xTransact( xDest, uno::UNO_QUERY );
184 if ( xTransact.is() )
185 xTransact->commit();
186 }
187 catch( ucb::InteractiveIOException& r )
188 {
189 if ( r.Code == ucb::IOErrorCode_NOT_EXISTING )
190 OSL_FAIL( "The folder does not exist!" );
191 else
192 throw;
193 }
194}
195
196// XInterface
197
199{
200 uno::Any aReturn = ::cppu::queryInterface
201 ( rType
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 ) );
209
210 if ( aReturn.hasValue() )
211 return aReturn ;
212
213 return OWeakObject::queryInterface( rType );
214}
215
216void SAL_CALL FSStorage::acquire() noexcept
217{
218 OWeakObject::acquire();
219}
220
221void SAL_CALL FSStorage::release() noexcept
222{
223 OWeakObject::release();
224}
225
226// XTypeProvider
227
228uno::Sequence< uno::Type > SAL_CALL FSStorage::getTypes()
229{
230 static const uno::Sequence<uno::Type> aTypes {
235 return aTypes;
236}
237
238uno::Sequence< sal_Int8 > SAL_CALL FSStorage::getImplementationId()
239{
240 return css::uno::Sequence<sal_Int8>();
241}
242
243// XStorage
244
245void SAL_CALL FSStorage::copyToStorage( const uno::Reference< embed::XStorage >& xDest )
246{
247 std::unique_lock aGuard( m_aMutex );
248
249 if ( !xDest.is() || xDest == getXWeak() )
250 throw lang::IllegalArgumentException(); // TODO:
251
252 try
253 {
255 }
256 catch( embed::InvalidStorageException& )
257 {
258 throw;
259 }
260 catch( lang::IllegalArgumentException& )
261 {
262 throw;
263 }
264 catch( embed::StorageWrappedTargetException& )
265 {
266 throw;
267 }
268 catch( io::IOException& )
269 {
270 throw;
271 }
272 catch( uno::RuntimeException& )
273 {
274 throw;
275 }
276 catch( uno::Exception& )
277 {
278 uno::Any aCaught( ::cppu::getCaughtException() );
279 throw embed::StorageWrappedTargetException("Can't copy raw stream",
280 uno::Reference< io::XInputStream >(),
281 aCaught );
282 }
283}
284
285uno::Reference< io::XStream > SAL_CALL FSStorage::openStreamElement(
286 const OUString& aStreamName, sal_Int32 nOpenMode )
287{
288 std::unique_lock aGuard( m_aMutex );
289 return openStreamElementImpl(aGuard, aStreamName, nOpenMode);
290}
291
292uno::Reference< io::XStream > FSStorage::openStreamElementImpl(
293 std::unique_lock<std::mutex>& /*rGuard*/,
294 std::u16string_view aStreamName, sal_Int32 nOpenMode )
295{
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 );
299
301 throw io::IOException();
302
303 if ( ( nOpenMode & embed::ElementModes::NOCREATE )
305 throw io::IOException(); // TODO:
306
307 uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
308 uno::Reference< io::XStream > xResult;
309 try
310 {
311 if ( nOpenMode & embed::ElementModes::WRITE )
312 {
313 if ( aFileURL.GetProtocol() == INetProtocol::File )
314 {
315 uno::Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess(
316 ucb::SimpleFileAccess::create( m_xContext ) );
317 xResult = xSimpleFileAccess->openFileReadWrite( aFileURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
318 }
319 else
320 {
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) ) );
326 }
327
328 if ( !xResult.is() )
329 throw io::IOException();
330
331 if ( nOpenMode & embed::ElementModes::TRUNCATE )
332 {
333 uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW );
334 xTrunc->truncate();
335 }
336 }
337 else
338 {
339 if ( ( nOpenMode & embed::ElementModes::TRUNCATE )
341 throw io::IOException(); // TODO: access denied
342
344 uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
345 xResult = new OFSInputStreamContainer(xInStream);
346 }
347 }
348 catch( embed::InvalidStorageException& )
349 {
350 throw;
351 }
352 catch( lang::IllegalArgumentException& )
353 {
354 throw;
355 }
356 catch( packages::WrongPasswordException& )
357 {
358 throw;
359 }
360 catch( embed::StorageWrappedTargetException& )
361 {
362 throw;
363 }
364 catch( io::IOException& )
365 {
366 throw;
367 }
368 catch( uno::RuntimeException& )
369 {
370 throw;
371 }
372 catch( uno::Exception& )
373 {
374 uno::Any aCaught( ::cppu::getCaughtException() );
375 throw embed::StorageWrappedTargetException("Can't copy raw stream",
376 uno::Reference< io::XInputStream >(),
377 aCaught );
378 }
379
380 return xResult;
381}
382
383uno::Reference< io::XStream > SAL_CALL FSStorage::openEncryptedStreamElement(
384 const OUString&, sal_Int32, const OUString& )
385{
386 throw packages::NoEncryptionException();
387}
388
389uno::Reference< embed::XStorage > SAL_CALL FSStorage::openStorageElement(
390 const OUString& aStorName, sal_Int32 nStorageMode )
391{
392 std::unique_lock aGuard( m_aMutex );
393 return openStorageElementImpl(aGuard, aStorName, nStorageMode);
394}
395
396uno::Reference< embed::XStorage > FSStorage::openStorageElementImpl(
397 std::unique_lock<std::mutex>& /*rGuard*/,
398 std::u16string_view aStorName, sal_Int32 nStorageMode )
399{
400 if ( ( nStorageMode & embed::ElementModes::WRITE )
401 && !( m_nMode & embed::ElementModes::WRITE ) )
402 throw io::IOException(); // TODO: error handling
403
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 );
407
410 throw io::IOException(); // TODO:
411
412 if ( ( nStorageMode & embed::ElementModes::NOCREATE ) && !bFolderExists )
413 throw io::IOException(); // TODO:
414
415 uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
416 uno::Reference< embed::XStorage > xResult;
417 try
418 {
419 if ( nStorageMode & embed::ElementModes::WRITE )
420 {
421 if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) && bFolderExists )
422 {
423 ::utl::UCBContentHelper::Kill( aFolderURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
424 bFolderExists =
425 MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); // TODO: not atomic :(
426 }
427 else if ( !bFolderExists )
428 {
429 bFolderExists =
430 MakeFolderNoUI( aFolderURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); // TODO: not atomic :(
431 }
432 }
433 else if ( nStorageMode & embed::ElementModes::TRUNCATE )
434 throw io::IOException(); // TODO: access denied
435
436 if ( !bFolderExists )
437 throw io::IOException(); // there is no such folder
438
440 xResult = new FSStorage( aResultContent, nStorageMode, m_xContext );
441 }
442 catch( embed::InvalidStorageException& )
443 {
444 throw;
445 }
446 catch( lang::IllegalArgumentException& )
447 {
448 throw;
449 }
450 catch( embed::StorageWrappedTargetException& )
451 {
452 throw;
453 }
454 catch( io::IOException& )
455 {
456 throw;
457 }
458 catch( uno::RuntimeException& )
459 {
460 throw;
461 }
462 catch( uno::Exception& )
463 {
464 uno::Any aCaught( ::cppu::getCaughtException() );
465 throw embed::StorageWrappedTargetException("Can't copy raw stream",
466 uno::Reference< io::XInputStream >(),
467 aCaught );
468 }
469
470 return xResult;
471}
472
473uno::Reference< io::XStream > SAL_CALL FSStorage::cloneStreamElement( const OUString& aStreamName )
474{
475 std::unique_lock aGuard( m_aMutex );
476
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 );
480
481 uno::Reference < io::XStream > xTempResult;
482 try
483 {
484 uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
486 uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
487
488 xTempResult = new utl::TempFileFastService;
489 uno::Reference < io::XOutputStream > xTempOut = xTempResult->getOutputStream();
490 uno::Reference < io::XInputStream > xTempIn = xTempResult->getInputStream();
491
493 xTempOut->closeOutput();
494 }
495 catch( embed::InvalidStorageException& )
496 {
497 throw;
498 }
499 catch( lang::IllegalArgumentException& )
500 {
501 throw;
502 }
503 catch( packages::WrongPasswordException& )
504 {
505 throw;
506 }
507 catch( io::IOException& )
508 {
509 throw;
510 }
511 catch( embed::StorageWrappedTargetException& )
512 {
513 throw;
514 }
515 catch( uno::RuntimeException& )
516 {
517 throw;
518 }
519 catch( uno::Exception& )
520 {
521 uno::Any aCaught( ::cppu::getCaughtException() );
522 throw embed::StorageWrappedTargetException("Can't copy raw stream",
523 uno::Reference< io::XInputStream >(),
524 aCaught );
525 }
526
527 return xTempResult;
528}
529
530uno::Reference< io::XStream > SAL_CALL FSStorage::cloneEncryptedStreamElement(
531 const OUString&,
532 const OUString& )
533{
534 throw packages::NoEncryptionException();
535}
536
538 const uno::Reference< embed::XStorage >& xTargetStorage )
539{
540 copyToStorage( xTargetStorage );
541}
542
544 const OUString& aStorName,
545 const uno::Reference< embed::XStorage >& xTargetStorage )
546{
547 std::unique_lock aGuard( m_aMutex );
548
549 uno::Reference< embed::XStorage > xSourceStor( openStorageElement( aStorName, embed::ElementModes::READ ),
550 uno::UNO_SET_THROW );
551 xSourceStor->copyToStorage( xTargetStorage );
552}
553
554sal_Bool SAL_CALL FSStorage::isStreamElement( const OUString& aElementName )
555{
556 std::unique_lock aGuard( m_aMutex );
557
559 aURL.Append( aElementName );
560
562}
563
564sal_Bool SAL_CALL FSStorage::isStorageElement( const OUString& aElementName )
565{
566 std::unique_lock aGuard( m_aMutex );
567
569 aURL.Append( aElementName );
570
572}
573
574void SAL_CALL FSStorage::removeElement( const OUString& aElementName )
575{
576 std::unique_lock aGuard( m_aMutex );
577
579 aURL.Append( aElementName );
580
583 throw container::NoSuchElementException(); // TODO:
584
585 ::utl::UCBContentHelper::Kill( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
586}
587
588void SAL_CALL FSStorage::renameElement( const OUString& aElementName, const OUString& aNewName )
589{
590 std::unique_lock aGuard( m_aMutex );
591
592 INetURLObject aOldURL( m_aURL );
593 aOldURL.Append( aElementName );
594
595 INetURLObject aNewURL( m_aURL );
596 aNewURL.Append( aNewName );
597
600 throw container::NoSuchElementException(); // TODO:
601
604 throw container::ElementExistException(); // TODO:
605
606 try
607 {
608 uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
610
612 ucb::NameClash::ERROR);
613 }
614 catch( embed::InvalidStorageException& )
615 {
616 throw;
617 }
618 catch( lang::IllegalArgumentException& )
619 {
620 throw;
621 }
622 catch( container::NoSuchElementException& )
623 {
624 throw;
625 }
626 catch( container::ElementExistException& )
627 {
628 throw;
629 }
630 catch( io::IOException& )
631 {
632 throw;
633 }
634 catch( embed::StorageWrappedTargetException& )
635 {
636 throw;
637 }
638 catch( uno::RuntimeException& )
639 {
640 throw;
641 }
642 catch( uno::Exception& )
643 {
644 uno::Any aCaught( ::cppu::getCaughtException() );
645 throw embed::StorageWrappedTargetException("Can't copy raw stream",
646 uno::Reference< io::XInputStream >(),
647 aCaught );
648 }
649}
650
651void SAL_CALL FSStorage::copyElementTo( const OUString& aElementName,
652 const uno::Reference< embed::XStorage >& xDest,
653 const OUString& aNewName )
654{
655 std::unique_lock aGuard( m_aMutex );
656
657 if ( !xDest.is() )
658 throw uno::RuntimeException();
659
660 INetURLObject aOwnURL( m_aURL );
661 aOwnURL.Append( aElementName );
662
663 if ( xDest->hasByName( aNewName ) )
664 throw container::ElementExistException(); // TODO:
665
666 try
667 {
668 uno::Reference< ucb::XCommandEnvironment > xDummyEnv;
670 {
672 uno::Reference< embed::XStorage > xDestSubStor(
673 xDest->openStorageElement( aNewName, embed::ElementModes::READWRITE ),
674 uno::UNO_SET_THROW );
675
676 CopyContentToStorage_Impl( aSourceContent, xDestSubStor );
677 }
679 {
681 }
682 else
683 throw container::NoSuchElementException(); // TODO:
684 }
685 catch( embed::InvalidStorageException& )
686 {
687 throw;
688 }
689 catch( lang::IllegalArgumentException& )
690 {
691 throw;
692 }
693 catch( container::NoSuchElementException& )
694 {
695 throw;
696 }
697 catch( container::ElementExistException& )
698 {
699 throw;
700 }
701 catch( embed::StorageWrappedTargetException& )
702 {
703 throw;
704 }
705 catch( io::IOException& )
706 {
707 throw;
708 }
709 catch( uno::RuntimeException& )
710 {
711 throw;
712 }
713 catch( uno::Exception& )
714 {
715 uno::Any aCaught( ::cppu::getCaughtException() );
716 throw embed::StorageWrappedTargetException("Can't copy raw stream",
717 uno::Reference< io::XInputStream >(),
718 aCaught );
719 }
720}
721
722void SAL_CALL FSStorage::moveElementTo( const OUString& aElementName,
723 const uno::Reference< embed::XStorage >& xDest,
724 const OUString& aNewName )
725{
726 std::unique_lock aGuard( m_aMutex );
727 copyElementTo( aElementName, xDest, aNewName );
728
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
733}
734
735// XNameAccess
736
737uno::Any SAL_CALL FSStorage::getByName( const OUString& aName )
738{
739 std::unique_lock aGuard( m_aMutex );
740
741 if ( aName.isEmpty() )
742 throw lang::IllegalArgumentException();
743
744 uno::Any aResult;
745 try
746 {
748 aURL.Append( aName );
749
750
752 {
753 aResult <<= openStorageElementImpl( aGuard, aName, embed::ElementModes::READ );
754 }
756 {
757 aResult <<= openStreamElementImpl( aGuard, aName, embed::ElementModes::READ );
758 }
759 else
760 throw container::NoSuchElementException(); // TODO:
761 }
762 catch (const container::NoSuchElementException&)
763 {
764 throw;
765 }
766 catch (const lang::WrappedTargetException&)
767 {
768 throw;
769 }
770 catch (const uno::RuntimeException&)
771 {
772 throw;
773 }
774 catch (const uno::Exception&)
775 {
776 uno::Any aCaught( ::cppu::getCaughtException() );
777 throw lang::WrappedTargetException( "Can not open element!",
778 getXWeak(),
779 aCaught );
780 }
781
782 return aResult;
783}
784
785
786uno::Sequence< OUString > SAL_CALL FSStorage::getElementNames()
787{
788 std::unique_lock aGuard( m_aMutex );
789
790 uno::Sequence< OUString > aResult;
791
792 try
793 {
794 uno::Sequence<OUString> aProps { "Title" };
795
796 sal_Int32 nSize = 0;
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() )
801 {
802 // go through the list
803 while ( xResultSet->next() )
804 {
805 OUString aName( xRow->getString( 1 ) );
806 aResult.realloc( ++nSize );
807 aResult.getArray()[nSize-1] = aName;
808 }
809 }
810 }
811 catch( const ucb::InteractiveIOException& r )
812 {
813 if ( r.Code == ucb::IOErrorCode_NOT_EXISTING )
814 OSL_FAIL( "The folder does not exist!" );
815 else
816 {
817 uno::Any aCaught( ::cppu::getCaughtException() );
818 throw lang::WrappedTargetRuntimeException( "Can not open storage!",
819 getXWeak(),
820 aCaught );
821 }
822 }
823 catch (const uno::RuntimeException&)
824 {
825 throw;
826 }
827 catch (const uno::Exception&)
828 {
829 uno::Any aCaught( ::cppu::getCaughtException() );
830 throw lang::WrappedTargetRuntimeException( "Can not open storage!",
831 getXWeak(),
832 aCaught );
833 }
834
835 return aResult;
836}
837
838sal_Bool SAL_CALL FSStorage::hasByName( const OUString& aName )
839{
840 std::unique_lock aGuard( m_aMutex );
841
842 if ( aName.isEmpty() )
843 throw lang::IllegalArgumentException();
844
846 aURL.Append( aName );
847
850}
851
853{
854 // it is a multitype container
855 return uno::Type();
856}
857
859{
860 std::unique_lock aGuard( m_aMutex );
861
862 try
863 {
864 uno::Sequence<OUString> aProps { "TargetURL" };
865
866 uno::Reference<sdbc::XResultSet> xResultSet
867 = m_aContent.createCursor(aProps, ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS);
868 return ( xResultSet.is() && xResultSet->next() );
869 }
870 catch (const uno::RuntimeException&)
871 {
872 throw;
873 }
874 catch (const uno::Exception& ex)
875 {
876 css::uno::Any anyEx = cppu::getCaughtException();
877 throw lang::WrappedTargetRuntimeException( ex.Message,
878 nullptr, anyEx );
879 }
880}
881
882// XDisposable
883void SAL_CALL FSStorage::dispose()
884{
885 std::unique_lock aGuard( m_aMutex );
886 disposeImpl(aGuard);
887}
888
889void FSStorage::disposeImpl(std::unique_lock<std::mutex>& rGuard)
890{
891 if ( m_aListenersContainer.getLength(rGuard) )
892 {
893 lang::EventObject aSource( getXWeak() );
894 m_aListenersContainer.disposeAndClear( rGuard, aSource );
895 }
896}
897
899 const uno::Reference< lang::XEventListener >& xListener )
900{
901 std::unique_lock aGuard( m_aMutex );
902
903 m_aListenersContainer.addInterface( aGuard, xListener );
904}
905
907 const uno::Reference< lang::XEventListener >& xListener )
908{
909 std::unique_lock aGuard( m_aMutex );
910
911 m_aListenersContainer.removeInterface( aGuard, xListener );
912}
913
914// XPropertySet
915
916uno::Reference< beans::XPropertySetInfo > SAL_CALL FSStorage::getPropertySetInfo()
917{
918 //TODO:
919 return uno::Reference< beans::XPropertySetInfo >();
920}
921
922
923void SAL_CALL FSStorage::setPropertyValue( const OUString& aPropertyName, const uno::Any& )
924{
925 if ( aPropertyName == "URL" || aPropertyName == "OpenMode" )
926 throw beans::PropertyVetoException(); // TODO
927 else
928 throw beans::UnknownPropertyException(aPropertyName); // TODO
929}
930
931
932uno::Any SAL_CALL FSStorage::getPropertyValue( const OUString& aPropertyName )
933{
934 std::unique_lock aGuard( m_aMutex );
935
936 if ( aPropertyName == "URL" )
937 return uno::Any( m_aURL );
938 else if ( aPropertyName == "OpenMode" )
939 return uno::Any( m_nMode );
940
941 throw beans::UnknownPropertyException(aPropertyName); // TODO
942}
943
944
946 const OUString& /*aPropertyName*/,
947 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
948{
949 //TODO:
950}
951
952
954 const OUString& /*aPropertyName*/,
955 const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
956{
957 //TODO:
958}
959
960
962 const OUString& /*PropertyName*/,
963 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
964{
965 //TODO:
966}
967
968
970 const OUString& /*PropertyName*/,
971 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
972{
973 //TODO:
974}
975
976// XHierarchicalStorageAccess
977uno::Reference< embed::XExtendedStorageStream > SAL_CALL FSStorage::openStreamElementByHierarchicalName( const OUString& sStreamPath, ::sal_Int32 nOpenMode )
978{
979 std::unique_lock aGuard( m_aMutex );
980
981 if ( sStreamPath.toChar() == '/' )
982 throw lang::IllegalArgumentException();
983
984 INetURLObject aBaseURL( m_aURL );
985 if ( !aBaseURL.setFinalSlash() )
986 throw uno::RuntimeException();
987
988 OUString aFileURL = INetURLObject::GetAbsURL(
990 sStreamPath );
991
992 if ( ::utl::UCBContentHelper::IsFolder( aFileURL ) )
993 throw io::IOException();
994
995 if ( ( nOpenMode & embed::ElementModes::NOCREATE )
997 throw io::IOException(); // TODO:
998
999 uno::Reference< ucb::XCommandEnvironment > xDummyEnv; // TODO: provide InteractionHandler if any
1000 uno::Reference< io::XStream > xResult;
1001 try
1002 {
1003 if ( nOpenMode & embed::ElementModes::WRITE )
1004 {
1005 if ( comphelper::isFileUrl( aFileURL ) )
1006 {
1007 uno::Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess(
1008 ucb::SimpleFileAccess::create( m_xContext ) );
1009 uno::Reference< io::XStream > xStream =
1010 xSimpleFileAccess->openFileReadWrite( aFileURL );
1011
1012 xResult = new OFSStreamContainer(xStream);
1013 }
1014 else
1015 {
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() )
1020 {
1021 uno::Reference< io::XStream > xStream( new ::utl::OStreamWrapper( std::move(pStream) ) );
1022 xResult = new OFSStreamContainer(xStream);
1023 }
1024 }
1025
1026 if ( !xResult.is() )
1027 throw io::IOException();
1028
1029 if ( nOpenMode & embed::ElementModes::TRUNCATE )
1030 {
1031 uno::Reference< io::XTruncate > xTrunc( xResult->getOutputStream(), uno::UNO_QUERY_THROW );
1032 xTrunc->truncate();
1033 }
1034 }
1035 else
1036 {
1037 if ( ( nOpenMode & embed::ElementModes::TRUNCATE )
1038 || !::utl::UCBContentHelper::IsDocument( aFileURL ) )
1039 throw io::IOException(); // TODO: access denied
1040
1041 ::ucbhelper::Content aResultContent( aFileURL, xDummyEnv, comphelper::getProcessComponentContext() );
1042 uno::Reference< io::XInputStream > xInStream = aResultContent.openStream();
1043 xResult = new OFSInputStreamContainer(xInStream);
1044 }
1045 }
1046 catch( embed::InvalidStorageException& )
1047 {
1048 throw;
1049 }
1050 catch( lang::IllegalArgumentException& )
1051 {
1052 throw;
1053 }
1054 catch( packages::WrongPasswordException& )
1055 {
1056 throw;
1057 }
1058 catch( embed::StorageWrappedTargetException& )
1059 {
1060 throw;
1061 }
1062 catch( io::IOException& )
1063 {
1064 throw;
1065 }
1066 catch( uno::RuntimeException& )
1067 {
1068 throw;
1069 }
1070 catch( uno::Exception& )
1071 {
1072 uno::Any aCaught( ::cppu::getCaughtException() );
1073 throw embed::StorageWrappedTargetException("Can't copy raw stream",
1074 uno::Reference< io::XInputStream >(),
1075 aCaught );
1076 }
1077
1078 return uno::Reference< embed::XExtendedStorageStream >( xResult, uno::UNO_QUERY_THROW );
1079}
1080
1081uno::Reference< embed::XExtendedStorageStream > SAL_CALL FSStorage::openEncryptedStreamElementByHierarchicalName( const OUString& /*sStreamName*/, ::sal_Int32 /*nOpenMode*/, const OUString& /*sPassword*/ )
1082{
1083 throw packages::NoEncryptionException();
1084}
1085
1086void SAL_CALL FSStorage::removeStreamElementByHierarchicalName( const OUString& sStreamPath )
1087{
1088 std::unique_lock aGuard( m_aMutex );
1089
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();
1094
1095 OUString aFileURL = INetURLObject::GetAbsURL(
1097 sStreamPath );
1098
1099 if ( !::utl::UCBContentHelper::IsDocument( aFileURL ) )
1100 {
1101 if ( ::utl::UCBContentHelper::IsFolder( aFileURL ) )
1102 throw lang::IllegalArgumentException();
1103 else
1104 throw container::NoSuchElementException(); // TODO:
1105 }
1106
1107 if ( !::utl::UCBContentHelper::Kill( aFileURL ) )
1108 throw io::IOException(); // TODO: error handling
1109}
1110
1111
1112/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XComponentContext > m_xContext
Reference< XInputStream > xStream
css::util::URL m_aURL
virtual void SAL_CALL dispose() override
Definition: fsstorage.cxx:883
virtual sal_Bool SAL_CALL isStreamElement(const OUString &aElementName) override
Definition: fsstorage.cxx:554
::comphelper::OInterfaceContainerHelper4< css::lang::XEventListener > m_aListenersContainer
Definition: fsstorage.hxx:45
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: fsstorage.cxx:737
virtual void SAL_CALL copyStorageElementLastCommitTo(const OUString &aStorName, const css::uno::Reference< css::embed::XStorage > &xTargetStorage) override
Definition: fsstorage.cxx:543
virtual void SAL_CALL renameElement(const OUString &rEleName, const OUString &rNewName) override
Definition: fsstorage.cxx:588
std::mutex m_aMutex
Definition: fsstorage.hxx:41
css::uno::Reference< css::io::XStream > openStreamElementImpl(std::unique_lock< std::mutex > &rGuard, std::u16string_view aStreamName, sal_Int32 nOpenMode)
Definition: fsstorage.cxx:292
sal_Int32 m_nMode
Definition: fsstorage.hxx:44
void disposeImpl(std::unique_lock< std::mutex > &rGuard)
Definition: fsstorage.cxx:889
virtual void SAL_CALL copyToStorage(const css::uno::Reference< css::embed::XStorage > &xDest) override
Definition: fsstorage.cxx:245
virtual css::uno::Reference< css::embed::XExtendedStorageStream > SAL_CALL openStreamElementByHierarchicalName(const OUString &sStreamPath, ::sal_Int32 nOpenMode) override
Definition: fsstorage.cxx:977
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: fsstorage.cxx:898
virtual void SAL_CALL removeStreamElementByHierarchicalName(const OUString &sElementPath) override
Definition: fsstorage.cxx:1086
virtual sal_Bool SAL_CALL hasElements() override
Definition: fsstorage.cxx:858
virtual sal_Bool SAL_CALL isStorageElement(const OUString &aElementName) override
Definition: fsstorage.cxx:564
FSStorage(const ::ucbhelper::Content &aContent, sal_Int32 nMode, css::uno::Reference< css::uno::XComponentContext > const &xContext)
Definition: fsstorage.cxx:60
OUString m_aURL
Definition: fsstorage.hxx:42
css::uno::Reference< css::embed::XStorage > openStorageElementImpl(std::unique_lock< std::mutex > &rGuard, std::u16string_view aStorName, sal_Int32 nStorageMode)
Definition: fsstorage.cxx:396
virtual void SAL_CALL addPropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: fsstorage.cxx:945
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: fsstorage.cxx:932
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
Definition: fsstorage.cxx:198
virtual void SAL_CALL copyLastCommitTo(const css::uno::Reference< css::embed::XStorage > &xTargetStorage) override
Definition: fsstorage.cxx:537
virtual ~FSStorage() override
Definition: fsstorage.cxx:76
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: fsstorage.cxx:786
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: fsstorage.hxx:46
virtual void SAL_CALL removePropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &aListener) override
Definition: fsstorage.cxx:953
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: fsstorage.cxx:906
static bool MakeFolderNoUI(std::u16string_view rFolder)
Definition: fsstorage.cxx:87
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
Definition: fsstorage.cxx:923
virtual void SAL_CALL copyElementTo(const OUString &aElementName, const css::uno::Reference< css::embed::XStorage > &xDest, const OUString &aNewName) override
Definition: fsstorage.cxx:651
virtual void SAL_CALL removeVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: fsstorage.cxx:969
virtual css::uno::Reference< css::io::XStream > SAL_CALL openStreamElement(const OUString &aStreamName, sal_Int32 nOpenMode) override
Definition: fsstorage.cxx:285
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
Definition: fsstorage.cxx:238
virtual void SAL_CALL acquire() noexcept override
Definition: fsstorage.cxx:216
virtual css::uno::Reference< css::io::XStream > SAL_CALL cloneStreamElement(const OUString &aStreamName) override
Definition: fsstorage.cxx:473
virtual void SAL_CALL release() noexcept override
Definition: fsstorage.cxx:221
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: fsstorage.cxx:838
virtual css::uno::Reference< css::io::XStream > SAL_CALL cloneEncryptedStreamElement(const OUString &aStreamName, const OUString &aPass) override
Definition: fsstorage.cxx:530
virtual css::uno::Reference< css::embed::XStorage > SAL_CALL openStorageElement(const OUString &aStorName, sal_Int32 nStorageMode) override
Definition: fsstorage.cxx:389
void CopyContentToStorage_Impl(ucbhelper::Content &rContent, const css::uno::Reference< css::embed::XStorage > &xDest)
Definition: fsstorage.cxx:138
virtual void SAL_CALL moveElementTo(const OUString &aElementName, const css::uno::Reference< css::embed::XStorage > &xDest, const OUString &rNewName) override
Definition: fsstorage.cxx:722
ucbhelper::Content & GetContent()
Definition: fsstorage.cxx:104
static void CopyStreamToSubStream(const OUString &aSourceURL, const css::uno::Reference< css::embed::XStorage > &xDest, const OUString &aNewEntryName)
Definition: fsstorage.cxx:110
virtual void SAL_CALL removeElement(const OUString &aElementName) override
Definition: fsstorage.cxx:574
virtual css::uno::Reference< css::embed::XExtendedStorageStream > SAL_CALL openEncryptedStreamElementByHierarchicalName(const OUString &sStreamName, ::sal_Int32 nOpenMode, const OUString &sPassword) override
Definition: fsstorage.cxx:1081
::ucbhelper::Content m_aContent
Definition: fsstorage.hxx:43
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: fsstorage.cxx:228
virtual css::uno::Reference< css::io::XStream > SAL_CALL openEncryptedStreamElement(const OUString &aStreamName, sal_Int32 nOpenMode, const OUString &aPass) override
Definition: fsstorage.cxx:383
virtual void SAL_CALL addVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: fsstorage.cxx:961
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: fsstorage.cxx:916
virtual css::uno::Type SAL_CALL getElementType() override
Definition: fsstorage.cxx:852
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
bool setFinalSlash()
static OUString GetAbsURL(std::u16string_view rTheBaseURIRef, OUString const &rTheRelURIRef, EncodeMechanism eEncodeMechanism=EncodeMechanism::WasEncoded, DecodeMechanism eDecodeMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
INetProtocol GetProtocol() const
bool Append(std::u16string_view rTheSegment, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
sal_Int32 addInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
void disposeAndClear(::std::unique_lock<::std::mutex > &rGuard, const css::lang::EventObject &rEvt)
sal_Int32 getLength(std::unique_lock< std::mutex > &rGuard) const
sal_Int32 removeInterface(std::unique_lock< std::mutex > &rGuard, const css::uno::Reference< ListenerT > &rxIFace)
static void CopyInputToOutput(const css::uno::Reference< css::io::XInputStream > &xInput, const css::uno::Reference< css::io::XOutputStream > &xOutput)
oslInterlockedCount m_refCount
css::uno::Type const & get()
void transferContent(const Content &rSourceContent, InsertOperation eOperation, const OUString &rTitle, const sal_Int32 nNameClashAction, const OUString &rMimeType=OUString(), bool bMajorVersion=false, const OUString &rCommentVersion=OUString(), OUString *pResultURL=nullptr, const OUString &rDocumentId=OUString()) const
static bool create(const OUString &rURL, const css::uno::Reference< css::ucb::XCommandEnvironment > &rEnv, const css::uno::Reference< css::uno::XComponentContext > &rCtx, Content &rContent)
css::uno::Reference< css::io::XInputStream > openStream()
css::uno::Reference< css::sdbc::XResultSet > createCursor(const css::uno::Sequence< OUString > &rPropertyNames, ResultSetInclude eMode=INCLUDE_FOLDERS_AND_DOCUMENTS)
virtual css::uno::Reference< css::io::XOutputStream > SAL_CALL getOutputStream() override
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
URL aURL
OUString aName
SVL_DLLPUBLIC bool IsFolder(const OUString &rURL)
Return if under the URL a folder exist.
Definition: fstathelper.cxx:78
SVL_DLLPUBLIC bool IsDocument(const OUString &rURL)
Return if under the URL a document exist.
Definition: fstathelper.cxx:62
COMPHELPER_DLLPUBLIC bool isFileUrl(std::u16string_view url)
Reference< XComponentContext > getProcessComponentContext()
Any SAL_CALL getCaughtException()
bool hasValue()
unsigned char sal_Bool
::ucbhelper::Content m_aContent
const SvXMLTokenMapEntry aTypes[]