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
{ "Compressed", "MediaType",
94 "UseCommonStoragePasswordEncryption" };
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
: std::as_const(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
= static_cast< io::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
= "URL";
305 for ( const auto& rProp
: std::as_const(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 ] <<= 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( "AllowRemoveOnInsert",
394 sal_Int32 nArgNum
= 2;
395 for ( const auto& rProp
: std::as_const(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
;
407 else if ( rProp
.Name
== "Password" )
409 // TODO: implement password setting for documents
410 // the password entry must be removed after setting
414 if ( m_nStorageType
== embed::StorageFormats::ZIP
)
416 // let the package support only plain zip format
417 beans::NamedValue aNamedValue
;
418 aNamedValue
.Name
= "StorageFormat";
419 aNamedValue
.Value
<<= OUString( "ZipFormat" );
420 aArguments
.realloc( ++nArgNum
);
421 pArguments
= aArguments
.getArray();
422 pArguments
[nArgNum
-1] <<= aNamedValue
;
424 else if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
426 // let the package support OFOPXML media type handling
427 beans::NamedValue aNamedValue
;
428 aNamedValue
.Name
= "StorageFormat";
429 aNamedValue
.Value
<<= OUString( "OFOPXMLFormat" );
430 aArguments
.realloc( ++nArgNum
);
431 pArguments
= aArguments
.getArray();
432 pArguments
[nArgNum
-1] <<= aNamedValue
;
435 m_xPackage
.set( m_xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(
436 "com.sun.star.packages.comp.ZipPackage", aArguments
, m_xContext
),
440 uno::Reference
< container::XHierarchicalNameAccess
> xHNameAccess( m_xPackage
, uno::UNO_QUERY
);
441 SAL_WARN_IF( !xHNameAccess
.is(), "package.xstor", "The package could not be created!" );
443 if ( xHNameAccess
.is() )
445 uno::Any aFolder
= xHNameAccess
->getByHierarchicalName("/");
446 aFolder
>>= m_xPackageFolder
;
450 SAL_WARN_IF( !m_xPackageFolder
.is(), "package.xstor", "The package root folder can not be opened!" );
451 if ( !m_xPackageFolder
.is() )
452 throw embed::InvalidStorageException( THROW_WHERE
);
455 bool OStorage_Impl::HasChildren()
457 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
460 return !m_aChildrenMap
.empty();
463 void OStorage_Impl::GetStorageProperties()
465 if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
)
468 uno::Reference
< beans::XPropertySet
> xProps( m_xPackageFolder
, uno::UNO_QUERY_THROW
);
470 if ( !m_bControlMediaType
)
472 uno::Reference
< beans::XPropertySet
> xPackageProps( m_xPackage
, uno::UNO_QUERY_THROW
);
473 xPackageProps
->getPropertyValue( MEDIATYPE_FALLBACK_USED_PROPERTY
) >>= m_bMTFallbackUsed
;
475 static constexpr OUStringLiteral
sMediaType(u
"MediaType");
476 xProps
->getPropertyValue( sMediaType
) >>= m_aMediaType
;
477 m_bControlMediaType
= true;
480 if ( !m_bControlVersion
)
482 xProps
->getPropertyValue( "Version" ) >>= m_aVersion
;
483 m_bControlVersion
= true;
486 // the properties of OFOPXML will be handled directly
489 void OStorage_Impl::ReadRelInfoIfNecessary()
491 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
494 if ( m_nRelInfoStatus
== RELINFO_NO_INIT
)
496 // Init from original stream
497 uno::Reference
< io::XInputStream
> xRelInfoStream
498 = GetRelInfoStreamForName( std::u16string_view() );
501 if ( xRelInfoStream
.is() )
502 m_aRelInfo
= ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
506 m_nRelInfoStatus
= RELINFO_READ
;
508 catch (css::uno::Exception
&)
510 TOOLS_INFO_EXCEPTION("package.xstor", "");
513 else if ( m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
515 // Init from the new stream
518 if ( m_xNewRelInfoStream
.is() )
519 m_aRelInfo
= ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
524 m_nRelInfoStatus
= RELINFO_CHANGED_STREAM_READ
;
526 catch( const uno::Exception
& )
528 m_nRelInfoStatus
= RELINFO_CHANGED_BROKEN
;
533 void OStorage_Impl::ReadContents()
535 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
537 if ( m_bListCreated
)
543 uno::Reference
< container::XEnumerationAccess
> xEnumAccess( m_xPackageFolder
, uno::UNO_QUERY_THROW
);
544 uno::Reference
< container::XEnumeration
> xEnum
= xEnumAccess
->createEnumeration();
546 throw uno::RuntimeException( THROW_WHERE
);
548 m_bListCreated
= true;
550 while( xEnum
->hasMoreElements() )
553 uno::Reference
< container::XNamed
> xNamed
;
554 xEnum
->nextElement() >>= xNamed
;
558 SAL_WARN( "package.xstor", "XNamed is not supported!" );
559 throw uno::RuntimeException( THROW_WHERE
);
562 OUString aName
= xNamed
->getName();
563 SAL_WARN_IF( aName
.isEmpty(), "package.xstor", "Empty name!" );
565 uno::Reference
< container::XNameContainer
> xNameContainer( xNamed
, uno::UNO_QUERY
);
567 std::unique_ptr
<SotElement_Impl
> xNewElement(new SotElement_Impl(aName
, xNameContainer
.is(), false));
568 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& aName
== "_rels" )
570 if (!xNewElement
->m_bIsStorage
)
571 throw io::IOException( THROW_WHERE
); // TODO: Unexpected format
573 m_pRelStorElement
= xNewElement
.release();
578 if ( ( m_nStorageMode
& embed::ElementModes::TRUNCATE
) == embed::ElementModes::TRUNCATE
)
580 // if a storage is truncated all of it elements are marked as deleted
581 xNewElement
->m_bIsRemoved
= true;
584 m_aChildrenMap
[aName
].push_back(xNewElement
.release());
587 catch( const container::NoSuchElementException
& )
589 TOOLS_WARN_EXCEPTION( "package.xstor", "hasMoreElements() implementation has problems!");
593 if ( ( m_nStorageMode
& embed::ElementModes::TRUNCATE
) == embed::ElementModes::TRUNCATE
)
595 // if a storage is truncated the relations information should be cleaned
596 m_xNewRelInfoStream
.clear();
597 m_aRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
598 m_nRelInfoStatus
= RELINFO_CHANGED
;
601 // cache changeable folder properties
602 GetStorageProperties();
605 void OStorage_Impl::CopyToStorage( const uno::Reference
< embed::XStorage
>& xDest
, bool bDirect
)
607 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
609 uno::Reference
< beans::XPropertySet
> xPropSet( xDest
, uno::UNO_QUERY
);
610 if ( !xPropSet
.is() )
611 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 );
613 sal_Int32 nDestMode
= embed::ElementModes::READ
;
614 xPropSet
->getPropertyValue( "OpenMode" ) >>= nDestMode
;
616 if ( !( nDestMode
& embed::ElementModes::WRITE
) )
617 throw io::IOException( THROW_WHERE
); // TODO: access_denied
621 if ( !m_xPackageFolder
.is() )
622 throw embed::InvalidStorageException( THROW_WHERE
);
624 for ( const auto& pair
: m_aChildrenMap
)
625 for (auto pElement
: pair
.second
)
627 if ( !pElement
->m_bIsRemoved
)
628 CopyStorageElement( pElement
, xDest
, /*aName*/pair
.first
, bDirect
);
631 // move storage properties to the destination one ( means changeable properties )
632 if ( m_nStorageType
== embed::StorageFormats::PACKAGE
)
634 xPropSet
->setPropertyValue( "MediaType", uno::Any( m_aMediaType
) );
635 xPropSet
->setPropertyValue( "Version", uno::Any( m_aVersion
) );
638 if ( m_nStorageType
== embed::StorageFormats::PACKAGE
)
640 // if this is a root storage, the common key from current one should be moved there
641 bool bIsRoot
= false;
642 if ( ( xPropSet
->getPropertyValue( "IsRoot" ) >>= bIsRoot
) && bIsRoot
)
646 uno::Reference
< embed::XEncryptionProtectedStorage
> xEncr( xDest
, uno::UNO_QUERY
);
649 xEncr
->setEncryptionData( GetCommonRootEncryptionData().getAsConstNamedValueList() );
651 uno::Sequence
< beans::NamedValue
> aAlgorithms
;
652 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_xPackage
, uno::UNO_QUERY_THROW
);
653 xPackPropSet
->getPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY
)
655 xEncr
->setEncryptionAlgorithms( aAlgorithms
);
658 catch( const packages::NoEncryptionException
& )
660 TOOLS_INFO_EXCEPTION("package.xstor", "No Encryption");
664 else if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
667 // TODO/LATER: currently the optimization is not active
668 // uno::Reference< io::XInputStream > xRelInfoStream = GetRelInfoStreamForName( OUString() ); // own stream
669 // if ( xRelInfoStream.is() )
671 // // Relations info stream is a writeonly property, introduced only to optimize copying
672 // // Should be used carefully since no check for stream consistency is done, and the stream must not stay locked
674 // OUString aRelInfoString = "RelationsInfoStream";
675 // xPropSet->setPropertyValue( aRelInfoString, uno::makeAny( GetSeekableTempCopy( xRelInfoStream, m_xFactory ) ) );
678 uno::Reference
< embed::XRelationshipAccess
> xRels( xDest
, uno::UNO_QUERY
);
680 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 );
682 xRels
->insertRelationships( GetAllRelationshipsIfAny(), false );
685 // if possible the destination storage should be committed after successful copying
686 uno::Reference
< embed::XTransactedObject
> xObjToCommit( xDest
, uno::UNO_QUERY
);
687 if ( xObjToCommit
.is() )
688 xObjToCommit
->commit();
691 void OStorage_Impl::CopyStorageElement( SotElement_Impl
* pElement
,
692 const uno::Reference
< embed::XStorage
>& xDest
,
693 const OUString
& aName
,
696 SAL_WARN_IF( !xDest
.is(), "package.xstor", "No destination storage!" );
697 SAL_WARN_IF( aName
.isEmpty(), "package.xstor", "Empty element name!" );
699 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
701 uno::Reference
< container::XNameAccess
> xDestAccess( xDest
, uno::UNO_QUERY_THROW
);
702 if ( xDestAccess
->hasByName( aName
)
703 && !( pElement
->m_bIsStorage
&& xDest
->isStorageElement( aName
) ) )
704 xDest
->removeElement( aName
);
706 if ( pElement
->m_bIsStorage
)
708 uno::Reference
< embed::XStorage
> xSubDest
=
709 xDest
->openStorageElement( aName
,
710 embed::ElementModes::WRITE
);
712 SAL_WARN_IF( !xSubDest
.is(), "package.xstor", "No destination substorage!" );
714 if (!pElement
->m_xStorage
)
716 OpenSubStorage( pElement
, embed::ElementModes::READ
);
717 if (!pElement
->m_xStorage
)
718 throw io::IOException( THROW_WHERE
);
721 pElement
->m_xStorage
->CopyToStorage(xSubDest
, bDirect
);
725 if (!pElement
->m_xStream
)
727 OpenSubStream( pElement
);
728 if (!pElement
->m_xStream
)
729 throw io::IOException( THROW_WHERE
);
732 if (!pElement
->m_xStream
->IsEncrypted())
736 // fill in the properties for the stream
737 uno::Sequence
< beans::PropertyValue
> aStrProps(0);
738 const uno::Sequence
< beans::PropertyValue
> aSrcPkgProps
= pElement
->m_xStream
->GetStreamProperties();
740 for ( const auto& rSrcPkgProp
: aSrcPkgProps
)
742 if ( rSrcPkgProp
.Name
== "MediaType" || rSrcPkgProp
.Name
== "Compressed" )
744 aStrProps
.realloc( ++nNum
);
745 auto pStrProps
= aStrProps
.getArray();
746 pStrProps
[nNum
-1].Name
= rSrcPkgProp
.Name
;
747 pStrProps
[nNum
-1].Value
= rSrcPkgProp
.Value
;
751 if ( m_nStorageType
== embed::StorageFormats::PACKAGE
)
753 aStrProps
.realloc( ++nNum
);
754 auto pStrProps
= aStrProps
.getArray();
755 pStrProps
[nNum
-1].Name
= "UseCommonStoragePasswordEncryption";
756 pStrProps
[nNum
-1].Value
<<= pElement
->m_xStream
->UsesCommonEncryption_Impl();
758 else if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
760 // TODO/LATER: currently the optimization is not active
761 // uno::Reference< io::XInputStream > xInStream = GetRelInfoStreamForName( OUString() ); // own rels stream
762 // if ( xInStream.is() )
764 // aStrProps.realloc( ++nNum );
765 // aStrProps[nNum-1].Name = "RelationsInfoStream";
766 // aStrProps[nNum-1].Value <<= GetSeekableTempCopy( xInStream, m_xFactory );
769 uno::Reference
< embed::XRelationshipAccess
> xRels( xDest
, uno::UNO_QUERY
);
771 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
773 xRels
->insertRelationships( GetAllRelationshipsIfAny(), false );
776 uno::Reference
< embed::XOptimizedStorage
> xOptDest( xDest
, uno::UNO_QUERY_THROW
);
777 uno::Reference
< io::XInputStream
> xInputToInsert
;
779 if (pElement
->m_xStream
->HasTempFile_Impl() || !pElement
->m_xStream
->m_xPackageStream
.is())
781 SAL_WARN_IF(!pElement
->m_xStream
->m_xPackageStream
.is(), "package.xstor", "No package stream!");
783 // if the stream is modified - the temporary file must be used for insertion
784 xInputToInsert
= pElement
->m_xStream
->GetTempFileAsInputStream();
788 // for now get just nonseekable access to the stream
789 // TODO/LATER: the raw stream can be used
791 xInputToInsert
= pElement
->m_xStream
->m_xPackageStream
->getDataStream();
794 if ( !xInputToInsert
.is() )
795 throw io::IOException( THROW_WHERE
);
797 xOptDest
->insertStreamElementDirect( aName
, xInputToInsert
, aStrProps
);
801 uno::Reference
< io::XStream
> xSubStr
=
802 xDest
->openStreamElement( aName
,
803 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
804 SAL_WARN_IF( !xSubStr
.is(), "package.xstor", "No destination substream!" );
806 pElement
->m_xStream
->CopyInternallyTo_Impl(xSubStr
);
809 else if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
)
811 SAL_WARN( "package.xstor", "Encryption is only supported in package storage!" );
812 throw io::IOException( THROW_WHERE
);
814 else if ( pElement
->m_xStream
->HasCachedEncryptionData()
815 && ( pElement
->m_xStream
->IsModified() || pElement
->m_xStream
->HasWriteOwner_Impl() ) )
817 ::comphelper::SequenceAsHashMap aCommonEncryptionData
;
818 bool bHasCommonEncryptionData
= false;
821 aCommonEncryptionData
= GetCommonRootEncryptionData();
822 bHasCommonEncryptionData
= true;
824 catch( const packages::NoEncryptionException
& )
826 TOOLS_INFO_EXCEPTION("package.xstor", "No Encryption");
829 if (bHasCommonEncryptionData
&& ::package::PackageEncryptionDataLessOrEqual(pElement
->m_xStream
->GetCachedEncryptionData(), aCommonEncryptionData
))
831 // If the stream can be opened with the common storage password
832 // it must be stored with the common storage password as well
833 uno::Reference
< io::XStream
> xDestStream
=
834 xDest
->openStreamElement( aName
,
835 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
837 pElement
->m_xStream
->CopyInternallyTo_Impl( xDestStream
);
839 uno::Reference
< beans::XPropertySet
> xProps( xDestStream
, uno::UNO_QUERY_THROW
);
840 xProps
->setPropertyValue(
841 "UseCommonStoragePasswordEncryption",
846 // the stream is already opened for writing or was changed
847 uno::Reference
< embed::XStorage2
> xDest2( xDest
, uno::UNO_QUERY_THROW
);
848 uno::Reference
< io::XStream
> xSubStr
=
849 xDest2
->openEncryptedStream( aName
,
850 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
,
851 pElement
->m_xStream
->GetCachedEncryptionData().getAsConstNamedValueList() );
852 SAL_WARN_IF( !xSubStr
.is(), "package.xstor", "No destination substream!" );
854 pElement
->m_xStream
->CopyInternallyTo_Impl(xSubStr
, pElement
->m_xStream
->GetCachedEncryptionData());
859 // the stream is not opened at all, so it can be just opened for reading
862 // If the stream can be opened with the common storage password
863 // it must be stored with the common storage password as well
865 uno::Reference
< io::XStream
> xOwnStream
= pElement
->m_xStream
->GetStream(embed::ElementModes::READ
,
867 uno::Reference
< io::XStream
> xDestStream
=
868 xDest
->openStreamElement( aName
,
869 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
870 SAL_WARN_IF( !xDestStream
.is(), "package.xstor", "No destination substream!" );
871 completeStorageStreamCopy_Impl( xOwnStream
, xDestStream
, m_nStorageType
, GetAllRelationshipsIfAny() );
873 uno::Reference
< beans::XPropertySet
> xProps( xDestStream
, uno::UNO_QUERY_THROW
);
874 xProps
->setPropertyValue(
875 "UseCommonStoragePasswordEncryption",
878 catch( const packages::WrongPasswordException
& )
880 TOOLS_INFO_EXCEPTION("package.xstor", "Handled exception");
882 // If the common storage password does not allow to open the stream
883 // it could be copied in raw way, the problem is that the StartKey should be the same
884 // in the ODF1.2 package, so an invalid package could be produced if the stream
885 // is copied from ODF1.1 package, where it is allowed to have different StartKeys
886 uno::Reference
< embed::XStorageRawAccess
> xRawDest( xDest
, uno::UNO_QUERY_THROW
);
887 uno::Reference
< io::XInputStream
> xRawInStream
= pElement
->m_xStream
->GetRawInStream();
888 xRawDest
->insertRawEncrStreamElement( aName
, xRawInStream
);
894 uno::Sequence
< uno::Sequence
< beans::StringPair
> > OStorage_Impl::GetAllRelationshipsIfAny()
896 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
897 return uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
899 ReadRelInfoIfNecessary();
901 if ( m_nRelInfoStatus
!= RELINFO_READ
902 && m_nRelInfoStatus
!= RELINFO_CHANGED_STREAM_READ
903 && m_nRelInfoStatus
!= RELINFO_CHANGED
)
904 throw io::IOException( THROW_WHERE
"Wrong relinfo stream!" );
905 // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
909 void OStorage_Impl::CopyLastCommitTo( const uno::Reference
< embed::XStorage
>& xNewStor
)
911 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
913 SAL_WARN_IF( !m_xPackageFolder
.is(), "package.xstor", "A committed storage is incomplete!" );
914 if ( !m_xPackageFolder
.is() )
915 throw uno::RuntimeException( THROW_WHERE
);
917 OStorage_Impl
aTempRepresent( nullptr,
918 embed::ElementModes::READ
,
924 // TODO/LATER: could use direct copying
925 aTempRepresent
.CopyToStorage( xNewStor
, false );
928 void OStorage_Impl::InsertIntoPackageFolder( const OUString
& aName
,
929 const uno::Reference
< container::XNameContainer
>& xParentPackageFolder
)
931 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
933 SAL_WARN_IF( !m_xPackageFolder
.is(), "package.xstor", "An inserted storage is incomplete!" );
934 uno::Reference
< uno::XInterface
> xTmp( m_xPackageFolder
, uno::UNO_QUERY_THROW
);
935 xParentPackageFolder
->insertByName( aName
, uno::Any( xTmp
) );
940 void OStorage_Impl::Commit()
942 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
944 if ( !m_bIsModified
)
947 // in case of a new empty storage it is possible that the contents are still not read
948 // ( the storage of course has no contents, but the initialization is postponed till the first use,
949 // thus if a new storage was created and committed immediately it must be initialized here )
952 // if storage is committed it should have a valid Package representation
953 SAL_WARN_IF( !m_xPackageFolder
.is(), "package.xstor", "The package representation should exist!" );
954 if ( !m_xPackageFolder
.is() )
955 throw embed::InvalidStorageException( THROW_WHERE
);
957 OSL_ENSURE( m_nStorageMode
& embed::ElementModes::WRITE
,
958 "Commit of readonly storage, should be detected before!" );
960 uno::Reference
< container::XNameContainer
> xNewPackageFolder
;
962 // here the storage will switch to the temporary package folder
963 // if the storage was already committed and the parent was not committed after that
964 // the switch should not be done since the package folder in use is a temporary one;
965 // it can be detected by m_bCommited flag ( root storage doesn't need temporary representation )
966 if ( !m_bCommited
&& !m_bIsRoot
)
968 uno::Sequence
< uno::Any
> aSeq
{ uno::Any(true) };
969 xNewPackageFolder
.set( m_xPackage
->createInstanceWithArguments( aSeq
),
973 xNewPackageFolder
= m_xPackageFolder
;
975 // remove replaced removed elements
976 for ( auto& pDeleted
: m_aDeletedVector
)
979 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& !pDeleted
->m_bIsStorage
)
980 RemoveStreamRelInfo( pDeleted
->m_aOriginalName
);
982 // the removed elements are not in new temporary storage
983 if ( m_bCommited
|| m_bIsRoot
)
984 xNewPackageFolder
->removeByName( pDeleted
->m_aOriginalName
);
988 m_aDeletedVector
.clear();
990 // remove removed elements
991 for (auto mapIt
= m_aChildrenMap
.begin(); mapIt
!= m_aChildrenMap
.end(); )
993 for (auto it
= mapIt
->second
.begin(); it
!= mapIt
->second
.end(); )
995 // renamed and inserted elements must be really inserted to package later
996 // since they can conflict with removed elements
997 auto & pElement
= *it
;
998 if ( pElement
->m_bIsRemoved
)
1000 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& !pElement
->m_bIsStorage
)
1001 RemoveStreamRelInfo( pElement
->m_aOriginalName
);
1003 // the removed elements are not in new temporary storage
1004 if ( m_bCommited
|| m_bIsRoot
)
1005 xNewPackageFolder
->removeByName( pElement
->m_aOriginalName
);
1008 it
= mapIt
->second
.erase(it
);
1013 if (mapIt
->second
.empty())
1014 mapIt
= m_aChildrenMap
.erase(mapIt
);
1020 // there should be no more deleted elements
1021 for ( const auto& pair
: m_aChildrenMap
)
1022 for (auto pElement
: pair
.second
)
1024 // if it is a 'duplicate commit' inserted elements must be really inserted to package later
1025 // since they can conflict with renamed elements
1026 if ( !pElement
->m_bIsInserted
)
1028 // for now stream is opened in direct mode that means that in case
1029 // storage is committed all the streams from it are committed in current state.
1030 // following two steps are separated to allow easily implement transacted mode
1031 // for streams if we need it in future.
1032 // Only hierarchical access uses transacted streams currently
1033 if ( !pElement
->m_bIsStorage
&& pElement
->m_xStream
1034 && !pElement
->m_xStream
->IsTransacted() )
1035 pElement
->m_xStream
->Commit();
1037 // if the storage was not open, there is no need to commit it ???
1038 // the storage should be checked that it is committed
1039 if (pElement
->m_bIsStorage
&& pElement
->m_xStorage
&& pElement
->m_xStorage
->m_bCommited
)
1041 // it's temporary PackageFolder should be inserted instead of current one
1042 // also the new copy of PackageFolder should be used by the children storages
1044 // the renamed elements are not in new temporary storage
1045 if ( m_bCommited
|| m_bIsRoot
)
1046 xNewPackageFolder
->removeByName( pElement
->m_aOriginalName
);
1048 pElement
->m_xStorage
->InsertIntoPackageFolder(/*aName*/pair
.first
, xNewPackageFolder
);
1050 else if (!pElement
->m_bIsStorage
&& pElement
->m_xStream
&& pElement
->m_xStream
->m_bFlushed
)
1052 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1053 CommitStreamRelInfo( /*aName*/pair
.first
, pElement
);
1055 // the renamed elements are not in new temporary storage
1056 if ( m_bCommited
|| m_bIsRoot
)
1057 xNewPackageFolder
->removeByName( pElement
->m_aOriginalName
);
1059 pElement
->m_xStream
->InsertIntoPackageFolder(/*aName*/pair
.first
, xNewPackageFolder
);
1061 else if ( !m_bCommited
&& !m_bIsRoot
)
1063 // the element must be just copied to the new temporary package folder
1064 // the connection with the original package should not be lost just because
1065 // the element is still referred by the folder in the original hierarchy
1066 uno::Any aPackageElement
= m_xPackageFolder
->getByName( pElement
->m_aOriginalName
);
1067 xNewPackageFolder
->insertByName( /*aName*/pair
.first
, aPackageElement
);
1069 else if ( pair
.first
!= pElement
->m_aOriginalName
)
1071 // this is the case when xNewPackageFolder refers to m_xPackageFolder
1072 // in case the name was changed and it is not a changed storage - rename the element
1073 uno::Any aPackageElement
= xNewPackageFolder
->getByName( pElement
->m_aOriginalName
);
1074 xNewPackageFolder
->removeByName( pElement
->m_aOriginalName
);
1075 xNewPackageFolder
->insertByName( /*aName*/pair
.first
, aPackageElement
);
1077 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& !pElement
->m_bIsStorage
)
1079 if (!pElement
->m_xStream
)
1081 OpenSubStream( pElement
);
1082 if (!pElement
->m_xStream
)
1083 throw uno::RuntimeException( THROW_WHERE
);
1086 CommitStreamRelInfo( /*aName*/pair
.first
, pElement
);
1090 pElement
->m_aOriginalName
= pair
.first
;
1094 for ( const auto& pair
: m_aChildrenMap
)
1095 for (auto pElement
: pair
.second
)
1097 // now inserted elements can be inserted to the package
1098 if ( pElement
->m_bIsInserted
)
1100 pElement
->m_aOriginalName
= pair
.first
;
1102 if ( pElement
->m_bIsStorage
)
1104 OSL_ENSURE(pElement
->m_xStorage
, "An inserted storage is incomplete!");
1105 if (!pElement
->m_xStorage
)
1106 throw uno::RuntimeException( THROW_WHERE
);
1108 if (pElement
->m_xStorage
->m_bCommited
)
1110 pElement
->m_xStorage
->InsertIntoPackageFolder(/*aName*/pair
.first
, xNewPackageFolder
);
1112 pElement
->m_bIsInserted
= false;
1117 OSL_ENSURE(pElement
->m_xStream
, "An inserted stream is incomplete!");
1118 if (!pElement
->m_xStream
)
1119 throw uno::RuntimeException( THROW_WHERE
);
1121 if (!pElement
->m_xStream
->IsTransacted())
1122 pElement
->m_xStream
->Commit();
1124 if (pElement
->m_xStream
->m_bFlushed
)
1126 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1127 CommitStreamRelInfo( /*aName*/pair
.first
, pElement
);
1129 pElement
->m_xStream
->InsertIntoPackageFolder( /*aName*/pair
.first
, xNewPackageFolder
);
1131 pElement
->m_bIsInserted
= false;
1137 if ( m_nStorageType
== embed::StorageFormats::PACKAGE
)
1139 // move properties to the destination package folder
1140 uno::Reference
< beans::XPropertySet
> xProps( xNewPackageFolder
, uno::UNO_QUERY_THROW
);
1141 xProps
->setPropertyValue( "MediaType", uno::Any( m_aMediaType
) );
1142 xProps
->setPropertyValue( "Version", uno::Any( m_aVersion
) );
1145 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1146 CommitRelInfo( xNewPackageFolder
); // store own relations and commit complete relations storage
1150 uno::Reference
< util::XChangesBatch
> xChangesBatch( m_xPackage
, uno::UNO_QUERY_THROW
);
1153 xChangesBatch
->commitChanges();
1155 catch( const lang::WrappedTargetException
& r
)
1157 css::uno::Any
ex( cppu::getCaughtException() );
1158 // the wrapped UseBackupException means that the target medium can be corrupted
1159 embed::UseBackupException aException
;
1160 if ( r
.TargetException
>>= aException
)
1163 m_xInputStream
.clear();
1167 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(ex
));
1171 else if ( !m_bCommited
)
1173 m_xPackageFolder
= xNewPackageFolder
;
1177 // after commit the mediatype treated as the correct one
1178 m_bMTFallbackUsed
= false;
1181 void OStorage_Impl::Revert()
1183 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1185 if ( !( m_nStorageMode
& embed::ElementModes::WRITE
) )
1186 return; // nothing to do
1188 // all the children must be removed
1189 // they will be created later on demand
1191 // rebuild the map - cannot do it in-place, because we're changing some of the key values
1192 std::unordered_map
<OUString
, std::vector
<SotElement_Impl
*>> oldMap
;
1193 std::swap(oldMap
, m_aChildrenMap
);
1195 for (const auto & rPair
: oldMap
)
1196 for (auto pElement
: rPair
.second
)
1198 if ( pElement
->m_bIsInserted
)
1202 ClearElement( pElement
);
1204 pElement
->m_bIsRemoved
= false;
1206 m_aChildrenMap
[pElement
->m_aOriginalName
].push_back(pElement
);
1210 // return replaced removed elements
1211 for ( auto& pDeleted
: m_aDeletedVector
)
1213 m_aChildrenMap
[pDeleted
->m_aOriginalName
].push_back(pDeleted
);
1215 ClearElement( pDeleted
);
1217 pDeleted
->m_bIsRemoved
= false;
1219 m_aDeletedVector
.clear();
1221 m_bControlMediaType
= false;
1222 m_bControlVersion
= false;
1224 GetStorageProperties();
1226 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1228 // currently the relations storage is changed only on commit
1229 m_xNewRelInfoStream
.clear();
1230 m_aRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
1231 m_nRelInfoStatus
= RELINFO_NO_INIT
;
1235 ::comphelper::SequenceAsHashMap
OStorage_Impl::GetCommonRootEncryptionData()
1237 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() ) ;
1239 if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
)
1240 throw packages::NoEncryptionException( THROW_WHERE
);
1244 if ( !m_bHasCommonEncryptionData
)
1245 throw packages::NoEncryptionException( THROW_WHERE
);
1247 return m_aCommonEncryptionData
;
1252 throw packages::NoEncryptionException( THROW_WHERE
);
1254 return m_pParent
->GetCommonRootEncryptionData();
1258 SotElement_Impl
* OStorage_Impl::FindElement( const OUString
& rName
)
1260 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1262 SAL_WARN_IF( rName
.isEmpty(), "package.xstor", "Name is empty!" );
1266 auto mapIt
= m_aChildrenMap
.find(rName
);
1267 if (mapIt
== m_aChildrenMap
.end())
1269 for (auto pElement
: mapIt
->second
)
1270 if (!pElement
->m_bIsRemoved
)
1276 SotElement_Impl
* OStorage_Impl::InsertStream( const OUString
& aName
, bool bEncr
)
1278 SAL_WARN_IF( !m_xPackage
.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1279 if ( !m_xPackage
.is() )
1280 throw embed::InvalidStorageException( THROW_WHERE
);
1282 uno::Sequence
< uno::Any
> aSeq
{ uno::Any(false) };
1283 uno::Reference
< uno::XInterface
> xNewElement( m_xPackage
->createInstanceWithArguments( aSeq
) );
1285 SAL_WARN_IF( !xNewElement
.is(), "package.xstor", "Not possible to create a new stream!" );
1286 if ( !xNewElement
.is() )
1287 throw io::IOException( THROW_WHERE
);
1289 uno::Reference
< packages::XDataSinkEncrSupport
> xPackageSubStream( xNewElement
, uno::UNO_QUERY_THROW
);
1291 OSL_ENSURE( m_nStorageType
== embed::StorageFormats::PACKAGE
|| !bEncr
, "Only package storage supports encryption!" );
1292 if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
&& bEncr
)
1293 throw packages::NoEncryptionException( THROW_WHERE
);
1295 // the mode is not needed for storage stream internal implementation
1296 SotElement_Impl
* pNewElement
= InsertElement( aName
, false );
1297 pNewElement
->m_xStream
.reset(new OWriteStream_Impl(this, xPackageSubStream
, m_xPackage
, m_xContext
, bEncr
, m_nStorageType
, true));
1299 m_aChildrenMap
[aName
].push_back( pNewElement
);
1300 m_bIsModified
= true;
1301 m_bBroadcastModified
= true;
1306 void OStorage_Impl::InsertRawStream( const OUString
& aName
, const uno::Reference
< io::XInputStream
>& xInStream
)
1308 // insert of raw stream means insert and commit
1309 SAL_WARN_IF( !m_xPackage
.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1310 if ( !m_xPackage
.is() )
1311 throw embed::InvalidStorageException( THROW_WHERE
);
1313 if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
)
1314 throw packages::NoEncryptionException( THROW_WHERE
);
1316 uno::Reference
< io::XSeekable
> xSeek( xInStream
, uno::UNO_QUERY
);
1317 uno::Reference
< io::XInputStream
> xInStrToInsert
= xSeek
.is() ? xInStream
:
1318 GetSeekableTempCopy( xInStream
);
1320 uno::Sequence
< uno::Any
> aSeq
{ uno::Any(false) };
1321 uno::Reference
< uno::XInterface
> xNewElement( m_xPackage
->createInstanceWithArguments( aSeq
) );
1323 SAL_WARN_IF( !xNewElement
.is(), "package.xstor", "Not possible to create a new stream!" );
1324 if ( !xNewElement
.is() )
1325 throw io::IOException( THROW_WHERE
);
1327 uno::Reference
< packages::XDataSinkEncrSupport
> xPackageSubStream( xNewElement
, uno::UNO_QUERY_THROW
);
1328 xPackageSubStream
->setRawStream( xInStrToInsert
);
1330 // the mode is not needed for storage stream internal implementation
1331 SotElement_Impl
* pNewElement
= InsertElement( aName
, false );
1332 pNewElement
->m_xStream
.reset(new OWriteStream_Impl(this, xPackageSubStream
, m_xPackage
, m_xContext
, true, m_nStorageType
, false));
1333 // the stream is inserted and must be treated as a committed one
1334 pNewElement
->m_xStream
->SetToBeCommited();
1336 m_aChildrenMap
[aName
].push_back( pNewElement
);
1337 m_bIsModified
= true;
1338 m_bBroadcastModified
= true;
1341 std::unique_ptr
<OStorage_Impl
> OStorage_Impl::CreateNewStorageImpl( sal_Int32 nStorageMode
)
1343 SAL_WARN_IF( !m_xPackage
.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1344 if ( !m_xPackage
.is() )
1345 throw embed::InvalidStorageException( THROW_WHERE
);
1347 uno::Sequence
< uno::Any
> aSeq
{ uno::Any(true) };
1348 uno::Reference
< uno::XInterface
> xNewElement( m_xPackage
->createInstanceWithArguments( aSeq
) );
1350 SAL_WARN_IF( !xNewElement
.is(), "package.xstor", "Not possible to create a new storage!" );
1351 if ( !xNewElement
.is() )
1352 throw io::IOException( THROW_WHERE
);
1354 uno::Reference
< container::XNameContainer
> xPackageSubFolder( xNewElement
, uno::UNO_QUERY_THROW
);
1355 std::unique_ptr
<OStorage_Impl
> pResult(
1356 new OStorage_Impl( this, nStorageMode
, xPackageSubFolder
, m_xPackage
, m_xContext
, m_nStorageType
));
1357 pResult
->m_bIsModified
= true;
1362 SotElement_Impl
* OStorage_Impl::InsertStorage( const OUString
& aName
, sal_Int32 nStorageMode
)
1364 SotElement_Impl
* pNewElement
= InsertElement( aName
, true );
1366 pNewElement
->m_xStorage
= CreateNewStorageImpl(nStorageMode
);
1368 m_aChildrenMap
[aName
].push_back( pNewElement
);
1373 SotElement_Impl
* OStorage_Impl::InsertElement( const OUString
& aName
, bool bIsStorage
)
1375 assert( FindElement(aName
) == nullptr && "Should not try to insert existing element");
1377 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1379 SotElement_Impl
* pDeletedElm
= nullptr;
1381 auto it
= m_aChildrenMap
.find(aName
);
1382 if (it
!= m_aChildrenMap
.end())
1383 for (auto pElement
: it
->second
)
1385 SAL_WARN_IF( !pElement
->m_bIsRemoved
, "package.xstor", "Try to insert an element instead of existing one!" );
1386 if ( pElement
->m_bIsRemoved
)
1388 SAL_WARN_IF( pElement
->m_bIsInserted
, "package.xstor", "Inserted elements must be deleted immediately!" );
1389 pDeletedElm
= pElement
;
1395 if ( pDeletedElm
->m_bIsStorage
)
1396 OpenSubStorage( pDeletedElm
, embed::ElementModes::READWRITE
);
1398 OpenSubStream( pDeletedElm
);
1400 auto & rVec
= m_aChildrenMap
[aName
];
1401 rVec
.erase(std::remove(rVec
.begin(), rVec
.end(), pDeletedElm
), rVec
.end());
1403 m_aChildrenMap
.erase(aName
);
1404 m_aDeletedVector
.push_back( pDeletedElm
);
1407 // create new element
1408 return new SotElement_Impl( aName
, bIsStorage
, true );
1411 void OStorage_Impl::OpenSubStorage( SotElement_Impl
* pElement
, sal_Int32 nStorageMode
)
1413 SAL_WARN_IF( !pElement
, "package.xstor", "pElement is not set!" );
1414 SAL_WARN_IF( !pElement
->m_bIsStorage
, "package.xstor", "Storage flag is not set!" );
1416 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1418 if (!pElement
->m_xStorage
)
1420 SAL_WARN_IF( pElement
->m_bIsInserted
, "package.xstor", "Inserted element must be created already!" );
1422 uno::Reference
< uno::XInterface
> xTmp
;
1423 m_xPackageFolder
->getByName( pElement
->m_aOriginalName
) >>= xTmp
;
1425 throw container::NoSuchElementException( THROW_WHERE
);
1427 uno::Reference
< container::XNameContainer
> xPackageSubFolder( xTmp
, uno::UNO_QUERY_THROW
);
1428 pElement
->m_xStorage
.reset(new OStorage_Impl(this, nStorageMode
, xPackageSubFolder
, m_xPackage
, m_xContext
, m_nStorageType
));
1432 void OStorage_Impl::OpenSubStream( SotElement_Impl
* pElement
)
1434 SAL_WARN_IF( !pElement
, "package.xstor", "pElement is not set!" );
1435 SAL_WARN_IF( pElement
->m_bIsStorage
, "package.xstor", "Storage flag is set!" );
1437 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1439 if (pElement
->m_xStream
)
1442 SAL_WARN_IF( pElement
->m_bIsInserted
, "package.xstor", "Inserted element must be created already!" );
1444 uno::Reference
< uno::XInterface
> xTmp
;
1445 m_xPackageFolder
->getByName( pElement
->m_aOriginalName
) >>= xTmp
;
1447 throw container::NoSuchElementException( THROW_WHERE
);
1449 uno::Reference
< packages::XDataSinkEncrSupport
> xPackageSubStream( xTmp
, uno::UNO_QUERY_THROW
);
1451 // the stream can never be inserted here, because inserted stream element holds the stream till commit or destruction
1452 pElement
->m_xStream
.reset(new OWriteStream_Impl(this, xPackageSubStream
, m_xPackage
, m_xContext
, false, m_nStorageType
, false, GetRelInfoStreamForName(pElement
->m_aOriginalName
)));
1455 uno::Sequence
< OUString
> OStorage_Impl::GetElementNames()
1457 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1462 for ( const auto& pair
: m_aChildrenMap
)
1463 for (auto pElement
: pair
.second
)
1465 if ( !pElement
->m_bIsRemoved
)
1469 uno::Sequence
<OUString
> aElementNames(nCnt
);
1470 OUString
* pArray
= aElementNames
.getArray();
1471 for ( const auto& pair
: m_aChildrenMap
)
1472 for (auto pElement
: pair
.second
)
1474 if ( !pElement
->m_bIsRemoved
)
1475 *pArray
++ = pair
.first
;
1478 return aElementNames
;
1481 void OStorage_Impl::RemoveElement( OUString
const & rName
, SotElement_Impl
* pElement
)
1485 if ( (pElement
->m_xStorage
&& ( pElement
->m_xStorage
->m_pAntiImpl
|| !pElement
->m_xStorage
->m_aReadOnlyWrapVector
.empty() ))
1486 || (pElement
->m_xStream
&& ( pElement
->m_xStream
->m_pAntiImpl
|| !pElement
->m_xStream
->m_aInputStreamsVector
.empty() )) )
1487 throw io::IOException( THROW_WHERE
); // TODO: Access denied
1489 auto mapIt
= m_aChildrenMap
.find(rName
);
1490 for (auto it
= mapIt
->second
.begin(); it
!= mapIt
->second
.end(); ++it
)
1491 if (pElement
== *it
)
1493 if ( pElement
->m_bIsInserted
)
1496 mapIt
->second
.erase(std::remove(mapIt
->second
.begin(), mapIt
->second
.end(), pElement
), mapIt
->second
.end());
1497 if (mapIt
->second
.empty())
1498 m_aChildrenMap
.erase(mapIt
);
1502 pElement
->m_bIsRemoved
= true;
1503 ClearElement( pElement
);
1507 assert(false && "not found");
1509 // TODO/OFOPXML: the rel stream should be removed as well
1512 void OStorage_Impl::ClearElement( SotElement_Impl
* pElement
)
1514 pElement
->m_xStorage
.reset();
1515 pElement
->m_xStream
.reset();
1518 void OStorage_Impl::CloneStreamElement( const OUString
& aStreamName
,
1519 bool bEncryptionDataProvided
,
1520 const ::comphelper::SequenceAsHashMap
& aEncryptionData
,
1521 uno::Reference
< io::XStream
>& xTargetStream
)
1523 SotElement_Impl
*pElement
= FindElement( aStreamName
);
1526 // element does not exist, throw exception
1527 throw io::IOException( THROW_WHERE
); // TODO: access_denied
1529 else if ( pElement
->m_bIsStorage
)
1530 throw io::IOException( THROW_WHERE
);
1532 if (!pElement
->m_xStream
)
1533 OpenSubStream( pElement
);
1535 if (!pElement
->m_xStream
|| !pElement
->m_xStream
->m_xPackageStream
.is())
1536 throw io::IOException( THROW_WHERE
); // TODO: general_error
1538 // the existence of m_pAntiImpl of the child is not interesting,
1539 // the copy will be created internally
1541 // usual copying is not applicable here, only last flushed version of the
1542 // child stream should be used for copying. Probably the children m_xPackageStream
1543 // can be used as a base of a new stream, that would be copied to result
1544 // storage. The only problem is that some package streams can be accessed from outside
1545 // at the same time (now solved by wrappers that remember own position).
1547 if (bEncryptionDataProvided
)
1548 pElement
->m_xStream
->GetCopyOfLastCommit(xTargetStream
, aEncryptionData
);
1550 pElement
->m_xStream
->GetCopyOfLastCommit(xTargetStream
);
1553 void OStorage_Impl::RemoveStreamRelInfo( std::u16string_view aOriginalName
)
1555 // this method should be used only in OStorage_Impl::Commit() method
1556 // the aOriginalName can be empty, in this case the storage relation info should be removed
1558 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& m_xRelStorage
.is() )
1560 OUString aRelStreamName
= OUString::Concat(aOriginalName
) + ".rels";
1562 if ( m_xRelStorage
->hasByName( aRelStreamName
) )
1563 m_xRelStorage
->removeElement( aRelStreamName
);
1567 void OStorage_Impl::CreateRelStorage()
1569 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
1572 if ( m_xRelStorage
.is() )
1575 if ( !m_pRelStorElement
)
1577 m_pRelStorElement
= new SotElement_Impl( "_rels", true, true );
1578 m_pRelStorElement
->m_xStorage
= CreateNewStorageImpl(embed::ElementModes::WRITE
);
1579 if (m_pRelStorElement
->m_xStorage
)
1580 m_pRelStorElement
->m_xStorage
->m_pParent
= nullptr; // the relation storage is completely controlled by parent
1583 if (!m_pRelStorElement
->m_xStorage
)
1584 OpenSubStorage( m_pRelStorElement
, embed::ElementModes::WRITE
);
1586 if (!m_pRelStorElement
->m_xStorage
)
1587 throw uno::RuntimeException( THROW_WHERE
);
1589 m_xRelStorage
= new OStorage(m_pRelStorElement
->m_xStorage
.get(), false);
1592 void OStorage_Impl::CommitStreamRelInfo( std::u16string_view rName
, SotElement_Impl
const * pStreamElement
)
1594 // this method should be used only in OStorage_Impl::Commit() method
1596 // the stream element must be provided
1597 if ( !pStreamElement
)
1598 throw uno::RuntimeException( THROW_WHERE
);
1600 if (m_nStorageType
== embed::StorageFormats::OFOPXML
&& pStreamElement
->m_xStream
)
1602 SAL_WARN_IF( rName
.empty(), "package.xstor", "The name must not be empty!" );
1604 if ( !m_xRelStorage
.is() )
1606 // Create new rels storage, this is commit scenario so it must be possible
1610 pStreamElement
->m_xStream
->CommitStreamRelInfo(m_xRelStorage
, pStreamElement
->m_aOriginalName
, rName
);
1614 uno::Reference
< io::XInputStream
> OStorage_Impl::GetRelInfoStreamForName(
1615 std::u16string_view aName
)
1617 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1620 if ( m_xRelStorage
.is() )
1622 OUString aRelStreamName
= OUString::Concat(aName
) + ".rels";
1623 if ( m_xRelStorage
->hasByName( aRelStreamName
) )
1625 uno::Reference
< io::XStream
> xStream
= m_xRelStorage
->openStreamElement( aRelStreamName
, embed::ElementModes::READ
);
1627 return xStream
->getInputStream();
1632 return uno::Reference
< io::XInputStream
>();
1635 void OStorage_Impl::CommitRelInfo( const uno::Reference
< container::XNameContainer
>& xNewPackageFolder
)
1637 // this method should be used only in OStorage_Impl::Commit() method
1638 OUString
aRelsStorName("_rels");
1640 if ( !xNewPackageFolder
.is() )
1641 throw uno::RuntimeException( THROW_WHERE
);
1643 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
1646 if ( m_nRelInfoStatus
== RELINFO_BROKEN
|| m_nRelInfoStatus
== RELINFO_CHANGED_BROKEN
)
1647 throw io::IOException( THROW_WHERE
);
1649 if (m_nRelInfoStatus
== RELINFO_CHANGED
)
1651 if (m_aRelInfo
.hasElements())
1655 uno::Reference
<io::XStream
> xRelsStream
= m_xRelStorage
->openStreamElement(
1656 ".rels", embed::ElementModes::TRUNCATE
| embed::ElementModes::READWRITE
);
1658 uno::Reference
<io::XOutputStream
> xOutStream
= xRelsStream
->getOutputStream();
1659 if (!xOutStream
.is())
1660 throw uno::RuntimeException(THROW_WHERE
);
1662 ::comphelper::OFOPXMLHelper::WriteRelationsInfoSequence(xOutStream
, m_aRelInfo
,
1665 // set the mediatype
1666 uno::Reference
<beans::XPropertySet
> xPropSet(xRelsStream
, uno::UNO_QUERY_THROW
);
1667 xPropSet
->setPropertyValue(
1668 "MediaType", uno::Any(OUString(
1669 "application/vnd.openxmlformats-package.relationships+xml")));
1671 m_nRelInfoStatus
= RELINFO_READ
;
1673 else if (m_xRelStorage
.is())
1674 RemoveStreamRelInfo(std::u16string_view()); // remove own rel info
1676 else if (m_nRelInfoStatus
== RELINFO_CHANGED_STREAM_READ
1677 || m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
1681 uno::Reference
<io::XStream
> xRelsStream
= m_xRelStorage
->openStreamElement(
1682 ".rels", embed::ElementModes::TRUNCATE
| embed::ElementModes::READWRITE
);
1684 uno::Reference
<io::XOutputStream
> xOutputStream
= xRelsStream
->getOutputStream();
1685 if (!xOutputStream
.is())
1686 throw uno::RuntimeException(THROW_WHERE
);
1688 uno::Reference
<io::XSeekable
> xSeek(m_xNewRelInfoStream
, uno::UNO_QUERY_THROW
);
1690 ::comphelper::OStorageHelper::CopyInputToOutput(m_xNewRelInfoStream
, xOutputStream
);
1692 // set the mediatype
1693 uno::Reference
<beans::XPropertySet
> xPropSet(xRelsStream
, uno::UNO_QUERY_THROW
);
1694 xPropSet
->setPropertyValue(
1696 uno::Any(OUString("application/vnd.openxmlformats-package.relationships+xml")));
1698 m_xNewRelInfoStream
.clear();
1699 if (m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
1701 m_aRelInfo
= uno::Sequence
<uno::Sequence
<beans::StringPair
>>();
1702 m_nRelInfoStatus
= RELINFO_NO_INIT
;
1705 m_nRelInfoStatus
= RELINFO_READ
;
1708 if ( !m_xRelStorage
.is() )
1711 if ( m_xRelStorage
->hasElements() )
1713 uno::Reference
< embed::XTransactedObject
> xTrans( m_xRelStorage
, uno::UNO_QUERY_THROW
);
1717 if ( xNewPackageFolder
.is() && xNewPackageFolder
->hasByName( aRelsStorName
) )
1718 xNewPackageFolder
->removeByName( aRelsStorName
);
1720 if ( !m_xRelStorage
->hasElements() )
1722 // the empty relations storage should not be created
1723 delete m_pRelStorElement
;
1724 m_pRelStorElement
= nullptr;
1725 m_xRelStorage
.clear();
1727 else if ( m_pRelStorElement
&& m_pRelStorElement
->m_xStorage
&& xNewPackageFolder
.is() )
1728 m_pRelStorElement
->m_xStorage
->InsertIntoPackageFolder( aRelsStorName
, xNewPackageFolder
);
1731 // OStorage implementation
1733 OStorage::OStorage( uno::Reference
< io::XInputStream
> const & xInputStream
,
1735 const uno::Sequence
< beans::PropertyValue
>& xProperties
,
1736 uno::Reference
< uno::XComponentContext
> const & xContext
,
1737 sal_Int32 nStorageType
)
1738 : m_pImpl( new OStorage_Impl( xInputStream
, nMode
, xProperties
, xContext
, nStorageType
) )
1739 , m_xSharedMutex( m_pImpl
->m_xMutex
)
1740 , m_aListenersContainer( m_pImpl
->m_xMutex
->GetMutex() )
1741 , m_bReadOnlyWrap( false )
1743 m_pImpl
->m_pAntiImpl
= this;
1746 OStorage::OStorage( uno::Reference
< io::XStream
> const & xStream
,
1748 const uno::Sequence
< beans::PropertyValue
>& xProperties
,
1749 uno::Reference
< uno::XComponentContext
> const & xContext
,
1750 sal_Int32 nStorageType
)
1751 : m_pImpl( new OStorage_Impl( xStream
, nMode
, xProperties
, xContext
, nStorageType
) )
1752 , m_xSharedMutex( m_pImpl
->m_xMutex
)
1753 , m_aListenersContainer( m_pImpl
->m_xMutex
->GetMutex() )
1754 , m_bReadOnlyWrap( false )
1756 m_pImpl
->m_pAntiImpl
= this;
1759 OStorage::OStorage( OStorage_Impl
* pImpl
, bool bReadOnlyWrap
)
1761 , m_xSharedMutex( m_pImpl
->m_xMutex
)
1762 , m_aListenersContainer( m_pImpl
->m_xMutex
->GetMutex() )
1763 , m_bReadOnlyWrap( bReadOnlyWrap
)
1765 // this call can be done only from OStorage_Impl implementation to create child storage
1766 assert( m_pImpl
&& m_pImpl
->m_xMutex
.is() && "The provided pointer & mutex MUST NOT be empty!" );
1768 OSL_ENSURE( ( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
) == embed::ElementModes::WRITE
||
1770 "The wrapper can not allow writing in case implementation does not!" );
1772 if ( !bReadOnlyWrap
)
1773 m_pImpl
->m_pAntiImpl
= this;
1776 OStorage::~OStorage()
1778 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
1781 osl_atomic_increment(&m_refCount
); // to call dispose
1785 catch( const uno::RuntimeException
& )
1787 TOOLS_INFO_EXCEPTION("package.xstor", "Handled exception");
1792 void OStorage::InternalDispose( bool bNotifyImpl
)
1797 // the source object is also a kind of locker for the current object
1798 // since the listeners could dispose the object while being notified
1799 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
1800 m_aListenersContainer
.disposeAndClear( aSource
);
1805 m_pImpl
->m_nModifiedListenerCount
= 0;
1807 if ( m_bReadOnlyWrap
)
1809 OSL_ENSURE( m_aOpenSubComponentsVector
.empty() || m_pSubElDispListener
,
1810 "If any subelements are open the listener must exist!" );
1812 if (m_pSubElDispListener
)
1814 m_pSubElDispListener
->OwnerIsDisposed();
1816 // iterate through m_pData->m_aOpenSubComponentsVector
1817 // deregister m_pData->m_pSubElDispListener and dispose all of them
1818 if ( !m_aOpenSubComponentsVector
.empty() )
1820 for ( const auto& pComp
: m_aOpenSubComponentsVector
)
1822 uno::Reference
< lang::XComponent
> xTmp
= pComp
;
1825 xTmp
->removeEventListener( uno::Reference
< lang::XEventListener
>(
1826 static_cast< lang::XEventListener
* >( m_pSubElDispListener
.get())));
1830 } catch( const uno::Exception
& )
1832 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
1837 m_aOpenSubComponentsVector
.clear();
1842 m_pImpl
->RemoveReadOnlyWrap( *this );
1846 m_pImpl
->m_pAntiImpl
= nullptr;
1850 if ( m_pImpl
->m_bIsRoot
)
1854 // the non-committed changes for the storage must be removed
1863 void OStorage::ChildIsDisposed( const uno::Reference
< uno::XInterface
>& xChild
)
1865 // this method can only be called by child disposing listener
1867 // this method must not contain any locking
1868 // the locking is done in the listener
1870 auto& rVec
= m_aOpenSubComponentsVector
;
1871 rVec
.erase(std::remove_if(rVec
.begin(), rVec
.end(),
1872 [&xChild
](const uno::Reference
<lang::XComponent
>& xTmp
) {
1873 return !xTmp
.is() || xTmp
== xChild
;
1878 void OStorage::BroadcastModifiedIfNecessary()
1880 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
1883 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
1884 throw lang::DisposedException( THROW_WHERE
);
1887 if ( !m_pImpl
->m_bBroadcastModified
)
1890 m_pImpl
->m_bBroadcastModified
= false;
1892 SAL_WARN_IF( m_bReadOnlyWrap
, "package.xstor", "The storage can not be modified at all!" );
1894 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
1896 comphelper::OInterfaceContainerHelper2
* pContainer
=
1897 m_aListenersContainer
.getContainer(
1898 cppu::UnoType
<util::XModifyListener
>::get());
1901 comphelper::OInterfaceIteratorHelper2
pIterator( *pContainer
);
1902 while ( pIterator
.hasMoreElements( ) )
1904 static_cast<util::XModifyListener
*>( pIterator
.next( ) )->modified( aSource
);
1909 void OStorage::BroadcastTransaction( sal_Int8 nMessage
)
1917 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
1920 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
1921 throw lang::DisposedException( THROW_WHERE
);
1924 SAL_WARN_IF( m_bReadOnlyWrap
, "package.xstor", "The storage can not be modified at all!" );
1926 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
1928 comphelper::OInterfaceContainerHelper2
* pContainer
=
1929 m_aListenersContainer
.getContainer(
1930 cppu::UnoType
<embed::XTransactionListener
>::get());
1934 comphelper::OInterfaceIteratorHelper2
pIterator( *pContainer
);
1935 while ( pIterator
.hasMoreElements( ) )
1937 OSL_ENSURE( nMessage
>= 1 && nMessage
<= 4, "Wrong internal notification code is used!" );
1941 case STOR_MESS_PRECOMMIT
:
1942 static_cast<embed::XTransactionListener
*>( pIterator
.next( ) )->preCommit( aSource
);
1944 case STOR_MESS_COMMITTED
:
1945 static_cast<embed::XTransactionListener
*>( pIterator
.next( ) )->commited( aSource
);
1947 case STOR_MESS_PREREVERT
:
1948 static_cast<embed::XTransactionListener
*>( pIterator
.next( ) )->preRevert( aSource
);
1950 case STOR_MESS_REVERTED
:
1951 static_cast<embed::XTransactionListener
*>( pIterator
.next( ) )->reverted( aSource
);
1957 SotElement_Impl
* OStorage::OpenStreamElement_Impl( const OUString
& aStreamName
, sal_Int32 nOpenMode
, bool bEncr
)
1959 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
1961 OSL_ENSURE( !m_bReadOnlyWrap
|| ( nOpenMode
& embed::ElementModes::WRITE
) != embed::ElementModes::WRITE
,
1962 "An element can not be opened for writing in readonly storage!" );
1964 SotElement_Impl
*pElement
= m_pImpl
->FindElement( aStreamName
);
1967 // element does not exist, check if creation is allowed
1968 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
)
1969 || (( nOpenMode
& embed::ElementModes::WRITE
) != embed::ElementModes::WRITE
)
1970 || ( nOpenMode
& embed::ElementModes::NOCREATE
) == embed::ElementModes::NOCREATE
)
1972 throw io::IOException("Element does not exist and cannot be "
1973 "created: \"" + aStreamName
+ "\""); // TODO: access_denied
1976 // create a new StreamElement and insert it into the list
1977 pElement
= m_pImpl
->InsertStream( aStreamName
, bEncr
);
1979 else if ( pElement
->m_bIsStorage
)
1981 throw io::IOException( THROW_WHERE
);
1984 SAL_WARN_IF( !pElement
, "package.xstor", "In case element can not be created an exception must be thrown!" );
1986 if (!pElement
->m_xStream
)
1987 m_pImpl
->OpenSubStream( pElement
);
1989 if (!pElement
->m_xStream
)
1990 throw io::IOException( THROW_WHERE
);
1995 void OStorage::MakeLinkToSubComponent_Impl( const uno::Reference
< lang::XComponent
>& xComponent
)
1997 if ( !xComponent
.is() )
1998 throw uno::RuntimeException( THROW_WHERE
);
2000 if (!m_pSubElDispListener
)
2002 m_pSubElDispListener
= new OChildDispListener_Impl( *this );
2005 xComponent
->addEventListener( m_pSubElDispListener
);
2007 m_aOpenSubComponentsVector
.emplace_back(xComponent
);
2012 uno::Any SAL_CALL
OStorage::queryInterface( const uno::Type
& rType
)
2014 // common interfaces
2015 uno::Any aReturn
= ::cppu::queryInterface
2017 , static_cast<lang::XTypeProvider
*> ( this )
2018 , static_cast<embed::XStorage
*> ( this )
2019 , static_cast<embed::XStorage2
*> ( this )
2020 , static_cast<embed::XTransactedObject
*> ( this )
2021 , static_cast<embed::XTransactionBroadcaster
*> ( this )
2022 , static_cast<util::XModifiable
*> ( this )
2023 , static_cast<container::XNameAccess
*> ( this )
2024 , static_cast<container::XElementAccess
*> ( this )
2025 , static_cast<lang::XComponent
*> ( this )
2026 , static_cast<beans::XPropertySet
*> ( this )
2027 , static_cast<embed::XOptimizedStorage
*> ( this ) );
2029 if ( aReturn
.hasValue() )
2032 aReturn
= ::cppu::queryInterface
2034 , static_cast<embed::XHierarchicalStorageAccess
*> ( this )
2035 , static_cast<embed::XHierarchicalStorageAccess2
*> ( this ) );
2037 if ( aReturn
.hasValue() )
2040 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::PACKAGE
)
2042 if ( m_pImpl
->m_bIsRoot
)
2044 aReturn
= ::cppu::queryInterface
2046 , static_cast<embed::XStorageRawAccess
*> ( this )
2047 , static_cast<embed::XEncryptionProtectedSource
*> ( this )
2048 , static_cast<embed::XEncryptionProtectedSource2
*> ( this )
2049 , static_cast<embed::XEncryptionProtectedStorage
*> ( this ) );
2053 aReturn
= ::cppu::queryInterface
2055 , static_cast<embed::XStorageRawAccess
*> ( this ) );
2058 else if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
)
2060 aReturn
= ::cppu::queryInterface
2062 , static_cast<embed::XRelationshipAccess
*> ( this ) );
2065 if ( aReturn
.hasValue() )
2068 return OWeakObject::queryInterface( rType
);
2071 void SAL_CALL
OStorage::acquire() noexcept
2073 OWeakObject::acquire();
2076 void SAL_CALL
OStorage::release() noexcept
2078 OWeakObject::release();
2082 uno::Sequence
< uno::Type
> SAL_CALL
OStorage::getTypes()
2084 if (! m_oTypeCollection
)
2086 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2088 if (! m_oTypeCollection
)
2090 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::PACKAGE
)
2092 if ( m_pImpl
->m_bIsRoot
)
2094 m_oTypeCollection
.emplace(
2095 cppu::UnoType
<lang::XTypeProvider
>::get()
2096 , cppu::UnoType
<embed::XStorage
>::get()
2097 , cppu::UnoType
<embed::XStorage2
>::get()
2098 , cppu::UnoType
<embed::XStorageRawAccess
>::get()
2099 , cppu::UnoType
<embed::XTransactedObject
>::get()
2100 , cppu::UnoType
<embed::XTransactionBroadcaster
>::get()
2101 , cppu::UnoType
<util::XModifiable
>::get()
2102 , cppu::UnoType
<embed::XEncryptionProtectedStorage
>::get()
2103 , cppu::UnoType
<embed::XEncryptionProtectedSource2
>::get()
2104 , cppu::UnoType
<embed::XEncryptionProtectedSource
>::get()
2105 , cppu::UnoType
<beans::XPropertySet
>::get());
2109 m_oTypeCollection
.emplace(
2110 cppu::UnoType
<lang::XTypeProvider
>::get()
2111 , cppu::UnoType
<embed::XStorage
>::get()
2112 , cppu::UnoType
<embed::XStorage2
>::get()
2113 , cppu::UnoType
<embed::XStorageRawAccess
>::get()
2114 , cppu::UnoType
<embed::XTransactedObject
>::get()
2115 , cppu::UnoType
<embed::XTransactionBroadcaster
>::get()
2116 , cppu::UnoType
<util::XModifiable
>::get()
2117 , cppu::UnoType
<beans::XPropertySet
>::get());
2120 else if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
)
2122 m_oTypeCollection
.emplace(
2123 cppu::UnoType
<lang::XTypeProvider
>::get()
2124 , cppu::UnoType
<embed::XStorage
>::get()
2125 , cppu::UnoType
<embed::XTransactedObject
>::get()
2126 , cppu::UnoType
<embed::XTransactionBroadcaster
>::get()
2127 , cppu::UnoType
<util::XModifiable
>::get()
2128 , cppu::UnoType
<embed::XRelationshipAccess
>::get()
2129 , cppu::UnoType
<beans::XPropertySet
>::get());
2133 m_oTypeCollection
.emplace(
2134 cppu::UnoType
<lang::XTypeProvider
>::get()
2135 , cppu::UnoType
<embed::XStorage
>::get()
2136 , cppu::UnoType
<embed::XTransactedObject
>::get()
2137 , cppu::UnoType
<embed::XTransactionBroadcaster
>::get()
2138 , cppu::UnoType
<util::XModifiable
>::get()
2139 , cppu::UnoType
<beans::XPropertySet
>::get());
2144 return m_oTypeCollection
->getTypes() ;
2147 uno::Sequence
< sal_Int8
> SAL_CALL
OStorage::getImplementationId()
2149 static const comphelper::UnoIdInit lcl_ImplId
;
2150 return lcl_ImplId
.getSeq();
2154 void SAL_CALL
OStorage::copyToStorage( const uno::Reference
< embed::XStorage
>& xDest
)
2156 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2160 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2161 throw lang::DisposedException( THROW_WHERE
);
2164 if ( !xDest
.is() || xDest
== uno::Reference
< uno::XInterface
>( static_cast< OWeakObject
*> ( this ), uno::UNO_QUERY
) )
2165 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 );
2168 m_pImpl
->CopyToStorage( xDest
, false );
2170 catch( const embed::InvalidStorageException
& )
2172 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2175 catch( const lang::IllegalArgumentException
& )
2177 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2180 catch( const embed::StorageWrappedTargetException
& )
2182 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2185 catch( const io::IOException
& )
2187 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2190 catch( const uno::RuntimeException
& )
2192 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2195 catch( const uno::Exception
& )
2197 uno::Any
aCaught( ::cppu::getCaughtException() );
2198 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2200 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy storage!",
2201 uno::Reference
< io::XInputStream
>(),
2206 uno::Reference
< io::XStream
> SAL_CALL
OStorage::openStreamElement(
2207 const OUString
& aStreamName
, sal_Int32 nOpenMode
)
2209 osl::ClearableMutexGuard
aGuard(m_xSharedMutex
->GetMutex());
2213 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2214 throw lang::DisposedException( THROW_WHERE
);
2217 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
2218 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2220 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStreamName
== "_rels" )
2221 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable element name
2223 if ( ( nOpenMode
& embed::ElementModes::WRITE
) && m_bReadOnlyWrap
)
2224 throw io::IOException( THROW_WHERE
); // TODO: access denied
2226 uno::Reference
< io::XStream
> xResult
;
2229 SotElement_Impl
*pElement
= OpenStreamElement_Impl( aStreamName
, nOpenMode
, false );
2230 OSL_ENSURE(pElement
&& pElement
->m_xStream
, "In case element can not be created an exception must be thrown!");
2232 xResult
= pElement
->m_xStream
->GetStream(nOpenMode
, false);
2233 SAL_WARN_IF( !xResult
.is(), "package.xstor", "The method must throw exception instead of removing empty result!" );
2235 if ( m_bReadOnlyWrap
)
2237 // before the storage disposes the stream it must deregister itself as listener
2238 uno::Reference
< lang::XComponent
> xStreamComponent( xResult
, uno::UNO_QUERY_THROW
);
2239 MakeLinkToSubComponent_Impl( xStreamComponent
);
2242 catch( const embed::InvalidStorageException
& )
2244 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2247 catch( const lang::IllegalArgumentException
& )
2249 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2252 catch( const packages::WrongPasswordException
& )
2254 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2257 catch( const embed::StorageWrappedTargetException
& )
2259 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2262 catch( const io::IOException
& )
2264 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2267 catch( const uno::RuntimeException
& )
2269 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2272 catch( const uno::Exception
& )
2274 uno::Any
aCaught( ::cppu::getCaughtException() );
2275 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2277 throw embed::StorageWrappedTargetException(THROW_WHERE
"Can't open stream element!",
2278 uno::Reference
< io::XInputStream
>(),
2284 BroadcastModifiedIfNecessary();
2289 uno::Reference
< io::XStream
> SAL_CALL
OStorage::openEncryptedStreamElement(
2290 const OUString
& aStreamName
, sal_Int32 nOpenMode
, const OUString
& aPass
)
2292 return openEncryptedStream( aStreamName
, nOpenMode
, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass
) );
2295 uno::Reference
< embed::XStorage
> SAL_CALL
OStorage::openStorageElement(
2296 const OUString
& aStorName
, sal_Int32 nStorageMode
)
2298 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2302 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2303 throw lang::DisposedException( THROW_WHERE
);
2306 if ( aStorName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName
, false ) )
2307 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2309 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStorName
== "_rels" )
2310 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable storage name
2312 if ( ( nStorageMode
& embed::ElementModes::WRITE
) && m_bReadOnlyWrap
)
2313 throw io::IOException( THROW_WHERE
); // TODO: access denied
2315 if ( ( nStorageMode
& embed::ElementModes::TRUNCATE
)
2316 && !( nStorageMode
& embed::ElementModes::WRITE
) )
2317 throw io::IOException( THROW_WHERE
); // TODO: access denied
2319 // it's always possible to read written storage in this implementation
2320 nStorageMode
|= embed::ElementModes::READ
;
2322 uno::Reference
< embed::XStorage
> xResult
;
2325 SotElement_Impl
*pElement
= m_pImpl
->FindElement( aStorName
);
2328 // element does not exist, check if creation is allowed
2329 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
)
2330 || (( nStorageMode
& embed::ElementModes::WRITE
) != embed::ElementModes::WRITE
)
2331 || ( nStorageMode
& embed::ElementModes::NOCREATE
) == embed::ElementModes::NOCREATE
)
2332 throw io::IOException( THROW_WHERE
); // TODO: access_denied
2334 // create a new StorageElement and insert it into the list
2335 pElement
= m_pImpl
->InsertStorage( aStorName
, nStorageMode
);
2337 else if ( !pElement
->m_bIsStorage
)
2339 throw io::IOException( THROW_WHERE
);
2341 else if (pElement
->m_xStorage
)
2343 // storage has already been opened; it may be opened another time, if it the mode allows to do so
2344 if (pElement
->m_xStorage
->m_pAntiImpl
)
2346 throw io::IOException( THROW_WHERE
); // TODO: access_denied
2348 else if ( !pElement
->m_xStorage
->m_aReadOnlyWrapVector
.empty()
2349 && ( nStorageMode
& embed::ElementModes::WRITE
) )
2351 throw io::IOException( THROW_WHERE
); // TODO: access_denied
2355 // in case parent storage allows writing the readonly mode of the child storage is
2356 // virtual, that means that it is just enough to change the flag to let it be writable
2357 // and since there is no AntiImpl nobody should be notified about it
2358 pElement
->m_xStorage
->m_nStorageMode
= nStorageMode
| embed::ElementModes::READ
;
2360 if ( nStorageMode
& embed::ElementModes::TRUNCATE
)
2362 for (const auto & rPair
: pElement
->m_xStorage
->m_aChildrenMap
)
2363 for (auto pElementToDel
: rPair
.second
)
2364 m_pImpl
->RemoveElement( /*aName*/rPair
.first
, pElementToDel
);
2369 if (!pElement
->m_xStorage
)
2370 m_pImpl
->OpenSubStorage(pElement
, nStorageMode
);
2372 if (!pElement
->m_xStorage
)
2373 throw io::IOException( THROW_WHERE
); // TODO: general_error
2375 bool bReadOnlyWrap
= ( ( nStorageMode
& embed::ElementModes::WRITE
) != embed::ElementModes::WRITE
);
2376 rtl::Reference
<OStorage
> pResultStorage
= new OStorage(pElement
->m_xStorage
.get(), bReadOnlyWrap
);
2377 xResult
= pResultStorage
;
2379 if ( bReadOnlyWrap
)
2381 // Before this call is done the object must be refcounted already
2382 pElement
->m_xStorage
->SetReadOnlyWrap(*pResultStorage
);
2384 // before the storage disposes the stream it must deregister itself as listener
2385 uno::Reference
< lang::XComponent
> xStorageComponent( xResult
, uno::UNO_QUERY_THROW
);
2386 MakeLinkToSubComponent_Impl( xStorageComponent
);
2389 catch( const embed::InvalidStorageException
& )
2391 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2394 catch( const lang::IllegalArgumentException
& )
2396 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2399 catch( const embed::StorageWrappedTargetException
& )
2401 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2404 catch( const io::IOException
& )
2406 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2409 catch( const uno::RuntimeException
& )
2411 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2414 catch( const uno::Exception
& )
2416 uno::Any
aCaught( ::cppu::getCaughtException() );
2417 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2419 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't open storage!",
2420 uno::Reference
< io::XInputStream
>(),
2427 uno::Reference
< io::XStream
> SAL_CALL
OStorage::cloneStreamElement( const OUString
& aStreamName
)
2429 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2433 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2434 throw lang::DisposedException( THROW_WHERE
);
2437 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
2438 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2440 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStreamName
== "_rels" )
2441 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable storage name
2445 uno::Reference
< io::XStream
> xResult
;
2446 m_pImpl
->CloneStreamElement( aStreamName
, false, ::comphelper::SequenceAsHashMap(), xResult
);
2447 if ( !xResult
.is() )
2448 throw uno::RuntimeException( THROW_WHERE
);
2451 catch( const embed::InvalidStorageException
& )
2453 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2456 catch( const lang::IllegalArgumentException
& )
2458 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2461 catch( const packages::WrongPasswordException
& )
2463 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2466 catch( const io::IOException
& )
2468 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2471 catch( const embed::StorageWrappedTargetException
& )
2473 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2476 catch( const uno::RuntimeException
& )
2478 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2481 catch( const uno::Exception
& )
2483 uno::Any
aCaught( ::cppu::getCaughtException() );
2484 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2486 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't clone stream!",
2487 uno::Reference
< io::XInputStream
>(),
2492 uno::Reference
< io::XStream
> SAL_CALL
OStorage::cloneEncryptedStreamElement(
2493 const OUString
& aStreamName
,
2494 const OUString
& aPass
)
2496 return cloneEncryptedStream( aStreamName
, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass
) );
2499 void SAL_CALL
OStorage::copyLastCommitTo(
2500 const uno::Reference
< embed::XStorage
>& xTargetStorage
)
2502 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2506 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2507 throw lang::DisposedException( THROW_WHERE
);
2512 m_pImpl
->CopyLastCommitTo( xTargetStorage
);
2514 catch( const embed::InvalidStorageException
& )
2516 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2519 catch( const lang::IllegalArgumentException
& )
2521 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2524 catch( const embed::StorageWrappedTargetException
& )
2526 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2529 catch( const io::IOException
& )
2531 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2534 catch( const uno::RuntimeException
& )
2536 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2539 catch( const uno::Exception
& )
2541 uno::Any
aCaught( ::cppu::getCaughtException() );
2542 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2544 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy last commit version!",
2545 uno::Reference
< io::XInputStream
>(),
2551 void SAL_CALL
OStorage::copyStorageElementLastCommitTo(
2552 const OUString
& aStorName
,
2553 const uno::Reference
< embed::XStorage
>& xTargetStorage
)
2555 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2559 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2560 throw lang::DisposedException( THROW_WHERE
);
2563 if ( aStorName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName
, false ) )
2564 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2566 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStorName
== "_rels" )
2567 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable storage name
2571 SotElement_Impl
*pElement
= m_pImpl
->FindElement( aStorName
);
2574 // element does not exist, throw exception
2575 throw io::IOException( THROW_WHERE
); // TODO: access_denied
2577 else if ( !pElement
->m_bIsStorage
)
2579 throw io::IOException( THROW_WHERE
);
2582 if (!pElement
->m_xStorage
)
2583 m_pImpl
->OpenSubStorage( pElement
, embed::ElementModes::READ
);
2585 if (!pElement
->m_xStorage
)
2586 throw io::IOException( THROW_WHERE
); // TODO: general_error
2588 // the existence of m_pAntiImpl of the child is not interesting,
2589 // the copy will be created internally
2591 pElement
->m_xStorage
->CopyLastCommitTo(xTargetStorage
);
2593 catch( const embed::InvalidStorageException
& )
2595 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2598 catch( const lang::IllegalArgumentException
& )
2600 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2603 catch( const io::IOException
& )
2605 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2608 catch( const embed::StorageWrappedTargetException
& )
2610 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2613 catch( const uno::RuntimeException
& )
2615 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2618 catch( const uno::Exception
& )
2620 uno::Any
aCaught( ::cppu::getCaughtException() );
2621 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2623 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy last commit element version!",
2624 uno::Reference
< io::XInputStream
>(),
2629 sal_Bool SAL_CALL
OStorage::isStreamElement( const OUString
& aElementName
)
2631 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2635 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2636 throw lang::DisposedException( THROW_WHERE
);
2639 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false ) )
2640 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2642 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aElementName
== "_rels" )
2643 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable name
2645 SotElement_Impl
* pElement
= nullptr;
2649 pElement
= m_pImpl
->FindElement( aElementName
);
2651 catch( const embed::InvalidStorageException
& )
2653 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2656 catch( const lang::IllegalArgumentException
& )
2658 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2661 catch( const container::NoSuchElementException
& )
2663 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2666 catch( const uno::RuntimeException
& )
2668 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2671 catch( const uno::Exception
& )
2673 uno::Any
aCaught( ::cppu::getCaughtException() );
2674 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2676 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can't detect whether it is a stream!",
2677 uno::Reference
< io::XInputStream
>(),
2682 throw container::NoSuchElementException( THROW_WHERE
); //???
2684 return !pElement
->m_bIsStorage
;
2687 sal_Bool SAL_CALL
OStorage::isStorageElement( const OUString
& aElementName
)
2689 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2693 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2694 throw lang::DisposedException( THROW_WHERE
);
2697 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false ) )
2698 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2700 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aElementName
== "_rels" )
2701 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 );
2703 SotElement_Impl
* pElement
= nullptr;
2707 pElement
= m_pImpl
->FindElement( aElementName
);
2709 catch( const embed::InvalidStorageException
& )
2711 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2714 catch( const lang::IllegalArgumentException
& )
2716 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2719 catch( const container::NoSuchElementException
& )
2721 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2724 catch( const uno::RuntimeException
& )
2726 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2729 catch( const uno::Exception
& )
2731 uno::Any
aCaught( ::cppu::getCaughtException() );
2732 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2734 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"can't detect whether it is a storage",
2735 uno::Reference
< io::XInputStream
>(),
2740 throw container::NoSuchElementException( THROW_WHERE
); //???
2742 return pElement
->m_bIsStorage
;
2745 void SAL_CALL
OStorage::removeElement( const OUString
& aElementName
)
2748 osl::MutexGuard
aGuard(m_xSharedMutex
->GetMutex());
2752 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2753 throw lang::DisposedException(THROW_WHERE
);
2756 if (aElementName
.isEmpty()
2757 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aElementName
, false))
2758 throw lang::IllegalArgumentException(THROW_WHERE
"Unexpected entry name syntax.",
2759 uno::Reference
<uno::XInterface
>(), 1);
2761 if (m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aElementName
== "_rels")
2762 throw lang::IllegalArgumentException(THROW_WHERE
, uno::Reference
<uno::XInterface
>(),
2763 1); // TODO: unacceptable name
2765 if (!(m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
))
2766 throw io::IOException(THROW_WHERE
); // TODO: access denied
2770 auto pElement
= m_pImpl
->FindElement(aElementName
);
2772 throw container::NoSuchElementException(THROW_WHERE
); //???
2774 m_pImpl
->RemoveElement(aElementName
, pElement
);
2776 m_pImpl
->m_bIsModified
= true;
2777 m_pImpl
->m_bBroadcastModified
= true;
2779 catch (const embed::InvalidStorageException
&)
2781 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2784 catch (const lang::IllegalArgumentException
&)
2786 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2789 catch (const container::NoSuchElementException
&)
2791 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2794 catch (const io::IOException
&)
2796 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2799 catch (const embed::StorageWrappedTargetException
&)
2801 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2804 catch (const uno::RuntimeException
&)
2806 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2809 catch (const uno::Exception
&)
2811 uno::Any
aCaught(::cppu::getCaughtException());
2812 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2814 throw embed::StorageWrappedTargetException(THROW_WHERE
"Can't remove element!",
2815 uno::Reference
<io::XInputStream
>(), aCaught
);
2819 BroadcastModifiedIfNecessary();
2822 void SAL_CALL
OStorage::renameElement( const OUString
& aElementName
, const OUString
& aNewName
)
2825 osl::MutexGuard
aGuard(m_xSharedMutex
->GetMutex());
2829 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2830 throw lang::DisposedException(THROW_WHERE
);
2833 if (aElementName
.isEmpty()
2834 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aElementName
, false)
2835 || aNewName
.isEmpty()
2836 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aNewName
, false))
2837 throw lang::IllegalArgumentException(THROW_WHERE
"Unexpected entry name syntax.",
2838 uno::Reference
<uno::XInterface
>(), 1);
2840 if (m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
2841 && (aElementName
== "_rels" || aNewName
== "_rels"))
2842 throw lang::IllegalArgumentException(THROW_WHERE
, uno::Reference
<uno::XInterface
>(),
2843 0); // TODO: unacceptable element name
2845 if (!(m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
))
2846 throw io::IOException(THROW_WHERE
); // TODO: access denied
2850 SotElement_Impl
* pRefElement
= m_pImpl
->FindElement(aNewName
);
2852 throw container::ElementExistException(THROW_WHERE
); //???
2854 auto pElement
= m_pImpl
->FindElement( aElementName
);
2856 throw container::NoSuchElementException(THROW_WHERE
); //???
2858 auto mapIt
= m_pImpl
->m_aChildrenMap
.find(aElementName
);
2859 auto rVec
= mapIt
->second
;
2860 for (auto it
= rVec
.begin(); it
!= rVec
.end(); ++it
)
2861 if (pElement
== *it
)
2863 rVec
.erase(std::remove(rVec
.begin(), rVec
.end(), pElement
), rVec
.end());
2865 m_pImpl
->m_aChildrenMap
.erase(mapIt
);
2868 m_pImpl
->m_aChildrenMap
[aNewName
].push_back(pElement
);
2869 m_pImpl
->m_bIsModified
= true;
2870 m_pImpl
->m_bBroadcastModified
= true;
2872 catch (const embed::InvalidStorageException
&)
2874 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2877 catch (const lang::IllegalArgumentException
&)
2879 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2882 catch (const container::NoSuchElementException
&)
2884 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2887 catch (const container::ElementExistException
&)
2889 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2892 catch (const io::IOException
&)
2894 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2897 catch (const embed::StorageWrappedTargetException
&)
2899 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2902 catch (const uno::RuntimeException
&)
2904 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2907 catch (const uno::Exception
&)
2909 uno::Any
aCaught(::cppu::getCaughtException());
2910 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2912 throw embed::StorageWrappedTargetException(THROW_WHERE
"Can't rename element!",
2913 uno::Reference
<io::XInputStream
>(), aCaught
);
2917 BroadcastModifiedIfNecessary();
2920 void SAL_CALL
OStorage::copyElementTo( const OUString
& aElementName
,
2921 const uno::Reference
< embed::XStorage
>& xDest
,
2922 const OUString
& aNewName
)
2924 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
2928 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2929 throw lang::DisposedException( THROW_WHERE
);
2932 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false )
2933 || aNewName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName
, false ) )
2934 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2937 // || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
2938 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
2940 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& ( aElementName
== "_rels" || aNewName
== "_rels" ) )
2941 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 ); // unacceptable element name
2945 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aElementName
);
2947 throw container::NoSuchElementException( THROW_WHERE
);
2949 uno::Reference
< XNameAccess
> xNameAccess( xDest
, uno::UNO_QUERY_THROW
);
2950 if ( xNameAccess
->hasByName( aNewName
) )
2951 throw container::ElementExistException( THROW_WHERE
);
2953 m_pImpl
->CopyStorageElement( pElement
, xDest
, aNewName
, false );
2955 catch( const embed::InvalidStorageException
& )
2957 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2960 catch( const lang::IllegalArgumentException
& )
2962 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2965 catch( const container::NoSuchElementException
& )
2967 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2970 catch( const container::ElementExistException
& )
2972 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2975 catch( const embed::StorageWrappedTargetException
& )
2977 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2980 catch( const io::IOException
& )
2982 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2985 catch( const uno::RuntimeException
& )
2987 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2990 catch( const uno::Exception
& )
2992 uno::Any
aCaught( ::cppu::getCaughtException() );
2993 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2995 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy element!",
2996 uno::Reference
< io::XInputStream
>(),
3001 void SAL_CALL
OStorage::moveElementTo( const OUString
& aElementName
,
3002 const uno::Reference
< embed::XStorage
>& xDest
,
3003 const OUString
& aNewName
)
3006 osl::MutexGuard
aGuard(m_xSharedMutex
->GetMutex());
3010 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3011 throw lang::DisposedException(THROW_WHERE
);
3014 if (aElementName
.isEmpty()
3015 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aElementName
, false)
3016 || aNewName
.isEmpty()
3017 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aNewName
, false))
3018 throw lang::IllegalArgumentException(THROW_WHERE
"Unexpected entry name syntax.",
3019 uno::Reference
<uno::XInterface
>(), 1);
3023 == uno::Reference
<uno::XInterface
>(static_cast<OWeakObject
*>(this),
3025 throw lang::IllegalArgumentException(THROW_WHERE
, uno::Reference
<uno::XInterface
>(), 2);
3027 if (m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
3028 && (aElementName
== "_rels" || aNewName
== "_rels"))
3029 throw lang::IllegalArgumentException(THROW_WHERE
, uno::Reference
<uno::XInterface
>(),
3030 0); // unacceptable element name
3032 if (!(m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
))
3033 throw io::IOException(THROW_WHERE
); // TODO: access denied
3037 auto pElement
= m_pImpl
->FindElement( aElementName
);
3039 throw container::NoSuchElementException(THROW_WHERE
); //???
3041 uno::Reference
<XNameAccess
> xNameAccess(xDest
, uno::UNO_QUERY_THROW
);
3042 if (xNameAccess
->hasByName(aNewName
))
3043 throw container::ElementExistException(THROW_WHERE
);
3045 m_pImpl
->CopyStorageElement(pElement
, xDest
, aNewName
, false);
3047 m_pImpl
->RemoveElement(aElementName
, pElement
);
3049 m_pImpl
->m_bIsModified
= true;
3050 m_pImpl
->m_bBroadcastModified
= true;
3052 catch (const embed::InvalidStorageException
&)
3054 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3057 catch (const lang::IllegalArgumentException
&)
3059 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3062 catch (const container::NoSuchElementException
&)
3064 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3067 catch (const container::ElementExistException
&)
3069 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3072 catch (const embed::StorageWrappedTargetException
&)
3074 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3077 catch (const io::IOException
&)
3079 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3082 catch (const uno::RuntimeException
&)
3084 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3087 catch (const uno::Exception
&)
3089 uno::Any
aCaught(::cppu::getCaughtException());
3090 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3092 throw embed::StorageWrappedTargetException(THROW_WHERE
"Can't move element!",
3093 uno::Reference
<io::XInputStream
>(), aCaught
);
3097 BroadcastModifiedIfNecessary();
3101 uno::Reference
< io::XStream
> SAL_CALL
OStorage::openEncryptedStream(
3102 const OUString
& aStreamName
, sal_Int32 nOpenMode
, const uno::Sequence
< beans::NamedValue
>& aEncryptionData
)
3104 osl::ClearableMutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3108 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3109 throw lang::DisposedException( THROW_WHERE
);
3112 if ( ( nOpenMode
& embed::ElementModes::WRITE
) && m_bReadOnlyWrap
)
3113 throw io::IOException( THROW_WHERE
); // TODO: access denied
3115 if ( !aEncryptionData
.hasElements() )
3116 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 3 );
3118 uno::Reference
< io::XStream
> xResult
;
3121 SotElement_Impl
*pElement
= OpenStreamElement_Impl( aStreamName
, nOpenMode
, true );
3122 OSL_ENSURE(pElement
&& pElement
->m_xStream
, "In case element can not be created an exception must be thrown!");
3124 xResult
= pElement
->m_xStream
->GetStream(nOpenMode
, aEncryptionData
, false);
3125 SAL_WARN_IF( !xResult
.is(), "package.xstor", "The method must throw exception instead of removing empty result!" );
3127 if ( m_bReadOnlyWrap
)
3129 // before the storage disposes the stream it must deregister itself as listener
3130 uno::Reference
< lang::XComponent
> xStreamComponent( xResult
, uno::UNO_QUERY_THROW
);
3131 MakeLinkToSubComponent_Impl( xStreamComponent
);
3134 catch( const embed::InvalidStorageException
& )
3136 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3139 catch( const lang::IllegalArgumentException
& )
3141 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3144 catch( const packages::NoEncryptionException
& )
3146 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3149 catch( const packages::WrongPasswordException
& )
3151 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3154 catch( const embed::StorageWrappedTargetException
& )
3156 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3159 catch( const io::IOException
& )
3161 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3164 catch( const uno::RuntimeException
& )
3166 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3169 catch( const uno::Exception
& )
3171 uno::Any
aCaught( ::cppu::getCaughtException() );
3172 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3174 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't open encrypted stream!",
3175 uno::Reference
< io::XInputStream
>(),
3181 BroadcastModifiedIfNecessary();
3186 uno::Reference
< io::XStream
> SAL_CALL
OStorage::cloneEncryptedStream(
3187 const OUString
& aStreamName
,
3188 const uno::Sequence
< beans::NamedValue
>& aEncryptionData
)
3190 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3194 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3195 throw lang::DisposedException( THROW_WHERE
);
3198 if ( !aEncryptionData
.hasElements() )
3199 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
3203 uno::Reference
< io::XStream
> xResult
;
3204 m_pImpl
->CloneStreamElement( aStreamName
, true, aEncryptionData
, xResult
);
3205 if ( !xResult
.is() )
3206 throw uno::RuntimeException( THROW_WHERE
);
3209 catch( const embed::InvalidStorageException
& )
3211 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3214 catch( const lang::IllegalArgumentException
& )
3216 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3219 catch( const packages::NoEncryptionException
& )
3221 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3224 catch( const packages::WrongPasswordException
& )
3226 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3229 catch( const io::IOException
& )
3231 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3234 catch( const embed::StorageWrappedTargetException
& )
3236 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3239 catch( const uno::RuntimeException
& )
3241 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3244 catch( const uno::Exception
& )
3246 uno::Any
aCaught( ::cppu::getCaughtException() );
3247 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3249 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't clone encrypted stream!",
3250 uno::Reference
< io::XInputStream
>(),
3255 // XStorageRawAccess
3256 uno::Reference
< io::XInputStream
> SAL_CALL
OStorage::getPlainRawStreamElement(
3257 const OUString
& sStreamName
)
3259 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3263 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3264 throw lang::DisposedException( THROW_WHERE
);
3267 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
)
3268 throw uno::RuntimeException( THROW_WHERE
); // the interface is not supported and must not be accessible
3270 if ( sStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName
, false ) )
3271 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
3273 uno::Reference
< io::XInputStream
> xTempIn
;
3276 SotElement_Impl
* pElement
= m_pImpl
->FindElement( sStreamName
);
3278 throw container::NoSuchElementException( THROW_WHERE
);
3280 if (!pElement
->m_xStream
)
3282 m_pImpl
->OpenSubStream( pElement
);
3283 if (!pElement
->m_xStream
)
3284 throw io::IOException( THROW_WHERE
);
3287 uno::Reference
<io::XInputStream
> xRawInStream
= pElement
->m_xStream
->GetPlainRawInStream();
3288 if ( !xRawInStream
.is() )
3289 throw io::IOException( THROW_WHERE
);
3291 rtl::Reference
< utl::TempFileFastService
> xTempFile
= new utl::TempFileFastService
;
3292 uno::Reference
< io::XOutputStream
> xTempOut
= xTempFile
->getOutputStream();
3293 xTempIn
= xTempFile
->getInputStream();
3295 if ( !xTempOut
.is() || !xTempIn
.is() )
3296 throw io::IOException( THROW_WHERE
);
3298 // Copy temporary file to a new one
3299 ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream
, xTempOut
);
3300 xTempOut
->closeOutput();
3301 xTempFile
->seek( 0 );
3303 catch( const embed::InvalidStorageException
& )
3305 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3308 catch( const lang::IllegalArgumentException
& )
3310 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3313 catch( const container::NoSuchElementException
& )
3315 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3318 catch( const embed::StorageWrappedTargetException
& )
3320 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3323 catch( const io::IOException
& )
3325 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3328 catch( const uno::RuntimeException
& )
3330 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3333 catch( const uno::Exception
& )
3335 uno::Any
aCaught( ::cppu::getCaughtException() );
3336 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3338 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't get plain raw stream!",
3339 uno::Reference
< io::XInputStream
>(),
3346 uno::Reference
< io::XInputStream
> SAL_CALL
OStorage::getRawEncrStreamElement(
3347 const OUString
& sStreamName
)
3349 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3353 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3354 throw lang::DisposedException( THROW_WHERE
);
3357 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
3358 throw packages::NoEncryptionException( THROW_WHERE
);
3360 if ( sStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName
, false ) )
3361 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
3363 uno::Reference
< io::XInputStream
> xTempIn
;
3366 SotElement_Impl
* pElement
= m_pImpl
->FindElement( sStreamName
);
3368 throw container::NoSuchElementException( THROW_WHERE
);
3370 if (!pElement
->m_xStream
)
3372 m_pImpl
->OpenSubStream( pElement
);
3373 if (!pElement
->m_xStream
)
3374 throw io::IOException( THROW_WHERE
);
3377 if (!pElement
->m_xStream
->IsEncrypted())
3378 throw packages::NoEncryptionException( THROW_WHERE
);
3380 uno::Reference
< io::XInputStream
> xRawInStream
= pElement
->m_xStream
->GetRawInStream();
3381 if ( !xRawInStream
.is() )
3382 throw io::IOException( THROW_WHERE
);
3384 rtl::Reference
< utl::TempFileFastService
> xTempFile
= new utl::TempFileFastService
;
3385 uno::Reference
< io::XOutputStream
> xTempOut
= xTempFile
;
3386 xTempIn
= xTempFile
;
3389 throw io::IOException( THROW_WHERE
);
3391 // Copy temporary file to a new one
3392 ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream
, xTempOut
);
3393 xTempFile
->closeOutput();
3394 xTempFile
->seek( 0 );
3397 catch( const embed::InvalidStorageException
& )
3399 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3402 catch( const lang::IllegalArgumentException
& )
3404 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3407 catch( const packages::NoEncryptionException
& )
3409 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3412 catch( const container::NoSuchElementException
& )
3414 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3417 catch( const embed::StorageWrappedTargetException
& )
3419 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3422 catch( const io::IOException
& )
3424 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3427 catch( const uno::RuntimeException
& )
3429 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3432 catch( const uno::Exception
& )
3434 uno::Any
aCaught( ::cppu::getCaughtException() );
3435 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3437 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't get raw stream!",
3438 uno::Reference
< io::XInputStream
>(),
3445 void SAL_CALL
OStorage::insertRawEncrStreamElement( const OUString
& aStreamName
,
3446 const uno::Reference
< io::XInputStream
>& xInStream
)
3448 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3452 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3453 throw lang::DisposedException( THROW_WHERE
);
3456 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
3457 throw embed::InvalidStorageException( THROW_WHERE
);
3459 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
3460 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
3462 if ( !xInStream
.is() )
3463 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
3465 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
) )
3466 throw io::IOException( THROW_WHERE
); // TODO: access denied
3470 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aStreamName
);
3472 throw container::ElementExistException( THROW_WHERE
);
3474 m_pImpl
->InsertRawStream( aStreamName
, xInStream
);
3476 catch( const embed::InvalidStorageException
& )
3478 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3481 catch( const lang::IllegalArgumentException
& )
3483 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3486 catch( const packages::NoRawFormatException
& )
3488 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3491 catch( const container::ElementExistException
& )
3493 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3496 catch( const embed::StorageWrappedTargetException
& )
3498 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3501 catch( const io::IOException
& )
3503 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3506 catch( const uno::RuntimeException
& )
3508 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3511 catch( const uno::Exception
& )
3513 uno::Any
aCaught( ::cppu::getCaughtException() );
3514 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3516 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't insert raw stream!",
3517 uno::Reference
< io::XInputStream
>(),
3522 // XTransactedObject
3523 void SAL_CALL
OStorage::commit()
3525 uno::Reference
< util::XModifiable
> xParentModif
;
3528 BroadcastTransaction( STOR_MESS_PRECOMMIT
);
3530 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3534 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3535 throw lang::DisposedException( THROW_WHERE
);
3538 if ( m_bReadOnlyWrap
)
3539 throw io::IOException( THROW_WHERE
); // TODO: access_denied
3541 m_pImpl
->Commit(); // the root storage initiates the storing to source
3543 // when the storage is committed the parent is modified
3544 if ( m_pImpl
->m_pParent
&& m_pImpl
->m_pParent
->m_pAntiImpl
)
3545 xParentModif
= static_cast<util::XModifiable
*>(m_pImpl
->m_pParent
->m_pAntiImpl
);
3547 catch( const io::IOException
& )
3549 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3552 catch( const embed::StorageWrappedTargetException
& )
3554 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3557 catch( const uno::RuntimeException
& )
3559 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3562 catch( const uno::Exception
& )
3564 uno::Any
aCaught( ::cppu::getCaughtException() );
3565 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3567 throw embed::StorageWrappedTargetException( THROW_WHERE
"Problems on commit!",
3568 static_cast< ::cppu::OWeakObject
* >( this ),
3572 setModified( false );
3573 if ( xParentModif
.is() )
3574 xParentModif
->setModified( true );
3576 BroadcastTransaction( STOR_MESS_COMMITTED
);
3579 void SAL_CALL
OStorage::revert()
3581 // the method removes all the changes done after last commit
3583 BroadcastTransaction( STOR_MESS_PREREVERT
);
3586 osl::MutexGuard
aGuard(m_xSharedMutex
->GetMutex());
3590 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3591 throw lang::DisposedException(THROW_WHERE
);
3594 for (const auto & rPair
: m_pImpl
->m_aChildrenMap
)
3595 for (auto pElement
: rPair
.second
)
3597 bool bThrow
= (pElement
->m_xStorage
3598 && (pElement
->m_xStorage
->m_pAntiImpl
3599 || !pElement
->m_xStorage
->m_aReadOnlyWrapVector
.empty()))
3600 || (pElement
->m_xStream
3601 && (pElement
->m_xStream
->m_pAntiImpl
3602 || !pElement
->m_xStream
->m_aInputStreamsVector
.empty()));
3604 throw io::IOException(THROW_WHERE
); // TODO: access denied
3607 if (m_bReadOnlyWrap
|| !m_pImpl
->m_bListCreated
)
3608 return; // nothing to do
3613 m_pImpl
->m_bIsModified
= false;
3614 m_pImpl
->m_bBroadcastModified
= true;
3616 catch (const io::IOException
&)
3618 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3621 catch (const embed::StorageWrappedTargetException
&)
3623 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3626 catch (const uno::RuntimeException
&)
3628 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3631 catch (const uno::Exception
&)
3633 uno::Any
aCaught(::cppu::getCaughtException());
3634 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3636 throw embed::StorageWrappedTargetException(THROW_WHERE
"Problems on revert!",
3637 static_cast<::cppu::OWeakObject
*>(this),
3642 setModified( false );
3643 BroadcastTransaction( STOR_MESS_REVERTED
);
3646 // XTransactionBroadcaster
3647 void SAL_CALL
OStorage::addTransactionListener( const uno::Reference
< embed::XTransactionListener
>& aListener
)
3649 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3653 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3654 throw lang::DisposedException( THROW_WHERE
);
3657 m_aListenersContainer
.addInterface( cppu::UnoType
<embed::XTransactionListener
>::get(),
3661 void SAL_CALL
OStorage::removeTransactionListener( const uno::Reference
< embed::XTransactionListener
>& aListener
)
3663 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3667 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3668 throw lang::DisposedException( THROW_WHERE
);
3671 m_aListenersContainer
.removeInterface( cppu::UnoType
<embed::XTransactionListener
>::get(),
3676 // TODO: if there will be no demand on this interface it will be removed from implementation,
3677 // I do not want to remove it now since it is still possible that it will be inserted
3678 // to the service back.
3680 sal_Bool SAL_CALL
OStorage::isModified()
3682 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3686 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3687 throw lang::DisposedException( THROW_WHERE
);
3690 return m_pImpl
->m_bIsModified
;
3693 void SAL_CALL
OStorage::setModified( sal_Bool bModified
)
3696 osl::MutexGuard
aGuard(m_xSharedMutex
->GetMutex());
3700 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3701 throw lang::DisposedException(THROW_WHERE
);
3704 if (m_bReadOnlyWrap
)
3705 throw beans::PropertyVetoException(THROW_WHERE
); // TODO: access denied
3707 if (m_pImpl
->m_bIsModified
!= bool(bModified
))
3708 m_pImpl
->m_bIsModified
= bModified
;
3713 m_pImpl
->m_bBroadcastModified
= true;
3714 BroadcastModifiedIfNecessary();
3718 void SAL_CALL
OStorage::addModifyListener(
3719 const uno::Reference
< util::XModifyListener
>& aListener
)
3721 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3725 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3726 throw lang::DisposedException( THROW_WHERE
);
3729 osl_atomic_increment( &m_pImpl
->m_nModifiedListenerCount
);
3730 m_aListenersContainer
.addInterface(
3731 cppu::UnoType
<util::XModifyListener
>::get(), aListener
);
3734 void SAL_CALL
OStorage::removeModifyListener(
3735 const uno::Reference
< util::XModifyListener
>& aListener
)
3737 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3741 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3742 throw lang::DisposedException( THROW_WHERE
);
3745 osl_atomic_decrement( &m_pImpl
->m_nModifiedListenerCount
);
3746 m_aListenersContainer
.removeInterface(
3747 cppu::UnoType
<util::XModifyListener
>::get(), aListener
);
3752 uno::Any SAL_CALL
OStorage::getByName( const OUString
& aName
)
3754 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3758 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3759 throw lang::DisposedException( THROW_WHERE
);
3762 if ( aName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aName
, false ) )
3763 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
3765 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aName
== "_rels" )
3766 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable element name
3771 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aName
);
3773 throw container::NoSuchElementException( THROW_WHERE
);
3775 if ( pElement
->m_bIsStorage
)
3776 aResult
<<= openStorageElement( aName
, embed::ElementModes::READ
);
3778 aResult
<<= openStreamElement( aName
, embed::ElementModes::READ
);
3780 catch( const container::NoSuchElementException
& )
3782 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3785 catch( const lang::WrappedTargetException
& )
3787 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3790 catch( const uno::RuntimeException
& )
3792 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3795 catch( const uno::Exception
& )
3797 uno::Any
aCaught( ::cppu::getCaughtException() );
3798 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3800 throw lang::WrappedTargetException( THROW_WHERE
"Can not open storage!",
3801 static_cast< OWeakObject
* >( this ),
3808 uno::Sequence
< OUString
> SAL_CALL
OStorage::getElementNames()
3810 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3814 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3815 throw lang::DisposedException( THROW_WHERE
);
3820 return m_pImpl
->GetElementNames();
3822 catch( const uno::RuntimeException
& )
3824 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3827 catch ( const uno::Exception
& )
3829 uno::Any
aCaught( ::cppu::getCaughtException() );
3830 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3832 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open storage!",
3833 static_cast< OWeakObject
* >( this ),
3838 sal_Bool SAL_CALL
OStorage::hasByName( const OUString
& aName
)
3840 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3844 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3845 throw lang::DisposedException( THROW_WHERE
);
3848 if ( aName
.isEmpty() )
3851 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aName
== "_rels" )
3854 SotElement_Impl
* pElement
= nullptr;
3857 pElement
= m_pImpl
->FindElement( aName
);
3859 catch( const uno::RuntimeException
& )
3861 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3864 catch ( const uno::Exception
& )
3866 uno::Any
aCaught( ::cppu::getCaughtException() );
3867 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3869 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open storage!",
3870 static_cast< OWeakObject
* >( this ),
3874 return ( pElement
!= nullptr );
3877 uno::Type SAL_CALL
OStorage::getElementType()
3879 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3883 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3884 throw lang::DisposedException( THROW_WHERE
);
3887 // it is a multitype container
3891 sal_Bool SAL_CALL
OStorage::hasElements()
3893 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3897 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3898 throw lang::DisposedException( THROW_WHERE
);
3903 return m_pImpl
->HasChildren();
3905 catch( const uno::RuntimeException
& )
3907 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3910 catch( const uno::Exception
& )
3912 uno::Any
aCaught( ::cppu::getCaughtException() );
3913 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3915 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open storage!",
3916 static_cast< OWeakObject
* >( this ),
3922 void SAL_CALL
OStorage::dispose()
3924 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3928 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3929 throw lang::DisposedException( THROW_WHERE
);
3934 InternalDispose( true );
3936 catch( const uno::RuntimeException
& )
3938 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3941 catch( const uno::Exception
& )
3943 uno::Any
aCaught( ::cppu::getCaughtException() );
3944 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3946 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open storage!",
3947 static_cast< OWeakObject
* >( this ),
3952 void SAL_CALL
OStorage::addEventListener(
3953 const uno::Reference
< lang::XEventListener
>& xListener
)
3955 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3959 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3960 throw lang::DisposedException( THROW_WHERE
);
3963 m_aListenersContainer
.addInterface(
3964 cppu::UnoType
<lang::XEventListener
>::get(), xListener
);
3967 void SAL_CALL
OStorage::removeEventListener(
3968 const uno::Reference
< lang::XEventListener
>& xListener
)
3970 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3974 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3975 throw lang::DisposedException( THROW_WHERE
);
3978 m_aListenersContainer
.removeInterface(
3979 cppu::UnoType
<lang::XEventListener
>::get(), xListener
);
3982 // XEncryptionProtectedSource
3984 void SAL_CALL
OStorage::setEncryptionPassword( const OUString
& aPass
)
3986 setEncryptionData( ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass
) );
3989 void SAL_CALL
OStorage::removeEncryption()
3991 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
3995 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3996 throw lang::DisposedException( THROW_WHERE
);
3999 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4000 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4002 SAL_WARN_IF( !m_pImpl
->m_bIsRoot
, "package.xstor", "removeEncryption() method is not available for nonroot storages!" );
4003 if ( !m_pImpl
->m_bIsRoot
)
4007 m_pImpl
->ReadContents();
4009 catch ( const uno::RuntimeException
& )
4011 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4014 catch ( const uno::Exception
& )
4016 uno::Any
aCaught( ::cppu::getCaughtException() );
4017 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4019 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4020 static_cast< OWeakObject
* >( this ),
4024 // TODO: check if the password is valid
4025 // update all streams that was encrypted with old password
4027 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4030 xPackPropSet
->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY
,
4031 uno::Any( uno::Sequence
< beans::NamedValue
>() ) );
4033 m_pImpl
->m_bHasCommonEncryptionData
= false;
4034 m_pImpl
->m_aCommonEncryptionData
.clear();
4036 catch( const uno::RuntimeException
& )
4038 TOOLS_WARN_EXCEPTION( "package.xstor", "The call must not fail, it is pretty simple!" );
4041 catch( const uno::Exception
& )
4043 TOOLS_WARN_EXCEPTION( "package.xstor", "The call must not fail, it is pretty simple!" );
4044 throw io::IOException( THROW_WHERE
);
4048 // XEncryptionProtectedSource2
4050 void SAL_CALL
OStorage::setEncryptionData( const uno::Sequence
< beans::NamedValue
>& aEncryptionData
)
4052 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4056 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4057 throw lang::DisposedException( THROW_WHERE
);
4060 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4061 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4063 if ( !aEncryptionData
.hasElements() )
4064 throw uno::RuntimeException( THROW_WHERE
"Unexpected empty encryption data!" );
4066 SAL_WARN_IF( !m_pImpl
->m_bIsRoot
, "package.xstor", "setEncryptionData() method is not available for nonroot storages!" );
4067 if ( !m_pImpl
->m_bIsRoot
)
4071 m_pImpl
->ReadContents();
4073 catch ( const uno::RuntimeException
& )
4075 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4078 catch ( const uno::Exception
& )
4080 uno::Any
aCaught( ::cppu::getCaughtException() );
4081 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4083 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4084 static_cast< OWeakObject
* >( this ),
4088 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4091 ::comphelper::SequenceAsHashMap
aEncryptionMap( aEncryptionData
);
4092 xPackPropSet
->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY
,
4093 uno::Any( aEncryptionMap
.getAsConstNamedValueList() ) );
4095 m_pImpl
->m_bHasCommonEncryptionData
= true;
4096 m_pImpl
->m_aCommonEncryptionData
= aEncryptionMap
;
4098 catch( const uno::Exception
& )
4100 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:" );
4102 throw io::IOException( THROW_WHERE
);
4106 sal_Bool SAL_CALL
OStorage::hasEncryptionData()
4108 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4110 return m_pImpl
&& m_pImpl
->m_bHasCommonEncryptionData
;
4113 // XEncryptionProtectedStorage
4115 void SAL_CALL
OStorage::setEncryptionAlgorithms( const uno::Sequence
< beans::NamedValue
>& aAlgorithms
)
4117 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4121 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4122 throw lang::DisposedException( THROW_WHERE
);
4125 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4126 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4128 if ( !aAlgorithms
.hasElements() )
4129 throw uno::RuntimeException( THROW_WHERE
"Unexpected empty encryption algorithms list!" );
4131 SAL_WARN_IF( !m_pImpl
->m_bIsRoot
, "package.xstor", "setEncryptionAlgorithms() method is not available for nonroot storages!" );
4132 if ( !m_pImpl
->m_bIsRoot
)
4136 m_pImpl
->ReadContents();
4138 catch ( const uno::RuntimeException
& )
4140 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4143 catch ( const uno::Exception
& )
4145 uno::Any
aCaught( ::cppu::getCaughtException() );
4146 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4148 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4149 static_cast< OWeakObject
* >( this ),
4153 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4156 xPackPropSet
->setPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY
,
4157 uno::Any( aAlgorithms
) );
4159 catch ( const uno::RuntimeException
& )
4161 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4164 catch( const uno::Exception
& )
4166 uno::Any
aCaught( ::cppu::getCaughtException() );
4167 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4169 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4170 static_cast< OWeakObject
* >( this ),
4175 void SAL_CALL
OStorage::setGpgProperties( const uno::Sequence
< uno::Sequence
< beans::NamedValue
> >& aProps
)
4177 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4181 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4182 throw lang::DisposedException( THROW_WHERE
);
4185 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4186 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4188 if ( !aProps
.hasElements() )
4189 throw uno::RuntimeException( THROW_WHERE
"Unexpected empty encryption algorithms list!" );
4191 SAL_WARN_IF( !m_pImpl
->m_bIsRoot
, "package.xstor", "setGpgProperties() method is not available for nonroot storages!" );
4192 if ( !m_pImpl
->m_bIsRoot
)
4196 m_pImpl
->ReadContents();
4198 catch ( const uno::RuntimeException
& aRuntimeException
)
4200 SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException
.Message
);
4203 catch ( const uno::Exception
& )
4205 uno::Any
aCaught( ::cppu::getCaughtException() );
4206 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4208 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4209 static_cast< OWeakObject
* >( this ),
4213 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4216 xPackPropSet
->setPropertyValue( ENCRYPTION_GPG_PROPERTIES
,
4217 uno::Any( aProps
) );
4219 catch ( const uno::RuntimeException
& aRuntimeException
)
4221 SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException
.Message
);
4224 catch( const uno::Exception
& )
4226 uno::Any
aCaught( ::cppu::getCaughtException() );
4227 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4229 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4230 static_cast< OWeakObject
* >( this ),
4235 uno::Sequence
< beans::NamedValue
> SAL_CALL
OStorage::getEncryptionAlgorithms()
4237 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4241 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4242 throw lang::DisposedException( THROW_WHERE
);
4245 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4246 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4248 uno::Sequence
< beans::NamedValue
> aResult
;
4249 SAL_WARN_IF( !m_pImpl
->m_bIsRoot
, "package.xstor", "getEncryptionAlgorithms() method is not available for nonroot storages!" );
4250 if ( m_pImpl
->m_bIsRoot
)
4253 m_pImpl
->ReadContents();
4255 catch ( const uno::RuntimeException
& )
4257 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4260 catch ( const uno::Exception
& )
4262 uno::Any
aCaught( ::cppu::getCaughtException() );
4263 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4265 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4266 static_cast< OWeakObject
* >( this ),
4270 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4273 xPackPropSet
->getPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY
) >>= aResult
;
4275 catch ( const uno::RuntimeException
& )
4277 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4280 catch( const uno::Exception
& )
4282 uno::Any
aCaught( ::cppu::getCaughtException() );
4283 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4285 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4286 static_cast< OWeakObject
* >( this ),
4296 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
OStorage::getPropertySetInfo()
4298 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4302 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4303 throw lang::DisposedException( THROW_WHERE
);
4307 return uno::Reference
< beans::XPropertySetInfo
>();
4310 void SAL_CALL
OStorage::setPropertyValue( const OUString
& aPropertyName
, const uno::Any
& aValue
)
4312 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4316 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4317 throw lang::DisposedException( THROW_WHERE
);
4320 //TODO: think about interaction handler
4323 // The old document might have no version in the manifest.xml, so we have to allow to set the version
4324 // even for readonly storages, so that the version from content.xml can be used.
4325 if ( m_bReadOnlyWrap
&& aPropertyName
!= "Version" )
4326 throw uno::RuntimeException( THROW_WHERE
); // TODO: Access denied
4328 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::ZIP
)
4329 throw beans::UnknownPropertyException( aPropertyName
);
4330 else if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::PACKAGE
)
4332 if ( aPropertyName
== "MediaType" )
4334 aValue
>>= m_pImpl
->m_aMediaType
;
4335 m_pImpl
->m_bControlMediaType
= true;
4337 m_pImpl
->m_bBroadcastModified
= true;
4338 m_pImpl
->m_bIsModified
= true;
4340 else if ( aPropertyName
== "Version" )
4342 aValue
>>= m_pImpl
->m_aVersion
;
4343 m_pImpl
->m_bControlVersion
= true;
4345 // this property can be set even for readonly storage
4346 if ( !m_bReadOnlyWrap
)
4348 m_pImpl
->m_bBroadcastModified
= true;
4349 m_pImpl
->m_bIsModified
= true;
4352 else if ( ( m_pImpl
->m_bIsRoot
&& ( aPropertyName
== HAS_ENCRYPTED_ENTRIES_PROPERTY
4353 || aPropertyName
== HAS_NONENCRYPTED_ENTRIES_PROPERTY
4354 || aPropertyName
== IS_INCONSISTENT_PROPERTY
4355 || aPropertyName
== "URL"
4356 || aPropertyName
== "RepairPackage"
4357 || aPropertyName
== ENCRYPTION_GPG_PROPERTIES
) )
4358 || aPropertyName
== "IsRoot"
4359 || aPropertyName
== MEDIATYPE_FALLBACK_USED_PROPERTY
)
4360 throw beans::PropertyVetoException( THROW_WHERE
);
4362 throw beans::UnknownPropertyException( aPropertyName
);
4364 else if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
)
4366 if ( aPropertyName
== "RelationsInfoStream" )
4368 uno::Reference
< io::XInputStream
> xInRelStream
;
4369 if ( !( aValue
>>= xInRelStream
) || !xInRelStream
.is() )
4370 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
4372 uno::Reference
< io::XSeekable
> xSeek( xInRelStream
, uno::UNO_QUERY
);
4375 // currently this is an internal property that is used for optimization
4376 // and the stream must support XSeekable interface
4377 // TODO/LATER: in future it can be changed if property is used from outside
4378 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
4381 m_pImpl
->m_xNewRelInfoStream
= xInRelStream
;
4382 m_pImpl
->m_aRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
4383 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED_STREAM
;
4384 m_pImpl
->m_bBroadcastModified
= true;
4385 m_pImpl
->m_bIsModified
= true;
4387 else if ( aPropertyName
== "RelationsInfo" )
4389 if ( !(aValue
>>= m_pImpl
->m_aRelInfo
) )
4390 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
4392 m_pImpl
->m_xNewRelInfoStream
.clear();
4393 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4394 m_pImpl
->m_bBroadcastModified
= true;
4395 m_pImpl
->m_bIsModified
= true;
4397 else if ( ( m_pImpl
->m_bIsRoot
&& ( aPropertyName
== "URL" || aPropertyName
== "RepairPackage") )
4398 || aPropertyName
== "IsRoot" )
4399 throw beans::PropertyVetoException( THROW_WHERE
);
4401 throw beans::UnknownPropertyException( aPropertyName
);
4404 throw beans::UnknownPropertyException( aPropertyName
);
4406 BroadcastModifiedIfNecessary();
4409 uno::Any SAL_CALL
OStorage::getPropertyValue( const OUString
& aPropertyName
)
4411 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4415 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4416 throw lang::DisposedException( THROW_WHERE
);
4419 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::PACKAGE
4420 && ( aPropertyName
== "MediaType" || aPropertyName
== MEDIATYPE_FALLBACK_USED_PROPERTY
|| aPropertyName
== "Version" ) )
4424 m_pImpl
->ReadContents();
4426 catch ( const uno::RuntimeException
& )
4428 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4431 catch ( const uno::Exception
& )
4433 uno::Any
aCaught( ::cppu::getCaughtException() );
4434 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4436 throw lang::WrappedTargetException(
4437 "Can't read contents!",
4438 static_cast< OWeakObject
* >( this ),
4442 if ( aPropertyName
== "MediaType" )
4443 return uno::Any( m_pImpl
->m_aMediaType
);
4444 else if ( aPropertyName
== "Version" )
4445 return uno::Any( m_pImpl
->m_aVersion
);
4447 return uno::Any( m_pImpl
->m_bMTFallbackUsed
);
4449 else if ( aPropertyName
== "IsRoot" )
4451 return uno::Any( m_pImpl
->m_bIsRoot
);
4453 else if ( aPropertyName
== "OpenMode" )
4455 return uno::Any( m_pImpl
->m_nStorageMode
);
4457 else if ( m_pImpl
->m_bIsRoot
)
4459 if ( aPropertyName
== "URL"
4460 || aPropertyName
== "RepairPackage" )
4462 auto pProp
= std::find_if(std::cbegin(m_pImpl
->m_xProperties
), std::cend(m_pImpl
->m_xProperties
),
4463 [&aPropertyName
](const css::beans::PropertyValue
& rProp
) { return rProp
.Name
== aPropertyName
; });
4464 if (pProp
!= std::cend(m_pImpl
->m_xProperties
))
4465 return pProp
->Value
;
4467 if ( aPropertyName
== "URL" )
4468 return uno::Any( OUString() );
4470 return uno::Any( false ); // RepairPackage
4472 else if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::PACKAGE
4473 && ( aPropertyName
== HAS_ENCRYPTED_ENTRIES_PROPERTY
4474 || aPropertyName
== HAS_NONENCRYPTED_ENTRIES_PROPERTY
4475 || aPropertyName
== ENCRYPTION_GPG_PROPERTIES
4476 || aPropertyName
== IS_INCONSISTENT_PROPERTY
) )
4479 m_pImpl
->ReadContents();
4480 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4481 return xPackPropSet
->getPropertyValue( aPropertyName
);
4483 catch ( const uno::RuntimeException
& )
4485 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4488 catch ( const uno::Exception
& )
4490 uno::Any
aCaught( ::cppu::getCaughtException() );
4491 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4493 throw lang::WrappedTargetException( THROW_WHERE
"Can not open package!",
4494 static_cast< OWeakObject
* >( this ),
4500 throw beans::UnknownPropertyException(aPropertyName
);
4503 void SAL_CALL
OStorage::addPropertyChangeListener(
4504 const OUString
& /*aPropertyName*/,
4505 const uno::Reference
< beans::XPropertyChangeListener
>& /*xListener*/ )
4507 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4511 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4512 throw lang::DisposedException( THROW_WHERE
);
4518 void SAL_CALL
OStorage::removePropertyChangeListener(
4519 const OUString
& /*aPropertyName*/,
4520 const uno::Reference
< beans::XPropertyChangeListener
>& /*aListener*/ )
4522 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4526 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4527 throw lang::DisposedException( THROW_WHERE
);
4533 void SAL_CALL
OStorage::addVetoableChangeListener(
4534 const OUString
& /*PropertyName*/,
4535 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
4537 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4541 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4542 throw lang::DisposedException( THROW_WHERE
);
4548 void SAL_CALL
OStorage::removeVetoableChangeListener(
4549 const OUString
& /*PropertyName*/,
4550 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
4552 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4556 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4557 throw lang::DisposedException( THROW_WHERE
);
4563 // XRelationshipAccess
4565 // TODO/LATER: the storage and stream implementations of this interface are very similar, they could use a helper class
4567 sal_Bool SAL_CALL
OStorage::hasByID( const OUString
& sID
)
4569 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4573 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4574 throw lang::DisposedException( THROW_WHERE
);
4577 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4578 throw uno::RuntimeException( THROW_WHERE
);
4582 getRelationshipByID( sID
);
4585 catch( const container::NoSuchElementException
& )
4587 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4596 const beans::StringPair
* lcl_findPairByName(const uno::Sequence
<beans::StringPair
>& rSeq
, const OUString
& rName
)
4598 return std::find_if(rSeq
.begin(), rSeq
.end(), [&rName
](const beans::StringPair
& rPair
) { return rPair
.First
== rName
; });
4603 OUString SAL_CALL
OStorage::getTargetByID( const OUString
& sID
)
4605 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4609 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4610 throw lang::DisposedException( THROW_WHERE
);
4613 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4614 throw uno::RuntimeException( THROW_WHERE
);
4616 const uno::Sequence
< beans::StringPair
> aSeq
= getRelationshipByID( sID
);
4617 auto pRel
= lcl_findPairByName(aSeq
, "Target");
4618 if (pRel
!= aSeq
.end())
4619 return pRel
->Second
;
4624 OUString SAL_CALL
OStorage::getTypeByID( const OUString
& sID
)
4626 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4630 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4631 throw lang::DisposedException( THROW_WHERE
);
4634 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4635 throw uno::RuntimeException( THROW_WHERE
);
4637 const uno::Sequence
< beans::StringPair
> aSeq
= getRelationshipByID( sID
);
4638 auto pRel
= lcl_findPairByName(aSeq
, "Type");
4639 if (pRel
!= aSeq
.end())
4640 return pRel
->Second
;
4645 uno::Sequence
< beans::StringPair
> SAL_CALL
OStorage::getRelationshipByID( const OUString
& sID
)
4647 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4651 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4652 throw lang::DisposedException( THROW_WHERE
);
4655 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4656 throw uno::RuntimeException( THROW_WHERE
);
4658 // TODO/LATER: in future the unification of the ID could be checked
4659 const uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4660 const beans::StringPair
aIDRel("Id", sID
);
4662 auto pRel
= std::find_if(aSeq
.begin(), aSeq
.end(),
4663 [&aIDRel
](const uno::Sequence
<beans::StringPair
>& rRel
) {
4664 return std::find(rRel
.begin(), rRel
.end(), aIDRel
) != rRel
.end(); });
4665 if (pRel
!= aSeq
.end())
4668 throw container::NoSuchElementException( THROW_WHERE
);
4671 uno::Sequence
< uno::Sequence
< beans::StringPair
> > SAL_CALL
OStorage::getRelationshipsByType( const OUString
& sType
)
4673 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4677 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4678 throw lang::DisposedException( THROW_WHERE
);
4681 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4682 throw uno::RuntimeException( THROW_WHERE
);
4684 // TODO/LATER: in future the unification of the ID could be checked
4685 const uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4686 std::vector
< uno::Sequence
< beans::StringPair
> > aResult
;
4687 aResult
.reserve(aSeq
.getLength());
4689 std::copy_if(aSeq
.begin(), aSeq
.end(), std::back_inserter(aResult
),
4690 [&sType
](const uno::Sequence
<beans::StringPair
>& rRel
) {
4691 auto pRel
= lcl_findPairByName(rRel
, "Type");
4692 return pRel
!= rRel
.end()
4693 // the type is usually a URL, so the check should be case insensitive
4694 && pRel
->Second
.equalsIgnoreAsciiCase( sType
);
4697 return comphelper::containerToSequence(aResult
);
4700 uno::Sequence
< uno::Sequence
< beans::StringPair
> > SAL_CALL
OStorage::getAllRelationships()
4702 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4706 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4707 throw lang::DisposedException( THROW_WHERE
);
4710 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4711 throw uno::RuntimeException( THROW_WHERE
);
4713 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aRet
;
4716 aRet
= m_pImpl
->GetAllRelationshipsIfAny();
4718 catch (const io::IOException
&)
4722 catch (const uno::RuntimeException
&)
4726 catch (const uno::Exception
&)
4728 uno::Any
aCaught( ::cppu::getCaughtException() );
4729 throw lang::WrappedTargetRuntimeException(THROW_WHERE
"Can't getAllRelationships!",
4730 uno::Reference
< uno::XInterface
>(),
4737 void SAL_CALL
OStorage::insertRelationshipByID( const OUString
& sID
, const uno::Sequence
< beans::StringPair
>& aEntry
, sal_Bool bReplace
)
4739 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4743 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4744 throw lang::DisposedException( THROW_WHERE
);
4747 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4748 throw uno::RuntimeException( THROW_WHERE
);
4750 const beans::StringPair
aIDRel("Id", sID
);
4752 uno::Sequence
<beans::StringPair
>* pResult
= nullptr;
4754 // TODO/LATER: in future the unification of the ID could be checked
4755 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4756 for ( sal_Int32 nInd
= 0; nInd
< aSeq
.getLength(); nInd
++ )
4758 const auto& rRel
= aSeq
[nInd
];
4759 if (std::find(rRel
.begin(), rRel
.end(), aIDRel
) != rRel
.end())
4760 pResult
= &aSeq
.getArray()[nInd
];
4763 if ( pResult
&& !bReplace
)
4764 throw container::ElementExistException( THROW_WHERE
);
4768 const sal_Int32 nIDInd
= aSeq
.getLength();
4769 aSeq
.realloc( nIDInd
+ 1 );
4770 pResult
= &aSeq
.getArray()[nIDInd
];
4773 std::vector
<beans::StringPair
> aResult
;
4774 aResult
.reserve(aEntry
.getLength() + 1);
4776 aResult
.push_back(aIDRel
);
4777 std::copy_if(aEntry
.begin(), aEntry
.end(), std::back_inserter(aResult
),
4778 [](const beans::StringPair
& rPair
) { return rPair
.First
!= "Id"; });
4780 *pResult
= comphelper::containerToSequence(aResult
);
4782 m_pImpl
->m_aRelInfo
= aSeq
;
4783 m_pImpl
->m_xNewRelInfoStream
.clear();
4784 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4787 void SAL_CALL
OStorage::removeRelationshipByID( const OUString
& sID
)
4789 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4793 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4794 throw lang::DisposedException( THROW_WHERE
);
4797 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4798 throw uno::RuntimeException( THROW_WHERE
);
4800 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4801 const beans::StringPair
aIDRel("Id", sID
);
4802 auto pRel
= std::find_if(std::cbegin(aSeq
), std::cend(aSeq
),
4803 [&aIDRel
](const uno::Sequence
< beans::StringPair
>& rRel
) {
4804 return std::find(rRel
.begin(), rRel
.end(), aIDRel
) != rRel
.end(); });
4805 if (pRel
!= std::cend(aSeq
))
4807 auto nInd
= static_cast<sal_Int32
>(std::distance(std::cbegin(aSeq
), pRel
));
4808 comphelper::removeElementAt(aSeq
, nInd
);
4810 m_pImpl
->m_aRelInfo
= aSeq
;
4811 m_pImpl
->m_xNewRelInfoStream
.clear();
4812 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4814 // TODO/LATER: in future the unification of the ID could be checked
4818 throw container::NoSuchElementException( THROW_WHERE
);
4821 void SAL_CALL
OStorage::insertRelationships( const uno::Sequence
< uno::Sequence
< beans::StringPair
> >& aEntries
, sal_Bool bReplace
)
4823 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4827 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4828 throw lang::DisposedException( THROW_WHERE
);
4831 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4832 throw uno::RuntimeException( THROW_WHERE
);
4834 OUString
aIDTag( "Id" );
4835 const uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4836 std::vector
< uno::Sequence
<beans::StringPair
> > aResultVec
;
4837 aResultVec
.reserve(aSeq
.getLength() + aEntries
.getLength());
4839 std::copy_if(aSeq
.begin(), aSeq
.end(), std::back_inserter(aResultVec
),
4840 [&aIDTag
, &aEntries
, bReplace
](const uno::Sequence
<beans::StringPair
>& rTargetRel
) {
4841 auto pTargetPair
= lcl_findPairByName(rTargetRel
, aIDTag
);
4842 if (pTargetPair
== rTargetRel
.end())
4845 bool bIsSourceSame
= std::any_of(aEntries
.begin(), aEntries
.end(),
4846 [&pTargetPair
](const uno::Sequence
<beans::StringPair
>& rSourceEntry
) {
4847 return std::find(rSourceEntry
.begin(), rSourceEntry
.end(), *pTargetPair
) != rSourceEntry
.end(); });
4849 if ( bIsSourceSame
&& !bReplace
)
4850 throw container::ElementExistException( THROW_WHERE
);
4852 // if no such element in the provided sequence
4853 return !bIsSourceSame
;
4856 std::transform(aEntries
.begin(), aEntries
.end(), std::back_inserter(aResultVec
),
4857 [&aIDTag
](const uno::Sequence
<beans::StringPair
>& rEntry
) -> uno::Sequence
<beans::StringPair
> {
4858 auto pPair
= lcl_findPairByName(rEntry
, aIDTag
);
4859 if (pPair
== rEntry
.end())
4860 throw io::IOException( THROW_WHERE
); // TODO: illegal relation ( no ID )
4862 auto aResult
= comphelper::sequenceToContainer
<std::vector
<beans::StringPair
>>(rEntry
);
4863 auto nIDInd
= std::distance(rEntry
.begin(), pPair
);
4864 std::rotate(aResult
.begin(), std::next(aResult
.begin(), nIDInd
), std::next(aResult
.begin(), nIDInd
+ 1));
4866 return comphelper::containerToSequence(aResult
);
4869 m_pImpl
->m_aRelInfo
= comphelper::containerToSequence(aResultVec
);
4870 m_pImpl
->m_xNewRelInfoStream
.clear();
4871 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4874 void SAL_CALL
OStorage::clearRelationships()
4876 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4880 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4881 throw lang::DisposedException( THROW_WHERE
);
4884 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4885 throw uno::RuntimeException( THROW_WHERE
);
4887 m_pImpl
->m_aRelInfo
.realloc( 0 );
4888 m_pImpl
->m_xNewRelInfoStream
.clear();
4889 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4892 // XOptimizedStorage
4893 void SAL_CALL
OStorage::insertRawNonEncrStreamElementDirect(
4894 const OUString
& /*sStreamName*/,
4895 const uno::Reference
< io::XInputStream
>& /*xInStream*/ )
4897 // not implemented currently because there is still no demand
4898 // might need to be implemented if direct copying of compressed streams is used
4899 throw io::IOException( THROW_WHERE
);
4902 void SAL_CALL
OStorage::insertStreamElementDirect(
4903 const OUString
& aStreamName
,
4904 const uno::Reference
< io::XInputStream
>& xInStream
,
4905 const uno::Sequence
< beans::PropertyValue
>& aProps
)
4907 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4911 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4912 throw lang::DisposedException( THROW_WHERE
);
4915 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
4916 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
4918 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStreamName
== "_rels" )
4919 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable storage name
4921 if ( m_bReadOnlyWrap
)
4922 throw io::IOException( THROW_WHERE
); // TODO: access denied
4926 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aStreamName
);
4929 throw container::ElementExistException( THROW_WHERE
);
4931 pElement
= OpenStreamElement_Impl( aStreamName
, embed::ElementModes::READWRITE
, false );
4932 OSL_ENSURE(pElement
&& pElement
->m_xStream
, "In case element can not be created an exception must be thrown!");
4934 pElement
->m_xStream
->InsertStreamDirectly(xInStream
, aProps
);
4936 catch( const embed::InvalidStorageException
& )
4938 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4941 catch( const lang::IllegalArgumentException
& )
4943 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4946 catch( const container::ElementExistException
& )
4948 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4951 catch( const embed::StorageWrappedTargetException
& )
4953 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4956 catch( const io::IOException
& )
4958 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4961 catch( const uno::RuntimeException
& )
4963 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4966 catch( const uno::Exception
& )
4968 uno::Any
aCaught( ::cppu::getCaughtException() );
4969 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4971 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't insert stream directly!",
4972 uno::Reference
< io::XInputStream
>(),
4977 void SAL_CALL
OStorage::copyElementDirectlyTo(
4978 const OUString
& aElementName
,
4979 const uno::Reference
< embed::XOptimizedStorage
>& xDest
,
4980 const OUString
& aNewName
)
4982 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
4986 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4987 throw lang::DisposedException( THROW_WHERE
);
4990 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false )
4991 || aNewName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName
, false ) )
4992 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
4994 if ( !xDest
.is() || xDest
== uno::Reference
< uno::XInterface
>( static_cast< OWeakObject
* >( this ), uno::UNO_QUERY
) )
4995 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
4997 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& ( aElementName
== "_rels" || aNewName
== "_rels" ) )
4998 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 ); // unacceptable name
5002 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aElementName
);
5004 throw container::NoSuchElementException( THROW_WHERE
);
5006 uno::Reference
< XNameAccess
> xNameAccess( xDest
, uno::UNO_QUERY_THROW
);
5007 if ( xNameAccess
->hasByName( aNewName
) )
5008 throw container::ElementExistException( THROW_WHERE
);
5010 // let the element be copied directly
5011 uno::Reference
< embed::XStorage
> xStorDest( xDest
, uno::UNO_QUERY_THROW
);
5012 m_pImpl
->CopyStorageElement( pElement
, xStorDest
, aNewName
, true );
5014 catch( const embed::InvalidStorageException
& )
5016 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5019 catch( const lang::IllegalArgumentException
& )
5021 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5024 catch( const container::NoSuchElementException
& )
5026 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5029 catch( const container::ElementExistException
& )
5031 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5034 catch( const embed::StorageWrappedTargetException
& )
5036 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5039 catch( const io::IOException
& )
5041 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5044 catch( const uno::RuntimeException
& )
5046 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5049 catch( const uno::Exception
& )
5051 uno::Any
aCaught( ::cppu::getCaughtException() );
5052 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5054 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy element directly!",
5055 uno::Reference
< io::XInputStream
>(),
5060 void SAL_CALL
OStorage::writeAndAttachToStream( const uno::Reference
< io::XStream
>& xStream
)
5062 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
5066 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5067 throw lang::DisposedException( THROW_WHERE
);
5070 if ( !m_pImpl
->m_bIsRoot
)
5071 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
5073 if ( !m_pImpl
->m_pSwitchStream
)
5074 throw uno::RuntimeException( THROW_WHERE
);
5078 m_pImpl
->m_pSwitchStream
->CopyAndSwitchPersistenceTo( xStream
);
5080 catch( const embed::InvalidStorageException
& )
5082 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5085 catch( const lang::IllegalArgumentException
& )
5087 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5090 catch( const embed::StorageWrappedTargetException
& )
5092 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5095 catch( const io::IOException
& )
5097 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:" );
5100 catch( const uno::RuntimeException
& )
5102 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5105 catch( const uno::Exception
& )
5107 uno::Any
aCaught( ::cppu::getCaughtException() );
5108 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5110 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't write and attach to stream!",
5111 uno::Reference
< io::XInputStream
>(),
5117 void SAL_CALL
OStorage::attachToURL( const OUString
& sURL
,
5118 sal_Bool bReadOnly
)
5120 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
5124 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5125 throw lang::DisposedException( THROW_WHERE
);
5128 if ( !m_pImpl
->m_bIsRoot
)
5129 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
5131 if ( !m_pImpl
->m_pSwitchStream
)
5132 throw uno::RuntimeException( THROW_WHERE
);
5134 uno::Reference
< ucb::XSimpleFileAccess3
> xAccess(
5135 ucb::SimpleFileAccess::create( m_pImpl
->m_xContext
) );
5141 uno::Reference
< io::XInputStream
> xInputStream
= xAccess
->openFileRead( sURL
);
5142 m_pImpl
->m_pSwitchStream
->SwitchPersistenceTo( xInputStream
);
5146 uno::Reference
< io::XStream
> xStream
= xAccess
->openFileReadWrite( sURL
);
5147 m_pImpl
->m_pSwitchStream
->SwitchPersistenceTo( xStream
);
5150 catch( const embed::InvalidStorageException
& )
5152 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5155 catch( const lang::IllegalArgumentException
& )
5157 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5160 catch( const embed::StorageWrappedTargetException
& )
5162 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5165 catch( const io::IOException
& )
5167 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5170 catch( const uno::RuntimeException
& )
5172 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5175 catch( const uno::Exception
& )
5177 uno::Any
aCaught( ::cppu::getCaughtException() );
5178 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5180 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't attach to URL!",
5181 uno::Reference
< io::XInputStream
>(),
5186 uno::Any SAL_CALL
OStorage::getElementPropertyValue( const OUString
& aElementName
, const OUString
& aPropertyName
)
5188 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
5192 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5193 throw lang::DisposedException( THROW_WHERE
);
5196 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false ) )
5197 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5199 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aElementName
== "_rels" )
5200 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // TODO: unacceptable name
5204 SotElement_Impl
*pElement
= m_pImpl
->FindElement( aElementName
);
5206 throw container::NoSuchElementException( THROW_WHERE
);
5208 // TODO/LATER: Currently it is only implemented for MediaType property of substorages, might be changed in future
5209 if ( !pElement
->m_bIsStorage
|| m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
|| aPropertyName
!= "MediaType" )
5210 throw beans::PropertyVetoException( THROW_WHERE
);
5212 if (!pElement
->m_xStorage
)
5213 m_pImpl
->OpenSubStorage( pElement
, embed::ElementModes::READ
);
5215 if (!pElement
->m_xStorage
)
5216 throw io::IOException( THROW_WHERE
); // TODO: general_error
5218 pElement
->m_xStorage
->ReadContents();
5219 return uno::Any(pElement
->m_xStorage
->m_aMediaType
);
5221 catch( const embed::InvalidStorageException
& )
5223 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5226 catch( const lang::IllegalArgumentException
& )
5228 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5231 catch( const container::NoSuchElementException
& )
5233 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5236 catch( const beans::UnknownPropertyException
& )
5238 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5241 catch( const beans::PropertyVetoException
& )
5243 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5246 catch( const embed::StorageWrappedTargetException
& )
5248 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5251 catch( const io::IOException
& )
5253 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5256 catch( const uno::RuntimeException
& )
5258 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5261 catch( const uno::Exception
& )
5263 uno::Any
aCaught( ::cppu::getCaughtException() );
5264 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5266 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't get element property!",
5267 uno::Reference
< io::XInputStream
>(),
5272 void SAL_CALL
OStorage::copyStreamElementData( const OUString
& aStreamName
, const uno::Reference
< io::XStream
>& xTargetStream
)
5274 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
5278 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5279 throw lang::DisposedException( THROW_WHERE
);
5282 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
5283 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5285 if ( m_pImpl
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStreamName
== "_rels" )
5286 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable name
5288 if ( !xTargetStream
.is() )
5289 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
5293 uno::Reference
< io::XStream
> xNonconstRef
= xTargetStream
;
5294 m_pImpl
->CloneStreamElement( aStreamName
, false, ::comphelper::SequenceAsHashMap(), xNonconstRef
);
5296 SAL_WARN_IF( xNonconstRef
!= xTargetStream
, "package.xstor", "The provided stream reference seems not be filled in correctly!" );
5297 if ( xNonconstRef
!= xTargetStream
)
5298 throw uno::RuntimeException( THROW_WHERE
); // if the stream reference is set it must not be changed!
5300 catch( const embed::InvalidStorageException
& )
5302 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5305 catch( const lang::IllegalArgumentException
& )
5307 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5310 catch( const packages::WrongPasswordException
& )
5312 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5315 catch( const io::IOException
& )
5317 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5320 catch( const embed::StorageWrappedTargetException
& )
5322 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5325 catch( const uno::RuntimeException
& )
5327 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5330 catch( const uno::Exception
& )
5332 uno::Any
aCaught( ::cppu::getCaughtException() );
5333 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5335 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy stream data!",
5336 uno::Reference
< io::XInputStream
>(),
5342 // XHierarchicalStorageAccess
5343 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
OStorage::openStreamElementByHierarchicalName( const OUString
& aStreamPath
, ::sal_Int32 nOpenMode
)
5345 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
5349 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5350 throw lang::DisposedException( THROW_WHERE
);
5353 if ( aStreamPath
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath
, true ) )
5354 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5356 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
)
5357 && ( nOpenMode
& embed::ElementModes::WRITE
) )
5358 throw io::IOException( THROW_WHERE
); // Access denied
5360 std::vector
<OUString
> aListPath
= OHierarchyHolder_Impl::GetListPathFromString( aStreamPath
);
5361 OSL_ENSURE( aListPath
.size(), "The result list must not be empty!" );
5363 uno::Reference
< embed::XExtendedStorageStream
> xResult
;
5364 if ( aListPath
.size() == 1 )
5368 // that must be a direct request for a stream
5369 // the transacted version of the stream should be opened
5371 SotElement_Impl
*pElement
= OpenStreamElement_Impl( aStreamPath
, nOpenMode
, false );
5372 assert(pElement
&& pElement
->m_xStream
&& "In case element can not be created an exception must be thrown!");
5374 xResult
.set(pElement
->m_xStream
->GetStream(nOpenMode
, true),
5375 uno::UNO_QUERY_THROW
);
5377 catch ( const container::NoSuchElementException
& )
5379 throw io::IOException( THROW_WHERE
); // file not found
5384 // there are still storages in between
5385 if ( !m_rHierarchyHolder
.is() )
5386 m_rHierarchyHolder
= new OHierarchyHolder_Impl(
5387 uno::Reference
< embed::XStorage
>( static_cast< embed::XStorage
* >( this ) ) );
5389 xResult
= m_rHierarchyHolder
->GetStreamHierarchically(
5390 ( m_pImpl
->m_nStorageMode
& embed::ElementModes::READWRITE
),
5395 if ( !xResult
.is() )
5396 throw uno::RuntimeException( THROW_WHERE
);
5401 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
OStorage::openEncryptedStreamElementByHierarchicalName( const OUString
& aStreamPath
, ::sal_Int32 nOpenMode
, const OUString
& sPassword
)
5403 return openEncryptedStreamByHierarchicalName( aStreamPath
, nOpenMode
, ::comphelper::OStorageHelper::CreatePackageEncryptionData( sPassword
) );
5406 void SAL_CALL
OStorage::removeStreamElementByHierarchicalName( const OUString
& aStreamPath
)
5408 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
5412 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5413 throw lang::DisposedException( THROW_WHERE
);
5416 if ( aStreamPath
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath
, true ) )
5417 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5419 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
) )
5420 throw io::IOException( THROW_WHERE
); // Access denied
5422 std::vector
<OUString
> aListPath
= OHierarchyHolder_Impl::GetListPathFromString( aStreamPath
);
5423 OSL_ENSURE( aListPath
.size(), "The result list must not be empty!" );
5425 if ( !m_rHierarchyHolder
.is() )
5426 m_rHierarchyHolder
= new OHierarchyHolder_Impl(
5427 uno::Reference
< embed::XStorage
>( static_cast< embed::XStorage
* >( this ) ) );
5429 m_rHierarchyHolder
->RemoveStreamHierarchically( aListPath
);
5432 // XHierarchicalStorageAccess2
5433 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
OStorage::openEncryptedStreamByHierarchicalName( const OUString
& aStreamPath
, ::sal_Int32 nOpenMode
, const uno::Sequence
< beans::NamedValue
>& aEncryptionData
)
5435 ::osl::MutexGuard
aGuard( m_xSharedMutex
->GetMutex() );
5439 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5440 throw lang::DisposedException( THROW_WHERE
);
5443 if ( m_pImpl
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
5444 throw packages::NoEncryptionException( THROW_WHERE
);
5446 if ( aStreamPath
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath
, true ) )
5447 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5449 if ( !aEncryptionData
.hasElements() )
5450 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 3 );
5452 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
)
5453 && ( nOpenMode
& embed::ElementModes::WRITE
) )
5454 throw io::IOException( THROW_WHERE
); // Access denied
5456 std::vector
<OUString
> aListPath
= OHierarchyHolder_Impl::GetListPathFromString( aStreamPath
);
5457 OSL_ENSURE( aListPath
.size(), "The result list must not be empty!" );
5459 uno::Reference
< embed::XExtendedStorageStream
> xResult
;
5460 if ( aListPath
.size() == 1 )
5462 // that must be a direct request for a stream
5463 // the transacted version of the stream should be opened
5465 SotElement_Impl
*pElement
= OpenStreamElement_Impl( aStreamPath
, nOpenMode
, true );
5466 OSL_ENSURE(pElement
&& pElement
->m_xStream
, "In case element can not be created an exception must be thrown!");
5468 xResult
.set(pElement
->m_xStream
->GetStream(nOpenMode
, aEncryptionData
, true),
5469 uno::UNO_QUERY_THROW
);
5473 // there are still storages in between
5474 if ( !m_rHierarchyHolder
.is() )
5475 m_rHierarchyHolder
= new OHierarchyHolder_Impl(
5476 uno::Reference
< embed::XStorage
>( static_cast< embed::XStorage
* >( this ) ) );
5478 xResult
= m_rHierarchyHolder
->GetStreamHierarchically(
5479 ( m_pImpl
->m_nStorageMode
& embed::ElementModes::READWRITE
),
5485 if ( !xResult
.is() )
5486 throw uno::RuntimeException( THROW_WHERE
);
5491 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */