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 .
21 #include <sal/config.h>
22 #include <sal/log.hxx>
25 #include <string_view>
27 #include <com/sun/star/beans/PropertyValue.hpp>
28 #include <com/sun/star/embed/ElementModes.hpp>
29 #include <com/sun/star/embed/InvalidStorageException.hpp>
30 #include <com/sun/star/embed/UseBackupException.hpp>
31 #include <com/sun/star/embed/StorageFormats.hpp>
32 #include <com/sun/star/embed/StorageWrappedTargetException.hpp>
33 #include <com/sun/star/packages/NoEncryptionException.hpp>
34 #include <com/sun/star/packages/NoRawFormatException.hpp>
35 #include <com/sun/star/packages/WrongPasswordException.hpp>
36 #include <com/sun/star/io/TempFile.hpp>
37 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
38 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
39 #include <com/sun/star/container/XEnumerationAccess.hpp>
40 #include <com/sun/star/container/XNamed.hpp>
41 #include <com/sun/star/util/XChangesBatch.hpp>
43 #include <com/sun/star/lang/XComponent.hpp>
44 #include <com/sun/star/lang/DisposedException.hpp>
45 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
46 #include <com/sun/star/beans/NamedValue.hpp>
48 #include <PackageConstants.hxx>
50 #include <comphelper/sequence.hxx>
51 #include <cppuhelper/queryinterface.hxx>
52 #include <cppuhelper/exc_hlp.hxx>
54 #include <comphelper/servicehelper.hxx>
55 #include <comphelper/storagehelper.hxx>
56 #include <comphelper/ofopxmlhelper.hxx>
58 #include <comphelper/diagnose_ex.hxx>
60 #include "xstorage.hxx"
61 #include "owriteablestream.hxx"
62 #include "switchpersistencestream.hxx"
64 using namespace ::com::sun::star
;
66 #if OSL_DEBUG_LEVEL > 0
67 #define THROW_WHERE SAL_WHERE
69 #define THROW_WHERE ""
73 void OStorage_Impl::completeStorageStreamCopy_Impl(
74 const uno::Reference
< io::XStream
>& xSource
,
75 const uno::Reference
< io::XStream
>& xDest
,
76 sal_Int32 nStorageType
,
77 const uno::Sequence
< uno::Sequence
< beans::StringPair
> >& aRelInfo
)
79 uno::Reference
< beans::XPropertySet
> xSourceProps( xSource
, uno::UNO_QUERY_THROW
);
80 uno::Reference
< beans::XPropertySet
> xDestProps( xDest
, uno::UNO_QUERY_THROW
);
82 uno::Reference
< io::XOutputStream
> xDestOutStream
= xDest
->getOutputStream();
83 if ( !xDestOutStream
.is() )
84 throw io::IOException( THROW_WHERE
);
86 uno::Reference
< io::XInputStream
> xSourceInStream
= xSource
->getInputStream();
87 if ( !xSourceInStream
.is() )
88 throw io::IOException( THROW_WHERE
);
90 // TODO: headers of encrypted streams should be copied also
91 ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInStream
, xDestOutStream
);
93 uno::Sequence
<OUString
> aPropNames
{ u
"Compressed"_ustr
, u
"MediaType"_ustr
,
94 u
"UseCommonStoragePasswordEncryption"_ustr
};
96 if ( nStorageType
== embed::StorageFormats::OFOPXML
)
98 // TODO/LATER: in future it might make sense to provide the stream if there is one
99 uno::Reference
< embed::XRelationshipAccess
> xRelAccess( xDest
, uno::UNO_QUERY_THROW
);
100 xRelAccess
->clearRelationships();
101 xRelAccess
->insertRelationships( aRelInfo
, false );
103 aPropNames
.realloc( 2 );
105 else if ( nStorageType
!= embed::StorageFormats::PACKAGE
)
107 aPropNames
.realloc( 1 );
110 for (const auto& rPropName
: aPropNames
)
111 xDestProps
->setPropertyValue( rPropName
, xSourceProps
->getPropertyValue( rPropName
) );
114 static uno::Reference
< io::XInputStream
> GetSeekableTempCopy( const uno::Reference
< io::XInputStream
>& xInStream
)
116 rtl::Reference
< utl::TempFileFastService
> xTempFile
= new utl::TempFileFastService
;
117 uno::Reference
< io::XOutputStream
> xTempOut
= xTempFile
->getOutputStream();
118 uno::Reference
< io::XInputStream
> xTempIn
= xTempFile
->getInputStream();
120 if ( !xTempOut
.is() || !xTempIn
.is() )
121 throw io::IOException( THROW_WHERE
);
123 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream
, xTempOut
);
124 xTempOut
->closeOutput();
129 SotElement_Impl::SotElement_Impl(OUString aName
, bool bStor
, bool bNew
)
130 : m_aOriginalName(std::move(aName
))
131 , m_bIsRemoved(false)
132 , m_bIsInserted(bNew
)
133 , m_bIsStorage(bStor
)
137 // most of properties are holt by the storage but are not used
138 OStorage_Impl::OStorage_Impl( uno::Reference
< io::XInputStream
> const & xInputStream
,
140 const uno::Sequence
< beans::PropertyValue
>& xProperties
,
141 uno::Reference
< uno::XComponentContext
> const & xContext
,
142 sal_Int32 nStorageType
)
143 : m_xMutex( new comphelper::RefCountedMutex
)
144 , m_pAntiImpl( nullptr )
145 , m_nStorageMode( nMode
& ~embed::ElementModes::SEEKABLE
)
146 , m_bIsModified( ( nMode
& ( embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
) ) == ( embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
) )
147 , m_bBroadcastModified( false )
148 , m_bCommited( false )
150 , m_bListCreated( false )
151 , m_nModifiedListenerCount( 0 )
152 , m_xContext( xContext
)
153 , m_xProperties( xProperties
)
154 , m_bHasCommonEncryptionData( false )
155 , m_pParent( nullptr )
156 , m_bControlMediaType( false )
157 , m_bMTFallbackUsed( false )
158 , m_bControlVersion( false )
159 , m_nStorageType( nStorageType
)
160 , m_pRelStorElement( nullptr )
161 , m_nRelInfoStatus( RELINFO_NO_INIT
)
163 // all the checks done below by assertion statements must be done by factory
164 SAL_WARN_IF( !xInputStream
.is(), "package.xstor", "No input stream is provided!" );
165 assert(xContext
.is());
167 m_pSwitchStream
= new SwitchablePersistenceStream(xInputStream
);
168 m_xInputStream
= m_pSwitchStream
->getInputStream();
170 if ( m_nStorageMode
& embed::ElementModes::WRITE
)
172 // check that the stream allows to write
173 SAL_WARN( "package.xstor", "No stream for writing is provided!" );
177 // most of properties are holt by the storage but are not used
178 OStorage_Impl::OStorage_Impl( uno::Reference
< io::XStream
> const & xStream
,
180 const uno::Sequence
< beans::PropertyValue
>& xProperties
,
181 uno::Reference
< uno::XComponentContext
> const & xContext
,
182 sal_Int32 nStorageType
)
183 : m_xMutex( new comphelper::RefCountedMutex
)
184 , m_pAntiImpl( nullptr )
185 , m_nStorageMode( nMode
& ~embed::ElementModes::SEEKABLE
)
186 , m_bIsModified( ( nMode
& ( embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
) ) == ( embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
) )
187 , m_bBroadcastModified( false )
188 , m_bCommited( false )
190 , m_bListCreated( false )
191 , m_nModifiedListenerCount( 0 )
192 , m_xContext( xContext
)
193 , m_xProperties( xProperties
)
194 , m_bHasCommonEncryptionData( false )
195 , m_pParent( nullptr )
196 , m_bControlMediaType( false )
197 , m_bMTFallbackUsed( false )
198 , m_bControlVersion( false )
199 , m_nStorageType( nStorageType
)
200 , m_pRelStorElement( nullptr )
201 , m_nRelInfoStatus( RELINFO_NO_INIT
)
203 // all the checks done below by assertion statements must be done by factory
204 SAL_WARN_IF( !xStream
.is(), "package.xstor", "No stream is provided!" );
205 assert(xContext
.is());
207 if ( m_nStorageMode
& embed::ElementModes::WRITE
)
209 m_pSwitchStream
= new SwitchablePersistenceStream(xStream
);
210 m_xStream
= m_pSwitchStream
.get();
214 m_pSwitchStream
= new SwitchablePersistenceStream(xStream
->getInputStream());
215 m_xInputStream
= m_pSwitchStream
->getInputStream();
219 OStorage_Impl::OStorage_Impl( OStorage_Impl
* pParent
,
221 uno::Reference
< container::XNameContainer
> const & xPackageFolder
,
222 uno::Reference
< lang::XSingleServiceFactory
> xPackage
,
223 uno::Reference
< uno::XComponentContext
> const & xContext
,
224 sal_Int32 nStorageType
)
225 : m_xMutex( new comphelper::RefCountedMutex
)
226 , m_pAntiImpl( nullptr )
227 , m_nStorageMode( nMode
& ~embed::ElementModes::SEEKABLE
)
228 , m_bIsModified( ( nMode
& ( embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
) ) == ( embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
) )
229 , m_bBroadcastModified( false )
230 , m_bCommited( false )
232 , m_bListCreated( false )
233 , m_nModifiedListenerCount( 0 )
234 , m_xPackageFolder( xPackageFolder
)
235 , m_xPackage(std::move( xPackage
))
236 , m_xContext( xContext
)
237 , m_bHasCommonEncryptionData( false )
238 , m_pParent( pParent
) // can be empty in case of temporary readonly substorages and relation storage
239 , m_bControlMediaType( false )
240 , m_bMTFallbackUsed( false )
241 , m_bControlVersion( false )
242 , m_nStorageType( nStorageType
)
243 , m_pRelStorElement( nullptr )
244 , m_nRelInfoStatus( RELINFO_NO_INIT
)
246 SAL_WARN_IF( !xPackageFolder
.is(), "package.xstor", "No package folder!" );
247 assert(xContext
.is());
250 OStorage_Impl::~OStorage_Impl()
253 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
254 if ( m_pAntiImpl
) // root storage wrapper must set this member to NULL before destruction of object
256 SAL_WARN_IF( m_bIsRoot
, "package.xstor", "The root storage wrapper must be disposed already" );
259 m_pAntiImpl
->InternalDispose( false );
261 catch ( const uno::Exception
& )
263 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
265 m_pAntiImpl
= nullptr;
267 else if ( !m_aReadOnlyWrapVector
.empty() )
269 for ( auto& rStorage
: m_aReadOnlyWrapVector
)
271 uno::Reference
< embed::XStorage
> xTmp
= rStorage
.m_xWeakRef
;
274 rStorage
.m_pPointer
->InternalDispose( false );
275 } catch( const uno::Exception
& )
277 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
281 m_aReadOnlyWrapVector
.clear();
287 for (const auto & pair
: m_aChildrenMap
)
288 for (auto pElement
: pair
.second
)
290 m_aChildrenMap
.clear();
292 std::for_each(m_aDeletedVector
.begin(), m_aDeletedVector
.end(), std::default_delete
<SotElement_Impl
>());
293 m_aDeletedVector
.clear();
295 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& m_pRelStorElement
)
297 delete m_pRelStorElement
;
298 m_pRelStorElement
= nullptr;
301 m_xPackageFolder
.clear();
304 OUString aPropertyName
= u
"URL"_ustr
;
305 for (const auto& rProp
: m_xProperties
)
307 if ( rProp
.Name
== aPropertyName
)
309 // the storage is URL based so all the streams are opened by factory and should be closed
312 if ( m_xInputStream
.is() )
314 m_xInputStream
->closeInput();
315 m_xInputStream
.clear();
318 if ( m_xStream
.is() )
320 uno::Reference
< io::XInputStream
> xInStr
= m_xStream
->getInputStream();
322 xInStr
->closeInput();
324 uno::Reference
< io::XOutputStream
> xOutStr
= m_xStream
->getOutputStream();
326 xOutStr
->closeOutput();
331 catch (const uno::Exception
&)
333 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
339 void OStorage_Impl::SetReadOnlyWrap( OStorage
& aStorage
)
341 // Weak reference is used inside the holder so the refcount must not be zero at this point
342 OSL_ENSURE( aStorage
.GetRefCount_Impl(), "There must be a reference alive to use this method!" );
343 m_aReadOnlyWrapVector
.emplace_back( &aStorage
);
346 void OStorage_Impl::RemoveReadOnlyWrap( const OStorage
& aStorage
)
348 for ( StorageHoldersType::iterator pStorageIter
= m_aReadOnlyWrapVector
.begin();
349 pStorageIter
!= m_aReadOnlyWrapVector
.end();)
351 uno::Reference
< embed::XStorage
> xTmp
= pStorageIter
->m_xWeakRef
;
352 if ( !xTmp
.is() || pStorageIter
->m_pPointer
== &aStorage
)
355 pStorageIter
->m_pPointer
->InternalDispose( false );
356 } catch( const uno::Exception
& )
358 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
361 pStorageIter
= m_aReadOnlyWrapVector
.erase(pStorageIter
);
368 void OStorage_Impl::OpenOwnPackage()
370 SAL_WARN_IF( !m_bIsRoot
, "package.xstor", "Opening of the package has no sense!" );
372 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
374 if ( !m_xPackageFolder
.is() )
376 if ( !m_xPackage
.is() )
378 uno::Sequence
< uno::Any
> aArguments( 2 );
379 auto pArguments
= aArguments
.getArray();
380 if ( m_nStorageMode
& embed::ElementModes::WRITE
)
381 pArguments
[ 0 ] <<= css::uno::Reference
< css::io::XStream
>(m_xStream
);
384 SAL_WARN_IF( !m_xInputStream
.is(), "package.xstor", "Input stream must be set for readonly access!" );
385 pArguments
[ 0 ] <<= m_xInputStream
;
386 // TODO: if input stream is not seekable or XSeekable interface is supported
387 // on XStream object a wrapper must be used
390 // do not allow elements to remove themself from the old container in case of insertion to another container
391 pArguments
[ 1 ] <<= beans::NamedValue( u
"AllowRemoveOnInsert"_ustr
,
394 sal_Int32 nArgNum
= 2;
395 for (const auto& rProp
: m_xProperties
)
397 if ( rProp
.Name
== "RepairPackage"
398 || rProp
.Name
== "ProgressHandler"
399 || rProp
.Name
== "NoFileSync" )
401 // Forward these to the package.
402 beans::NamedValue
aNamedValue( rProp
.Name
, rProp
.Value
);
403 aArguments
.realloc( ++nArgNum
);
404 pArguments
= aArguments
.getArray();
405 pArguments
[nArgNum
-1] <<= aNamedValue
;
406 if (rProp
.Name
== "RepairPackage")
407 rProp
.Value
>>= m_bRepairPackage
;
409 else if ( rProp
.Name
== "Password" )
411 // TODO: implement password setting for documents
412 // the password entry must be removed after setting
416 if ( m_nStorageType
== embed::StorageFormats::ZIP
)
418 // let the package support only plain zip format
419 beans::NamedValue aNamedValue
;
420 aNamedValue
.Name
= "StorageFormat";
421 aNamedValue
.Value
<<= u
"ZipFormat"_ustr
;
422 aArguments
.realloc( ++nArgNum
);
423 pArguments
= aArguments
.getArray();
424 pArguments
[nArgNum
-1] <<= aNamedValue
;
426 else if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
428 // let the package support OFOPXML media type handling
429 beans::NamedValue aNamedValue
;
430 aNamedValue
.Name
= "StorageFormat";
431 aNamedValue
.Value
<<= u
"OFOPXMLFormat"_ustr
;
432 aArguments
.realloc( ++nArgNum
);
433 pArguments
= aArguments
.getArray();
434 pArguments
[nArgNum
-1] <<= aNamedValue
;
437 m_xPackage
.set( m_xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(
438 u
"com.sun.star.packages.comp.ZipPackage"_ustr
, aArguments
, m_xContext
),
442 uno::Reference
< container::XHierarchicalNameAccess
> xHNameAccess( m_xPackage
, uno::UNO_QUERY
);
443 SAL_WARN_IF( !xHNameAccess
.is(), "package.xstor", "The package could not be created!" );
445 if ( xHNameAccess
.is() )
447 uno::Any aFolder
= xHNameAccess
->getByHierarchicalName(u
"/"_ustr
);
448 aFolder
>>= m_xPackageFolder
;
452 SAL_WARN_IF( !m_xPackageFolder
.is(), "package.xstor", "The package root folder can not be opened!" );
453 if ( !m_xPackageFolder
.is() )
454 throw embed::InvalidStorageException( THROW_WHERE
);
457 bool OStorage_Impl::HasChildren()
459 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
462 return !m_aChildrenMap
.empty();
465 void OStorage_Impl::GetStorageProperties()
467 if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
)
470 uno::Reference
< beans::XPropertySet
> xProps( m_xPackageFolder
, uno::UNO_QUERY_THROW
);
472 if ( !m_bControlMediaType
)
474 uno::Reference
< beans::XPropertySet
> xPackageProps( m_xPackage
, uno::UNO_QUERY_THROW
);
475 xPackageProps
->getPropertyValue( MEDIATYPE_FALLBACK_USED_PROPERTY
) >>= m_bMTFallbackUsed
;
477 static constexpr OUStringLiteral
sMediaType(u
"MediaType");
478 xProps
->getPropertyValue( sMediaType
) >>= m_aMediaType
;
479 m_bControlMediaType
= true;
482 if ( !m_bControlVersion
)
484 xProps
->getPropertyValue( u
"Version"_ustr
) >>= m_aVersion
;
485 m_bControlVersion
= true;
488 // the properties of OFOPXML will be handled directly
491 void OStorage_Impl::ReadRelInfoIfNecessary()
493 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
496 if ( m_nRelInfoStatus
== RELINFO_NO_INIT
)
498 // Init from original stream
499 uno::Reference
< io::XInputStream
> xRelInfoStream
500 = GetRelInfoStreamForName( std::u16string_view() );
503 if ( xRelInfoStream
.is() )
504 m_aRelInfo
= ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
508 m_nRelInfoStatus
= RELINFO_READ
;
510 catch (css::uno::Exception
&)
512 TOOLS_INFO_EXCEPTION("package.xstor", "");
515 else if ( m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
517 // Init from the new stream
520 if ( m_xNewRelInfoStream
.is() )
521 m_aRelInfo
= ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
526 m_nRelInfoStatus
= RELINFO_CHANGED_STREAM_READ
;
528 catch( const uno::Exception
& )
530 m_nRelInfoStatus
= RELINFO_CHANGED_BROKEN
;
535 void OStorage_Impl::ReadContents()
537 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
539 if ( m_bListCreated
)
545 uno::Reference
< container::XEnumerationAccess
> xEnumAccess( m_xPackageFolder
, uno::UNO_QUERY_THROW
);
546 uno::Reference
< container::XEnumeration
> xEnum
= xEnumAccess
->createEnumeration();
548 throw uno::RuntimeException( THROW_WHERE
);
550 m_bListCreated
= true;
552 while( xEnum
->hasMoreElements() )
555 uno::Reference
< container::XNamed
> xNamed
;
556 xEnum
->nextElement() >>= xNamed
;
560 SAL_WARN( "package.xstor", "XNamed is not supported!" );
561 throw uno::RuntimeException( THROW_WHERE
);
564 OUString aName
= xNamed
->getName();
565 SAL_WARN_IF( aName
.isEmpty(), "package.xstor", "Empty name!" );
567 uno::Reference
< container::XNameContainer
> xNameContainer( xNamed
, uno::UNO_QUERY
);
569 std::unique_ptr
<SotElement_Impl
> xNewElement(new SotElement_Impl(aName
, xNameContainer
.is(), false));
570 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& aName
== "_rels" )
572 if (!xNewElement
->m_bIsStorage
)
573 throw io::IOException( THROW_WHERE
); // TODO: Unexpected format
575 m_pRelStorElement
= xNewElement
.release();
580 if ( ( m_nStorageMode
& embed::ElementModes::TRUNCATE
) == embed::ElementModes::TRUNCATE
)
582 // if a storage is truncated all of it elements are marked as deleted
583 xNewElement
->m_bIsRemoved
= true;
586 m_aChildrenMap
[aName
].push_back(xNewElement
.release());
589 catch( const container::NoSuchElementException
& )
591 TOOLS_WARN_EXCEPTION( "package.xstor", "hasMoreElements() implementation has problems!");
595 if ( ( m_nStorageMode
& embed::ElementModes::TRUNCATE
) == embed::ElementModes::TRUNCATE
)
597 // if a storage is truncated the relations information should be cleaned
598 m_xNewRelInfoStream
.clear();
599 m_aRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
600 m_nRelInfoStatus
= RELINFO_CHANGED
;
603 // cache changeable folder properties
604 GetStorageProperties();
607 void OStorage_Impl::CopyToStorage( const uno::Reference
< embed::XStorage
>& xDest
, bool bDirect
)
609 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
611 uno::Reference
< beans::XPropertySet
> xPropSet( xDest
, uno::UNO_QUERY
);
612 if ( !xPropSet
.is() )
613 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 );
615 sal_Int32 nDestMode
= embed::ElementModes::READ
;
616 xPropSet
->getPropertyValue( u
"OpenMode"_ustr
) >>= nDestMode
;
618 if ( !( nDestMode
& embed::ElementModes::WRITE
) )
619 throw io::IOException( THROW_WHERE
); // TODO: access_denied
623 if ( !m_xPackageFolder
.is() )
624 throw embed::InvalidStorageException( THROW_WHERE
);
626 for ( const auto& pair
: m_aChildrenMap
)
627 for (auto pElement
: pair
.second
)
629 if ( !pElement
->m_bIsRemoved
)
630 CopyStorageElement( pElement
, xDest
, /*aName*/pair
.first
, bDirect
);
633 // move storage properties to the destination one ( means changeable properties )
634 if ( m_nStorageType
== embed::StorageFormats::PACKAGE
)
636 xPropSet
->setPropertyValue( u
"MediaType"_ustr
, uno::Any( m_aMediaType
) );
637 xPropSet
->setPropertyValue( u
"Version"_ustr
, uno::Any( m_aVersion
) );
640 if ( m_nStorageType
== embed::StorageFormats::PACKAGE
)
642 // if this is a root storage, the common key from current one should be moved there
643 bool bIsRoot
= false;
644 if ( ( xPropSet
->getPropertyValue( u
"IsRoot"_ustr
) >>= bIsRoot
) && bIsRoot
)
648 uno::Reference
< embed::XEncryptionProtectedStorage
> xEncr( xDest
, uno::UNO_QUERY
);
651 xEncr
->setEncryptionData( GetCommonRootEncryptionData().getAsConstNamedValueList() );
653 uno::Sequence
< beans::NamedValue
> aAlgorithms
;
654 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_xPackage
, uno::UNO_QUERY_THROW
);
655 xPackPropSet
->getPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY
)
657 xEncr
->setEncryptionAlgorithms( aAlgorithms
);
660 catch( const packages::NoEncryptionException
& )
662 TOOLS_INFO_EXCEPTION("package.xstor", "No Encryption");
666 else if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
669 // TODO/LATER: currently the optimization is not active
670 // uno::Reference< io::XInputStream > xRelInfoStream = GetRelInfoStreamForName( OUString() ); // own stream
671 // if ( xRelInfoStream.is() )
673 // // Relations info stream is a writeonly property, introduced only to optimize copying
674 // // Should be used carefully since no check for stream consistency is done, and the stream must not stay locked
676 // OUString aRelInfoString = "RelationsInfoStream";
677 // xPropSet->setPropertyValue( aRelInfoString, uno::makeAny( GetSeekableTempCopy( xRelInfoStream, m_xFactory ) ) );
680 uno::Reference
< embed::XRelationshipAccess
> xRels( xDest
, uno::UNO_QUERY
);
682 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 );
684 xRels
->insertRelationships( GetAllRelationshipsIfAny(), false );
687 // if possible the destination storage should be committed after successful copying
688 uno::Reference
< embed::XTransactedObject
> xObjToCommit( xDest
, uno::UNO_QUERY
);
689 if ( xObjToCommit
.is() )
690 xObjToCommit
->commit();
693 void OStorage_Impl::CopyStorageElement( SotElement_Impl
* pElement
,
694 const uno::Reference
< embed::XStorage
>& xDest
,
695 const OUString
& aName
,
698 SAL_WARN_IF( !xDest
.is(), "package.xstor", "No destination storage!" );
699 SAL_WARN_IF( aName
.isEmpty(), "package.xstor", "Empty element name!" );
701 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
703 uno::Reference
< container::XNameAccess
> xDestAccess( xDest
, uno::UNO_QUERY_THROW
);
704 if ( xDestAccess
->hasByName( aName
)
705 && !( pElement
->m_bIsStorage
&& xDest
->isStorageElement( aName
) ) )
706 xDest
->removeElement( aName
);
708 if ( pElement
->m_bIsStorage
)
710 uno::Reference
< embed::XStorage
> xSubDest
=
711 xDest
->openStorageElement( aName
,
712 embed::ElementModes::WRITE
);
714 SAL_WARN_IF( !xSubDest
.is(), "package.xstor", "No destination substorage!" );
716 if (!pElement
->m_xStorage
)
718 OpenSubStorage( pElement
, embed::ElementModes::READ
);
719 if (!pElement
->m_xStorage
)
720 throw io::IOException( THROW_WHERE
);
723 pElement
->m_xStorage
->CopyToStorage(xSubDest
, bDirect
);
727 if (!pElement
->m_xStream
)
729 OpenSubStream( pElement
);
730 if (!pElement
->m_xStream
)
731 throw io::IOException( THROW_WHERE
);
734 if (!pElement
->m_xStream
->IsEncrypted())
738 // fill in the properties for the stream
739 uno::Sequence
< beans::PropertyValue
> aStrProps(0);
740 const uno::Sequence
< beans::PropertyValue
> aSrcPkgProps
= pElement
->m_xStream
->GetStreamProperties();
742 for ( const auto& rSrcPkgProp
: aSrcPkgProps
)
744 if ( rSrcPkgProp
.Name
== "MediaType" || rSrcPkgProp
.Name
== "Compressed" )
746 aStrProps
.realloc( ++nNum
);
747 auto pStrProps
= aStrProps
.getArray();
748 pStrProps
[nNum
-1].Name
= rSrcPkgProp
.Name
;
749 pStrProps
[nNum
-1].Value
= rSrcPkgProp
.Value
;
753 if ( m_nStorageType
== embed::StorageFormats::PACKAGE
)
755 aStrProps
.realloc( ++nNum
);
756 auto pStrProps
= aStrProps
.getArray();
757 pStrProps
[nNum
-1].Name
= "UseCommonStoragePasswordEncryption";
758 pStrProps
[nNum
-1].Value
<<= pElement
->m_xStream
->UsesCommonEncryption_Impl();
760 else if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
762 // TODO/LATER: currently the optimization is not active
763 // uno::Reference< io::XInputStream > xInStream = GetRelInfoStreamForName( OUString() ); // own rels stream
764 // if ( xInStream.is() )
766 // aStrProps.realloc( ++nNum );
767 // aStrProps[nNum-1].Name = "RelationsInfoStream";
768 // aStrProps[nNum-1].Value <<= GetSeekableTempCopy( xInStream, m_xFactory );
771 uno::Reference
< embed::XRelationshipAccess
> xRels( xDest
, uno::UNO_QUERY
);
773 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
775 xRels
->insertRelationships( GetAllRelationshipsIfAny(), false );
778 uno::Reference
< embed::XOptimizedStorage
> xOptDest( xDest
, uno::UNO_QUERY_THROW
);
779 uno::Reference
< io::XInputStream
> xInputToInsert
;
781 if (pElement
->m_xStream
->HasTempFile_Impl() || !pElement
->m_xStream
->m_xPackageStream
.is())
783 SAL_WARN_IF(!pElement
->m_xStream
->m_xPackageStream
.is(), "package.xstor", "No package stream!");
785 // if the stream is modified - the temporary file must be used for insertion
786 xInputToInsert
= pElement
->m_xStream
->GetTempFileAsInputStream();
790 // for now get just nonseekable access to the stream
791 // TODO/LATER: the raw stream can be used
793 xInputToInsert
= pElement
->m_xStream
->m_xPackageStream
->getDataStream();
796 if ( !xInputToInsert
.is() )
797 throw io::IOException( THROW_WHERE
);
799 xOptDest
->insertStreamElementDirect( aName
, xInputToInsert
, aStrProps
);
803 uno::Reference
< io::XStream
> xSubStr
=
804 xDest
->openStreamElement( aName
,
805 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
806 SAL_WARN_IF( !xSubStr
.is(), "package.xstor", "No destination substream!" );
808 pElement
->m_xStream
->CopyInternallyTo_Impl(xSubStr
);
811 else if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
)
813 SAL_WARN( "package.xstor", "Encryption is only supported in package storage!" );
814 throw io::IOException( THROW_WHERE
);
816 else if ( pElement
->m_xStream
->HasCachedEncryptionData()
817 && ( pElement
->m_xStream
->IsModified() || pElement
->m_xStream
->HasWriteOwner_Impl() ) )
819 ::comphelper::SequenceAsHashMap aCommonEncryptionData
;
820 bool bHasCommonEncryptionData
= false;
823 aCommonEncryptionData
= GetCommonRootEncryptionData();
824 bHasCommonEncryptionData
= true;
826 catch( const packages::NoEncryptionException
& )
828 TOOLS_INFO_EXCEPTION("package.xstor", "No Encryption");
831 if (bHasCommonEncryptionData
&& ::package::PackageEncryptionDataLessOrEqual(pElement
->m_xStream
->GetCachedEncryptionData(), aCommonEncryptionData
))
833 // If the stream can be opened with the common storage password
834 // it must be stored with the common storage password as well
835 uno::Reference
< io::XStream
> xDestStream
=
836 xDest
->openStreamElement( aName
,
837 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
839 pElement
->m_xStream
->CopyInternallyTo_Impl( xDestStream
);
841 uno::Reference
< beans::XPropertySet
> xProps( xDestStream
, uno::UNO_QUERY_THROW
);
842 xProps
->setPropertyValue(
843 u
"UseCommonStoragePasswordEncryption"_ustr
,
848 // the stream is already opened for writing or was changed
849 uno::Reference
< embed::XStorage2
> xDest2( xDest
, uno::UNO_QUERY_THROW
);
850 uno::Reference
< io::XStream
> xSubStr
=
851 xDest2
->openEncryptedStream( aName
,
852 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
,
853 pElement
->m_xStream
->GetCachedEncryptionData().getAsConstNamedValueList() );
854 SAL_WARN_IF( !xSubStr
.is(), "package.xstor", "No destination substream!" );
856 pElement
->m_xStream
->CopyInternallyTo_Impl(xSubStr
, pElement
->m_xStream
->GetCachedEncryptionData());
861 // the stream is not opened at all, so it can be just opened for reading
864 // If the stream can be opened with the common storage password
865 // it must be stored with the common storage password as well
867 uno::Reference
< io::XStream
> xOwnStream
= pElement
->m_xStream
->GetStream(embed::ElementModes::READ
,
869 uno::Reference
< io::XStream
> xDestStream
=
870 xDest
->openStreamElement( aName
,
871 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
872 SAL_WARN_IF( !xDestStream
.is(), "package.xstor", "No destination substream!" );
873 completeStorageStreamCopy_Impl( xOwnStream
, xDestStream
, m_nStorageType
, GetAllRelationshipsIfAny() );
875 uno::Reference
< beans::XPropertySet
> xProps( xDestStream
, uno::UNO_QUERY_THROW
);
876 xProps
->setPropertyValue(
877 u
"UseCommonStoragePasswordEncryption"_ustr
,
880 catch( const packages::WrongPasswordException
& )
882 TOOLS_INFO_EXCEPTION("package.xstor", "Handled exception");
884 // If the common storage password does not allow to open the stream
885 // it could be copied in raw way, the problem is that the StartKey should be the same
886 // in the ODF1.2 package, so an invalid package could be produced if the stream
887 // is copied from ODF1.1 package, where it is allowed to have different StartKeys
888 uno::Reference
< embed::XStorageRawAccess
> xRawDest( xDest
, uno::UNO_QUERY_THROW
);
889 uno::Reference
< io::XInputStream
> xRawInStream
= pElement
->m_xStream
->GetRawInStream();
890 xRawDest
->insertRawEncrStreamElement( aName
, xRawInStream
);
896 uno::Sequence
< uno::Sequence
< beans::StringPair
> > OStorage_Impl::GetAllRelationshipsIfAny()
898 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
899 return uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
901 ReadRelInfoIfNecessary();
903 if ( m_nRelInfoStatus
!= RELINFO_READ
904 && m_nRelInfoStatus
!= RELINFO_CHANGED_STREAM_READ
905 && m_nRelInfoStatus
!= RELINFO_CHANGED
)
906 throw io::IOException( THROW_WHERE
"Wrong relinfo stream!" );
907 // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
911 void OStorage_Impl::CopyLastCommitTo( const uno::Reference
< embed::XStorage
>& xNewStor
)
913 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
915 SAL_WARN_IF( !m_xPackageFolder
.is(), "package.xstor", "A committed storage is incomplete!" );
916 if ( !m_xPackageFolder
.is() )
917 throw uno::RuntimeException( THROW_WHERE
);
919 OStorage_Impl
aTempRepresent( nullptr,
920 embed::ElementModes::READ
,
926 // TODO/LATER: could use direct copying
927 aTempRepresent
.CopyToStorage( xNewStor
, false );
930 void OStorage_Impl::InsertIntoPackageFolder( const OUString
& aName
,
931 const uno::Reference
< container::XNameContainer
>& xParentPackageFolder
)
933 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
935 SAL_WARN_IF( !m_xPackageFolder
.is(), "package.xstor", "An inserted storage is incomplete!" );
936 uno::Reference
< uno::XInterface
> xTmp( m_xPackageFolder
, uno::UNO_QUERY_THROW
);
937 xParentPackageFolder
->insertByName( aName
, uno::Any( xTmp
) );
942 void OStorage_Impl::Commit()
944 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
946 if ( !m_bIsModified
)
949 // in case of a new empty storage it is possible that the contents are still not read
950 // ( the storage of course has no contents, but the initialization is postponed till the first use,
951 // thus if a new storage was created and committed immediately it must be initialized here )
954 // if storage is committed it should have a valid Package representation
955 SAL_WARN_IF( !m_xPackageFolder
.is(), "package.xstor", "The package representation should exist!" );
956 if ( !m_xPackageFolder
.is() )
957 throw embed::InvalidStorageException( THROW_WHERE
);
959 OSL_ENSURE( m_nStorageMode
& embed::ElementModes::WRITE
,
960 "Commit of readonly storage, should be detected before!" );
962 uno::Reference
< container::XNameContainer
> xNewPackageFolder
;
964 // here the storage will switch to the temporary package folder
965 // if the storage was already committed and the parent was not committed after that
966 // the switch should not be done since the package folder in use is a temporary one;
967 // it can be detected by m_bCommited flag ( root storage doesn't need temporary representation )
968 if ( !m_bCommited
&& !m_bIsRoot
)
970 uno::Sequence
< uno::Any
> aSeq
{ uno::Any(true) };
971 xNewPackageFolder
.set( m_xPackage
->createInstanceWithArguments( aSeq
),
975 xNewPackageFolder
= m_xPackageFolder
;
977 // remove replaced removed elements
978 for ( auto& pDeleted
: m_aDeletedVector
)
981 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& !pDeleted
->m_bIsStorage
)
982 RemoveStreamRelInfo( pDeleted
->m_aOriginalName
);
984 // the removed elements are not in new temporary storage
985 if ( m_bCommited
|| m_bIsRoot
)
986 xNewPackageFolder
->removeByName( pDeleted
->m_aOriginalName
);
990 m_aDeletedVector
.clear();
992 // remove removed elements
993 for (auto mapIt
= m_aChildrenMap
.begin(); mapIt
!= m_aChildrenMap
.end(); )
995 for (auto it
= mapIt
->second
.begin(); it
!= mapIt
->second
.end(); )
997 // renamed and inserted elements must be really inserted to package later
998 // since they can conflict with removed elements
999 auto & pElement
= *it
;
1000 if ( pElement
->m_bIsRemoved
)
1002 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& !pElement
->m_bIsStorage
)
1003 RemoveStreamRelInfo( pElement
->m_aOriginalName
);
1005 // the removed elements are not in new temporary storage
1006 if ( m_bCommited
|| m_bIsRoot
)
1007 xNewPackageFolder
->removeByName( pElement
->m_aOriginalName
);
1010 it
= mapIt
->second
.erase(it
);
1015 if (mapIt
->second
.empty())
1016 mapIt
= m_aChildrenMap
.erase(mapIt
);
1022 // there should be no more deleted elements
1023 for ( const auto& pair
: m_aChildrenMap
)
1024 for (auto pElement
: pair
.second
)
1026 // if it is a 'duplicate commit' inserted elements must be really inserted to package later
1027 // since they can conflict with renamed elements
1028 if ( !pElement
->m_bIsInserted
)
1030 // for now stream is opened in direct mode that means that in case
1031 // storage is committed all the streams from it are committed in current state.
1032 // following two steps are separated to allow easily implement transacted mode
1033 // for streams if we need it in future.
1034 // Only hierarchical access uses transacted streams currently
1035 if ( !pElement
->m_bIsStorage
&& pElement
->m_xStream
1036 && !pElement
->m_xStream
->IsTransacted() )
1037 pElement
->m_xStream
->Commit();
1039 // if the storage was not open, there is no need to commit it ???
1040 // the storage should be checked that it is committed
1041 if (pElement
->m_bIsStorage
&& pElement
->m_xStorage
&& pElement
->m_xStorage
->m_bCommited
)
1043 // it's temporary PackageFolder should be inserted instead of current one
1044 // also the new copy of PackageFolder should be used by the children storages
1046 // the renamed elements are not in new temporary storage
1047 if ( m_bCommited
|| m_bIsRoot
)
1048 xNewPackageFolder
->removeByName( pElement
->m_aOriginalName
);
1050 pElement
->m_xStorage
->InsertIntoPackageFolder(/*aName*/pair
.first
, xNewPackageFolder
);
1052 else if (!pElement
->m_bIsStorage
&& pElement
->m_xStream
&& pElement
->m_xStream
->m_bFlushed
)
1054 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1055 CommitStreamRelInfo( /*aName*/pair
.first
, pElement
);
1057 // the renamed elements are not in new temporary storage
1058 if ( m_bCommited
|| m_bIsRoot
)
1059 xNewPackageFolder
->removeByName( pElement
->m_aOriginalName
);
1061 pElement
->m_xStream
->InsertIntoPackageFolder(/*aName*/pair
.first
, xNewPackageFolder
);
1063 else if ( !m_bCommited
&& !m_bIsRoot
)
1065 // the element must be just copied to the new temporary package folder
1066 // the connection with the original package should not be lost just because
1067 // the element is still referred by the folder in the original hierarchy
1068 uno::Any aPackageElement
= m_xPackageFolder
->getByName( pElement
->m_aOriginalName
);
1069 xNewPackageFolder
->insertByName( /*aName*/pair
.first
, aPackageElement
);
1071 else if ( pair
.first
!= pElement
->m_aOriginalName
)
1073 // this is the case when xNewPackageFolder refers to m_xPackageFolder
1074 // in case the name was changed and it is not a changed storage - rename the element
1075 uno::Any aPackageElement
= xNewPackageFolder
->getByName( pElement
->m_aOriginalName
);
1076 xNewPackageFolder
->removeByName( pElement
->m_aOriginalName
);
1077 xNewPackageFolder
->insertByName( /*aName*/pair
.first
, aPackageElement
);
1079 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& !pElement
->m_bIsStorage
)
1081 if (!pElement
->m_xStream
)
1083 OpenSubStream( pElement
);
1084 if (!pElement
->m_xStream
)
1085 throw uno::RuntimeException( THROW_WHERE
);
1088 CommitStreamRelInfo( /*aName*/pair
.first
, pElement
);
1092 pElement
->m_aOriginalName
= pair
.first
;
1096 for ( const auto& pair
: m_aChildrenMap
)
1097 for (auto pElement
: pair
.second
)
1099 // now inserted elements can be inserted to the package
1100 if ( pElement
->m_bIsInserted
)
1102 pElement
->m_aOriginalName
= pair
.first
;
1104 if ( pElement
->m_bIsStorage
)
1106 OSL_ENSURE(pElement
->m_xStorage
, "An inserted storage is incomplete!");
1107 if (!pElement
->m_xStorage
)
1108 throw uno::RuntimeException( THROW_WHERE
);
1110 if (pElement
->m_xStorage
->m_bCommited
)
1112 pElement
->m_xStorage
->InsertIntoPackageFolder(/*aName*/pair
.first
, xNewPackageFolder
);
1114 pElement
->m_bIsInserted
= false;
1119 OSL_ENSURE(pElement
->m_xStream
, "An inserted stream is incomplete!");
1120 if (!pElement
->m_xStream
)
1121 throw uno::RuntimeException( THROW_WHERE
);
1123 if (!pElement
->m_xStream
->IsTransacted())
1124 pElement
->m_xStream
->Commit();
1126 if (pElement
->m_xStream
->m_bFlushed
)
1128 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1129 CommitStreamRelInfo( /*aName*/pair
.first
, pElement
);
1131 pElement
->m_xStream
->InsertIntoPackageFolder( /*aName*/pair
.first
, xNewPackageFolder
);
1133 pElement
->m_bIsInserted
= false;
1139 if ( m_nStorageType
== embed::StorageFormats::PACKAGE
)
1141 // move properties to the destination package folder
1142 uno::Reference
< beans::XPropertySet
> xProps( xNewPackageFolder
, uno::UNO_QUERY_THROW
);
1143 xProps
->setPropertyValue( u
"MediaType"_ustr
, uno::Any( m_aMediaType
) );
1144 xProps
->setPropertyValue( u
"Version"_ustr
, uno::Any( m_aVersion
) );
1147 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1148 CommitRelInfo( xNewPackageFolder
); // store own relations and commit complete relations storage
1152 uno::Reference
< util::XChangesBatch
> xChangesBatch( m_xPackage
, uno::UNO_QUERY_THROW
);
1155 xChangesBatch
->commitChanges();
1157 catch( const lang::WrappedTargetException
& r
)
1159 css::uno::Any
ex( cppu::getCaughtException() );
1160 // the wrapped UseBackupException means that the target medium can be corrupted
1161 embed::UseBackupException aException
;
1162 if ( r
.TargetException
>>= aException
)
1165 m_xInputStream
.clear();
1169 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(ex
));
1173 else if ( !m_bCommited
)
1175 m_xPackageFolder
= std::move(xNewPackageFolder
);
1179 // after commit the mediatype treated as the correct one
1180 m_bMTFallbackUsed
= false;
1183 void OStorage_Impl::Revert()
1185 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1187 if ( !( m_nStorageMode
& embed::ElementModes::WRITE
) )
1188 return; // nothing to do
1190 // all the children must be removed
1191 // they will be created later on demand
1193 // rebuild the map - cannot do it in-place, because we're changing some of the key values
1194 std::unordered_map
<OUString
, std::vector
<SotElement_Impl
*>> oldMap
;
1195 std::swap(oldMap
, m_aChildrenMap
);
1197 for (const auto & rPair
: oldMap
)
1198 for (auto pElement
: rPair
.second
)
1200 if ( pElement
->m_bIsInserted
)
1204 ClearElement( pElement
);
1206 pElement
->m_bIsRemoved
= false;
1208 m_aChildrenMap
[pElement
->m_aOriginalName
].push_back(pElement
);
1212 // return replaced removed elements
1213 for ( auto& pDeleted
: m_aDeletedVector
)
1215 m_aChildrenMap
[pDeleted
->m_aOriginalName
].push_back(pDeleted
);
1217 ClearElement( pDeleted
);
1219 pDeleted
->m_bIsRemoved
= false;
1221 m_aDeletedVector
.clear();
1223 m_bControlMediaType
= false;
1224 m_bControlVersion
= false;
1226 GetStorageProperties();
1228 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1230 // currently the relations storage is changed only on commit
1231 m_xNewRelInfoStream
.clear();
1232 m_aRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
1233 m_nRelInfoStatus
= RELINFO_NO_INIT
;
1237 ::comphelper::SequenceAsHashMap
OStorage_Impl::GetCommonRootEncryptionData()
1239 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() ) ;
1241 if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
)
1242 throw packages::NoEncryptionException( THROW_WHERE
);
1246 if ( !m_bHasCommonEncryptionData
)
1247 throw packages::NoEncryptionException( THROW_WHERE
);
1249 return m_aCommonEncryptionData
;
1254 throw packages::NoEncryptionException( THROW_WHERE
);
1256 return m_pParent
->GetCommonRootEncryptionData();
1260 SotElement_Impl
* OStorage_Impl::FindElement( const OUString
& rName
)
1262 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1264 SAL_WARN_IF( rName
.isEmpty(), "package.xstor", "Name is empty!" );
1268 auto mapIt
= m_aChildrenMap
.find(rName
);
1269 if (mapIt
== m_aChildrenMap
.end() && m_bRepairPackage
)
1270 mapIt
= std::find_if(m_aChildrenMap
.begin(), m_aChildrenMap
.end(),
1271 [&rName
](const auto& pair
)
1272 { return rName
.equalsIgnoreAsciiCase(pair
.first
); });
1273 if (mapIt
== m_aChildrenMap
.end())
1275 for (auto pElement
: mapIt
->second
)
1276 if (!pElement
->m_bIsRemoved
)
1282 SotElement_Impl
* OStorage_Impl::InsertStream( const OUString
& aName
, bool bEncr
)
1284 SAL_WARN_IF( !m_xPackage
.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1285 if ( !m_xPackage
.is() )
1286 throw embed::InvalidStorageException( THROW_WHERE
);
1288 uno::Sequence
< uno::Any
> aSeq
{ uno::Any(false) };
1289 uno::Reference
< uno::XInterface
> xNewElement( m_xPackage
->createInstanceWithArguments( aSeq
) );
1291 SAL_WARN_IF( !xNewElement
.is(), "package.xstor", "Not possible to create a new stream!" );
1292 if ( !xNewElement
.is() )
1293 throw io::IOException( THROW_WHERE
);
1295 uno::Reference
< packages::XDataSinkEncrSupport
> xPackageSubStream( xNewElement
, uno::UNO_QUERY_THROW
);
1297 OSL_ENSURE( m_nStorageType
== embed::StorageFormats::PACKAGE
|| !bEncr
, "Only package storage supports encryption!" );
1298 if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
&& bEncr
)
1299 throw packages::NoEncryptionException( THROW_WHERE
);
1301 // the mode is not needed for storage stream internal implementation
1302 SotElement_Impl
* pNewElement
= InsertElement( aName
, false );
1303 pNewElement
->m_xStream
.reset(new OWriteStream_Impl(this, xPackageSubStream
, m_xPackage
, m_xContext
, bEncr
, m_nStorageType
, true));
1305 m_aChildrenMap
[aName
].push_back( pNewElement
);
1306 m_bIsModified
= true;
1307 m_bBroadcastModified
= true;
1312 void OStorage_Impl::InsertRawStream( const OUString
& aName
, const uno::Reference
< io::XInputStream
>& xInStream
)
1314 // insert of raw stream means insert and commit
1315 SAL_WARN_IF( !m_xPackage
.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1316 if ( !m_xPackage
.is() )
1317 throw embed::InvalidStorageException( THROW_WHERE
);
1319 if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
)
1320 throw packages::NoEncryptionException( THROW_WHERE
);
1322 uno::Reference
< io::XSeekable
> xSeek( xInStream
, uno::UNO_QUERY
);
1323 uno::Reference
< io::XInputStream
> xInStrToInsert
= xSeek
.is() ? xInStream
:
1324 GetSeekableTempCopy( xInStream
);
1326 uno::Sequence
< uno::Any
> aSeq
{ uno::Any(false) };
1327 uno::Reference
< uno::XInterface
> xNewElement( m_xPackage
->createInstanceWithArguments( aSeq
) );
1329 SAL_WARN_IF( !xNewElement
.is(), "package.xstor", "Not possible to create a new stream!" );
1330 if ( !xNewElement
.is() )
1331 throw io::IOException( THROW_WHERE
);
1333 uno::Reference
< packages::XDataSinkEncrSupport
> xPackageSubStream( xNewElement
, uno::UNO_QUERY_THROW
);
1334 xPackageSubStream
->setRawStream( xInStrToInsert
);
1336 // the mode is not needed for storage stream internal implementation
1337 SotElement_Impl
* pNewElement
= InsertElement( aName
, false );
1338 pNewElement
->m_xStream
.reset(new OWriteStream_Impl(this, xPackageSubStream
, m_xPackage
, m_xContext
, true, m_nStorageType
, false));
1339 // the stream is inserted and must be treated as a committed one
1340 pNewElement
->m_xStream
->SetToBeCommited();
1342 m_aChildrenMap
[aName
].push_back( pNewElement
);
1343 m_bIsModified
= true;
1344 m_bBroadcastModified
= true;
1347 std::unique_ptr
<OStorage_Impl
> OStorage_Impl::CreateNewStorageImpl( sal_Int32 nStorageMode
)
1349 SAL_WARN_IF( !m_xPackage
.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1350 if ( !m_xPackage
.is() )
1351 throw embed::InvalidStorageException( THROW_WHERE
);
1353 uno::Sequence
< uno::Any
> aSeq
{ uno::Any(true) };
1354 uno::Reference
< uno::XInterface
> xNewElement( m_xPackage
->createInstanceWithArguments( aSeq
) );
1356 SAL_WARN_IF( !xNewElement
.is(), "package.xstor", "Not possible to create a new storage!" );
1357 if ( !xNewElement
.is() )
1358 throw io::IOException( THROW_WHERE
);
1360 uno::Reference
< container::XNameContainer
> xPackageSubFolder( xNewElement
, uno::UNO_QUERY_THROW
);
1361 std::unique_ptr
<OStorage_Impl
> pResult(
1362 new OStorage_Impl( this, nStorageMode
, xPackageSubFolder
, m_xPackage
, m_xContext
, m_nStorageType
));
1363 pResult
->m_bIsModified
= true;
1368 SotElement_Impl
* OStorage_Impl::InsertStorage( const OUString
& aName
, sal_Int32 nStorageMode
)
1370 SotElement_Impl
* pNewElement
= InsertElement( aName
, true );
1372 pNewElement
->m_xStorage
= CreateNewStorageImpl(nStorageMode
);
1374 m_aChildrenMap
[aName
].push_back( pNewElement
);
1379 SotElement_Impl
* OStorage_Impl::InsertElement( const OUString
& aName
, bool bIsStorage
)
1381 assert( FindElement(aName
) == nullptr && "Should not try to insert existing element");
1383 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1385 SotElement_Impl
* pDeletedElm
= nullptr;
1387 auto it
= m_aChildrenMap
.find(aName
);
1388 if (it
!= m_aChildrenMap
.end())
1389 for (auto pElement
: it
->second
)
1391 SAL_WARN_IF( !pElement
->m_bIsRemoved
, "package.xstor", "Try to insert an element instead of existing one!" );
1392 if ( pElement
->m_bIsRemoved
)
1394 SAL_WARN_IF( pElement
->m_bIsInserted
, "package.xstor", "Inserted elements must be deleted immediately!" );
1395 pDeletedElm
= pElement
;
1401 if ( pDeletedElm
->m_bIsStorage
)
1402 OpenSubStorage( pDeletedElm
, embed::ElementModes::READWRITE
);
1404 OpenSubStream( pDeletedElm
);
1406 auto & rVec
= m_aChildrenMap
[aName
];
1407 std::erase(rVec
, pDeletedElm
);
1409 m_aChildrenMap
.erase(aName
);
1410 m_aDeletedVector
.push_back( pDeletedElm
);
1413 // create new element
1414 return new SotElement_Impl( aName
, bIsStorage
, true );
1417 void OStorage_Impl::OpenSubStorage( SotElement_Impl
* pElement
, sal_Int32 nStorageMode
)
1419 assert(pElement
&& "pElement is not set!");
1420 SAL_WARN_IF( !pElement
->m_bIsStorage
, "package.xstor", "Storage flag is not set!" );
1422 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1424 if (!pElement
->m_xStorage
)
1426 SAL_WARN_IF( pElement
->m_bIsInserted
, "package.xstor", "Inserted element must be created already!" );
1428 uno::Reference
< uno::XInterface
> xTmp
;
1429 m_xPackageFolder
->getByName( pElement
->m_aOriginalName
) >>= xTmp
;
1431 throw container::NoSuchElementException( THROW_WHERE
);
1433 uno::Reference
< container::XNameContainer
> xPackageSubFolder( xTmp
, uno::UNO_QUERY_THROW
);
1434 pElement
->m_xStorage
.reset(new OStorage_Impl(this, nStorageMode
, xPackageSubFolder
, m_xPackage
, m_xContext
, m_nStorageType
));
1438 void OStorage_Impl::OpenSubStream( SotElement_Impl
* pElement
)
1440 assert(pElement
&& "pElement is not set!");
1441 SAL_WARN_IF( pElement
->m_bIsStorage
, "package.xstor", "Storage flag is set!" );
1443 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1445 if (pElement
->m_xStream
)
1448 SAL_WARN_IF( pElement
->m_bIsInserted
, "package.xstor", "Inserted element must be created already!" );
1450 uno::Reference
< uno::XInterface
> xTmp
;
1451 m_xPackageFolder
->getByName( pElement
->m_aOriginalName
) >>= xTmp
;
1453 throw container::NoSuchElementException( THROW_WHERE
);
1455 uno::Reference
< packages::XDataSinkEncrSupport
> xPackageSubStream( xTmp
, uno::UNO_QUERY_THROW
);
1457 // the stream can never be inserted here, because inserted stream element holds the stream till commit or destruction
1458 pElement
->m_xStream
.reset(new OWriteStream_Impl(this, xPackageSubStream
, m_xPackage
, m_xContext
, false, m_nStorageType
, false, GetRelInfoStreamForName(pElement
->m_aOriginalName
)));
1461 uno::Sequence
< OUString
> OStorage_Impl::GetElementNames()
1463 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1468 for ( const auto& pair
: m_aChildrenMap
)
1469 for (auto pElement
: pair
.second
)
1471 if ( !pElement
->m_bIsRemoved
)
1475 uno::Sequence
<OUString
> aElementNames(nCnt
);
1476 OUString
* pArray
= aElementNames
.getArray();
1477 for ( const auto& pair
: m_aChildrenMap
)
1478 for (auto pElement
: pair
.second
)
1480 if ( !pElement
->m_bIsRemoved
)
1481 *pArray
++ = pair
.first
;
1484 return aElementNames
;
1487 void OStorage_Impl::RemoveElement( OUString
const & rName
, SotElement_Impl
* pElement
)
1491 if ( (pElement
->m_xStorage
&& ( pElement
->m_xStorage
->m_pAntiImpl
|| !pElement
->m_xStorage
->m_aReadOnlyWrapVector
.empty() ))
1492 || (pElement
->m_xStream
&& ( pElement
->m_xStream
->m_pAntiImpl
|| !pElement
->m_xStream
->m_aInputStreamsVector
.empty() )) )
1493 throw io::IOException( THROW_WHERE
); // TODO: Access denied
1495 auto mapIt
= m_aChildrenMap
.find(rName
);
1496 for (auto it
= mapIt
->second
.begin(); it
!= mapIt
->second
.end(); ++it
)
1497 if (pElement
== *it
)
1499 if ( pElement
->m_bIsInserted
)
1502 std::erase(mapIt
->second
, pElement
);
1503 if (mapIt
->second
.empty())
1504 m_aChildrenMap
.erase(mapIt
);
1508 pElement
->m_bIsRemoved
= true;
1509 ClearElement( pElement
);
1513 assert(false && "not found");
1515 // TODO/OFOPXML: the rel stream should be removed as well
1518 void OStorage_Impl::ClearElement( SotElement_Impl
* pElement
)
1520 pElement
->m_xStorage
.reset();
1521 pElement
->m_xStream
.reset();
1524 void OStorage_Impl::CloneStreamElement( const OUString
& aStreamName
,
1525 bool bEncryptionDataProvided
,
1526 const ::comphelper::SequenceAsHashMap
& aEncryptionData
,
1527 uno::Reference
< io::XStream
>& xTargetStream
)
1529 SotElement_Impl
*pElement
= FindElement( aStreamName
);
1532 // element does not exist, throw exception
1533 throw io::IOException( THROW_WHERE
); // TODO: access_denied
1535 else if ( pElement
->m_bIsStorage
)
1536 throw io::IOException( THROW_WHERE
);
1538 if (!pElement
->m_xStream
)
1539 OpenSubStream( pElement
);
1541 if (!pElement
->m_xStream
|| !pElement
->m_xStream
->m_xPackageStream
.is())
1542 throw io::IOException( THROW_WHERE
); // TODO: general_error
1544 // the existence of m_pAntiImpl of the child is not interesting,
1545 // the copy will be created internally
1547 // usual copying is not applicable here, only last flushed version of the
1548 // child stream should be used for copying. Probably the children m_xPackageStream
1549 // can be used as a base of a new stream, that would be copied to result
1550 // storage. The only problem is that some package streams can be accessed from outside
1551 // at the same time (now solved by wrappers that remember own position).
1553 if (bEncryptionDataProvided
)
1554 pElement
->m_xStream
->GetCopyOfLastCommit(xTargetStream
, aEncryptionData
);
1556 pElement
->m_xStream
->GetCopyOfLastCommit(xTargetStream
);
1559 void OStorage_Impl::RemoveStreamRelInfo( std::u16string_view aOriginalName
)
1561 // this method should be used only in OStorage_Impl::Commit() method
1562 // the aOriginalName can be empty, in this case the storage relation info should be removed
1564 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& m_xRelStorage
.is() )
1566 OUString aRelStreamName
= OUString::Concat(aOriginalName
) + ".rels";
1568 if ( m_xRelStorage
->hasByName( aRelStreamName
) )
1569 m_xRelStorage
->removeElement( aRelStreamName
);
1573 void OStorage_Impl::CreateRelStorage()
1575 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
1578 if ( m_xRelStorage
.is() )
1581 if ( !m_pRelStorElement
)
1583 m_pRelStorElement
= new SotElement_Impl( u
"_rels"_ustr
, true, true );
1584 m_pRelStorElement
->m_xStorage
= CreateNewStorageImpl(embed::ElementModes::WRITE
);
1585 m_pRelStorElement
->m_xStorage
->m_pParent
= nullptr; // the relation storage is completely controlled by parent
1588 if (!m_pRelStorElement
->m_xStorage
)
1589 OpenSubStorage( m_pRelStorElement
, embed::ElementModes::WRITE
);
1591 if (!m_pRelStorElement
->m_xStorage
)
1592 throw uno::RuntimeException( THROW_WHERE
);
1594 m_xRelStorage
= new OStorage(m_pRelStorElement
->m_xStorage
.get(), false);
1597 void OStorage_Impl::CommitStreamRelInfo( std::u16string_view rName
, SotElement_Impl
const * pStreamElement
)
1599 // this method should be used only in OStorage_Impl::Commit() method
1601 // the stream element must be provided
1602 if ( !pStreamElement
)
1603 throw uno::RuntimeException( THROW_WHERE
);
1605 if (m_nStorageType
== embed::StorageFormats::OFOPXML
&& pStreamElement
->m_xStream
)
1607 SAL_WARN_IF( rName
.empty(), "package.xstor", "The name must not be empty!" );
1609 if ( !m_xRelStorage
.is() )
1611 // Create new rels storage, this is commit scenario so it must be possible
1615 pStreamElement
->m_xStream
->CommitStreamRelInfo(m_xRelStorage
, pStreamElement
->m_aOriginalName
, rName
);
1619 uno::Reference
< io::XInputStream
> OStorage_Impl::GetRelInfoStreamForName(
1620 std::u16string_view aName
)
1622 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1625 if ( m_xRelStorage
.is() )
1627 OUString aRelStreamName
= OUString::Concat(aName
) + ".rels";
1628 if ( m_xRelStorage
->hasByName( aRelStreamName
) )
1630 uno::Reference
< io::XStream
> xStream
= m_xRelStorage
->openStreamElement( aRelStreamName
, embed::ElementModes::READ
);
1632 return xStream
->getInputStream();
1637 return uno::Reference
< io::XInputStream
>();
1640 void OStorage_Impl::CommitRelInfo( const uno::Reference
< container::XNameContainer
>& xNewPackageFolder
)
1642 // this method should be used only in OStorage_Impl::Commit() method
1643 OUString
aRelsStorName(u
"_rels"_ustr
);
1645 if ( !xNewPackageFolder
.is() )
1646 throw uno::RuntimeException( THROW_WHERE
);
1648 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
1651 if ( m_nRelInfoStatus
== RELINFO_BROKEN
|| m_nRelInfoStatus
== RELINFO_CHANGED_BROKEN
)
1652 throw io::IOException( THROW_WHERE
);
1654 if (m_nRelInfoStatus
== RELINFO_CHANGED
)
1656 if (m_aRelInfo
.hasElements())
1660 uno::Reference
<io::XStream
> xRelsStream
= m_xRelStorage
->openStreamElement(
1661 u
".rels"_ustr
, embed::ElementModes::TRUNCATE
| embed::ElementModes::READWRITE
);
1663 uno::Reference
<io::XOutputStream
> xOutStream
= xRelsStream
->getOutputStream();
1664 if (!xOutStream
.is())
1665 throw uno::RuntimeException(THROW_WHERE
);
1667 ::comphelper::OFOPXMLHelper::WriteRelationsInfoSequence(xOutStream
, m_aRelInfo
,
1670 // set the mediatype
1671 uno::Reference
<beans::XPropertySet
> xPropSet(xRelsStream
, uno::UNO_QUERY_THROW
);
1672 xPropSet
->setPropertyValue(
1673 u
"MediaType"_ustr
, uno::Any(u
"application/vnd.openxmlformats-package.relationships+xml"_ustr
));
1675 m_nRelInfoStatus
= RELINFO_READ
;
1677 else if (m_xRelStorage
.is())
1678 RemoveStreamRelInfo(std::u16string_view()); // remove own rel info
1680 else if (m_nRelInfoStatus
== RELINFO_CHANGED_STREAM_READ
1681 || m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
1685 uno::Reference
<io::XStream
> xRelsStream
= m_xRelStorage
->openStreamElement(
1686 u
".rels"_ustr
, embed::ElementModes::TRUNCATE
| embed::ElementModes::READWRITE
);
1688 uno::Reference
<io::XOutputStream
> xOutputStream
= xRelsStream
->getOutputStream();
1689 if (!xOutputStream
.is())
1690 throw uno::RuntimeException(THROW_WHERE
);
1692 uno::Reference
<io::XSeekable
> xSeek(m_xNewRelInfoStream
, uno::UNO_QUERY_THROW
);
1694 ::comphelper::OStorageHelper::CopyInputToOutput(m_xNewRelInfoStream
, xOutputStream
);
1696 // set the mediatype
1697 uno::Reference
<beans::XPropertySet
> xPropSet(xRelsStream
, uno::UNO_QUERY_THROW
);
1698 xPropSet
->setPropertyValue(
1700 uno::Any(u
"application/vnd.openxmlformats-package.relationships+xml"_ustr
));
1702 m_xNewRelInfoStream
.clear();
1703 if (m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
1705 m_aRelInfo
= uno::Sequence
<uno::Sequence
<beans::StringPair
>>();
1706 m_nRelInfoStatus
= RELINFO_NO_INIT
;
1709 m_nRelInfoStatus
= RELINFO_READ
;
1712 if ( !m_xRelStorage
.is() )
1715 if ( m_xRelStorage
->hasElements() )
1717 m_xRelStorage
->commit();
1720 if ( xNewPackageFolder
.is() && xNewPackageFolder
->hasByName( aRelsStorName
) )
1721 xNewPackageFolder
->removeByName( aRelsStorName
);
1723 if ( !m_xRelStorage
->hasElements() )
1725 // the empty relations storage should not be created
1726 delete m_pRelStorElement
;
1727 m_pRelStorElement
= nullptr;
1728 m_xRelStorage
.clear();
1730 else if ( m_pRelStorElement
&& m_pRelStorElement
->m_xStorage
&& xNewPackageFolder
.is() )
1731 m_pRelStorElement
->m_xStorage
->InsertIntoPackageFolder( aRelsStorName
, xNewPackageFolder
);
1734 // OStorage implementation
1736 OStorage::OStorage( uno::Reference
< io::XInputStream
> const & xInputStream
,
1738 const uno::Sequence
< beans::PropertyValue
>& xProperties
,
1739 uno::Reference
< uno::XComponentContext
> const & xContext
,
1740 sal_Int32 nStorageType
)
1741 : m_pImpl( new OStorage_Impl( xInputStream
, nMode
, xProperties
, xContext
, nStorageType
) )
1742 , m_xSharedMutex( m_pImpl
->m_xMutex
)
1743 , m_aListenersContainer( m_pImpl
->m_xMutex
->GetMutex() )
1744 , m_bReadOnlyWrap( false )
1746 m_pImpl
->m_pAntiImpl
= this;
1749 OStorage::OStorage( uno::Reference
< io::XStream
> const & xStream
,
1751 const uno::Sequence
< beans::PropertyValue
>& xProperties
,
1752 uno::Reference
< uno::XComponentContext
> const & xContext
,
1753 sal_Int32 nStorageType
)
1754 : m_pImpl( new OStorage_Impl( xStream
, nMode
, xProperties
, xContext
, nStorageType
) )
1755 , m_xSharedMutex( m_pImpl
->m_xMutex
)
1756 , m_aListenersContainer( m_pImpl
->m_xMutex
->GetMutex() )
1757 , m_bReadOnlyWrap( false )
1759 m_pImpl
->m_pAntiImpl
= this;
1762 OStorage::OStorage( OStorage_Impl
* pImpl
, bool bReadOnlyWrap
)
1764 , m_xSharedMutex( m_pImpl
->m_xMutex
)
1765 , m_aListenersContainer( m_pImpl
->m_xMutex
->GetMutex() )
1766 , m_bReadOnlyWrap( bReadOnlyWrap
)
1768 // this call can be done only from OStorage_Impl implementation to create child storage
1769 assert( m_pImpl
&& m_pImpl
->m_xMutex
.is() && "The provided pointer & mutex MUST NOT be empty!" );
1771 OSL_ENSURE( ( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
) == embed::ElementModes::WRITE
||
1773 "The wrapper can not allow writing in case implementation does not!" );
1775 if ( !bReadOnlyWrap
)
1776 m_pImpl
->m_pAntiImpl
= this;
1779 OStorage::~OStorage()
1781 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
1784 osl_atomic_increment(&m_refCount
); // to call dispose
1788 catch( const uno::RuntimeException
& )
1790 TOOLS_INFO_EXCEPTION("package.xstor", "Handled exception");
1795 void OStorage::InternalDispose( bool bNotifyImpl
)
1800 // the source object is also a kind of locker for the current object
1801 // since the listeners could dispose the object while being notified
1802 lang::EventObject
aSource( getXWeak() );
1803 m_aListenersContainer
.disposeAndClear( aSource
);
1808 m_pImpl
->m_nModifiedListenerCount
= 0;
1810 if ( m_bReadOnlyWrap
)
1812 OSL_ENSURE( m_aOpenSubComponentsVector
.empty() || m_pSubElDispListener
,
1813 "If any subelements are open the listener must exist!" );
1815 if (m_pSubElDispListener
)
1817 m_pSubElDispListener
->OwnerIsDisposed();
1819 // iterate through m_pData->m_aOpenSubComponentsVector
1820 // deregister m_pData->m_pSubElDispListener and dispose all of them
1821 if ( !m_aOpenSubComponentsVector
.empty() )
1823 for ( const auto& pComp
: m_aOpenSubComponentsVector
)
1825 uno::Reference
< lang::XComponent
> xTmp
= pComp
;
1828 xTmp
->removeEventListener( uno::Reference
< lang::XEventListener
>(
1829 static_cast< lang::XEventListener
* >( m_pSubElDispListener
.get())));
1833 } catch( const uno::Exception
& )
1835 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
1840 m_aOpenSubComponentsVector
.clear();
1845 m_pImpl
->RemoveReadOnlyWrap( *this );
1849 m_pImpl
->m_pAntiImpl
= nullptr;
1853 if ( m_pImpl
->m_bIsRoot
)
1857 // the non-committed changes for the storage must be removed
1866 void OStorage::ChildIsDisposed( const uno::Reference
< uno::XInterface
>& xChild
)
1868 // this method can only be called by child disposing listener
1870 // this method must not contain any locking
1871 // the locking is done in the listener
1873 auto& rVec
= m_aOpenSubComponentsVector
;
1875 [&xChild
](const uno::Reference
<lang::XComponent
>& xTmp
) {
1876 return !xTmp
.is() || xTmp
== xChild
;
1880 void OStorage::BroadcastModifiedIfNecessary()
1882 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
1885 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
1886 throw lang::DisposedException( THROW_WHERE
);
1889 if ( !m_pImpl
->m_bBroadcastModified
)
1892 m_pImpl
->m_bBroadcastModified
= false;
1894 SAL_WARN_IF( m_bReadOnlyWrap
, "package.xstor", "The storage can not be modified at all!" );
1896 lang::EventObject
aSource( getXWeak() );
1898 comphelper::OInterfaceContainerHelper2
* pContainer
=
1899 m_aListenersContainer
.getContainer(
1900 cppu::UnoType
<util::XModifyListener
>::get());
1903 comphelper::OInterfaceIteratorHelper2
pIterator( *pContainer
);
1904 while ( pIterator
.hasMoreElements( ) )
1906 static_cast<util::XModifyListener
*>( pIterator
.next( ) )->modified( aSource
);
1911 void OStorage::BroadcastTransaction( sal_Int8 nMessage
)
1919 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
1922 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
1923 throw lang::DisposedException( THROW_WHERE
);
1926 SAL_WARN_IF( m_bReadOnlyWrap
, "package.xstor", "The storage can not be modified at all!" );
1928 lang::EventObject
aSource( getXWeak() );
1930 comphelper::OInterfaceContainerHelper2
* pContainer
=
1931 m_aListenersContainer
.getContainer(
1932 cppu::UnoType
<embed::XTransactionListener
>::get());
1936 comphelper::OInterfaceIteratorHelper2
pIterator( *pContainer
);
1937 while ( pIterator
.hasMoreElements( ) )
1939 OSL_ENSURE( nMessage
>= 1 && nMessage
<= 4, "Wrong internal notification code is used!" );
1943 case STOR_MESS_PRECOMMIT
:
1944 static_cast<embed::XTransactionListener
*>( pIterator
.next( ) )->preCommit( aSource
);
1946 case STOR_MESS_COMMITTED
:
1947 static_cast<embed::XTransactionListener
*>( pIterator
.next( ) )->commited( aSource
);
1949 case STOR_MESS_PREREVERT
:
1950 static_cast<embed::XTransactionListener
*>( pIterator
.next( ) )->preRevert( aSource
);
1952 case STOR_MESS_REVERTED
:
1953 static_cast<embed::XTransactionListener
*>( pIterator
.next( ) )->reverted( aSource
);
1959 SotElement_Impl
* OStorage::OpenStreamElement_Impl( const OUString
& aStreamName
, sal_Int32 nOpenMode
, bool bEncr
)
1961 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
1963 OSL_ENSURE( !m_bReadOnlyWrap
|| ( nOpenMode
& embed::ElementModes::WRITE
) != embed::ElementModes::WRITE
,
1964 "An element can not be opened for writing in readonly storage!" );
1966 SotElement_Impl
*pElement
= m_pImpl
->FindElement( aStreamName
);
1969 // element does not exist, check if creation is allowed
1970 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
)
1971 || (( nOpenMode
& embed::ElementModes::WRITE
) != embed::ElementModes::WRITE
)
1972 || ( nOpenMode
& embed::ElementModes::NOCREATE
) == embed::ElementModes::NOCREATE
)
1974 throw io::IOException("Element does not exist and cannot be "
1975 "created: \"" + aStreamName
+ "\""); // TODO: access_denied
1978 // create a new StreamElement and insert it into the list
1979 pElement
= m_pImpl
->InsertStream( aStreamName
, bEncr
);
1981 else if ( pElement
->m_bIsStorage
)
1983 throw io::IOException( THROW_WHERE
);
1986 assert(pElement
&& "In case element can not be created an exception must be thrown!");
1988 if (!pElement
->m_xStream
)
1989 m_pImpl
->OpenSubStream( pElement
);
1991 if (!pElement
->m_xStream
)
1992 throw io::IOException( THROW_WHERE
);
1997 void OStorage::MakeLinkToSubComponent_Impl( const uno::Reference
< lang::XComponent
>& xComponent
)
1999 if ( !xComponent
.is() )
2000 throw uno::RuntimeException( THROW_WHERE
);
2002 if (!m_pSubElDispListener
)
2004 m_pSubElDispListener
= new OChildDispListener_Impl( *this );
2007 xComponent
->addEventListener( m_pSubElDispListener
);
2009 m_aOpenSubComponentsVector
.emplace_back(xComponent
);
2014 uno::Any SAL_CALL
OStorage::queryInterface( const uno::Type
& rType
)
2016 // common interfaces
2017 uno::Any aReturn
= ::cppu::queryInterface
2019 , static_cast<lang::XTypeProvider
*> ( this )
2020 , static_cast<embed::XStorage
*> ( this )
2021 , static_cast<embed::XStorage2
*> ( this )
2022 , static_cast<embed::XTransactedObject
*> ( this )
2023 , static_cast<embed::XTransactionBroadcaster
*> ( this )
2024 , static_cast<util::XModifiable
*> ( this )
2025 , static_cast<container::XNameAccess
*> ( this )
2026 , static_cast<container::XElementAccess
*> ( this )
2027 , static_cast<lang::XComponent
*> ( this )
2028 , static_cast<beans::XPropertySet
*> ( this )
2029 , static_cast<embed::XOptimizedStorage
*> ( this ) );
2031 if ( aReturn
.hasValue() )
2034 aReturn
= ::cppu::queryInterface
2036 , static_cast<embed::XHierarchicalStorageAccess
*> ( this )
2037 , static_cast<embed::XHierarchicalStorageAccess2
*> ( this ) );
2039 if ( aReturn
.hasValue() )
2042 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::PACKAGE
)
2044 if ( m_pImpl
->m_bIsRoot
)
2046 aReturn
= ::cppu::queryInterface
2048 , static_cast<embed::XStorageRawAccess
*> ( this )
2049 , static_cast<embed::XEncryptionProtectedSource
*> ( this )
2050 , static_cast<embed::XEncryptionProtectedSource2
*> ( this )
2051 , static_cast<embed::XEncryptionProtectedStorage
*> ( this ) );
2055 aReturn
= ::cppu::queryInterface
2057 , static_cast<embed::XStorageRawAccess
*> ( this ) );
2060 else if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
)
2062 aReturn
= ::cppu::queryInterface
2064 , static_cast<embed::XRelationshipAccess
*> ( this ) );
2067 if ( aReturn
.hasValue() )
2070 return OWeakObject::queryInterface( rType
);
2073 void SAL_CALL
OStorage::acquire() noexcept
2075 OWeakObject::acquire();
2078 void SAL_CALL
OStorage::release() noexcept
2080 OWeakObject::release();
2084 uno::Sequence
< uno::Type
> SAL_CALL
OStorage::getTypes()
2086 if (! m_oTypeCollection
)
2088 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2090 if (! m_oTypeCollection
)
2092 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::PACKAGE
)
2094 if ( m_pImpl
->m_bIsRoot
)
2096 m_oTypeCollection
.emplace(
2097 cppu::UnoType
<lang::XTypeProvider
>::get()
2098 , cppu::UnoType
<embed::XStorage
>::get()
2099 , cppu::UnoType
<embed::XStorage2
>::get()
2100 , cppu::UnoType
<embed::XStorageRawAccess
>::get()
2101 , cppu::UnoType
<embed::XTransactedObject
>::get()
2102 , cppu::UnoType
<embed::XTransactionBroadcaster
>::get()
2103 , cppu::UnoType
<util::XModifiable
>::get()
2104 , cppu::UnoType
<embed::XEncryptionProtectedStorage
>::get()
2105 , cppu::UnoType
<embed::XEncryptionProtectedSource2
>::get()
2106 , cppu::UnoType
<embed::XEncryptionProtectedSource
>::get()
2107 , cppu::UnoType
<beans::XPropertySet
>::get());
2111 m_oTypeCollection
.emplace(
2112 cppu::UnoType
<lang::XTypeProvider
>::get()
2113 , cppu::UnoType
<embed::XStorage
>::get()
2114 , cppu::UnoType
<embed::XStorage2
>::get()
2115 , cppu::UnoType
<embed::XStorageRawAccess
>::get()
2116 , cppu::UnoType
<embed::XTransactedObject
>::get()
2117 , cppu::UnoType
<embed::XTransactionBroadcaster
>::get()
2118 , cppu::UnoType
<util::XModifiable
>::get()
2119 , cppu::UnoType
<beans::XPropertySet
>::get());
2122 else if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
)
2124 m_oTypeCollection
.emplace(
2125 cppu::UnoType
<lang::XTypeProvider
>::get()
2126 , cppu::UnoType
<embed::XStorage
>::get()
2127 , cppu::UnoType
<embed::XTransactedObject
>::get()
2128 , cppu::UnoType
<embed::XTransactionBroadcaster
>::get()
2129 , cppu::UnoType
<util::XModifiable
>::get()
2130 , cppu::UnoType
<embed::XRelationshipAccess
>::get()
2131 , cppu::UnoType
<beans::XPropertySet
>::get());
2135 m_oTypeCollection
.emplace(
2136 cppu::UnoType
<lang::XTypeProvider
>::get()
2137 , cppu::UnoType
<embed::XStorage
>::get()
2138 , cppu::UnoType
<embed::XTransactedObject
>::get()
2139 , cppu::UnoType
<embed::XTransactionBroadcaster
>::get()
2140 , cppu::UnoType
<util::XModifiable
>::get()
2141 , cppu::UnoType
<beans::XPropertySet
>::get());
2146 return m_oTypeCollection
->getTypes() ;
2149 uno::Sequence
< sal_Int8
> SAL_CALL
OStorage::getImplementationId()
2151 static const comphelper::UnoIdInit lcl_ImplId
;
2152 return lcl_ImplId
.getSeq();
2156 void SAL_CALL
OStorage::copyToStorage( const uno::Reference
< embed::XStorage
>& xDest
)
2158 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2162 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2163 throw lang::DisposedException( THROW_WHERE
);
2166 if ( !xDest
.is() || xDest
== getXWeak() )
2167 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 );
2170 m_pImpl
->CopyToStorage( xDest
, false );
2172 catch( const embed::InvalidStorageException
& )
2174 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2177 catch( const lang::IllegalArgumentException
& )
2179 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2182 catch( const embed::StorageWrappedTargetException
& )
2184 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2187 catch( const io::IOException
& )
2189 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2192 catch( const uno::RuntimeException
& )
2194 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2197 catch( const uno::Exception
& )
2199 uno::Any
aCaught( ::cppu::getCaughtException() );
2200 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2202 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy storage!",
2203 uno::Reference
< io::XInputStream
>(),
2208 uno::Reference
< io::XStream
> SAL_CALL
OStorage::openStreamElement(
2209 const OUString
& aStreamName
, sal_Int32 nOpenMode
)
2211 osl::ClearableMutexGuard
aGuard(m_xSharedMutex
->GetMutex());
2215 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2216 throw lang::DisposedException( THROW_WHERE
);
2219 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
2220 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2222 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStreamName
== "_rels" )
2223 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable element name
2225 if ( ( nOpenMode
& embed::ElementModes::WRITE
) && m_bReadOnlyWrap
)
2226 throw io::IOException( THROW_WHERE
); // TODO: access denied
2228 uno::Reference
< io::XStream
> xResult
;
2231 SotElement_Impl
*pElement
= OpenStreamElement_Impl( aStreamName
, nOpenMode
, false );
2232 assert(pElement
&& pElement
->m_xStream
&& "In case element can not be created an exception must be thrown!");
2234 xResult
= pElement
->m_xStream
->GetStream(nOpenMode
, false);
2235 SAL_WARN_IF( !xResult
.is(), "package.xstor", "The method must throw exception instead of removing empty result!" );
2237 if ( m_bReadOnlyWrap
)
2239 // before the storage disposes the stream it must deregister itself as listener
2240 uno::Reference
< lang::XComponent
> xStreamComponent( xResult
, uno::UNO_QUERY_THROW
);
2241 MakeLinkToSubComponent_Impl( xStreamComponent
);
2244 catch( const embed::InvalidStorageException
& )
2246 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2249 catch( const lang::IllegalArgumentException
& )
2251 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2254 catch( const packages::WrongPasswordException
& )
2256 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2259 catch( const embed::StorageWrappedTargetException
& )
2261 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2264 catch( const io::IOException
& )
2266 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2269 catch( const uno::RuntimeException
& )
2271 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2274 catch( const uno::Exception
& )
2276 uno::Any
aCaught( ::cppu::getCaughtException() );
2277 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2279 throw embed::StorageWrappedTargetException(THROW_WHERE
"Can't open stream element!",
2280 uno::Reference
< io::XInputStream
>(),
2286 BroadcastModifiedIfNecessary();
2291 uno::Reference
< io::XStream
> SAL_CALL
OStorage::openEncryptedStreamElement(
2292 const OUString
& aStreamName
, sal_Int32 nOpenMode
, const OUString
& aPass
)
2294 return openEncryptedStream( aStreamName
, nOpenMode
, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass
) );
2297 uno::Reference
< embed::XStorage
> SAL_CALL
OStorage::openStorageElement(
2298 const OUString
& aStorName
, sal_Int32 nStorageMode
)
2300 return openStorageElement2(aStorName
, nStorageMode
);
2303 rtl::Reference
< OStorage
> OStorage::openStorageElement2(
2304 const OUString
& aStorName
, sal_Int32 nStorageMode
)
2306 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2310 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2311 throw lang::DisposedException( THROW_WHERE
);
2314 if ( aStorName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName
, false ) )
2315 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2317 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStorName
== "_rels" )
2318 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable storage name
2320 if ( ( nStorageMode
& embed::ElementModes::WRITE
) && m_bReadOnlyWrap
)
2321 throw io::IOException( THROW_WHERE
); // TODO: access denied
2323 if ( ( nStorageMode
& embed::ElementModes::TRUNCATE
)
2324 && !( nStorageMode
& embed::ElementModes::WRITE
) )
2325 throw io::IOException( THROW_WHERE
); // TODO: access denied
2327 // it's always possible to read written storage in this implementation
2328 nStorageMode
|= embed::ElementModes::READ
;
2330 rtl::Reference
< OStorage
> xResult
;
2333 SotElement_Impl
*pElement
= m_pImpl
->FindElement( aStorName
);
2336 // element does not exist, check if creation is allowed
2337 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
)
2338 || (( nStorageMode
& embed::ElementModes::WRITE
) != embed::ElementModes::WRITE
)
2339 || ( nStorageMode
& embed::ElementModes::NOCREATE
) == embed::ElementModes::NOCREATE
)
2340 throw io::IOException( THROW_WHERE
); // TODO: access_denied
2342 // create a new StorageElement and insert it into the list
2343 pElement
= m_pImpl
->InsertStorage( aStorName
, nStorageMode
);
2345 else if ( !pElement
->m_bIsStorage
)
2347 throw io::IOException( THROW_WHERE
);
2349 else if (pElement
->m_xStorage
)
2351 // storage has already been opened; it may be opened another time, if it the mode allows to do so
2352 if (pElement
->m_xStorage
->m_pAntiImpl
)
2354 throw io::IOException( THROW_WHERE
); // TODO: access_denied
2356 else if ( !pElement
->m_xStorage
->m_aReadOnlyWrapVector
.empty()
2357 && ( nStorageMode
& embed::ElementModes::WRITE
) )
2359 throw io::IOException( THROW_WHERE
); // TODO: access_denied
2363 // in case parent storage allows writing the readonly mode of the child storage is
2364 // virtual, that means that it is just enough to change the flag to let it be writable
2365 // and since there is no AntiImpl nobody should be notified about it
2366 pElement
->m_xStorage
->m_nStorageMode
= nStorageMode
| embed::ElementModes::READ
;
2368 if ( nStorageMode
& embed::ElementModes::TRUNCATE
)
2370 for (const auto & rPair
: pElement
->m_xStorage
->m_aChildrenMap
)
2371 for (auto pElementToDel
: rPair
.second
)
2372 m_pImpl
->RemoveElement( /*aName*/rPair
.first
, pElementToDel
);
2377 if (!pElement
->m_xStorage
)
2378 m_pImpl
->OpenSubStorage(pElement
, nStorageMode
);
2380 if (!pElement
->m_xStorage
)
2381 throw io::IOException( THROW_WHERE
); // TODO: general_error
2383 bool bReadOnlyWrap
= ( ( nStorageMode
& embed::ElementModes::WRITE
) != embed::ElementModes::WRITE
);
2384 rtl::Reference
<OStorage
> pResultStorage
= new OStorage(pElement
->m_xStorage
.get(), bReadOnlyWrap
);
2385 xResult
= pResultStorage
;
2387 if ( bReadOnlyWrap
)
2389 // Before this call is done the object must be refcounted already
2390 pElement
->m_xStorage
->SetReadOnlyWrap(*pResultStorage
);
2392 // before the storage disposes the stream it must deregister itself as listener
2393 MakeLinkToSubComponent_Impl( xResult
);
2396 catch( const embed::InvalidStorageException
& )
2398 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2401 catch( const lang::IllegalArgumentException
& )
2403 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2406 catch( const embed::StorageWrappedTargetException
& )
2408 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2411 catch( const io::IOException
& )
2413 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2416 catch( const uno::RuntimeException
& )
2418 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2421 catch( const uno::Exception
& )
2423 uno::Any
aCaught( ::cppu::getCaughtException() );
2424 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2426 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't open storage!",
2427 uno::Reference
< io::XInputStream
>(),
2434 uno::Reference
< io::XStream
> SAL_CALL
OStorage::cloneStreamElement( const OUString
& aStreamName
)
2436 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2440 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2441 throw lang::DisposedException( THROW_WHERE
);
2444 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
2445 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2447 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStreamName
== "_rels" )
2448 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable storage name
2452 uno::Reference
< io::XStream
> xResult
;
2453 m_pImpl
->CloneStreamElement( aStreamName
, false, ::comphelper::SequenceAsHashMap(), xResult
);
2454 if ( !xResult
.is() )
2455 throw uno::RuntimeException( THROW_WHERE
);
2458 catch( const embed::InvalidStorageException
& )
2460 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2463 catch( const lang::IllegalArgumentException
& )
2465 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2468 catch( const packages::WrongPasswordException
& )
2470 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2473 catch( const io::IOException
& )
2475 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2478 catch( const embed::StorageWrappedTargetException
& )
2480 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2483 catch( const uno::RuntimeException
& )
2485 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2488 catch( const uno::Exception
& )
2490 uno::Any
aCaught( ::cppu::getCaughtException() );
2491 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2493 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't clone stream!",
2494 uno::Reference
< io::XInputStream
>(),
2499 uno::Reference
< io::XStream
> SAL_CALL
OStorage::cloneEncryptedStreamElement(
2500 const OUString
& aStreamName
,
2501 const OUString
& aPass
)
2503 return cloneEncryptedStream( aStreamName
, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass
) );
2506 void SAL_CALL
OStorage::copyLastCommitTo(
2507 const uno::Reference
< embed::XStorage
>& xTargetStorage
)
2509 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2513 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2514 throw lang::DisposedException( THROW_WHERE
);
2519 m_pImpl
->CopyLastCommitTo( xTargetStorage
);
2521 catch( const embed::InvalidStorageException
& )
2523 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2526 catch( const lang::IllegalArgumentException
& )
2528 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2531 catch( const embed::StorageWrappedTargetException
& )
2533 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2536 catch( const io::IOException
& )
2538 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2541 catch( const uno::RuntimeException
& )
2543 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2546 catch( const uno::Exception
& )
2548 uno::Any
aCaught( ::cppu::getCaughtException() );
2549 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2551 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy last commit version!",
2552 uno::Reference
< io::XInputStream
>(),
2558 void SAL_CALL
OStorage::copyStorageElementLastCommitTo(
2559 const OUString
& aStorName
,
2560 const uno::Reference
< embed::XStorage
>& xTargetStorage
)
2562 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2566 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2567 throw lang::DisposedException( THROW_WHERE
);
2570 if ( aStorName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName
, false ) )
2571 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2573 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStorName
== "_rels" )
2574 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable storage name
2578 SotElement_Impl
*pElement
= m_pImpl
->FindElement( aStorName
);
2581 // element does not exist, throw exception
2582 throw io::IOException( THROW_WHERE
); // TODO: access_denied
2584 else if ( !pElement
->m_bIsStorage
)
2586 throw io::IOException( THROW_WHERE
);
2589 if (!pElement
->m_xStorage
)
2590 m_pImpl
->OpenSubStorage( pElement
, embed::ElementModes::READ
);
2592 if (!pElement
->m_xStorage
)
2593 throw io::IOException( THROW_WHERE
); // TODO: general_error
2595 // the existence of m_pAntiImpl of the child is not interesting,
2596 // the copy will be created internally
2598 pElement
->m_xStorage
->CopyLastCommitTo(xTargetStorage
);
2600 catch( const embed::InvalidStorageException
& )
2602 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2605 catch( const lang::IllegalArgumentException
& )
2607 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2610 catch( const io::IOException
& )
2612 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2615 catch( const embed::StorageWrappedTargetException
& )
2617 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2620 catch( const uno::RuntimeException
& )
2622 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2625 catch( const uno::Exception
& )
2627 uno::Any
aCaught( ::cppu::getCaughtException() );
2628 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2630 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy last commit element version!",
2631 uno::Reference
< io::XInputStream
>(),
2636 sal_Bool SAL_CALL
OStorage::isStreamElement( const OUString
& aElementName
)
2638 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2642 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2643 throw lang::DisposedException( THROW_WHERE
);
2646 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false ) )
2647 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2649 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aElementName
== "_rels" )
2650 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable name
2652 SotElement_Impl
* pElement
= nullptr;
2656 pElement
= m_pImpl
->FindElement( aElementName
);
2658 catch( const embed::InvalidStorageException
& )
2660 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2663 catch( const lang::IllegalArgumentException
& )
2665 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2668 catch( const container::NoSuchElementException
& )
2670 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2673 catch( const uno::RuntimeException
& )
2675 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2678 catch( const uno::Exception
& )
2680 uno::Any
aCaught( ::cppu::getCaughtException() );
2681 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2683 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can't detect whether it is a stream!",
2684 uno::Reference
< io::XInputStream
>(),
2689 throw container::NoSuchElementException( THROW_WHERE
); //???
2691 return !pElement
->m_bIsStorage
;
2694 sal_Bool SAL_CALL
OStorage::isStorageElement( const OUString
& aElementName
)
2696 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2700 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2701 throw lang::DisposedException( THROW_WHERE
);
2704 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false ) )
2705 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2707 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aElementName
== "_rels" )
2708 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 );
2710 SotElement_Impl
* pElement
= nullptr;
2714 pElement
= m_pImpl
->FindElement( aElementName
);
2716 catch( const embed::InvalidStorageException
& )
2718 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2721 catch( const lang::IllegalArgumentException
& )
2723 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2726 catch( const container::NoSuchElementException
& )
2728 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2731 catch( const uno::RuntimeException
& )
2733 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2736 catch( const uno::Exception
& )
2738 uno::Any
aCaught( ::cppu::getCaughtException() );
2739 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2741 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"can't detect whether it is a storage",
2742 uno::Reference
< io::XInputStream
>(),
2747 throw container::NoSuchElementException( THROW_WHERE
); //???
2749 return pElement
->m_bIsStorage
;
2752 void SAL_CALL
OStorage::removeElement( const OUString
& aElementName
)
2755 osl::MutexGuard
aGuard(m_xSharedMutex
->GetMutex());
2759 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2760 throw lang::DisposedException(THROW_WHERE
);
2763 if (aElementName
.isEmpty()
2764 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aElementName
, false))
2765 throw lang::IllegalArgumentException(THROW_WHERE
"Unexpected entry name syntax.",
2766 uno::Reference
<uno::XInterface
>(), 1);
2768 if (m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aElementName
== "_rels")
2769 throw lang::IllegalArgumentException(THROW_WHERE
, uno::Reference
<uno::XInterface
>(),
2770 1); // TODO: unacceptable name
2772 if (!(m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
))
2773 throw io::IOException(THROW_WHERE
); // TODO: access denied
2777 auto pElement
= m_pImpl
->FindElement(aElementName
);
2779 throw container::NoSuchElementException(THROW_WHERE
); //???
2781 m_pImpl
->RemoveElement(aElementName
, pElement
);
2783 m_pImpl
->m_bIsModified
= true;
2784 m_pImpl
->m_bBroadcastModified
= true;
2786 catch (const embed::InvalidStorageException
&)
2788 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2791 catch (const lang::IllegalArgumentException
&)
2793 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2796 catch (const container::NoSuchElementException
&)
2798 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2801 catch (const io::IOException
&)
2803 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2806 catch (const embed::StorageWrappedTargetException
&)
2808 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2811 catch (const uno::RuntimeException
&)
2813 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2816 catch (const uno::Exception
&)
2818 uno::Any
aCaught(::cppu::getCaughtException());
2819 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2821 throw embed::StorageWrappedTargetException(THROW_WHERE
"Can't remove element!",
2822 uno::Reference
<io::XInputStream
>(), aCaught
);
2826 BroadcastModifiedIfNecessary();
2829 void SAL_CALL
OStorage::renameElement( const OUString
& aElementName
, const OUString
& aNewName
)
2832 osl::MutexGuard
aGuard(m_xSharedMutex
->GetMutex());
2836 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2837 throw lang::DisposedException(THROW_WHERE
);
2840 if (aElementName
.isEmpty()
2841 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aElementName
, false)
2842 || aNewName
.isEmpty()
2843 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aNewName
, false))
2844 throw lang::IllegalArgumentException(THROW_WHERE
"Unexpected entry name syntax.",
2845 uno::Reference
<uno::XInterface
>(), 1);
2847 if (m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
2848 && (aElementName
== "_rels" || aNewName
== "_rels"))
2849 throw lang::IllegalArgumentException(THROW_WHERE
, uno::Reference
<uno::XInterface
>(),
2850 0); // TODO: unacceptable element name
2852 if (!(m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
))
2853 throw io::IOException(THROW_WHERE
); // TODO: access denied
2857 SotElement_Impl
* pRefElement
= m_pImpl
->FindElement(aNewName
);
2859 throw container::ElementExistException(THROW_WHERE
); //???
2861 auto pElement
= m_pImpl
->FindElement( aElementName
);
2863 throw container::NoSuchElementException(THROW_WHERE
); //???
2865 auto mapIt
= m_pImpl
->m_aChildrenMap
.find(aElementName
);
2866 auto rVec
= mapIt
->second
;
2867 for (auto it
= rVec
.begin(); it
!= rVec
.end(); ++it
)
2868 if (pElement
== *it
)
2870 std::erase(rVec
, pElement
);
2872 m_pImpl
->m_aChildrenMap
.erase(mapIt
);
2875 m_pImpl
->m_aChildrenMap
[aNewName
].push_back(pElement
);
2876 m_pImpl
->m_bIsModified
= true;
2877 m_pImpl
->m_bBroadcastModified
= true;
2879 catch (const embed::InvalidStorageException
&)
2881 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2884 catch (const lang::IllegalArgumentException
&)
2886 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2889 catch (const container::NoSuchElementException
&)
2891 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2894 catch (const container::ElementExistException
&)
2896 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2899 catch (const io::IOException
&)
2901 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2904 catch (const embed::StorageWrappedTargetException
&)
2906 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2909 catch (const uno::RuntimeException
&)
2911 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2914 catch (const uno::Exception
&)
2916 uno::Any
aCaught(::cppu::getCaughtException());
2917 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2919 throw embed::StorageWrappedTargetException(THROW_WHERE
"Can't rename element!",
2920 uno::Reference
<io::XInputStream
>(), aCaught
);
2924 BroadcastModifiedIfNecessary();
2927 void SAL_CALL
OStorage::copyElementTo( const OUString
& aElementName
,
2928 const uno::Reference
< embed::XStorage
>& xDest
,
2929 const OUString
& aNewName
)
2931 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2935 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2936 throw lang::DisposedException( THROW_WHERE
);
2939 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false )
2940 || aNewName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName
, false ) )
2941 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2944 // || xDest == getXWeak() )
2945 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
2947 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& ( aElementName
== "_rels" || aNewName
== "_rels" ) )
2948 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 ); // unacceptable element name
2952 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aElementName
);
2954 throw container::NoSuchElementException( THROW_WHERE
);
2956 uno::Reference
< XNameAccess
> xNameAccess( xDest
, uno::UNO_QUERY_THROW
);
2957 if ( xNameAccess
->hasByName( aNewName
) )
2958 throw container::ElementExistException( THROW_WHERE
);
2960 m_pImpl
->CopyStorageElement( pElement
, xDest
, aNewName
, false );
2962 catch( const embed::InvalidStorageException
& )
2964 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2967 catch( const lang::IllegalArgumentException
& )
2969 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2972 catch( const container::NoSuchElementException
& )
2974 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2977 catch( const container::ElementExistException
& )
2979 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2982 catch( const embed::StorageWrappedTargetException
& )
2984 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2987 catch( const io::IOException
& )
2989 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2992 catch( const uno::RuntimeException
& )
2994 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2997 catch( const uno::Exception
& )
2999 uno::Any
aCaught( ::cppu::getCaughtException() );
3000 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3002 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy element!",
3003 uno::Reference
< io::XInputStream
>(),
3008 void SAL_CALL
OStorage::moveElementTo( const OUString
& aElementName
,
3009 const uno::Reference
< embed::XStorage
>& xDest
,
3010 const OUString
& aNewName
)
3013 osl::MutexGuard
aGuard(m_xSharedMutex
->GetMutex());
3017 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3018 throw lang::DisposedException(THROW_WHERE
);
3021 if (aElementName
.isEmpty()
3022 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aElementName
, false)
3023 || aNewName
.isEmpty()
3024 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aNewName
, false))
3025 throw lang::IllegalArgumentException(THROW_WHERE
"Unexpected entry name syntax.",
3026 uno::Reference
<uno::XInterface
>(), 1);
3028 if (!xDest
.is() || xDest
== getXWeak())
3029 throw lang::IllegalArgumentException(THROW_WHERE
, uno::Reference
<uno::XInterface
>(), 2);
3031 if (m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
3032 && (aElementName
== "_rels" || aNewName
== "_rels"))
3033 throw lang::IllegalArgumentException(THROW_WHERE
, uno::Reference
<uno::XInterface
>(),
3034 0); // unacceptable element name
3036 if (!(m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
))
3037 throw io::IOException(THROW_WHERE
); // TODO: access denied
3041 auto pElement
= m_pImpl
->FindElement( aElementName
);
3043 throw container::NoSuchElementException(THROW_WHERE
); //???
3045 uno::Reference
<XNameAccess
> xNameAccess(xDest
, uno::UNO_QUERY_THROW
);
3046 if (xNameAccess
->hasByName(aNewName
))
3047 throw container::ElementExistException(THROW_WHERE
);
3049 m_pImpl
->CopyStorageElement(pElement
, xDest
, aNewName
, false);
3051 m_pImpl
->RemoveElement(aElementName
, pElement
);
3053 m_pImpl
->m_bIsModified
= true;
3054 m_pImpl
->m_bBroadcastModified
= true;
3056 catch (const embed::InvalidStorageException
&)
3058 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3061 catch (const lang::IllegalArgumentException
&)
3063 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3066 catch (const container::NoSuchElementException
&)
3068 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3071 catch (const container::ElementExistException
&)
3073 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3076 catch (const embed::StorageWrappedTargetException
&)
3078 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3081 catch (const io::IOException
&)
3083 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3086 catch (const uno::RuntimeException
&)
3088 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3091 catch (const uno::Exception
&)
3093 uno::Any
aCaught(::cppu::getCaughtException());
3094 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3096 throw embed::StorageWrappedTargetException(THROW_WHERE
"Can't move element!",
3097 uno::Reference
<io::XInputStream
>(), aCaught
);
3101 BroadcastModifiedIfNecessary();
3105 uno::Reference
< io::XStream
> SAL_CALL
OStorage::openEncryptedStream(
3106 const OUString
& aStreamName
, sal_Int32 nOpenMode
, const uno::Sequence
< beans::NamedValue
>& aEncryptionData
)
3108 osl::ClearableMutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3112 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3113 throw lang::DisposedException( THROW_WHERE
);
3116 if ( ( nOpenMode
& embed::ElementModes::WRITE
) && m_bReadOnlyWrap
)
3117 throw io::IOException( THROW_WHERE
); // TODO: access denied
3119 if ( !aEncryptionData
.hasElements() )
3120 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 3 );
3122 uno::Reference
< io::XStream
> xResult
;
3125 SotElement_Impl
*pElement
= OpenStreamElement_Impl( aStreamName
, nOpenMode
, true );
3126 assert(pElement
&& pElement
->m_xStream
&& "In case element can not be created an exception must be thrown!");
3128 xResult
= pElement
->m_xStream
->GetStream(nOpenMode
, aEncryptionData
, false);
3129 SAL_WARN_IF( !xResult
.is(), "package.xstor", "The method must throw exception instead of removing empty result!" );
3131 if ( m_bReadOnlyWrap
)
3133 // before the storage disposes the stream it must deregister itself as listener
3134 uno::Reference
< lang::XComponent
> xStreamComponent( xResult
, uno::UNO_QUERY_THROW
);
3135 MakeLinkToSubComponent_Impl( xStreamComponent
);
3138 catch( const embed::InvalidStorageException
& )
3140 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3143 catch( const lang::IllegalArgumentException
& )
3145 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3148 catch( const packages::NoEncryptionException
& )
3150 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3153 catch( const packages::WrongPasswordException
& )
3155 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3158 catch( const embed::StorageWrappedTargetException
& )
3160 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3163 catch( const io::IOException
& )
3165 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3168 catch( const uno::RuntimeException
& )
3170 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3173 catch( const uno::Exception
& )
3175 uno::Any
aCaught( ::cppu::getCaughtException() );
3176 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3178 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't open encrypted stream!",
3179 uno::Reference
< io::XInputStream
>(),
3185 BroadcastModifiedIfNecessary();
3190 uno::Reference
< io::XStream
> SAL_CALL
OStorage::cloneEncryptedStream(
3191 const OUString
& aStreamName
,
3192 const uno::Sequence
< beans::NamedValue
>& aEncryptionData
)
3194 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3198 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3199 throw lang::DisposedException( THROW_WHERE
);
3202 if ( !aEncryptionData
.hasElements() )
3203 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
3207 uno::Reference
< io::XStream
> xResult
;
3208 m_pImpl
->CloneStreamElement( aStreamName
, true, aEncryptionData
, xResult
);
3209 if ( !xResult
.is() )
3210 throw uno::RuntimeException( THROW_WHERE
);
3213 catch( const embed::InvalidStorageException
& )
3215 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3218 catch( const lang::IllegalArgumentException
& )
3220 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3223 catch( const packages::NoEncryptionException
& )
3225 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3228 catch( const packages::WrongPasswordException
& )
3230 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3233 catch( const io::IOException
& )
3235 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3238 catch( const embed::StorageWrappedTargetException
& )
3240 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3243 catch( const uno::RuntimeException
& )
3245 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3248 catch( const uno::Exception
& )
3250 uno::Any
aCaught( ::cppu::getCaughtException() );
3251 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3253 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't clone encrypted stream!",
3254 uno::Reference
< io::XInputStream
>(),
3259 // XStorageRawAccess
3260 uno::Reference
< io::XInputStream
> SAL_CALL
OStorage::getPlainRawStreamElement(
3261 const OUString
& sStreamName
)
3263 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3267 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3268 throw lang::DisposedException( THROW_WHERE
);
3271 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
)
3272 throw uno::RuntimeException( THROW_WHERE
); // the interface is not supported and must not be accessible
3274 if ( sStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName
, false ) )
3275 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
3277 uno::Reference
< io::XInputStream
> xTempIn
;
3280 SotElement_Impl
* pElement
= m_pImpl
->FindElement( sStreamName
);
3282 throw container::NoSuchElementException( THROW_WHERE
);
3284 if (!pElement
->m_xStream
)
3286 m_pImpl
->OpenSubStream( pElement
);
3287 if (!pElement
->m_xStream
)
3288 throw io::IOException( THROW_WHERE
);
3291 uno::Reference
<io::XInputStream
> xRawInStream
= pElement
->m_xStream
->GetPlainRawInStream();
3292 if ( !xRawInStream
.is() )
3293 throw io::IOException( THROW_WHERE
);
3295 rtl::Reference
< utl::TempFileFastService
> xTempFile
= new utl::TempFileFastService
;
3296 uno::Reference
< io::XOutputStream
> xTempOut
= xTempFile
->getOutputStream();
3297 xTempIn
= xTempFile
->getInputStream();
3299 if ( !xTempOut
.is() || !xTempIn
.is() )
3300 throw io::IOException( THROW_WHERE
);
3302 // Copy temporary file to a new one
3303 ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream
, xTempOut
);
3304 xTempOut
->closeOutput();
3305 xTempFile
->seek( 0 );
3307 catch( const embed::InvalidStorageException
& )
3309 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3312 catch( const lang::IllegalArgumentException
& )
3314 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3317 catch( const container::NoSuchElementException
& )
3319 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3322 catch( const embed::StorageWrappedTargetException
& )
3324 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3327 catch( const io::IOException
& )
3329 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3332 catch( const uno::RuntimeException
& )
3334 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3337 catch( const uno::Exception
& )
3339 uno::Any
aCaught( ::cppu::getCaughtException() );
3340 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3342 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't get plain raw stream!",
3343 uno::Reference
< io::XInputStream
>(),
3350 uno::Reference
< io::XInputStream
> SAL_CALL
OStorage::getRawEncrStreamElement(
3351 const OUString
& sStreamName
)
3353 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3357 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3358 throw lang::DisposedException( THROW_WHERE
);
3361 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
3362 throw packages::NoEncryptionException( THROW_WHERE
);
3364 if ( sStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName
, false ) )
3365 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
3367 uno::Reference
< io::XInputStream
> xTempIn
;
3370 SotElement_Impl
* pElement
= m_pImpl
->FindElement( sStreamName
);
3372 throw container::NoSuchElementException( THROW_WHERE
);
3374 if (!pElement
->m_xStream
)
3376 m_pImpl
->OpenSubStream( pElement
);
3377 if (!pElement
->m_xStream
)
3378 throw io::IOException( THROW_WHERE
);
3381 if (!pElement
->m_xStream
->IsEncrypted())
3382 throw packages::NoEncryptionException( THROW_WHERE
);
3384 uno::Reference
< io::XInputStream
> xRawInStream
= pElement
->m_xStream
->GetRawInStream();
3385 if ( !xRawInStream
.is() )
3386 throw io::IOException( THROW_WHERE
);
3388 rtl::Reference
< utl::TempFileFastService
> xTempFile
= new utl::TempFileFastService
;
3389 uno::Reference
< io::XOutputStream
> xTempOut
= xTempFile
;
3390 xTempIn
= xTempFile
;
3393 throw io::IOException( THROW_WHERE
);
3395 // Copy temporary file to a new one
3396 ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream
, xTempOut
);
3397 xTempFile
->closeOutput();
3398 xTempFile
->seek( 0 );
3401 catch( const embed::InvalidStorageException
& )
3403 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3406 catch( const lang::IllegalArgumentException
& )
3408 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3411 catch( const packages::NoEncryptionException
& )
3413 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3416 catch( const container::NoSuchElementException
& )
3418 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3421 catch( const embed::StorageWrappedTargetException
& )
3423 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3426 catch( const io::IOException
& )
3428 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3431 catch( const uno::RuntimeException
& )
3433 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3436 catch( const uno::Exception
& )
3438 uno::Any
aCaught( ::cppu::getCaughtException() );
3439 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3441 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't get raw stream!",
3442 uno::Reference
< io::XInputStream
>(),
3449 void SAL_CALL
OStorage::insertRawEncrStreamElement( const OUString
& aStreamName
,
3450 const uno::Reference
< io::XInputStream
>& xInStream
)
3452 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3456 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3457 throw lang::DisposedException( THROW_WHERE
);
3460 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
3461 throw embed::InvalidStorageException( THROW_WHERE
);
3463 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
3464 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
3466 if ( !xInStream
.is() )
3467 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
3469 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
) )
3470 throw io::IOException( THROW_WHERE
); // TODO: access denied
3474 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aStreamName
);
3476 throw container::ElementExistException( THROW_WHERE
);
3478 m_pImpl
->InsertRawStream( aStreamName
, xInStream
);
3480 catch( const embed::InvalidStorageException
& )
3482 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3485 catch( const lang::IllegalArgumentException
& )
3487 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3490 catch( const packages::NoRawFormatException
& )
3492 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3495 catch( const container::ElementExistException
& )
3497 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3500 catch( const embed::StorageWrappedTargetException
& )
3502 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3505 catch( const io::IOException
& )
3507 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3510 catch( const uno::RuntimeException
& )
3512 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3515 catch( const uno::Exception
& )
3517 uno::Any
aCaught( ::cppu::getCaughtException() );
3518 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3520 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't insert raw stream!",
3521 uno::Reference
< io::XInputStream
>(),
3526 // XTransactedObject
3527 void SAL_CALL
OStorage::commit()
3529 uno::Reference
< util::XModifiable
> xParentModif
;
3532 BroadcastTransaction( STOR_MESS_PRECOMMIT
);
3534 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3538 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3539 throw lang::DisposedException( THROW_WHERE
);
3542 if ( m_bReadOnlyWrap
)
3543 throw io::IOException( THROW_WHERE
); // TODO: access_denied
3545 m_pImpl
->Commit(); // the root storage initiates the storing to source
3547 // when the storage is committed the parent is modified
3548 if ( m_pImpl
->m_pParent
&& m_pImpl
->m_pParent
->m_pAntiImpl
)
3549 xParentModif
= static_cast<util::XModifiable
*>(m_pImpl
->m_pParent
->m_pAntiImpl
);
3551 catch( const io::IOException
& )
3553 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3556 catch( const embed::StorageWrappedTargetException
& )
3558 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3561 catch( const uno::RuntimeException
& )
3563 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3566 catch( const uno::Exception
& )
3568 uno::Any
aCaught( ::cppu::getCaughtException() );
3569 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3571 throw embed::StorageWrappedTargetException( THROW_WHERE
"Problems on commit!",
3576 setModified( false );
3577 if ( xParentModif
.is() )
3578 xParentModif
->setModified( true );
3580 BroadcastTransaction( STOR_MESS_COMMITTED
);
3583 void SAL_CALL
OStorage::revert()
3585 // the method removes all the changes done after last commit
3587 BroadcastTransaction( STOR_MESS_PREREVERT
);
3590 osl::MutexGuard
aGuard(m_xSharedMutex
->GetMutex());
3594 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3595 throw lang::DisposedException(THROW_WHERE
);
3598 for (const auto & rPair
: m_pImpl
->m_aChildrenMap
)
3599 for (auto pElement
: rPair
.second
)
3601 bool bThrow
= (pElement
->m_xStorage
3602 && (pElement
->m_xStorage
->m_pAntiImpl
3603 || !pElement
->m_xStorage
->m_aReadOnlyWrapVector
.empty()))
3604 || (pElement
->m_xStream
3605 && (pElement
->m_xStream
->m_pAntiImpl
3606 || !pElement
->m_xStream
->m_aInputStreamsVector
.empty()));
3608 throw io::IOException(THROW_WHERE
); // TODO: access denied
3611 if (m_bReadOnlyWrap
|| !m_pImpl
->m_bListCreated
)
3612 return; // nothing to do
3617 m_pImpl
->m_bIsModified
= false;
3618 m_pImpl
->m_bBroadcastModified
= true;
3620 catch (const io::IOException
&)
3622 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3625 catch (const embed::StorageWrappedTargetException
&)
3627 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3630 catch (const uno::RuntimeException
&)
3632 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3635 catch (const uno::Exception
&)
3637 uno::Any
aCaught(::cppu::getCaughtException());
3638 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3640 throw embed::StorageWrappedTargetException(THROW_WHERE
"Problems on revert!",
3646 setModified( false );
3647 BroadcastTransaction( STOR_MESS_REVERTED
);
3650 // XTransactionBroadcaster
3651 void SAL_CALL
OStorage::addTransactionListener( const uno::Reference
< embed::XTransactionListener
>& aListener
)
3653 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3657 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3658 throw lang::DisposedException( THROW_WHERE
);
3661 m_aListenersContainer
.addInterface( cppu::UnoType
<embed::XTransactionListener
>::get(),
3665 void SAL_CALL
OStorage::removeTransactionListener( const uno::Reference
< embed::XTransactionListener
>& aListener
)
3667 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3671 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3672 throw lang::DisposedException( THROW_WHERE
);
3675 m_aListenersContainer
.removeInterface( cppu::UnoType
<embed::XTransactionListener
>::get(),
3680 // TODO: if there will be no demand on this interface it will be removed from implementation,
3681 // I do not want to remove it now since it is still possible that it will be inserted
3682 // to the service back.
3684 sal_Bool SAL_CALL
OStorage::isModified()
3686 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3690 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3691 throw lang::DisposedException( THROW_WHERE
);
3694 return m_pImpl
->m_bIsModified
;
3697 void SAL_CALL
OStorage::setModified( sal_Bool bModified
)
3700 osl::MutexGuard
aGuard(m_xSharedMutex
->GetMutex());
3704 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3705 throw lang::DisposedException(THROW_WHERE
);
3708 if (m_bReadOnlyWrap
)
3709 throw beans::PropertyVetoException(THROW_WHERE
); // TODO: access denied
3711 if (m_pImpl
->m_bIsModified
!= bool(bModified
))
3712 m_pImpl
->m_bIsModified
= bModified
;
3717 m_pImpl
->m_bBroadcastModified
= true;
3718 BroadcastModifiedIfNecessary();
3722 void SAL_CALL
OStorage::addModifyListener(
3723 const uno::Reference
< util::XModifyListener
>& aListener
)
3725 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3729 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3730 throw lang::DisposedException( THROW_WHERE
);
3733 osl_atomic_increment( &m_pImpl
->m_nModifiedListenerCount
);
3734 m_aListenersContainer
.addInterface(
3735 cppu::UnoType
<util::XModifyListener
>::get(), aListener
);
3738 void SAL_CALL
OStorage::removeModifyListener(
3739 const uno::Reference
< util::XModifyListener
>& aListener
)
3741 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3745 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3746 throw lang::DisposedException( THROW_WHERE
);
3749 osl_atomic_decrement( &m_pImpl
->m_nModifiedListenerCount
);
3750 m_aListenersContainer
.removeInterface(
3751 cppu::UnoType
<util::XModifyListener
>::get(), aListener
);
3756 uno::Any SAL_CALL
OStorage::getByName( const OUString
& aName
)
3758 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3762 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3763 throw lang::DisposedException( THROW_WHERE
);
3766 if ( aName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aName
, false ) )
3767 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
3769 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aName
== "_rels" )
3770 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable element name
3775 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aName
);
3777 throw container::NoSuchElementException( THROW_WHERE
);
3779 if ( pElement
->m_bIsStorage
)
3780 aResult
<<= openStorageElement( aName
, embed::ElementModes::READ
);
3782 aResult
<<= openStreamElement( aName
, embed::ElementModes::READ
);
3784 catch( const container::NoSuchElementException
& )
3786 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3789 catch( const lang::WrappedTargetException
& )
3791 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3794 catch( const uno::RuntimeException
& )
3796 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3799 catch( const uno::Exception
& )
3801 uno::Any
aCaught( ::cppu::getCaughtException() );
3802 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3804 throw lang::WrappedTargetException( THROW_WHERE
"Can not open storage!",
3812 uno::Sequence
< OUString
> SAL_CALL
OStorage::getElementNames()
3814 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3818 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3819 throw lang::DisposedException( THROW_WHERE
);
3824 return m_pImpl
->GetElementNames();
3826 catch( const uno::RuntimeException
& )
3828 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3831 catch ( const uno::Exception
& )
3833 uno::Any
aCaught( ::cppu::getCaughtException() );
3834 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3836 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open storage!",
3842 sal_Bool SAL_CALL
OStorage::hasByName( const OUString
& aName
)
3844 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3848 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3849 throw lang::DisposedException( THROW_WHERE
);
3852 if ( aName
.isEmpty() )
3855 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aName
== "_rels" )
3858 SotElement_Impl
* pElement
= nullptr;
3861 pElement
= m_pImpl
->FindElement( aName
);
3863 catch( const uno::RuntimeException
& )
3865 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3868 catch ( const uno::Exception
& )
3870 uno::Any
aCaught( ::cppu::getCaughtException() );
3871 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3873 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open storage!",
3878 return ( pElement
!= nullptr );
3881 uno::Type SAL_CALL
OStorage::getElementType()
3883 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3887 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3888 throw lang::DisposedException( THROW_WHERE
);
3891 // it is a multitype container
3895 sal_Bool SAL_CALL
OStorage::hasElements()
3897 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3901 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3902 throw lang::DisposedException( THROW_WHERE
);
3907 return m_pImpl
->HasChildren();
3909 catch( const uno::RuntimeException
& )
3911 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3914 catch( const uno::Exception
& )
3916 uno::Any
aCaught( ::cppu::getCaughtException() );
3917 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3919 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open storage!",
3926 void SAL_CALL
OStorage::dispose()
3928 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3932 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3933 throw lang::DisposedException( THROW_WHERE
);
3938 InternalDispose( true );
3940 catch( const uno::RuntimeException
& )
3942 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3945 catch( const uno::Exception
& )
3947 uno::Any
aCaught( ::cppu::getCaughtException() );
3948 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3950 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open storage!",
3956 void SAL_CALL
OStorage::addEventListener(
3957 const uno::Reference
< lang::XEventListener
>& xListener
)
3959 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3963 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3964 throw lang::DisposedException( THROW_WHERE
);
3967 m_aListenersContainer
.addInterface(
3968 cppu::UnoType
<lang::XEventListener
>::get(), xListener
);
3971 void SAL_CALL
OStorage::removeEventListener(
3972 const uno::Reference
< lang::XEventListener
>& xListener
)
3974 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3978 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3979 throw lang::DisposedException( THROW_WHERE
);
3982 m_aListenersContainer
.removeInterface(
3983 cppu::UnoType
<lang::XEventListener
>::get(), xListener
);
3986 // XEncryptionProtectedSource
3988 void SAL_CALL
OStorage::setEncryptionPassword( const OUString
& aPass
)
3990 setEncryptionData( ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass
) );
3993 void SAL_CALL
OStorage::removeEncryption()
3995 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3999 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4000 throw lang::DisposedException( THROW_WHERE
);
4003 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4004 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4006 SAL_WARN_IF( !m_pImpl
->m_bIsRoot
, "package.xstor", "removeEncryption() method is not available for nonroot storages!" );
4007 if ( !m_pImpl
->m_bIsRoot
)
4011 m_pImpl
->ReadContents();
4013 catch ( const uno::RuntimeException
& )
4015 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4018 catch ( const uno::Exception
& )
4020 uno::Any
aCaught( ::cppu::getCaughtException() );
4021 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4023 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4028 // TODO: check if the password is valid
4029 // update all streams that was encrypted with old password
4031 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4034 xPackPropSet
->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY
,
4035 uno::Any( uno::Sequence
< beans::NamedValue
>() ) );
4037 m_pImpl
->m_bHasCommonEncryptionData
= false;
4038 m_pImpl
->m_aCommonEncryptionData
.clear();
4040 catch( const uno::RuntimeException
& )
4042 TOOLS_WARN_EXCEPTION( "package.xstor", "The call must not fail, it is pretty simple!" );
4045 catch( const uno::Exception
& )
4047 TOOLS_WARN_EXCEPTION( "package.xstor", "The call must not fail, it is pretty simple!" );
4048 throw io::IOException( THROW_WHERE
);
4052 // XEncryptionProtectedSource2
4054 void SAL_CALL
OStorage::setEncryptionData( const uno::Sequence
< beans::NamedValue
>& aEncryptionData
)
4056 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4060 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4061 throw lang::DisposedException( THROW_WHERE
);
4064 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4065 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4067 if ( !aEncryptionData
.hasElements() )
4068 throw uno::RuntimeException( THROW_WHERE
"Unexpected empty encryption data!" );
4070 SAL_WARN_IF( !m_pImpl
->m_bIsRoot
, "package.xstor", "setEncryptionData() method is not available for nonroot storages!" );
4071 if ( !m_pImpl
->m_bIsRoot
)
4075 m_pImpl
->ReadContents();
4077 catch ( const uno::RuntimeException
& )
4079 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4082 catch ( const uno::Exception
& )
4084 uno::Any
aCaught( ::cppu::getCaughtException() );
4085 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4087 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4092 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4095 ::comphelper::SequenceAsHashMap
aEncryptionMap( aEncryptionData
);
4096 xPackPropSet
->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY
,
4097 uno::Any( aEncryptionMap
.getAsConstNamedValueList() ) );
4099 m_pImpl
->m_bHasCommonEncryptionData
= true;
4100 m_pImpl
->m_aCommonEncryptionData
= std::move(aEncryptionMap
);
4102 catch( const uno::Exception
& )
4104 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:" );
4106 throw io::IOException( THROW_WHERE
);
4110 sal_Bool SAL_CALL
OStorage::hasEncryptionData()
4112 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4114 return m_pImpl
&& m_pImpl
->m_bHasCommonEncryptionData
;
4117 // XEncryptionProtectedStorage
4119 void SAL_CALL
OStorage::setEncryptionAlgorithms( const uno::Sequence
< beans::NamedValue
>& aAlgorithms
)
4121 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4125 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4126 throw lang::DisposedException( THROW_WHERE
);
4129 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4130 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4132 if ( !aAlgorithms
.hasElements() )
4133 throw uno::RuntimeException( THROW_WHERE
"Unexpected empty encryption algorithms list!" );
4135 SAL_WARN_IF( !m_pImpl
->m_bIsRoot
, "package.xstor", "setEncryptionAlgorithms() method is not available for nonroot storages!" );
4136 if ( !m_pImpl
->m_bIsRoot
)
4140 m_pImpl
->ReadContents();
4142 catch ( const uno::RuntimeException
& )
4144 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4147 catch ( const uno::Exception
& )
4149 uno::Any
aCaught( ::cppu::getCaughtException() );
4150 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4152 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4157 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4160 xPackPropSet
->setPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY
,
4161 uno::Any( aAlgorithms
) );
4163 catch ( const uno::RuntimeException
& )
4165 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4168 catch( const uno::Exception
& )
4170 uno::Any
aCaught( ::cppu::getCaughtException() );
4171 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4173 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4179 void SAL_CALL
OStorage::setGpgProperties( const uno::Sequence
< uno::Sequence
< beans::NamedValue
> >& aProps
)
4181 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4185 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4186 throw lang::DisposedException( THROW_WHERE
);
4189 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4190 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4192 if ( !aProps
.hasElements() )
4193 throw uno::RuntimeException( THROW_WHERE
"Unexpected empty encryption algorithms list!" );
4195 SAL_WARN_IF( !m_pImpl
->m_bIsRoot
, "package.xstor", "setGpgProperties() method is not available for nonroot storages!" );
4196 if ( !m_pImpl
->m_bIsRoot
)
4200 m_pImpl
->ReadContents();
4202 catch ( const uno::RuntimeException
& aRuntimeException
)
4204 SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException
.Message
);
4207 catch ( const uno::Exception
& )
4209 uno::Any
aCaught( ::cppu::getCaughtException() );
4210 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4212 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4217 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4220 xPackPropSet
->setPropertyValue( ENCRYPTION_GPG_PROPERTIES
,
4221 uno::Any( aProps
) );
4223 catch ( const uno::RuntimeException
& aRuntimeException
)
4225 SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException
.Message
);
4228 catch( const uno::Exception
& )
4230 uno::Any
aCaught( ::cppu::getCaughtException() );
4231 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4233 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4239 uno::Sequence
< beans::NamedValue
> SAL_CALL
OStorage::getEncryptionAlgorithms()
4241 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4245 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4246 throw lang::DisposedException( THROW_WHERE
);
4249 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4250 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4252 uno::Sequence
< beans::NamedValue
> aResult
;
4253 SAL_WARN_IF( !m_pImpl
->m_bIsRoot
, "package.xstor", "getEncryptionAlgorithms() method is not available for nonroot storages!" );
4254 if ( m_pImpl
->m_bIsRoot
)
4257 m_pImpl
->ReadContents();
4259 catch ( const uno::RuntimeException
& )
4261 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4264 catch ( const uno::Exception
& )
4266 uno::Any
aCaught( ::cppu::getCaughtException() );
4267 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4269 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4274 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4277 xPackPropSet
->getPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY
) >>= aResult
;
4279 catch ( const uno::RuntimeException
& )
4281 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4284 catch( const uno::Exception
& )
4286 uno::Any
aCaught( ::cppu::getCaughtException() );
4287 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4289 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4300 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
OStorage::getPropertySetInfo()
4302 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4306 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4307 throw lang::DisposedException( THROW_WHERE
);
4311 return uno::Reference
< beans::XPropertySetInfo
>();
4314 void SAL_CALL
OStorage::setPropertyValue( const OUString
& aPropertyName
, const uno::Any
& aValue
)
4316 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4320 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4321 throw lang::DisposedException( THROW_WHERE
);
4324 //TODO: think about interaction handler
4327 // The old document might have no version in the manifest.xml, so we have to allow to set the version
4328 // even for readonly storages, so that the version from content.xml can be used.
4329 if ( m_bReadOnlyWrap
&& aPropertyName
!= "Version" )
4330 throw uno::RuntimeException( THROW_WHERE
); // TODO: Access denied
4332 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::ZIP
)
4333 throw beans::UnknownPropertyException( aPropertyName
);
4334 else if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::PACKAGE
)
4336 if ( aPropertyName
== "MediaType" )
4338 aValue
>>= m_pImpl
->m_aMediaType
;
4339 m_pImpl
->m_bControlMediaType
= true;
4341 m_pImpl
->m_bBroadcastModified
= true;
4342 m_pImpl
->m_bIsModified
= true;
4344 else if ( aPropertyName
== "Version" )
4346 aValue
>>= m_pImpl
->m_aVersion
;
4347 m_pImpl
->m_bControlVersion
= true;
4349 // this property can be set even for readonly storage
4350 if ( !m_bReadOnlyWrap
)
4352 m_pImpl
->m_bBroadcastModified
= true;
4353 m_pImpl
->m_bIsModified
= true;
4356 else if ( ( m_pImpl
->m_bIsRoot
&& ( aPropertyName
== HAS_ENCRYPTED_ENTRIES_PROPERTY
4357 || aPropertyName
== HAS_NONENCRYPTED_ENTRIES_PROPERTY
4358 || aPropertyName
== IS_INCONSISTENT_PROPERTY
4359 || aPropertyName
== "URL"
4360 || aPropertyName
== "RepairPackage"
4361 || aPropertyName
== ENCRYPTION_GPG_PROPERTIES
) )
4362 || aPropertyName
== "IsRoot"
4363 || aPropertyName
== MEDIATYPE_FALLBACK_USED_PROPERTY
)
4364 throw beans::PropertyVetoException( THROW_WHERE
);
4366 throw beans::UnknownPropertyException( aPropertyName
);
4368 else if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
)
4370 if ( aPropertyName
== "RelationsInfoStream" )
4372 uno::Reference
< io::XInputStream
> xInRelStream
;
4373 if ( !( aValue
>>= xInRelStream
) || !xInRelStream
.is() )
4374 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
4376 uno::Reference
< io::XSeekable
> xSeek( xInRelStream
, uno::UNO_QUERY
);
4379 // currently this is an internal property that is used for optimization
4380 // and the stream must support XSeekable interface
4381 // TODO/LATER: in future it can be changed if property is used from outside
4382 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
4385 m_pImpl
->m_xNewRelInfoStream
= std::move(xInRelStream
);
4386 m_pImpl
->m_aRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
4387 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED_STREAM
;
4388 m_pImpl
->m_bBroadcastModified
= true;
4389 m_pImpl
->m_bIsModified
= true;
4391 else if ( aPropertyName
== "RelationsInfo" )
4393 if ( !(aValue
>>= m_pImpl
->m_aRelInfo
) )
4394 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
4396 m_pImpl
->m_xNewRelInfoStream
.clear();
4397 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4398 m_pImpl
->m_bBroadcastModified
= true;
4399 m_pImpl
->m_bIsModified
= true;
4401 else if ( ( m_pImpl
->m_bIsRoot
&& ( aPropertyName
== "URL" || aPropertyName
== "RepairPackage") )
4402 || aPropertyName
== "IsRoot" )
4403 throw beans::PropertyVetoException( THROW_WHERE
);
4405 throw beans::UnknownPropertyException( aPropertyName
);
4408 throw beans::UnknownPropertyException( aPropertyName
);
4410 BroadcastModifiedIfNecessary();
4413 uno::Any SAL_CALL
OStorage::getPropertyValue( const OUString
& aPropertyName
)
4415 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4419 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4420 throw lang::DisposedException( THROW_WHERE
);
4423 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::PACKAGE
4424 && ( aPropertyName
== "MediaType" || aPropertyName
== MEDIATYPE_FALLBACK_USED_PROPERTY
|| aPropertyName
== "Version" ) )
4428 m_pImpl
->ReadContents();
4430 catch ( const uno::RuntimeException
& )
4432 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4435 catch ( const uno::Exception
& )
4437 uno::Any
aCaught( ::cppu::getCaughtException() );
4438 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4440 throw lang::WrappedTargetException(
4441 u
"Can't read contents!"_ustr
,
4446 if ( aPropertyName
== "MediaType" )
4447 return uno::Any( m_pImpl
->m_aMediaType
);
4448 else if ( aPropertyName
== "Version" )
4449 return uno::Any( m_pImpl
->m_aVersion
);
4451 return uno::Any( m_pImpl
->m_bMTFallbackUsed
);
4453 else if ( aPropertyName
== "IsRoot" )
4455 return uno::Any( m_pImpl
->m_bIsRoot
);
4457 else if ( aPropertyName
== "OpenMode" )
4459 return uno::Any( m_pImpl
->m_nStorageMode
);
4461 else if ( m_pImpl
->m_bIsRoot
)
4463 if ( aPropertyName
== "URL"
4464 || aPropertyName
== "RepairPackage" )
4466 auto pProp
= std::find_if(std::cbegin(m_pImpl
->m_xProperties
), std::cend(m_pImpl
->m_xProperties
),
4467 [&aPropertyName
](const css::beans::PropertyValue
& rProp
) { return rProp
.Name
== aPropertyName
; });
4468 if (pProp
!= std::cend(m_pImpl
->m_xProperties
))
4469 return pProp
->Value
;
4471 if ( aPropertyName
== "URL" )
4472 return uno::Any( OUString() );
4474 return uno::Any( false ); // RepairPackage
4476 else if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::PACKAGE
4477 && ( aPropertyName
== HAS_ENCRYPTED_ENTRIES_PROPERTY
4478 || aPropertyName
== HAS_NONENCRYPTED_ENTRIES_PROPERTY
4479 || aPropertyName
== ENCRYPTION_GPG_PROPERTIES
4480 || aPropertyName
== IS_INCONSISTENT_PROPERTY
) )
4483 m_pImpl
->ReadContents();
4484 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4485 return xPackPropSet
->getPropertyValue( aPropertyName
);
4487 catch ( const uno::RuntimeException
& )
4489 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4492 catch ( const uno::Exception
& )
4494 uno::Any
aCaught( ::cppu::getCaughtException() );
4495 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4497 throw lang::WrappedTargetException( THROW_WHERE
"Can not open package!",
4504 throw beans::UnknownPropertyException(aPropertyName
);
4507 void SAL_CALL
OStorage::addPropertyChangeListener(
4508 const OUString
& /*aPropertyName*/,
4509 const uno::Reference
< beans::XPropertyChangeListener
>& /*xListener*/ )
4511 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4515 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4516 throw lang::DisposedException( THROW_WHERE
);
4522 void SAL_CALL
OStorage::removePropertyChangeListener(
4523 const OUString
& /*aPropertyName*/,
4524 const uno::Reference
< beans::XPropertyChangeListener
>& /*aListener*/ )
4526 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4530 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4531 throw lang::DisposedException( THROW_WHERE
);
4537 void SAL_CALL
OStorage::addVetoableChangeListener(
4538 const OUString
& /*PropertyName*/,
4539 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
4541 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4545 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4546 throw lang::DisposedException( THROW_WHERE
);
4552 void SAL_CALL
OStorage::removeVetoableChangeListener(
4553 const OUString
& /*PropertyName*/,
4554 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
4556 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4560 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4561 throw lang::DisposedException( THROW_WHERE
);
4567 // XRelationshipAccess
4569 // TODO/LATER: the storage and stream implementations of this interface are very similar, they could use a helper class
4571 sal_Bool SAL_CALL
OStorage::hasByID( const OUString
& sID
)
4573 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4577 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4578 throw lang::DisposedException( THROW_WHERE
);
4581 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4582 throw uno::RuntimeException( THROW_WHERE
);
4586 getRelationshipByID( sID
);
4589 catch( const container::NoSuchElementException
& )
4591 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4600 const beans::StringPair
* lcl_findPairByName(const uno::Sequence
<beans::StringPair
>& rSeq
, const OUString
& rName
)
4602 return std::find_if(rSeq
.begin(), rSeq
.end(), [&rName
](const beans::StringPair
& rPair
) { return rPair
.First
== rName
; });
4607 OUString SAL_CALL
OStorage::getTargetByID( const OUString
& sID
)
4609 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4613 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4614 throw lang::DisposedException( THROW_WHERE
);
4617 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4618 throw uno::RuntimeException( THROW_WHERE
);
4620 const uno::Sequence
< beans::StringPair
> aSeq
= getRelationshipByID( sID
);
4621 auto pRel
= lcl_findPairByName(aSeq
, u
"Target"_ustr
);
4622 if (pRel
!= aSeq
.end())
4623 return pRel
->Second
;
4628 OUString SAL_CALL
OStorage::getTypeByID( const OUString
& sID
)
4630 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4634 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4635 throw lang::DisposedException( THROW_WHERE
);
4638 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4639 throw uno::RuntimeException( THROW_WHERE
);
4641 const uno::Sequence
< beans::StringPair
> aSeq
= getRelationshipByID( sID
);
4642 auto pRel
= lcl_findPairByName(aSeq
, u
"Type"_ustr
);
4643 if (pRel
!= aSeq
.end())
4644 return pRel
->Second
;
4649 uno::Sequence
< beans::StringPair
> SAL_CALL
OStorage::getRelationshipByID( const OUString
& sID
)
4651 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4655 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4656 throw lang::DisposedException( THROW_WHERE
);
4659 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4660 throw uno::RuntimeException( THROW_WHERE
);
4662 // TODO/LATER: in future the unification of the ID could be checked
4663 const uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4664 const beans::StringPair
aIDRel(u
"Id"_ustr
, sID
);
4666 auto pRel
= std::find_if(aSeq
.begin(), aSeq
.end(),
4667 [&aIDRel
](const uno::Sequence
<beans::StringPair
>& rRel
) {
4668 return std::find(rRel
.begin(), rRel
.end(), aIDRel
) != rRel
.end(); });
4669 if (pRel
!= aSeq
.end())
4672 throw container::NoSuchElementException( THROW_WHERE
);
4675 uno::Sequence
< uno::Sequence
< beans::StringPair
> > SAL_CALL
OStorage::getRelationshipsByType( const OUString
& sType
)
4677 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4681 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4682 throw lang::DisposedException( THROW_WHERE
);
4685 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4686 throw uno::RuntimeException( THROW_WHERE
);
4688 // TODO/LATER: in future the unification of the ID could be checked
4689 const uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4690 std::vector
< uno::Sequence
< beans::StringPair
> > aResult
;
4691 aResult
.reserve(aSeq
.getLength());
4693 std::copy_if(aSeq
.begin(), aSeq
.end(), std::back_inserter(aResult
),
4694 [&sType
](const uno::Sequence
<beans::StringPair
>& rRel
) {
4695 auto pRel
= lcl_findPairByName(rRel
, u
"Type"_ustr
);
4696 return pRel
!= rRel
.end()
4697 // the type is usually a URL, so the check should be case insensitive
4698 && pRel
->Second
.equalsIgnoreAsciiCase( sType
);
4701 return comphelper::containerToSequence(aResult
);
4704 uno::Sequence
< uno::Sequence
< beans::StringPair
> > SAL_CALL
OStorage::getAllRelationships()
4706 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4710 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4711 throw lang::DisposedException( THROW_WHERE
);
4714 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4715 throw uno::RuntimeException( THROW_WHERE
);
4717 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aRet
;
4720 aRet
= m_pImpl
->GetAllRelationshipsIfAny();
4722 catch (const io::IOException
&)
4726 catch (const uno::RuntimeException
&)
4730 catch (const uno::Exception
&)
4732 uno::Any
aCaught( ::cppu::getCaughtException() );
4733 throw lang::WrappedTargetRuntimeException(THROW_WHERE
"Can't getAllRelationships!",
4734 uno::Reference
< uno::XInterface
>(),
4741 void SAL_CALL
OStorage::insertRelationshipByID( const OUString
& sID
, const uno::Sequence
< beans::StringPair
>& aEntry
, sal_Bool bReplace
)
4743 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4747 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4748 throw lang::DisposedException( THROW_WHERE
);
4751 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4752 throw uno::RuntimeException( THROW_WHERE
);
4754 const beans::StringPair
aIDRel(u
"Id"_ustr
, sID
);
4756 uno::Sequence
<beans::StringPair
>* pResult
= nullptr;
4758 // TODO/LATER: in future the unification of the ID could be checked
4759 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4760 for ( sal_Int32 nInd
= 0; nInd
< aSeq
.getLength(); nInd
++ )
4762 const auto& rRel
= aSeq
[nInd
];
4763 if (std::find(rRel
.begin(), rRel
.end(), aIDRel
) != rRel
.end())
4764 pResult
= &aSeq
.getArray()[nInd
];
4767 if ( pResult
&& !bReplace
)
4768 throw container::ElementExistException( THROW_WHERE
);
4772 const sal_Int32 nIDInd
= aSeq
.getLength();
4773 aSeq
.realloc( nIDInd
+ 1 );
4774 pResult
= &aSeq
.getArray()[nIDInd
];
4777 std::vector
<beans::StringPair
> aResult
;
4778 aResult
.reserve(aEntry
.getLength() + 1);
4780 aResult
.push_back(aIDRel
);
4781 std::copy_if(aEntry
.begin(), aEntry
.end(), std::back_inserter(aResult
),
4782 [](const beans::StringPair
& rPair
) { return rPair
.First
!= "Id"; });
4784 *pResult
= comphelper::containerToSequence(aResult
);
4786 m_pImpl
->m_aRelInfo
= std::move(aSeq
);
4787 m_pImpl
->m_xNewRelInfoStream
.clear();
4788 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4791 void SAL_CALL
OStorage::removeRelationshipByID( const OUString
& sID
)
4793 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4797 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4798 throw lang::DisposedException( THROW_WHERE
);
4801 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4802 throw uno::RuntimeException( THROW_WHERE
);
4804 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4805 const beans::StringPair
aIDRel(u
"Id"_ustr
, sID
);
4806 auto pRel
= std::find_if(std::cbegin(aSeq
), std::cend(aSeq
),
4807 [&aIDRel
](const uno::Sequence
< beans::StringPair
>& rRel
) {
4808 return std::find(rRel
.begin(), rRel
.end(), aIDRel
) != rRel
.end(); });
4809 if (pRel
!= std::cend(aSeq
))
4811 auto nInd
= static_cast<sal_Int32
>(std::distance(std::cbegin(aSeq
), pRel
));
4812 comphelper::removeElementAt(aSeq
, nInd
);
4814 m_pImpl
->m_aRelInfo
= std::move(aSeq
);
4815 m_pImpl
->m_xNewRelInfoStream
.clear();
4816 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4818 // TODO/LATER: in future the unification of the ID could be checked
4822 throw container::NoSuchElementException( THROW_WHERE
);
4825 void SAL_CALL
OStorage::insertRelationships( const uno::Sequence
< uno::Sequence
< beans::StringPair
> >& aEntries
, sal_Bool bReplace
)
4827 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4831 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4832 throw lang::DisposedException( THROW_WHERE
);
4835 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4836 throw uno::RuntimeException( THROW_WHERE
);
4838 OUString
aIDTag( u
"Id"_ustr
);
4839 const uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4840 std::vector
< uno::Sequence
<beans::StringPair
> > aResultVec
;
4841 aResultVec
.reserve(aSeq
.getLength() + aEntries
.getLength());
4843 std::copy_if(aSeq
.begin(), aSeq
.end(), std::back_inserter(aResultVec
),
4844 [&aIDTag
, &aEntries
, bReplace
](const uno::Sequence
<beans::StringPair
>& rTargetRel
) {
4845 auto pTargetPair
= lcl_findPairByName(rTargetRel
, aIDTag
);
4846 if (pTargetPair
== rTargetRel
.end())
4849 bool bIsSourceSame
= std::any_of(aEntries
.begin(), aEntries
.end(),
4850 [&pTargetPair
](const uno::Sequence
<beans::StringPair
>& rSourceEntry
) {
4851 return std::find(rSourceEntry
.begin(), rSourceEntry
.end(), *pTargetPair
) != rSourceEntry
.end(); });
4853 if ( bIsSourceSame
&& !bReplace
)
4854 throw container::ElementExistException( THROW_WHERE
);
4856 // if no such element in the provided sequence
4857 return !bIsSourceSame
;
4860 std::transform(aEntries
.begin(), aEntries
.end(), std::back_inserter(aResultVec
),
4861 [&aIDTag
](const uno::Sequence
<beans::StringPair
>& rEntry
) -> uno::Sequence
<beans::StringPair
> {
4862 auto pPair
= lcl_findPairByName(rEntry
, aIDTag
);
4863 if (pPair
== rEntry
.end())
4864 throw io::IOException( THROW_WHERE
); // TODO: illegal relation ( no ID )
4866 auto aResult
= comphelper::sequenceToContainer
<std::vector
<beans::StringPair
>>(rEntry
);
4867 auto nIDInd
= std::distance(rEntry
.begin(), pPair
);
4868 std::rotate(aResult
.begin(), std::next(aResult
.begin(), nIDInd
), std::next(aResult
.begin(), nIDInd
+ 1));
4870 return comphelper::containerToSequence(aResult
);
4873 m_pImpl
->m_aRelInfo
= comphelper::containerToSequence(aResultVec
);
4874 m_pImpl
->m_xNewRelInfoStream
.clear();
4875 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4878 void SAL_CALL
OStorage::clearRelationships()
4880 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4884 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4885 throw lang::DisposedException( THROW_WHERE
);
4888 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4889 throw uno::RuntimeException( THROW_WHERE
);
4891 m_pImpl
->m_aRelInfo
.realloc( 0 );
4892 m_pImpl
->m_xNewRelInfoStream
.clear();
4893 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4896 // XOptimizedStorage
4897 void SAL_CALL
OStorage::insertRawNonEncrStreamElementDirect(
4898 const OUString
& /*sStreamName*/,
4899 const uno::Reference
< io::XInputStream
>& /*xInStream*/ )
4901 // not implemented currently because there is still no demand
4902 // might need to be implemented if direct copying of compressed streams is used
4903 throw io::IOException( THROW_WHERE
);
4906 void SAL_CALL
OStorage::insertStreamElementDirect(
4907 const OUString
& aStreamName
,
4908 const uno::Reference
< io::XInputStream
>& xInStream
,
4909 const uno::Sequence
< beans::PropertyValue
>& aProps
)
4911 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4915 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4916 throw lang::DisposedException( THROW_WHERE
);
4919 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
4920 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
4922 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStreamName
== "_rels" )
4923 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable storage name
4925 if ( m_bReadOnlyWrap
)
4926 throw io::IOException( THROW_WHERE
); // TODO: access denied
4930 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aStreamName
);
4933 throw container::ElementExistException( THROW_WHERE
);
4935 pElement
= OpenStreamElement_Impl( aStreamName
, embed::ElementModes::READWRITE
, false );
4936 assert(pElement
&& pElement
->m_xStream
&& "In case element can not be created an exception must be thrown!");
4938 pElement
->m_xStream
->InsertStreamDirectly(xInStream
, aProps
);
4940 catch( const embed::InvalidStorageException
& )
4942 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4945 catch( const lang::IllegalArgumentException
& )
4947 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4950 catch( const container::ElementExistException
& )
4952 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4955 catch( const embed::StorageWrappedTargetException
& )
4957 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4960 catch( const io::IOException
& )
4962 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4965 catch( const uno::RuntimeException
& )
4967 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4970 catch( const uno::Exception
& )
4972 uno::Any
aCaught( ::cppu::getCaughtException() );
4973 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4975 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't insert stream directly!",
4976 uno::Reference
< io::XInputStream
>(),
4981 void SAL_CALL
OStorage::copyElementDirectlyTo(
4982 const OUString
& aElementName
,
4983 const uno::Reference
< embed::XOptimizedStorage
>& xDest
,
4984 const OUString
& aNewName
)
4986 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4990 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4991 throw lang::DisposedException( THROW_WHERE
);
4994 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false )
4995 || aNewName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName
, false ) )
4996 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
4998 if ( !xDest
.is() || xDest
== getXWeak() )
4999 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
5001 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& ( aElementName
== "_rels" || aNewName
== "_rels" ) )
5002 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 ); // unacceptable name
5006 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aElementName
);
5008 throw container::NoSuchElementException( THROW_WHERE
);
5010 uno::Reference
< XNameAccess
> xNameAccess( xDest
, uno::UNO_QUERY_THROW
);
5011 if ( xNameAccess
->hasByName( aNewName
) )
5012 throw container::ElementExistException( THROW_WHERE
);
5014 // let the element be copied directly
5015 uno::Reference
< embed::XStorage
> xStorDest( xDest
, uno::UNO_QUERY_THROW
);
5016 m_pImpl
->CopyStorageElement( pElement
, xStorDest
, aNewName
, true );
5018 catch( const embed::InvalidStorageException
& )
5020 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5023 catch( const lang::IllegalArgumentException
& )
5025 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5028 catch( const container::NoSuchElementException
& )
5030 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5033 catch( const container::ElementExistException
& )
5035 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5038 catch( const embed::StorageWrappedTargetException
& )
5040 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5043 catch( const io::IOException
& )
5045 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5048 catch( const uno::RuntimeException
& )
5050 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5053 catch( const uno::Exception
& )
5055 uno::Any
aCaught( ::cppu::getCaughtException() );
5056 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5058 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy element directly!",
5059 uno::Reference
< io::XInputStream
>(),
5064 void SAL_CALL
OStorage::writeAndAttachToStream( const uno::Reference
< io::XStream
>& xStream
)
5066 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
5070 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5071 throw lang::DisposedException( THROW_WHERE
);
5074 if ( !m_pImpl
->m_bIsRoot
)
5075 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
5077 if ( !m_pImpl
->m_pSwitchStream
)
5078 throw uno::RuntimeException( THROW_WHERE
);
5082 m_pImpl
->m_pSwitchStream
->CopyAndSwitchPersistenceTo( xStream
);
5084 catch( const embed::InvalidStorageException
& )
5086 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5089 catch( const lang::IllegalArgumentException
& )
5091 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5094 catch( const embed::StorageWrappedTargetException
& )
5096 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5099 catch( const io::IOException
& )
5101 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:" );
5104 catch( const uno::RuntimeException
& )
5106 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5109 catch( const uno::Exception
& )
5111 uno::Any
aCaught( ::cppu::getCaughtException() );
5112 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5114 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't write and attach to stream!",
5115 uno::Reference
< io::XInputStream
>(),
5121 void SAL_CALL
OStorage::attachToURL( const OUString
& sURL
,
5122 sal_Bool bReadOnly
)
5124 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
5128 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5129 throw lang::DisposedException( THROW_WHERE
);
5132 if ( !m_pImpl
->m_bIsRoot
)
5133 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
5135 if ( !m_pImpl
->m_pSwitchStream
)
5136 throw uno::RuntimeException( THROW_WHERE
);
5138 uno::Reference
< ucb::XSimpleFileAccess3
> xAccess(
5139 ucb::SimpleFileAccess::create( m_pImpl
->m_xContext
) );
5145 uno::Reference
< io::XInputStream
> xInputStream
= xAccess
->openFileRead( sURL
);
5146 m_pImpl
->m_pSwitchStream
->SwitchPersistenceTo( xInputStream
);
5150 uno::Reference
< io::XStream
> xStream
= xAccess
->openFileReadWrite( sURL
);
5151 m_pImpl
->m_pSwitchStream
->SwitchPersistenceTo( xStream
);
5154 catch( const embed::InvalidStorageException
& )
5156 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5159 catch( const lang::IllegalArgumentException
& )
5161 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5164 catch( const embed::StorageWrappedTargetException
& )
5166 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5169 catch( const io::IOException
& )
5171 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5174 catch( const uno::RuntimeException
& )
5176 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5179 catch( const uno::Exception
& )
5181 uno::Any
aCaught( ::cppu::getCaughtException() );
5182 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5184 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't attach to URL!",
5185 uno::Reference
< io::XInputStream
>(),
5190 uno::Any SAL_CALL
OStorage::getElementPropertyValue( const OUString
& aElementName
, const OUString
& aPropertyName
)
5192 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
5196 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5197 throw lang::DisposedException( THROW_WHERE
);
5200 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false ) )
5201 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5203 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aElementName
== "_rels" )
5204 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // TODO: unacceptable name
5208 SotElement_Impl
*pElement
= m_pImpl
->FindElement( aElementName
);
5210 throw container::NoSuchElementException( THROW_WHERE
);
5212 // TODO/LATER: Currently it is only implemented for MediaType property of substorages, might be changed in future
5213 if ( !pElement
->m_bIsStorage
|| m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
|| aPropertyName
!= "MediaType" )
5214 throw beans::PropertyVetoException( THROW_WHERE
);
5216 if (!pElement
->m_xStorage
)
5217 m_pImpl
->OpenSubStorage( pElement
, embed::ElementModes::READ
);
5219 if (!pElement
->m_xStorage
)
5220 throw io::IOException( THROW_WHERE
); // TODO: general_error
5222 pElement
->m_xStorage
->ReadContents();
5223 return uno::Any(pElement
->m_xStorage
->m_aMediaType
);
5225 catch( const embed::InvalidStorageException
& )
5227 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5230 catch( const lang::IllegalArgumentException
& )
5232 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5235 catch( const container::NoSuchElementException
& )
5237 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5240 catch( const beans::UnknownPropertyException
& )
5242 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5245 catch( const beans::PropertyVetoException
& )
5247 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5250 catch( const embed::StorageWrappedTargetException
& )
5252 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5255 catch( const io::IOException
& )
5257 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5260 catch( const uno::RuntimeException
& )
5262 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5265 catch( const uno::Exception
& )
5267 uno::Any
aCaught( ::cppu::getCaughtException() );
5268 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5270 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't get element property!",
5271 uno::Reference
< io::XInputStream
>(),
5276 void SAL_CALL
OStorage::copyStreamElementData( const OUString
& aStreamName
, const uno::Reference
< io::XStream
>& xTargetStream
)
5278 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
5282 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5283 throw lang::DisposedException( THROW_WHERE
);
5286 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
5287 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5289 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStreamName
== "_rels" )
5290 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable name
5292 if ( !xTargetStream
.is() )
5293 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
5297 uno::Reference
< io::XStream
> xNonconstRef
= xTargetStream
;
5298 m_pImpl
->CloneStreamElement( aStreamName
, false, ::comphelper::SequenceAsHashMap(), xNonconstRef
);
5300 SAL_WARN_IF( xNonconstRef
!= xTargetStream
, "package.xstor", "The provided stream reference seems not be filled in correctly!" );
5301 if ( xNonconstRef
!= xTargetStream
)
5302 throw uno::RuntimeException( THROW_WHERE
); // if the stream reference is set it must not be changed!
5304 catch( const embed::InvalidStorageException
& )
5306 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5309 catch( const lang::IllegalArgumentException
& )
5311 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5314 catch( const packages::WrongPasswordException
& )
5316 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5319 catch( const io::IOException
& )
5321 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5324 catch( const embed::StorageWrappedTargetException
& )
5326 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5329 catch( const uno::RuntimeException
& )
5331 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5334 catch( const uno::Exception
& )
5336 uno::Any
aCaught( ::cppu::getCaughtException() );
5337 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5339 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy stream data!",
5340 uno::Reference
< io::XInputStream
>(),
5346 // XHierarchicalStorageAccess
5347 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
OStorage::openStreamElementByHierarchicalName( const OUString
& aStreamPath
, ::sal_Int32 nOpenMode
)
5349 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
5353 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5354 throw lang::DisposedException( THROW_WHERE
);
5357 if ( aStreamPath
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath
, true ) )
5358 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5360 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
)
5361 && ( nOpenMode
& embed::ElementModes::WRITE
) )
5362 throw io::IOException( THROW_WHERE
); // Access denied
5364 std::vector
<OUString
> aListPath
= OHierarchyHolder_Impl::GetListPathFromString( aStreamPath
);
5365 OSL_ENSURE( aListPath
.size(), "The result list must not be empty!" );
5367 uno::Reference
< embed::XExtendedStorageStream
> xResult
;
5368 if ( aListPath
.size() == 1 )
5372 // that must be a direct request for a stream
5373 // the transacted version of the stream should be opened
5375 SotElement_Impl
*pElement
= OpenStreamElement_Impl( aStreamPath
, nOpenMode
, false );
5376 assert(pElement
&& pElement
->m_xStream
&& "In case element can not be created an exception must be thrown!");
5378 xResult
.set(pElement
->m_xStream
->GetStream(nOpenMode
, true),
5379 uno::UNO_QUERY_THROW
);
5381 catch ( const container::NoSuchElementException
& )
5383 throw io::IOException( THROW_WHERE
); // file not found
5388 // there are still storages in between
5389 if (!m_pHierarchyHolder
)
5390 m_pHierarchyHolder
.reset(new OHierarchyHolder_Impl(this));
5392 xResult
= m_pHierarchyHolder
->GetStreamHierarchically(
5393 ( m_pImpl
->m_nStorageMode
& embed::ElementModes::READWRITE
),
5398 if ( !xResult
.is() )
5399 throw uno::RuntimeException( THROW_WHERE
);
5404 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
OStorage::openEncryptedStreamElementByHierarchicalName( const OUString
& aStreamPath
, ::sal_Int32 nOpenMode
, const OUString
& sPassword
)
5406 return openEncryptedStreamByHierarchicalName( aStreamPath
, nOpenMode
, ::comphelper::OStorageHelper::CreatePackageEncryptionData( sPassword
) );
5409 void SAL_CALL
OStorage::removeStreamElementByHierarchicalName( const OUString
& aStreamPath
)
5411 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
5415 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5416 throw lang::DisposedException( THROW_WHERE
);
5419 if ( aStreamPath
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath
, true ) )
5420 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5422 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
) )
5423 throw io::IOException( THROW_WHERE
); // Access denied
5425 std::vector
<OUString
> aListPath
= OHierarchyHolder_Impl::GetListPathFromString( aStreamPath
);
5426 OSL_ENSURE( aListPath
.size(), "The result list must not be empty!" );
5428 if (!m_pHierarchyHolder
)
5429 m_pHierarchyHolder
.reset(new OHierarchyHolder_Impl(this));
5431 m_pHierarchyHolder
->RemoveStreamHierarchically(aListPath
);
5434 // XHierarchicalStorageAccess2
5435 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
OStorage::openEncryptedStreamByHierarchicalName( const OUString
& aStreamPath
, ::sal_Int32 nOpenMode
, const uno::Sequence
< beans::NamedValue
>& aEncryptionData
)
5437 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
5441 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5442 throw lang::DisposedException( THROW_WHERE
);
5445 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
5446 throw packages::NoEncryptionException( THROW_WHERE
);
5448 if ( aStreamPath
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath
, true ) )
5449 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5451 if ( !aEncryptionData
.hasElements() )
5452 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 3 );
5454 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
)
5455 && ( nOpenMode
& embed::ElementModes::WRITE
) )
5456 throw io::IOException( THROW_WHERE
); // Access denied
5458 std::vector
<OUString
> aListPath
= OHierarchyHolder_Impl::GetListPathFromString( aStreamPath
);
5459 OSL_ENSURE( aListPath
.size(), "The result list must not be empty!" );
5461 uno::Reference
< embed::XExtendedStorageStream
> xResult
;
5462 if ( aListPath
.size() == 1 )
5464 // that must be a direct request for a stream
5465 // the transacted version of the stream should be opened
5467 SotElement_Impl
*pElement
= OpenStreamElement_Impl( aStreamPath
, nOpenMode
, true );
5468 assert(pElement
&& pElement
->m_xStream
&& "In case element can not be created an exception must be thrown!");
5470 xResult
.set(pElement
->m_xStream
->GetStream(nOpenMode
, aEncryptionData
, true),
5471 uno::UNO_QUERY_THROW
);
5475 // there are still storages in between
5476 if (!m_pHierarchyHolder
)
5477 m_pHierarchyHolder
.reset(new OHierarchyHolder_Impl(this));
5479 xResult
= m_pHierarchyHolder
->GetStreamHierarchically(
5480 ( m_pImpl
->m_nStorageMode
& embed::ElementModes::READWRITE
),
5486 if ( !xResult
.is() )
5487 throw uno::RuntimeException( THROW_WHERE
);
5492 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */