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/NoRawFormatException.hpp>
34 #include <com/sun/star/packages/WrongPasswordException.hpp>
35 #include <com/sun/star/ucb/XProgressHandler.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>
42 #include <com/sun/star/util/XCloneable.hpp>
44 #include <com/sun/star/lang/XUnoTunnel.hpp>
45 #include <com/sun/star/lang/XComponent.hpp>
46 #include <com/sun/star/lang/DisposedException.hpp>
47 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
48 #include <com/sun/star/beans/NamedValue.hpp>
50 #include <PackageConstants.hxx>
52 #include <comphelper/sequence.hxx>
53 #include <cppuhelper/queryinterface.hxx>
54 #include <cppuhelper/typeprovider.hxx>
55 #include <cppuhelper/exc_hlp.hxx>
57 #include <comphelper/storagehelper.hxx>
58 #include <comphelper/ofopxmlhelper.hxx>
59 #include <tools/diagnose_ex.h>
61 #include "xstorage.hxx"
62 #include "owriteablestream.hxx"
63 #include "disposelistener.hxx"
64 #include "switchpersistencestream.hxx"
65 #include "ohierarchyholder.hxx"
67 using namespace ::com::sun::star
;
69 #if OSL_DEBUG_LEVEL > 0
70 #define THROW_WHERE SAL_WHERE
72 #define THROW_WHERE ""
75 struct StorInternalData_Impl
77 rtl::Reference
<comphelper::RefCountedMutex
> m_xSharedMutex
;
78 ::cppu::OMultiTypeInterfaceContainerHelper m_aListenersContainer
; // list of listeners
79 ::std::unique_ptr
< ::cppu::OTypeCollection
> m_pTypeCollection
;
81 sal_Int32 m_nStorageType
; // the mode in which the storage is used
84 ::rtl::Reference
<OChildDispListener_Impl
> m_pSubElDispListener
;
86 ::std::vector
< uno::WeakReference
< lang::XComponent
> > m_aOpenSubComponentsVector
;
88 ::rtl::Reference
< OHierarchyHolder_Impl
> m_rHierarchyHolder
;
90 // the mutex reference MUST NOT be empty
91 StorInternalData_Impl( const rtl::Reference
<comphelper::RefCountedMutex
>& rMutexRef
, bool bRoot
, sal_Int32 nStorageType
, bool bReadOnlyWrap
)
92 : m_xSharedMutex( rMutexRef
)
93 , m_aListenersContainer( rMutexRef
->GetMutex() )
96 , m_nStorageType( nStorageType
)
97 , m_bReadOnlyWrap( bReadOnlyWrap
)
98 , m_pSubElDispListener()
103 void OStorage_Impl::completeStorageStreamCopy_Impl(
104 const uno::Reference
< io::XStream
>& xSource
,
105 const uno::Reference
< io::XStream
>& xDest
,
106 sal_Int32 nStorageType
,
107 const uno::Sequence
< uno::Sequence
< beans::StringPair
> >& aRelInfo
)
109 uno::Reference
< beans::XPropertySet
> xSourceProps( xSource
, uno::UNO_QUERY_THROW
);
110 uno::Reference
< beans::XPropertySet
> xDestProps( xDest
, uno::UNO_QUERY_THROW
);
112 uno::Reference
< io::XOutputStream
> xDestOutStream
= xDest
->getOutputStream();
113 if ( !xDestOutStream
.is() )
114 throw io::IOException( THROW_WHERE
);
116 uno::Reference
< io::XInputStream
> xSourceInStream
= xSource
->getInputStream();
117 if ( !xSourceInStream
.is() )
118 throw io::IOException( THROW_WHERE
);
120 // TODO: headers of encrypted streams should be copied also
121 ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInStream
, xDestOutStream
);
123 uno::Sequence
<OUString
> aPropNames
{ "Compressed" };
125 if ( nStorageType
== embed::StorageFormats::PACKAGE
)
127 aPropNames
.realloc( 3 );
128 aPropNames
[1] = "MediaType";
129 aPropNames
[2] = "UseCommonStoragePasswordEncryption";
131 else if ( nStorageType
== embed::StorageFormats::OFOPXML
)
133 // TODO/LATER: in future it might make sense to provide the stream if there is one
134 uno::Reference
< embed::XRelationshipAccess
> xRelAccess( xDest
, uno::UNO_QUERY_THROW
);
135 xRelAccess
->clearRelationships();
136 xRelAccess
->insertRelationships( aRelInfo
, false );
138 aPropNames
.realloc( 2 );
139 aPropNames
[1] = "MediaType";
142 for ( const auto& rPropName
: std::as_const(aPropNames
) )
143 xDestProps
->setPropertyValue( rPropName
, xSourceProps
->getPropertyValue( rPropName
) );
146 static uno::Reference
< io::XInputStream
> GetSeekableTempCopy( const uno::Reference
< io::XInputStream
>& xInStream
,
147 const uno::Reference
< uno::XComponentContext
>& xContext
)
149 uno::Reference
< io::XTempFile
> xTempFile
= io::TempFile::create(xContext
);
150 uno::Reference
< io::XOutputStream
> xTempOut
= xTempFile
->getOutputStream();
151 uno::Reference
< io::XInputStream
> xTempIn
= xTempFile
->getInputStream();
153 if ( !xTempOut
.is() || !xTempIn
.is() )
154 throw io::IOException( THROW_WHERE
);
156 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream
, xTempOut
);
157 xTempOut
->closeOutput();
162 SotElement_Impl::SotElement_Impl(const OUString
& rName
, bool bStor
, bool bNew
)
163 : m_aOriginalName(rName
)
164 , m_bIsRemoved(false)
165 , m_bIsInserted(bNew
)
166 , m_bIsStorage(bStor
)
170 // most of properties are holt by the storage but are not used
171 OStorage_Impl::OStorage_Impl( uno::Reference
< io::XInputStream
> const & xInputStream
,
173 const uno::Sequence
< beans::PropertyValue
>& xProperties
,
174 uno::Reference
< uno::XComponentContext
> const & xContext
,
175 sal_Int32 nStorageType
)
176 : m_xMutex( new comphelper::RefCountedMutex
)
177 , m_pAntiImpl( nullptr )
178 , m_nStorageMode( nMode
& ~embed::ElementModes::SEEKABLE
)
179 , m_bIsModified( ( nMode
& ( embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
) ) == ( embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
) )
180 , m_bBroadcastModified( false )
181 , m_bCommited( false )
183 , m_bListCreated( false )
184 , m_nModifiedListenerCount( 0 )
185 , m_xContext( xContext
)
186 , m_xProperties( xProperties
)
187 , m_bHasCommonEncryptionData( false )
188 , m_pParent( nullptr )
189 , m_bControlMediaType( false )
190 , m_bMTFallbackUsed( false )
191 , m_bControlVersion( false )
192 , m_nStorageType( nStorageType
)
193 , m_pRelStorElement( nullptr )
194 , m_nRelInfoStatus( RELINFO_NO_INIT
)
196 // all the checks done below by assertion statements must be done by factory
197 SAL_WARN_IF( !xInputStream
.is(), "package.xstor", "No input stream is provided!" );
198 assert(xContext
.is());
200 m_pSwitchStream
= new SwitchablePersistenceStream(xContext
, xInputStream
);
201 m_xInputStream
= m_pSwitchStream
->getInputStream();
203 if ( m_nStorageMode
& embed::ElementModes::WRITE
)
205 // check that the stream allows to write
206 SAL_WARN( "package.xstor", "No stream for writing is provided!" );
210 // most of properties are holt by the storage but are not used
211 OStorage_Impl::OStorage_Impl( uno::Reference
< io::XStream
> const & xStream
,
213 const uno::Sequence
< beans::PropertyValue
>& xProperties
,
214 uno::Reference
< uno::XComponentContext
> const & xContext
,
215 sal_Int32 nStorageType
)
216 : m_xMutex( new comphelper::RefCountedMutex
)
217 , m_pAntiImpl( nullptr )
218 , m_nStorageMode( nMode
& ~embed::ElementModes::SEEKABLE
)
219 , m_bIsModified( ( nMode
& ( embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
) ) == ( embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
) )
220 , m_bBroadcastModified( false )
221 , m_bCommited( false )
223 , m_bListCreated( false )
224 , m_nModifiedListenerCount( 0 )
225 , m_xContext( xContext
)
226 , m_xProperties( xProperties
)
227 , m_bHasCommonEncryptionData( false )
228 , m_pParent( nullptr )
229 , m_bControlMediaType( false )
230 , m_bMTFallbackUsed( false )
231 , m_bControlVersion( false )
232 , m_nStorageType( nStorageType
)
233 , m_pRelStorElement( nullptr )
234 , m_nRelInfoStatus( RELINFO_NO_INIT
)
236 // all the checks done below by assertion statements must be done by factory
237 SAL_WARN_IF( !xStream
.is(), "package.xstor", "No stream is provided!" );
238 assert(xContext
.is());
240 if ( m_nStorageMode
& embed::ElementModes::WRITE
)
242 m_pSwitchStream
= new SwitchablePersistenceStream(xContext
, xStream
);
243 m_xStream
= static_cast< io::XStream
* >( m_pSwitchStream
.get() );
247 m_pSwitchStream
= new SwitchablePersistenceStream(xContext
, xStream
->getInputStream());
248 m_xInputStream
= m_pSwitchStream
->getInputStream();
252 OStorage_Impl::OStorage_Impl( OStorage_Impl
* pParent
,
254 uno::Reference
< container::XNameContainer
> const & xPackageFolder
,
255 uno::Reference
< lang::XSingleServiceFactory
> const & xPackage
,
256 uno::Reference
< uno::XComponentContext
> const & xContext
,
257 sal_Int32 nStorageType
)
258 : m_xMutex( new comphelper::RefCountedMutex
)
259 , m_pAntiImpl( nullptr )
260 , m_nStorageMode( nMode
& ~embed::ElementModes::SEEKABLE
)
261 , m_bIsModified( ( nMode
& ( embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
) ) == ( embed::ElementModes::WRITE
| embed::ElementModes::TRUNCATE
) )
262 , m_bBroadcastModified( false )
263 , m_bCommited( false )
265 , m_bListCreated( false )
266 , m_nModifiedListenerCount( 0 )
267 , m_xPackageFolder( xPackageFolder
)
268 , m_xPackage( xPackage
)
269 , m_xContext( xContext
)
270 , m_bHasCommonEncryptionData( false )
271 , m_pParent( pParent
) // can be empty in case of temporary readonly substorages and relation storage
272 , m_bControlMediaType( false )
273 , m_bMTFallbackUsed( false )
274 , m_bControlVersion( false )
275 , m_nStorageType( nStorageType
)
276 , m_pRelStorElement( nullptr )
277 , m_nRelInfoStatus( RELINFO_NO_INIT
)
279 SAL_WARN_IF( !xPackageFolder
.is(), "package.xstor", "No package folder!" );
280 assert(xContext
.is());
283 OStorage_Impl::~OStorage_Impl()
286 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
287 if ( m_pAntiImpl
) // root storage wrapper must set this member to NULL before destruction of object
289 SAL_WARN_IF( m_bIsRoot
, "package.xstor", "The root storage wrapper must be disposed already" );
292 m_pAntiImpl
->InternalDispose( false );
294 catch ( const uno::Exception
& )
296 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
298 m_pAntiImpl
= nullptr;
300 else if ( !m_aReadOnlyWrapVector
.empty() )
302 for ( auto& rStorage
: m_aReadOnlyWrapVector
)
304 uno::Reference
< embed::XStorage
> xTmp
= rStorage
.m_xWeakRef
;
307 rStorage
.m_pPointer
->InternalDispose( false );
308 } catch( const uno::Exception
& )
310 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
314 m_aReadOnlyWrapVector
.clear();
320 for (const auto & pair
: m_aChildrenMap
)
321 for (auto pElement
: pair
.second
)
323 m_aChildrenMap
.clear();
325 std::for_each(m_aDeletedVector
.begin(), m_aDeletedVector
.end(), std::default_delete
<SotElement_Impl
>());
326 m_aDeletedVector
.clear();
328 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& m_pRelStorElement
)
330 delete m_pRelStorElement
;
331 m_pRelStorElement
= nullptr;
334 m_xPackageFolder
.clear();
337 OUString aPropertyName
= "URL";
338 for ( const auto& rProp
: std::as_const(m_xProperties
) )
340 if ( rProp
.Name
== aPropertyName
)
342 // the storage is URL based so all the streams are opened by factory and should be closed
345 if ( m_xInputStream
.is() )
347 m_xInputStream
->closeInput();
348 m_xInputStream
.clear();
351 if ( m_xStream
.is() )
353 uno::Reference
< io::XInputStream
> xInStr
= m_xStream
->getInputStream();
355 xInStr
->closeInput();
357 uno::Reference
< io::XOutputStream
> xOutStr
= m_xStream
->getOutputStream();
359 xOutStr
->closeOutput();
364 catch (const uno::Exception
&)
366 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
372 void OStorage_Impl::SetReadOnlyWrap( OStorage
& aStorage
)
374 // Weak reference is used inside the holder so the refcount must not be zero at this point
375 OSL_ENSURE( aStorage
.GetRefCount_Impl(), "There must be a reference alive to use this method!" );
376 m_aReadOnlyWrapVector
.emplace_back( &aStorage
);
379 void OStorage_Impl::RemoveReadOnlyWrap( OStorage
& aStorage
)
381 for ( StorageHoldersType::iterator pStorageIter
= m_aReadOnlyWrapVector
.begin();
382 pStorageIter
!= m_aReadOnlyWrapVector
.end();)
384 uno::Reference
< embed::XStorage
> xTmp
= pStorageIter
->m_xWeakRef
;
385 if ( !xTmp
.is() || pStorageIter
->m_pPointer
== &aStorage
)
388 pStorageIter
->m_pPointer
->InternalDispose( false );
389 } catch( const uno::Exception
& )
391 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
394 pStorageIter
= m_aReadOnlyWrapVector
.erase(pStorageIter
);
401 void OStorage_Impl::OpenOwnPackage()
403 SAL_WARN_IF( !m_bIsRoot
, "package.xstor", "Opening of the package has no sense!" );
405 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
407 if ( !m_xPackageFolder
.is() )
409 if ( !m_xPackage
.is() )
411 uno::Sequence
< uno::Any
> aArguments( 2 );
412 if ( m_nStorageMode
& embed::ElementModes::WRITE
)
413 aArguments
[ 0 ] <<= m_xStream
;
416 SAL_WARN_IF( !m_xInputStream
.is(), "package.xstor", "Input stream must be set for readonly access!" );
417 aArguments
[ 0 ] <<= m_xInputStream
;
418 // TODO: if input stream is not seekable or XSeekable interface is supported
419 // on XStream object a wrapper must be used
422 // do not allow elements to remove themself from the old container in case of insertion to another container
423 aArguments
[ 1 ] <<= beans::NamedValue( "AllowRemoveOnInsert",
424 uno::makeAny( false ) );
426 sal_Int32 nArgNum
= 2;
427 for ( const auto& rProp
: std::as_const(m_xProperties
) )
429 if ( rProp
.Name
== "RepairPackage"
430 || rProp
.Name
== "ProgressHandler"
431 || rProp
.Name
== "NoFileSync" )
433 // Forward these to the package.
434 beans::NamedValue
aNamedValue( rProp
.Name
, rProp
.Value
);
435 aArguments
.realloc( ++nArgNum
);
436 aArguments
[nArgNum
-1] <<= aNamedValue
;
438 else if ( rProp
.Name
== "Password" )
440 // TODO: implement password setting for documents
441 // the password entry must be removed after setting
445 if ( m_nStorageType
== embed::StorageFormats::ZIP
)
447 // let the package support only plain zip format
448 beans::NamedValue aNamedValue
;
449 aNamedValue
.Name
= "StorageFormat";
450 aNamedValue
.Value
<<= OUString( "ZipFormat" );
451 aArguments
.realloc( ++nArgNum
);
452 aArguments
[nArgNum
-1] <<= aNamedValue
;
454 else if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
456 // let the package support OFOPXML media type handling
457 beans::NamedValue aNamedValue
;
458 aNamedValue
.Name
= "StorageFormat";
459 aNamedValue
.Value
<<= OUString( "OFOPXMLFormat" );
460 aArguments
.realloc( ++nArgNum
);
461 aArguments
[nArgNum
-1] <<= aNamedValue
;
464 m_xPackage
.set( m_xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(
465 "com.sun.star.packages.comp.ZipPackage", aArguments
, m_xContext
),
469 uno::Reference
< container::XHierarchicalNameAccess
> xHNameAccess( m_xPackage
, uno::UNO_QUERY
);
470 SAL_WARN_IF( !xHNameAccess
.is(), "package.xstor", "The package could not be created!" );
472 if ( xHNameAccess
.is() )
474 uno::Any aFolder
= xHNameAccess
->getByHierarchicalName("/");
475 aFolder
>>= m_xPackageFolder
;
479 SAL_WARN_IF( !m_xPackageFolder
.is(), "package.xstor", "The package root folder can not be opened!" );
480 if ( !m_xPackageFolder
.is() )
481 throw embed::InvalidStorageException( THROW_WHERE
);
484 bool OStorage_Impl::HasChildren()
486 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
489 return !m_aChildrenMap
.empty();
492 void OStorage_Impl::GetStorageProperties()
494 if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
)
497 uno::Reference
< beans::XPropertySet
> xProps( m_xPackageFolder
, uno::UNO_QUERY_THROW
);
499 if ( !m_bControlMediaType
)
501 uno::Reference
< beans::XPropertySet
> xPackageProps( m_xPackage
, uno::UNO_QUERY_THROW
);
502 xPackageProps
->getPropertyValue( MEDIATYPE_FALLBACK_USED_PROPERTY
) >>= m_bMTFallbackUsed
;
504 xProps
->getPropertyValue( "MediaType" ) >>= m_aMediaType
;
505 m_bControlMediaType
= true;
508 if ( !m_bControlVersion
)
510 xProps
->getPropertyValue( "Version" ) >>= m_aVersion
;
511 m_bControlVersion
= true;
514 // the properties of OFOPXML will be handled directly
517 void OStorage_Impl::ReadRelInfoIfNecessary()
519 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
522 if ( m_nRelInfoStatus
== RELINFO_NO_INIT
)
524 // Init from original stream
525 uno::Reference
< io::XInputStream
> xRelInfoStream
526 = GetRelInfoStreamForName( std::u16string_view() );
529 if ( xRelInfoStream
.is() )
530 m_aRelInfo
= ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
534 m_nRelInfoStatus
= RELINFO_READ
;
536 catch (css::uno::Exception
&)
538 TOOLS_INFO_EXCEPTION("package.xstor", "");
541 else if ( m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
543 // Init from the new stream
546 if ( m_xNewRelInfoStream
.is() )
547 m_aRelInfo
= ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
552 m_nRelInfoStatus
= RELINFO_CHANGED_STREAM_READ
;
554 catch( const uno::Exception
& )
556 m_nRelInfoStatus
= RELINFO_CHANGED_BROKEN
;
561 void OStorage_Impl::ReadContents()
563 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
565 if ( m_bListCreated
)
571 uno::Reference
< container::XEnumerationAccess
> xEnumAccess( m_xPackageFolder
, uno::UNO_QUERY_THROW
);
572 uno::Reference
< container::XEnumeration
> xEnum
= xEnumAccess
->createEnumeration();
574 throw uno::RuntimeException( THROW_WHERE
);
576 m_bListCreated
= true;
578 while( xEnum
->hasMoreElements() )
581 uno::Reference
< container::XNamed
> xNamed
;
582 xEnum
->nextElement() >>= xNamed
;
586 SAL_WARN( "package.xstor", "XNamed is not supported!" );
587 throw uno::RuntimeException( THROW_WHERE
);
590 OUString aName
= xNamed
->getName();
591 SAL_WARN_IF( aName
.isEmpty(), "package.xstor", "Empty name!" );
593 uno::Reference
< container::XNameContainer
> xNameContainer( xNamed
, uno::UNO_QUERY
);
595 std::unique_ptr
<SotElement_Impl
> xNewElement(new SotElement_Impl(aName
, xNameContainer
.is(), false));
596 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& aName
== "_rels" )
598 if (!xNewElement
->m_bIsStorage
)
599 throw io::IOException( THROW_WHERE
); // TODO: Unexpected format
601 m_pRelStorElement
= xNewElement
.release();
606 if ( ( m_nStorageMode
& embed::ElementModes::TRUNCATE
) == embed::ElementModes::TRUNCATE
)
608 // if a storage is truncated all of it elements are marked as deleted
609 xNewElement
->m_bIsRemoved
= true;
612 m_aChildrenMap
[aName
].push_back(xNewElement
.release());
615 catch( const container::NoSuchElementException
& )
617 TOOLS_WARN_EXCEPTION( "package.xstor", "hasMoreElements() implementation has problems!");
621 if ( ( m_nStorageMode
& embed::ElementModes::TRUNCATE
) == embed::ElementModes::TRUNCATE
)
623 // if a storage is truncated the relations information should be cleaned
624 m_xNewRelInfoStream
.clear();
625 m_aRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
626 m_nRelInfoStatus
= RELINFO_CHANGED
;
629 // cache changeable folder properties
630 GetStorageProperties();
633 void OStorage_Impl::CopyToStorage( const uno::Reference
< embed::XStorage
>& xDest
, bool bDirect
)
635 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
637 uno::Reference
< beans::XPropertySet
> xPropSet( xDest
, uno::UNO_QUERY
);
638 if ( !xPropSet
.is() )
639 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 );
641 sal_Int32 nDestMode
= embed::ElementModes::READ
;
642 xPropSet
->getPropertyValue( "OpenMode" ) >>= nDestMode
;
644 if ( !( nDestMode
& embed::ElementModes::WRITE
) )
645 throw io::IOException( THROW_WHERE
); // TODO: access_denied
649 if ( !m_xPackageFolder
.is() )
650 throw embed::InvalidStorageException( THROW_WHERE
);
652 for ( const auto& pair
: m_aChildrenMap
)
653 for (auto pElement
: pair
.second
)
655 if ( !pElement
->m_bIsRemoved
)
656 CopyStorageElement( pElement
, xDest
, /*aName*/pair
.first
, bDirect
);
659 // move storage properties to the destination one ( means changeable properties )
660 if ( m_nStorageType
== embed::StorageFormats::PACKAGE
)
662 xPropSet
->setPropertyValue( "MediaType", uno::makeAny( m_aMediaType
) );
663 xPropSet
->setPropertyValue( "Version", uno::makeAny( m_aVersion
) );
666 if ( m_nStorageType
== embed::StorageFormats::PACKAGE
)
668 // if this is a root storage, the common key from current one should be moved there
669 bool bIsRoot
= false;
670 if ( ( xPropSet
->getPropertyValue( "IsRoot" ) >>= bIsRoot
) && bIsRoot
)
674 uno::Reference
< embed::XEncryptionProtectedStorage
> xEncr( xDest
, uno::UNO_QUERY
);
677 xEncr
->setEncryptionData( GetCommonRootEncryptionData().getAsConstNamedValueList() );
679 uno::Sequence
< beans::NamedValue
> aAlgorithms
;
680 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_xPackage
, uno::UNO_QUERY_THROW
);
681 xPackPropSet
->getPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY
)
683 xEncr
->setEncryptionAlgorithms( aAlgorithms
);
686 catch( const packages::NoEncryptionException
& )
688 TOOLS_INFO_EXCEPTION("package.xstor", "No Encryption");
692 else if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
695 // TODO/LATER: currently the optimization is not active
696 // uno::Reference< io::XInputStream > xRelInfoStream = GetRelInfoStreamForName( OUString() ); // own stream
697 // if ( xRelInfoStream.is() )
699 // // Relations info stream is a writeonly property, introduced only to optimize copying
700 // // Should be used carefully since no check for stream consistency is done, and the stream must not stay locked
702 // OUString aRelInfoString = "RelationsInfoStream";
703 // xPropSet->setPropertyValue( aRelInfoString, uno::makeAny( GetSeekableTempCopy( xRelInfoStream, m_xFactory ) ) );
706 uno::Reference
< embed::XRelationshipAccess
> xRels( xDest
, uno::UNO_QUERY
);
708 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 );
710 xRels
->insertRelationships( GetAllRelationshipsIfAny(), false );
713 // if possible the destination storage should be committed after successful copying
714 uno::Reference
< embed::XTransactedObject
> xObjToCommit( xDest
, uno::UNO_QUERY
);
715 if ( xObjToCommit
.is() )
716 xObjToCommit
->commit();
719 void OStorage_Impl::CopyStorageElement( SotElement_Impl
* pElement
,
720 const uno::Reference
< embed::XStorage
>& xDest
,
721 const OUString
& aName
,
724 SAL_WARN_IF( !xDest
.is(), "package.xstor", "No destination storage!" );
725 SAL_WARN_IF( aName
.isEmpty(), "package.xstor", "Empty element name!" );
727 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
729 uno::Reference
< container::XNameAccess
> xDestAccess( xDest
, uno::UNO_QUERY_THROW
);
730 if ( xDestAccess
->hasByName( aName
)
731 && !( pElement
->m_bIsStorage
&& xDest
->isStorageElement( aName
) ) )
732 xDest
->removeElement( aName
);
734 if ( pElement
->m_bIsStorage
)
736 uno::Reference
< embed::XStorage
> xSubDest
=
737 xDest
->openStorageElement( aName
,
738 embed::ElementModes::WRITE
);
740 SAL_WARN_IF( !xSubDest
.is(), "package.xstor", "No destination substorage!" );
742 if (!pElement
->m_xStorage
)
744 OpenSubStorage( pElement
, embed::ElementModes::READ
);
745 if (!pElement
->m_xStorage
)
746 throw io::IOException( THROW_WHERE
);
749 pElement
->m_xStorage
->CopyToStorage(xSubDest
, bDirect
);
753 if (!pElement
->m_xStream
)
755 OpenSubStream( pElement
);
756 if (!pElement
->m_xStream
)
757 throw io::IOException( THROW_WHERE
);
760 if (!pElement
->m_xStream
->IsEncrypted())
764 // fill in the properties for the stream
765 uno::Sequence
< beans::PropertyValue
> aStrProps(0);
766 const uno::Sequence
< beans::PropertyValue
> aSrcPkgProps
= pElement
->m_xStream
->GetStreamProperties();
768 for ( const auto& rSrcPkgProp
: aSrcPkgProps
)
770 if ( rSrcPkgProp
.Name
== "MediaType" || rSrcPkgProp
.Name
== "Compressed" )
772 aStrProps
.realloc( ++nNum
);
773 aStrProps
[nNum
-1].Name
= rSrcPkgProp
.Name
;
774 aStrProps
[nNum
-1].Value
= rSrcPkgProp
.Value
;
778 if ( m_nStorageType
== embed::StorageFormats::PACKAGE
)
780 aStrProps
.realloc( ++nNum
);
781 aStrProps
[nNum
-1].Name
= "UseCommonStoragePasswordEncryption";
782 aStrProps
[nNum
-1].Value
<<= pElement
->m_xStream
->UsesCommonEncryption_Impl();
784 else if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
786 // TODO/LATER: currently the optimization is not active
787 // uno::Reference< io::XInputStream > xInStream = GetRelInfoStreamForName( OUString() ); // own rels stream
788 // if ( xInStream.is() )
790 // aStrProps.realloc( ++nNum );
791 // aStrProps[nNum-1].Name = "RelationsInfoStream";
792 // aStrProps[nNum-1].Value <<= GetSeekableTempCopy( xInStream, m_xFactory );
795 uno::Reference
< embed::XRelationshipAccess
> xRels( xDest
, uno::UNO_QUERY
);
797 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
799 xRels
->insertRelationships( GetAllRelationshipsIfAny(), false );
802 uno::Reference
< embed::XOptimizedStorage
> xOptDest( xDest
, uno::UNO_QUERY_THROW
);
803 uno::Reference
< io::XInputStream
> xInputToInsert
;
805 if (pElement
->m_xStream
->HasTempFile_Impl() || !pElement
->m_xStream
->m_xPackageStream
.is())
807 SAL_WARN_IF(!pElement
->m_xStream
->m_xPackageStream
.is(), "package.xstor", "No package stream!");
809 // if the stream is modified - the temporary file must be used for insertion
810 xInputToInsert
= pElement
->m_xStream
->GetTempFileAsInputStream();
814 // for now get just nonseekable access to the stream
815 // TODO/LATER: the raw stream can be used
817 xInputToInsert
= pElement
->m_xStream
->m_xPackageStream
->getDataStream();
820 if ( !xInputToInsert
.is() )
821 throw io::IOException( THROW_WHERE
);
823 xOptDest
->insertStreamElementDirect( aName
, xInputToInsert
, aStrProps
);
827 uno::Reference
< io::XStream
> xSubStr
=
828 xDest
->openStreamElement( aName
,
829 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
830 SAL_WARN_IF( !xSubStr
.is(), "package.xstor", "No destination substream!" );
832 pElement
->m_xStream
->CopyInternallyTo_Impl(xSubStr
);
835 else if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
)
837 SAL_WARN( "package.xstor", "Encryption is only supported in package storage!" );
838 throw io::IOException( THROW_WHERE
);
840 else if ( pElement
->m_xStream
->HasCachedEncryptionData()
841 && ( pElement
->m_xStream
->IsModified() || pElement
->m_xStream
->HasWriteOwner_Impl() ) )
843 ::comphelper::SequenceAsHashMap aCommonEncryptionData
;
844 bool bHasCommonEncryptionData
= false;
847 aCommonEncryptionData
= GetCommonRootEncryptionData();
848 bHasCommonEncryptionData
= true;
850 catch( const packages::NoEncryptionException
& )
852 TOOLS_INFO_EXCEPTION("package.xstor", "No Encryption");
855 if (bHasCommonEncryptionData
&& ::package::PackageEncryptionDataLessOrEqual(pElement
->m_xStream
->GetCachedEncryptionData(), aCommonEncryptionData
))
857 // If the stream can be opened with the common storage password
858 // it must be stored with the common storage password as well
859 uno::Reference
< io::XStream
> xDestStream
=
860 xDest
->openStreamElement( aName
,
861 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
863 pElement
->m_xStream
->CopyInternallyTo_Impl( xDestStream
);
865 uno::Reference
< beans::XPropertySet
> xProps( xDestStream
, uno::UNO_QUERY_THROW
);
866 xProps
->setPropertyValue(
867 "UseCommonStoragePasswordEncryption",
872 // the stream is already opened for writing or was changed
873 uno::Reference
< embed::XStorage2
> xDest2( xDest
, uno::UNO_QUERY_THROW
);
874 uno::Reference
< io::XStream
> xSubStr
=
875 xDest2
->openEncryptedStream( aName
,
876 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
,
877 pElement
->m_xStream
->GetCachedEncryptionData().getAsConstNamedValueList() );
878 SAL_WARN_IF( !xSubStr
.is(), "package.xstor", "No destination substream!" );
880 pElement
->m_xStream
->CopyInternallyTo_Impl(xSubStr
, pElement
->m_xStream
->GetCachedEncryptionData());
885 // the stream is not opened at all, so it can be just opened for reading
888 // If the stream can be opened with the common storage password
889 // it must be stored with the common storage password as well
891 uno::Reference
< io::XStream
> xOwnStream
= pElement
->m_xStream
->GetStream(embed::ElementModes::READ
,
893 uno::Reference
< io::XStream
> xDestStream
=
894 xDest
->openStreamElement( aName
,
895 embed::ElementModes::READWRITE
| embed::ElementModes::TRUNCATE
);
896 SAL_WARN_IF( !xDestStream
.is(), "package.xstor", "No destination substream!" );
897 completeStorageStreamCopy_Impl( xOwnStream
, xDestStream
, m_nStorageType
, GetAllRelationshipsIfAny() );
899 uno::Reference
< beans::XPropertySet
> xProps( xDestStream
, uno::UNO_QUERY_THROW
);
900 xProps
->setPropertyValue(
901 "UseCommonStoragePasswordEncryption",
904 catch( const packages::WrongPasswordException
& )
906 TOOLS_INFO_EXCEPTION("package.xstor", "Handled exception");
908 // If the common storage password does not allow to open the stream
909 // it could be copied in raw way, the problem is that the StartKey should be the same
910 // in the ODF1.2 package, so an invalid package could be produced if the stream
911 // is copied from ODF1.1 package, where it is allowed to have different StartKeys
912 uno::Reference
< embed::XStorageRawAccess
> xRawDest( xDest
, uno::UNO_QUERY_THROW
);
913 uno::Reference
< io::XInputStream
> xRawInStream
= pElement
->m_xStream
->GetRawInStream();
914 xRawDest
->insertRawEncrStreamElement( aName
, xRawInStream
);
920 uno::Sequence
< uno::Sequence
< beans::StringPair
> > OStorage_Impl::GetAllRelationshipsIfAny()
922 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
923 return uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
925 ReadRelInfoIfNecessary();
927 if ( m_nRelInfoStatus
!= RELINFO_READ
928 && m_nRelInfoStatus
!= RELINFO_CHANGED_STREAM_READ
929 && m_nRelInfoStatus
!= RELINFO_CHANGED
)
930 throw io::IOException( THROW_WHERE
"Wrong relinfo stream!" );
931 // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
935 void OStorage_Impl::CopyLastCommitTo( const uno::Reference
< embed::XStorage
>& xNewStor
)
937 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
939 SAL_WARN_IF( !m_xPackageFolder
.is(), "package.xstor", "A committed storage is incomplete!" );
940 if ( !m_xPackageFolder
.is() )
941 throw uno::RuntimeException( THROW_WHERE
);
943 OStorage_Impl
aTempRepresent( nullptr,
944 embed::ElementModes::READ
,
950 // TODO/LATER: could use direct copying
951 aTempRepresent
.CopyToStorage( xNewStor
, false );
954 void OStorage_Impl::InsertIntoPackageFolder( const OUString
& aName
,
955 const uno::Reference
< container::XNameContainer
>& xParentPackageFolder
)
957 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
959 SAL_WARN_IF( !m_xPackageFolder
.is(), "package.xstor", "An inserted storage is incomplete!" );
960 uno::Reference
< lang::XUnoTunnel
> xTunnel( m_xPackageFolder
, uno::UNO_QUERY_THROW
);
961 xParentPackageFolder
->insertByName( aName
, uno::makeAny( xTunnel
) );
966 void OStorage_Impl::Commit()
968 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
970 if ( !m_bIsModified
)
973 // in case of a new empty storage it is possible that the contents are still not read
974 // ( the storage of course has no contents, but the initialization is postponed till the first use,
975 // thus if a new storage was created and committed immediately it must be initialized here )
978 // if storage is committed it should have a valid Package representation
979 SAL_WARN_IF( !m_xPackageFolder
.is(), "package.xstor", "The package representation should exist!" );
980 if ( !m_xPackageFolder
.is() )
981 throw embed::InvalidStorageException( THROW_WHERE
);
983 OSL_ENSURE( m_nStorageMode
& embed::ElementModes::WRITE
,
984 "Commit of readonly storage, should be detected before!" );
986 uno::Reference
< container::XNameContainer
> xNewPackageFolder
;
988 // here the storage will switch to the temporary package folder
989 // if the storage was already committed and the parent was not committed after that
990 // the switch should not be done since the package folder in use is a temporary one;
991 // it can be detected by m_bCommited flag ( root storage doesn't need temporary representation )
992 if ( !m_bCommited
&& !m_bIsRoot
)
994 uno::Sequence
< uno::Any
> aSeq( 1 );
997 xNewPackageFolder
.set( m_xPackage
->createInstanceWithArguments( aSeq
),
1001 xNewPackageFolder
= m_xPackageFolder
;
1003 // remove replaced removed elements
1004 for ( auto& pDeleted
: m_aDeletedVector
)
1007 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& !pDeleted
->m_bIsStorage
)
1008 RemoveStreamRelInfo( pDeleted
->m_aOriginalName
);
1010 // the removed elements are not in new temporary storage
1011 if ( m_bCommited
|| m_bIsRoot
)
1012 xNewPackageFolder
->removeByName( pDeleted
->m_aOriginalName
);
1016 m_aDeletedVector
.clear();
1018 // remove removed elements
1019 for (auto mapIt
= m_aChildrenMap
.begin(); mapIt
!= m_aChildrenMap
.end(); )
1021 for (auto it
= mapIt
->second
.begin(); it
!= mapIt
->second
.end(); )
1023 // renamed and inserted elements must be really inserted to package later
1024 // since they can conflict with removed elements
1025 auto & pElement
= *it
;
1026 if ( pElement
->m_bIsRemoved
)
1028 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& !pElement
->m_bIsStorage
)
1029 RemoveStreamRelInfo( pElement
->m_aOriginalName
);
1031 // the removed elements are not in new temporary storage
1032 if ( m_bCommited
|| m_bIsRoot
)
1033 xNewPackageFolder
->removeByName( pElement
->m_aOriginalName
);
1036 it
= mapIt
->second
.erase(it
);
1041 if (mapIt
->second
.empty())
1042 mapIt
= m_aChildrenMap
.erase(mapIt
);
1048 // there should be no more deleted elements
1049 for ( const auto& pair
: m_aChildrenMap
)
1050 for (auto pElement
: pair
.second
)
1052 // if it is a 'duplicate commit' inserted elements must be really inserted to package later
1053 // since they can conflict with renamed elements
1054 if ( !pElement
->m_bIsInserted
)
1056 // for now stream is opened in direct mode that means that in case
1057 // storage is committed all the streams from it are committed in current state.
1058 // following two steps are separated to allow easily implement transacted mode
1059 // for streams if we need it in future.
1060 // Only hierarchical access uses transacted streams currently
1061 if ( !pElement
->m_bIsStorage
&& pElement
->m_xStream
1062 && !pElement
->m_xStream
->IsTransacted() )
1063 pElement
->m_xStream
->Commit();
1065 // if the storage was not open, there is no need to commit it ???
1066 // the storage should be checked that it is committed
1067 if (pElement
->m_bIsStorage
&& pElement
->m_xStorage
&& pElement
->m_xStorage
->m_bCommited
)
1069 // it's temporary PackageFolder should be inserted instead of current one
1070 // also the new copy of PackageFolder should be used by the children storages
1072 // the renamed elements are not in new temporary storage
1073 if ( m_bCommited
|| m_bIsRoot
)
1074 xNewPackageFolder
->removeByName( pElement
->m_aOriginalName
);
1076 pElement
->m_xStorage
->InsertIntoPackageFolder(/*aName*/pair
.first
, xNewPackageFolder
);
1078 else if (!pElement
->m_bIsStorage
&& pElement
->m_xStream
&& pElement
->m_xStream
->m_bFlushed
)
1080 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1081 CommitStreamRelInfo( /*aName*/pair
.first
, pElement
);
1083 // the renamed elements are not in new temporary storage
1084 if ( m_bCommited
|| m_bIsRoot
)
1085 xNewPackageFolder
->removeByName( pElement
->m_aOriginalName
);
1087 pElement
->m_xStream
->InsertIntoPackageFolder(/*aName*/pair
.first
, xNewPackageFolder
);
1089 else if ( !m_bCommited
&& !m_bIsRoot
)
1091 // the element must be just copied to the new temporary package folder
1092 // the connection with the original package should not be lost just because
1093 // the element is still referred by the folder in the original hierarchy
1094 uno::Any aPackageElement
= m_xPackageFolder
->getByName( pElement
->m_aOriginalName
);
1095 xNewPackageFolder
->insertByName( /*aName*/pair
.first
, aPackageElement
);
1097 else if ( pair
.first
!= pElement
->m_aOriginalName
)
1099 // this is the case when xNewPackageFolder refers to m_xPackageFolder
1100 // in case the name was changed and it is not a changed storage - rename the element
1101 uno::Any aPackageElement
= xNewPackageFolder
->getByName( pElement
->m_aOriginalName
);
1102 xNewPackageFolder
->removeByName( pElement
->m_aOriginalName
);
1103 xNewPackageFolder
->insertByName( /*aName*/pair
.first
, aPackageElement
);
1105 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& !pElement
->m_bIsStorage
)
1107 if (!pElement
->m_xStream
)
1109 OpenSubStream( pElement
);
1110 if (!pElement
->m_xStream
)
1111 throw uno::RuntimeException( THROW_WHERE
);
1114 CommitStreamRelInfo( /*aName*/pair
.first
, pElement
);
1118 pElement
->m_aOriginalName
= pair
.first
;
1122 for ( const auto& pair
: m_aChildrenMap
)
1123 for (auto pElement
: pair
.second
)
1125 // now inserted elements can be inserted to the package
1126 if ( pElement
->m_bIsInserted
)
1128 pElement
->m_aOriginalName
= pair
.first
;
1130 if ( pElement
->m_bIsStorage
)
1132 if (pElement
->m_xStorage
->m_bCommited
)
1134 OSL_ENSURE(pElement
->m_xStorage
, "An inserted storage is incomplete!");
1135 if (!pElement
->m_xStorage
)
1136 throw uno::RuntimeException( THROW_WHERE
);
1138 pElement
->m_xStorage
->InsertIntoPackageFolder(/*aName*/pair
.first
, xNewPackageFolder
);
1140 pElement
->m_bIsInserted
= false;
1145 OSL_ENSURE(pElement
->m_xStream
, "An inserted stream is incomplete!");
1146 if (!pElement
->m_xStream
)
1147 throw uno::RuntimeException( THROW_WHERE
);
1149 if (!pElement
->m_xStream
->IsTransacted())
1150 pElement
->m_xStream
->Commit();
1152 if (pElement
->m_xStream
->m_bFlushed
)
1154 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1155 CommitStreamRelInfo( /*aName*/pair
.first
, pElement
);
1157 pElement
->m_xStream
->InsertIntoPackageFolder( /*aName*/pair
.first
, xNewPackageFolder
);
1159 pElement
->m_bIsInserted
= false;
1165 if ( m_nStorageType
== embed::StorageFormats::PACKAGE
)
1167 // move properties to the destination package folder
1168 uno::Reference
< beans::XPropertySet
> xProps( xNewPackageFolder
, uno::UNO_QUERY_THROW
);
1169 xProps
->setPropertyValue( "MediaType", uno::makeAny( m_aMediaType
) );
1170 xProps
->setPropertyValue( "Version", uno::makeAny( m_aVersion
) );
1173 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1174 CommitRelInfo( xNewPackageFolder
); // store own relations and commit complete relations storage
1178 uno::Reference
< util::XChangesBatch
> xChangesBatch( m_xPackage
, uno::UNO_QUERY_THROW
);
1181 xChangesBatch
->commitChanges();
1183 catch( const lang::WrappedTargetException
& r
)
1185 css::uno::Any
ex( cppu::getCaughtException() );
1186 // the wrapped UseBackupException means that the target medium can be corrupted
1187 embed::UseBackupException aException
;
1188 if ( r
.TargetException
>>= aException
)
1191 m_xInputStream
.clear();
1195 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(ex
));
1199 else if ( !m_bCommited
)
1201 m_xPackageFolder
= xNewPackageFolder
;
1205 // after commit the mediatype treated as the correct one
1206 m_bMTFallbackUsed
= false;
1209 void OStorage_Impl::Revert()
1211 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1213 if ( !( m_nStorageMode
& embed::ElementModes::WRITE
) )
1214 return; // nothing to do
1216 // all the children must be removed
1217 // they will be created later on demand
1219 // rebuild the map - cannot do it in-place, because we're changing some of the key values
1220 std::unordered_map
<OUString
, std::vector
<SotElement_Impl
*>> oldMap
;
1221 std::swap(oldMap
, m_aChildrenMap
);
1223 for (const auto & rPair
: oldMap
)
1224 for (auto pElement
: rPair
.second
)
1226 if ( pElement
->m_bIsInserted
)
1230 ClearElement( pElement
);
1232 pElement
->m_bIsRemoved
= false;
1234 m_aChildrenMap
[pElement
->m_aOriginalName
].push_back(pElement
);
1238 // return replaced removed elements
1239 for ( auto& pDeleted
: m_aDeletedVector
)
1241 m_aChildrenMap
[pDeleted
->m_aOriginalName
].push_back(pDeleted
);
1243 ClearElement( pDeleted
);
1245 pDeleted
->m_bIsRemoved
= false;
1247 m_aDeletedVector
.clear();
1249 m_bControlMediaType
= false;
1250 m_bControlVersion
= false;
1252 GetStorageProperties();
1254 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1256 // currently the relations storage is changed only on commit
1257 m_xNewRelInfoStream
.clear();
1258 m_aRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
1259 m_nRelInfoStatus
= RELINFO_NO_INIT
;
1263 ::comphelper::SequenceAsHashMap
OStorage_Impl::GetCommonRootEncryptionData()
1265 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() ) ;
1267 if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
)
1268 throw packages::NoEncryptionException( THROW_WHERE
);
1272 if ( !m_bHasCommonEncryptionData
)
1273 throw packages::NoEncryptionException( THROW_WHERE
);
1275 return m_aCommonEncryptionData
;
1280 throw packages::NoEncryptionException( THROW_WHERE
);
1282 return m_pParent
->GetCommonRootEncryptionData();
1286 SotElement_Impl
* OStorage_Impl::FindElement( const OUString
& rName
)
1288 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1290 SAL_WARN_IF( rName
.isEmpty(), "package.xstor", "Name is empty!" );
1294 auto mapIt
= m_aChildrenMap
.find(rName
);
1295 if (mapIt
== m_aChildrenMap
.end())
1297 for (auto pElement
: mapIt
->second
)
1298 if (!pElement
->m_bIsRemoved
)
1304 SotElement_Impl
* OStorage_Impl::InsertStream( const OUString
& aName
, bool bEncr
)
1306 SAL_WARN_IF( !m_xPackage
.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1307 if ( !m_xPackage
.is() )
1308 throw embed::InvalidStorageException( THROW_WHERE
);
1310 uno::Sequence
< uno::Any
> aSeq( 1 );
1312 uno::Reference
< lang::XUnoTunnel
> xNewElement( m_xPackage
->createInstanceWithArguments( aSeq
),
1315 SAL_WARN_IF( !xNewElement
.is(), "package.xstor", "Not possible to create a new stream!" );
1316 if ( !xNewElement
.is() )
1317 throw io::IOException( THROW_WHERE
);
1319 uno::Reference
< packages::XDataSinkEncrSupport
> xPackageSubStream( xNewElement
, uno::UNO_QUERY_THROW
);
1321 OSL_ENSURE( m_nStorageType
== embed::StorageFormats::PACKAGE
|| !bEncr
, "Only package storage supports encryption!" );
1322 if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
&& bEncr
)
1323 throw packages::NoEncryptionException( THROW_WHERE
);
1325 // the mode is not needed for storage stream internal implementation
1326 SotElement_Impl
* pNewElement
= InsertElement( aName
, false );
1327 pNewElement
->m_xStream
.reset(new OWriteStream_Impl(this, xPackageSubStream
, m_xPackage
, m_xContext
, bEncr
, m_nStorageType
, true));
1329 m_aChildrenMap
[aName
].push_back( pNewElement
);
1330 m_bIsModified
= true;
1331 m_bBroadcastModified
= true;
1336 void OStorage_Impl::InsertRawStream( const OUString
& aName
, const uno::Reference
< io::XInputStream
>& xInStream
)
1338 // insert of raw stream means insert and commit
1339 SAL_WARN_IF( !m_xPackage
.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1340 if ( !m_xPackage
.is() )
1341 throw embed::InvalidStorageException( THROW_WHERE
);
1343 if ( m_nStorageType
!= embed::StorageFormats::PACKAGE
)
1344 throw packages::NoEncryptionException( THROW_WHERE
);
1346 uno::Reference
< io::XSeekable
> xSeek( xInStream
, uno::UNO_QUERY
);
1347 uno::Reference
< io::XInputStream
> xInStrToInsert
= xSeek
.is() ? xInStream
:
1348 GetSeekableTempCopy( xInStream
, m_xContext
);
1350 uno::Sequence
< uno::Any
> aSeq( 1 );
1352 uno::Reference
< lang::XUnoTunnel
> xNewElement( m_xPackage
->createInstanceWithArguments( aSeq
),
1355 SAL_WARN_IF( !xNewElement
.is(), "package.xstor", "Not possible to create a new stream!" );
1356 if ( !xNewElement
.is() )
1357 throw io::IOException( THROW_WHERE
);
1359 uno::Reference
< packages::XDataSinkEncrSupport
> xPackageSubStream( xNewElement
, uno::UNO_QUERY_THROW
);
1360 xPackageSubStream
->setRawStream( xInStrToInsert
);
1362 // the mode is not needed for storage stream internal implementation
1363 SotElement_Impl
* pNewElement
= InsertElement( aName
, false );
1364 pNewElement
->m_xStream
.reset(new OWriteStream_Impl(this, xPackageSubStream
, m_xPackage
, m_xContext
, true, m_nStorageType
, false));
1365 // the stream is inserted and must be treated as a committed one
1366 pNewElement
->m_xStream
->SetToBeCommited();
1368 m_aChildrenMap
[aName
].push_back( pNewElement
);
1369 m_bIsModified
= true;
1370 m_bBroadcastModified
= true;
1373 std::unique_ptr
<OStorage_Impl
> OStorage_Impl::CreateNewStorageImpl( sal_Int32 nStorageMode
)
1375 SAL_WARN_IF( !m_xPackage
.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1376 if ( !m_xPackage
.is() )
1377 throw embed::InvalidStorageException( THROW_WHERE
);
1379 uno::Sequence
< uno::Any
> aSeq( 1 );
1381 uno::Reference
< lang::XUnoTunnel
> xNewElement( m_xPackage
->createInstanceWithArguments( aSeq
),
1384 SAL_WARN_IF( !xNewElement
.is(), "package.xstor", "Not possible to create a new storage!" );
1385 if ( !xNewElement
.is() )
1386 throw io::IOException( THROW_WHERE
);
1388 uno::Reference
< container::XNameContainer
> xPackageSubFolder( xNewElement
, uno::UNO_QUERY_THROW
);
1389 std::unique_ptr
<OStorage_Impl
> pResult(
1390 new OStorage_Impl( this, nStorageMode
, xPackageSubFolder
, m_xPackage
, m_xContext
, m_nStorageType
));
1391 pResult
->m_bIsModified
= true;
1396 SotElement_Impl
* OStorage_Impl::InsertStorage( const OUString
& aName
, sal_Int32 nStorageMode
)
1398 SotElement_Impl
* pNewElement
= InsertElement( aName
, true );
1400 pNewElement
->m_xStorage
= CreateNewStorageImpl(nStorageMode
);
1402 m_aChildrenMap
[aName
].push_back( pNewElement
);
1407 SotElement_Impl
* OStorage_Impl::InsertElement( const OUString
& aName
, bool bIsStorage
)
1409 assert( FindElement(aName
) == nullptr && "Should not try to insert existing element");
1411 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1413 SotElement_Impl
* pDeletedElm
= nullptr;
1415 auto it
= m_aChildrenMap
.find(aName
);
1416 if (it
!= m_aChildrenMap
.end())
1417 for (auto pElement
: it
->second
)
1419 SAL_WARN_IF( !pElement
->m_bIsRemoved
, "package.xstor", "Try to insert an element instead of existing one!" );
1420 if ( pElement
->m_bIsRemoved
)
1422 SAL_WARN_IF( pElement
->m_bIsInserted
, "package.xstor", "Inserted elements must be deleted immediately!" );
1423 pDeletedElm
= pElement
;
1429 if ( pDeletedElm
->m_bIsStorage
)
1430 OpenSubStorage( pDeletedElm
, embed::ElementModes::READWRITE
);
1432 OpenSubStream( pDeletedElm
);
1434 auto & rVec
= m_aChildrenMap
[aName
];
1435 rVec
.erase(std::remove(rVec
.begin(), rVec
.end(), pDeletedElm
), rVec
.end());
1437 m_aChildrenMap
.erase(aName
);
1438 m_aDeletedVector
.push_back( pDeletedElm
);
1441 // create new element
1442 return new SotElement_Impl( aName
, bIsStorage
, true );
1445 void OStorage_Impl::OpenSubStorage( SotElement_Impl
* pElement
, sal_Int32 nStorageMode
)
1447 SAL_WARN_IF( !pElement
, "package.xstor", "pElement is not set!" );
1448 SAL_WARN_IF( !pElement
->m_bIsStorage
, "package.xstor", "Storage flag is not set!" );
1450 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1452 if (!pElement
->m_xStorage
)
1454 SAL_WARN_IF( pElement
->m_bIsInserted
, "package.xstor", "Inserted element must be created already!" );
1456 uno::Reference
< lang::XUnoTunnel
> xTunnel
;
1457 m_xPackageFolder
->getByName( pElement
->m_aOriginalName
) >>= xTunnel
;
1458 if ( !xTunnel
.is() )
1459 throw container::NoSuchElementException( THROW_WHERE
);
1461 uno::Reference
< container::XNameContainer
> xPackageSubFolder( xTunnel
, uno::UNO_QUERY_THROW
);
1462 pElement
->m_xStorage
.reset(new OStorage_Impl(this, nStorageMode
, xPackageSubFolder
, m_xPackage
, m_xContext
, m_nStorageType
));
1466 void OStorage_Impl::OpenSubStream( SotElement_Impl
* pElement
)
1468 SAL_WARN_IF( !pElement
, "package.xstor", "pElement is not set!" );
1469 SAL_WARN_IF( pElement
->m_bIsStorage
, "package.xstor", "Storage flag is set!" );
1471 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1473 if (pElement
->m_xStream
)
1476 SAL_WARN_IF( pElement
->m_bIsInserted
, "package.xstor", "Inserted element must be created already!" );
1478 uno::Reference
< lang::XUnoTunnel
> xTunnel
;
1479 m_xPackageFolder
->getByName( pElement
->m_aOriginalName
) >>= xTunnel
;
1480 if ( !xTunnel
.is() )
1481 throw container::NoSuchElementException( THROW_WHERE
);
1483 uno::Reference
< packages::XDataSinkEncrSupport
> xPackageSubStream( xTunnel
, uno::UNO_QUERY_THROW
);
1485 // the stream can never be inserted here, because inserted stream element holds the stream till commit or destruction
1486 pElement
->m_xStream
.reset(new OWriteStream_Impl(this, xPackageSubStream
, m_xPackage
, m_xContext
, false, m_nStorageType
, false, GetRelInfoStreamForName(pElement
->m_aOriginalName
)));
1489 uno::Sequence
< OUString
> OStorage_Impl::GetElementNames()
1491 ::osl::MutexGuard
aGuard( m_xMutex
->GetMutex() );
1495 std::vector
< OUString
> aElementNames
;
1496 aElementNames
.reserve( m_aChildrenMap
.size() );
1498 for ( const auto& pair
: m_aChildrenMap
)
1499 for (auto pElement
: pair
.second
)
1501 if ( !pElement
->m_bIsRemoved
)
1502 aElementNames
.push_back(pair
.first
);
1505 return comphelper::containerToSequence(aElementNames
);
1508 void OStorage_Impl::RemoveElement( OUString
const & rName
, SotElement_Impl
* pElement
)
1512 if ( (pElement
->m_xStorage
&& ( pElement
->m_xStorage
->m_pAntiImpl
|| !pElement
->m_xStorage
->m_aReadOnlyWrapVector
.empty() ))
1513 || (pElement
->m_xStream
&& ( pElement
->m_xStream
->m_pAntiImpl
|| !pElement
->m_xStream
->m_aInputStreamsVector
.empty() )) )
1514 throw io::IOException( THROW_WHERE
); // TODO: Access denied
1516 auto mapIt
= m_aChildrenMap
.find(rName
);
1517 for (auto it
= mapIt
->second
.begin(); it
!= mapIt
->second
.end(); ++it
)
1518 if (pElement
== *it
)
1520 if ( pElement
->m_bIsInserted
)
1523 mapIt
->second
.erase(std::remove(mapIt
->second
.begin(), mapIt
->second
.end(), pElement
), mapIt
->second
.end());
1524 if (mapIt
->second
.empty())
1525 m_aChildrenMap
.erase(mapIt
);
1529 pElement
->m_bIsRemoved
= true;
1530 ClearElement( pElement
);
1534 assert(false && "not found");
1536 // TODO/OFOPXML: the rel stream should be removed as well
1539 void OStorage_Impl::ClearElement( SotElement_Impl
* pElement
)
1541 pElement
->m_xStorage
.reset();
1542 pElement
->m_xStream
.reset();
1545 void OStorage_Impl::CloneStreamElement( const OUString
& aStreamName
,
1546 bool bEncryptionDataProvided
,
1547 const ::comphelper::SequenceAsHashMap
& aEncryptionData
,
1548 uno::Reference
< io::XStream
>& xTargetStream
)
1550 SotElement_Impl
*pElement
= FindElement( aStreamName
);
1553 // element does not exist, throw exception
1554 throw io::IOException( THROW_WHERE
); // TODO: access_denied
1556 else if ( pElement
->m_bIsStorage
)
1557 throw io::IOException( THROW_WHERE
);
1559 if (!pElement
->m_xStream
)
1560 OpenSubStream( pElement
);
1562 if (!pElement
->m_xStream
|| !pElement
->m_xStream
->m_xPackageStream
.is())
1563 throw io::IOException( THROW_WHERE
); // TODO: general_error
1565 // the existence of m_pAntiImpl of the child is not interesting,
1566 // the copy will be created internally
1568 // usual copying is not applicable here, only last flushed version of the
1569 // child stream should be used for copying. Probably the children m_xPackageStream
1570 // can be used as a base of a new stream, that would be copied to result
1571 // storage. The only problem is that some package streams can be accessed from outside
1572 // at the same time (now solved by wrappers that remember own position).
1574 if (bEncryptionDataProvided
)
1575 pElement
->m_xStream
->GetCopyOfLastCommit(xTargetStream
, aEncryptionData
);
1577 pElement
->m_xStream
->GetCopyOfLastCommit(xTargetStream
);
1580 void OStorage_Impl::RemoveStreamRelInfo( std::u16string_view aOriginalName
)
1582 // this method should be used only in OStorage_Impl::Commit() method
1583 // the aOriginalName can be empty, in this case the storage relation info should be removed
1585 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
&& m_xRelStorage
.is() )
1587 OUString aRelStreamName
= OUString::Concat(aOriginalName
) + ".rels";
1589 if ( m_xRelStorage
->hasByName( aRelStreamName
) )
1590 m_xRelStorage
->removeElement( aRelStreamName
);
1594 void OStorage_Impl::CreateRelStorage()
1596 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
1599 if ( m_xRelStorage
.is() )
1602 if ( !m_pRelStorElement
)
1604 m_pRelStorElement
= new SotElement_Impl( "_rels", true, true );
1605 m_pRelStorElement
->m_xStorage
= CreateNewStorageImpl(embed::ElementModes::WRITE
);
1606 if (m_pRelStorElement
->m_xStorage
)
1607 m_pRelStorElement
->m_xStorage
->m_pParent
= nullptr; // the relation storage is completely controlled by parent
1610 if (!m_pRelStorElement
->m_xStorage
)
1611 OpenSubStorage( m_pRelStorElement
, embed::ElementModes::WRITE
);
1613 if (!m_pRelStorElement
->m_xStorage
)
1614 throw uno::RuntimeException( THROW_WHERE
);
1616 m_xRelStorage
= new OStorage(m_pRelStorElement
->m_xStorage
.get(), false);
1619 void OStorage_Impl::CommitStreamRelInfo( std::u16string_view rName
, SotElement_Impl
const * pStreamElement
)
1621 // this method should be used only in OStorage_Impl::Commit() method
1623 // the stream element must be provided
1624 if ( !pStreamElement
)
1625 throw uno::RuntimeException( THROW_WHERE
);
1627 if (m_nStorageType
== embed::StorageFormats::OFOPXML
&& pStreamElement
->m_xStream
)
1629 SAL_WARN_IF( rName
.empty(), "package.xstor", "The name must not be empty!" );
1631 if ( !m_xRelStorage
.is() )
1633 // Create new rels storage, this is commit scenario so it must be possible
1637 pStreamElement
->m_xStream
->CommitStreamRelInfo(m_xRelStorage
, pStreamElement
->m_aOriginalName
, rName
);
1641 uno::Reference
< io::XInputStream
> OStorage_Impl::GetRelInfoStreamForName(
1642 std::u16string_view aName
)
1644 if ( m_nStorageType
== embed::StorageFormats::OFOPXML
)
1647 if ( m_xRelStorage
.is() )
1649 OUString aRelStreamName
= OUString::Concat(aName
) + ".rels";
1650 if ( m_xRelStorage
->hasByName( aRelStreamName
) )
1652 uno::Reference
< io::XStream
> xStream
= m_xRelStorage
->openStreamElement( aRelStreamName
, embed::ElementModes::READ
);
1654 return xStream
->getInputStream();
1659 return uno::Reference
< io::XInputStream
>();
1662 void OStorage_Impl::CommitRelInfo( const uno::Reference
< container::XNameContainer
>& xNewPackageFolder
)
1664 // this method should be used only in OStorage_Impl::Commit() method
1665 OUString
aRelsStorName("_rels");
1667 if ( !xNewPackageFolder
.is() )
1668 throw uno::RuntimeException( THROW_WHERE
);
1670 if ( m_nStorageType
!= embed::StorageFormats::OFOPXML
)
1673 if ( m_nRelInfoStatus
== RELINFO_BROKEN
|| m_nRelInfoStatus
== RELINFO_CHANGED_BROKEN
)
1674 throw io::IOException( THROW_WHERE
);
1676 if (m_nRelInfoStatus
== RELINFO_CHANGED
)
1678 if (m_aRelInfo
.hasElements())
1682 uno::Reference
<io::XStream
> xRelsStream
= m_xRelStorage
->openStreamElement(
1683 ".rels", embed::ElementModes::TRUNCATE
| embed::ElementModes::READWRITE
);
1685 uno::Reference
<io::XOutputStream
> xOutStream
= xRelsStream
->getOutputStream();
1686 if (!xOutStream
.is())
1687 throw uno::RuntimeException(THROW_WHERE
);
1689 ::comphelper::OFOPXMLHelper::WriteRelationsInfoSequence(xOutStream
, m_aRelInfo
,
1692 // set the mediatype
1693 uno::Reference
<beans::XPropertySet
> xPropSet(xRelsStream
, uno::UNO_QUERY_THROW
);
1694 xPropSet
->setPropertyValue(
1695 "MediaType", uno::makeAny(OUString(
1696 "application/vnd.openxmlformats-package.relationships+xml")));
1698 m_nRelInfoStatus
= RELINFO_READ
;
1700 else if (m_xRelStorage
.is())
1701 RemoveStreamRelInfo(std::u16string_view()); // remove own rel info
1703 else if (m_nRelInfoStatus
== RELINFO_CHANGED_STREAM_READ
1704 || m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
1708 uno::Reference
<io::XStream
> xRelsStream
= m_xRelStorage
->openStreamElement(
1709 ".rels", embed::ElementModes::TRUNCATE
| embed::ElementModes::READWRITE
);
1711 uno::Reference
<io::XOutputStream
> xOutputStream
= xRelsStream
->getOutputStream();
1712 if (!xOutputStream
.is())
1713 throw uno::RuntimeException(THROW_WHERE
);
1715 uno::Reference
<io::XSeekable
> xSeek(m_xNewRelInfoStream
, uno::UNO_QUERY_THROW
);
1717 ::comphelper::OStorageHelper::CopyInputToOutput(m_xNewRelInfoStream
, xOutputStream
);
1719 // set the mediatype
1720 uno::Reference
<beans::XPropertySet
> xPropSet(xRelsStream
, uno::UNO_QUERY_THROW
);
1721 xPropSet
->setPropertyValue(
1723 uno::makeAny(OUString("application/vnd.openxmlformats-package.relationships+xml")));
1725 m_xNewRelInfoStream
.clear();
1726 if (m_nRelInfoStatus
== RELINFO_CHANGED_STREAM
)
1728 m_aRelInfo
= uno::Sequence
<uno::Sequence
<beans::StringPair
>>();
1729 m_nRelInfoStatus
= RELINFO_NO_INIT
;
1732 m_nRelInfoStatus
= RELINFO_READ
;
1735 if ( !m_xRelStorage
.is() )
1738 if ( m_xRelStorage
->hasElements() )
1740 uno::Reference
< embed::XTransactedObject
> xTrans( m_xRelStorage
, uno::UNO_QUERY_THROW
);
1744 if ( xNewPackageFolder
.is() && xNewPackageFolder
->hasByName( aRelsStorName
) )
1745 xNewPackageFolder
->removeByName( aRelsStorName
);
1747 if ( !m_xRelStorage
->hasElements() )
1749 // the empty relations storage should not be created
1750 delete m_pRelStorElement
;
1751 m_pRelStorElement
= nullptr;
1752 m_xRelStorage
.clear();
1754 else if ( m_pRelStorElement
&& m_pRelStorElement
->m_xStorage
&& xNewPackageFolder
.is() )
1755 m_pRelStorElement
->m_xStorage
->InsertIntoPackageFolder( aRelsStorName
, xNewPackageFolder
);
1758 // OStorage implementation
1760 OStorage::OStorage( uno::Reference
< io::XInputStream
> const & xInputStream
,
1762 const uno::Sequence
< beans::PropertyValue
>& xProperties
,
1763 uno::Reference
< uno::XComponentContext
> const & xContext
,
1764 sal_Int32 nStorageType
)
1765 : m_pImpl( new OStorage_Impl( xInputStream
, nMode
, xProperties
, xContext
, nStorageType
) )
1767 m_pImpl
->m_pAntiImpl
= this;
1768 m_pData
.reset(new StorInternalData_Impl( m_pImpl
->m_xMutex
, m_pImpl
->m_bIsRoot
, m_pImpl
->m_nStorageType
, false));
1771 OStorage::OStorage( uno::Reference
< io::XStream
> const & xStream
,
1773 const uno::Sequence
< beans::PropertyValue
>& xProperties
,
1774 uno::Reference
< uno::XComponentContext
> const & xContext
,
1775 sal_Int32 nStorageType
)
1776 : m_pImpl( new OStorage_Impl( xStream
, nMode
, xProperties
, xContext
, nStorageType
) )
1778 m_pImpl
->m_pAntiImpl
= this;
1779 m_pData
.reset(new StorInternalData_Impl( m_pImpl
->m_xMutex
, m_pImpl
->m_bIsRoot
, m_pImpl
->m_nStorageType
, false));
1782 OStorage::OStorage( OStorage_Impl
* pImpl
, bool bReadOnlyWrap
)
1785 // this call can be done only from OStorage_Impl implementation to create child storage
1786 OSL_ENSURE( m_pImpl
&& m_pImpl
->m_xMutex
.is(), "The provided pointer & mutex MUST NOT be empty!" );
1788 m_pData
.reset(new StorInternalData_Impl( m_pImpl
->m_xMutex
, m_pImpl
->m_bIsRoot
, m_pImpl
->m_nStorageType
, bReadOnlyWrap
));
1790 OSL_ENSURE( ( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
) == embed::ElementModes::WRITE
||
1791 m_pData
->m_bReadOnlyWrap
,
1792 "The wrapper can not allow writing in case implementation does not!" );
1794 if ( !bReadOnlyWrap
)
1795 m_pImpl
->m_pAntiImpl
= this;
1798 OStorage::~OStorage()
1800 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
1803 osl_atomic_increment(&m_refCount
); // to call dispose
1807 catch( const uno::RuntimeException
& )
1809 TOOLS_INFO_EXCEPTION("package.xstor", "Handled exception");
1814 void OStorage::InternalDispose( bool bNotifyImpl
)
1818 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
1819 throw lang::DisposedException( THROW_WHERE
);
1822 // the source object is also a kind of locker for the current object
1823 // since the listeners could dispose the object while being notified
1824 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
1825 m_pData
->m_aListenersContainer
.disposeAndClear( aSource
);
1829 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
1830 throw lang::DisposedException( THROW_WHERE
);
1833 m_pImpl
->m_nModifiedListenerCount
= 0;
1835 if ( m_pData
->m_bReadOnlyWrap
)
1837 OSL_ENSURE( m_pData
->m_aOpenSubComponentsVector
.empty() || m_pData
->m_pSubElDispListener
,
1838 "If any subelements are open the listener must exist!" );
1840 if (m_pData
->m_pSubElDispListener
)
1842 m_pData
->m_pSubElDispListener
->OwnerIsDisposed();
1844 // iterate through m_pData->m_aOpenSubComponentsVector
1845 // deregister m_pData->m_pSubElDispListener and dispose all of them
1846 if ( !m_pData
->m_aOpenSubComponentsVector
.empty() )
1848 for ( const auto& pComp
: m_pData
->m_aOpenSubComponentsVector
)
1850 uno::Reference
< lang::XComponent
> xTmp
= pComp
;
1853 xTmp
->removeEventListener( uno::Reference
< lang::XEventListener
>(
1854 static_cast< lang::XEventListener
* >( m_pData
->m_pSubElDispListener
.get())));
1858 } catch( const uno::Exception
& )
1860 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
1865 m_pData
->m_aOpenSubComponentsVector
.clear();
1870 m_pImpl
->RemoveReadOnlyWrap( *this );
1874 m_pImpl
->m_pAntiImpl
= nullptr;
1878 if ( m_pData
->m_bIsRoot
)
1882 // the non-committed changes for the storage must be removed
1891 void OStorage::ChildIsDisposed( const uno::Reference
< uno::XInterface
>& xChild
)
1893 // this method can only be called by child disposing listener
1895 // this method must not contain any locking
1896 // the locking is done in the listener
1898 auto& rVec
= m_pData
->m_aOpenSubComponentsVector
;
1899 rVec
.erase(std::remove_if(rVec
.begin(), rVec
.end(),
1900 [&xChild
](const uno::Reference
<lang::XComponent
>& xTmp
) {
1901 return !xTmp
.is() || xTmp
== xChild
;
1906 void OStorage::BroadcastModifiedIfNecessary()
1908 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
1911 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
1912 throw lang::DisposedException( THROW_WHERE
);
1915 if ( !m_pImpl
->m_bBroadcastModified
)
1918 m_pImpl
->m_bBroadcastModified
= false;
1920 SAL_WARN_IF( m_pData
->m_bReadOnlyWrap
, "package.xstor", "The storage can not be modified at all!" );
1922 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
1924 ::cppu::OInterfaceContainerHelper
* pContainer
=
1925 m_pData
->m_aListenersContainer
.getContainer(
1926 cppu::UnoType
<util::XModifyListener
>::get());
1929 ::cppu::OInterfaceIteratorHelper
pIterator( *pContainer
);
1930 while ( pIterator
.hasMoreElements( ) )
1932 static_cast<util::XModifyListener
*>( pIterator
.next( ) )->modified( aSource
);
1937 void OStorage::BroadcastTransaction( sal_Int8 nMessage
)
1945 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
1948 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
1949 throw lang::DisposedException( THROW_WHERE
);
1952 SAL_WARN_IF( m_pData
->m_bReadOnlyWrap
, "package.xstor", "The storage can not be modified at all!" );
1954 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
1956 ::cppu::OInterfaceContainerHelper
* pContainer
=
1957 m_pData
->m_aListenersContainer
.getContainer(
1958 cppu::UnoType
<embed::XTransactionListener
>::get());
1962 ::cppu::OInterfaceIteratorHelper
pIterator( *pContainer
);
1963 while ( pIterator
.hasMoreElements( ) )
1965 OSL_ENSURE( nMessage
>= 1 && nMessage
<= 4, "Wrong internal notification code is used!" );
1969 case STOR_MESS_PRECOMMIT
:
1970 static_cast<embed::XTransactionListener
*>( pIterator
.next( ) )->preCommit( aSource
);
1972 case STOR_MESS_COMMITTED
:
1973 static_cast<embed::XTransactionListener
*>( pIterator
.next( ) )->commited( aSource
);
1975 case STOR_MESS_PREREVERT
:
1976 static_cast<embed::XTransactionListener
*>( pIterator
.next( ) )->preRevert( aSource
);
1978 case STOR_MESS_REVERTED
:
1979 static_cast<embed::XTransactionListener
*>( pIterator
.next( ) )->reverted( aSource
);
1985 SotElement_Impl
* OStorage::OpenStreamElement_Impl( const OUString
& aStreamName
, sal_Int32 nOpenMode
, bool bEncr
)
1987 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
1989 OSL_ENSURE( !m_pData
->m_bReadOnlyWrap
|| ( nOpenMode
& embed::ElementModes::WRITE
) != embed::ElementModes::WRITE
,
1990 "An element can not be opened for writing in readonly storage!" );
1992 SotElement_Impl
*pElement
= m_pImpl
->FindElement( aStreamName
);
1995 // element does not exist, check if creation is allowed
1996 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
)
1997 || (( nOpenMode
& embed::ElementModes::WRITE
) != embed::ElementModes::WRITE
)
1998 || ( nOpenMode
& embed::ElementModes::NOCREATE
) == embed::ElementModes::NOCREATE
)
2000 throw io::IOException("Element does not exist and cannot be "
2001 "created: \"" + aStreamName
+ "\""); // TODO: access_denied
2004 // create a new StreamElement and insert it into the list
2005 pElement
= m_pImpl
->InsertStream( aStreamName
, bEncr
);
2007 else if ( pElement
->m_bIsStorage
)
2009 throw io::IOException( THROW_WHERE
);
2012 SAL_WARN_IF( !pElement
, "package.xstor", "In case element can not be created an exception must be thrown!" );
2014 if (!pElement
->m_xStream
)
2015 m_pImpl
->OpenSubStream( pElement
);
2017 if (!pElement
->m_xStream
)
2018 throw io::IOException( THROW_WHERE
);
2023 void OStorage::MakeLinkToSubComponent_Impl( const uno::Reference
< lang::XComponent
>& xComponent
)
2025 if ( !xComponent
.is() )
2026 throw uno::RuntimeException( THROW_WHERE
);
2028 if (!m_pData
->m_pSubElDispListener
)
2030 m_pData
->m_pSubElDispListener
= new OChildDispListener_Impl( *this );
2033 xComponent
->addEventListener( uno::Reference
< lang::XEventListener
>(
2034 static_cast< ::cppu::OWeakObject
* >(m_pData
->m_pSubElDispListener
.get()), uno::UNO_QUERY
));
2036 m_pData
->m_aOpenSubComponentsVector
.emplace_back(xComponent
);
2041 uno::Any SAL_CALL
OStorage::queryInterface( const uno::Type
& rType
)
2043 // common interfaces
2044 uno::Any aReturn
= ::cppu::queryInterface
2046 , static_cast<lang::XTypeProvider
*> ( this )
2047 , static_cast<embed::XStorage
*> ( this )
2048 , static_cast<embed::XStorage2
*> ( this )
2049 , static_cast<embed::XTransactedObject
*> ( this )
2050 , static_cast<embed::XTransactionBroadcaster
*> ( this )
2051 , static_cast<util::XModifiable
*> ( this )
2052 , static_cast<container::XNameAccess
*> ( this )
2053 , static_cast<container::XElementAccess
*> ( this )
2054 , static_cast<lang::XComponent
*> ( this )
2055 , static_cast<beans::XPropertySet
*> ( this )
2056 , static_cast<embed::XOptimizedStorage
*> ( this ) );
2058 if ( aReturn
.hasValue() )
2061 aReturn
= ::cppu::queryInterface
2063 , static_cast<embed::XHierarchicalStorageAccess
*> ( this )
2064 , static_cast<embed::XHierarchicalStorageAccess2
*> ( this ) );
2066 if ( aReturn
.hasValue() )
2069 if ( m_pData
->m_nStorageType
== embed::StorageFormats::PACKAGE
)
2071 if ( m_pData
->m_bIsRoot
)
2073 aReturn
= ::cppu::queryInterface
2075 , static_cast<embed::XStorageRawAccess
*> ( this )
2076 , static_cast<embed::XEncryptionProtectedSource
*> ( this )
2077 , static_cast<embed::XEncryptionProtectedSource2
*> ( this )
2078 , static_cast<embed::XEncryptionProtectedStorage
*> ( this ) );
2082 aReturn
= ::cppu::queryInterface
2084 , static_cast<embed::XStorageRawAccess
*> ( this ) );
2087 else if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
)
2089 aReturn
= ::cppu::queryInterface
2091 , static_cast<embed::XRelationshipAccess
*> ( this ) );
2094 if ( aReturn
.hasValue() )
2097 return OWeakObject::queryInterface( rType
);
2100 void SAL_CALL
OStorage::acquire() noexcept
2102 OWeakObject::acquire();
2105 void SAL_CALL
OStorage::release() noexcept
2107 OWeakObject::release();
2111 uno::Sequence
< uno::Type
> SAL_CALL
OStorage::getTypes()
2113 if (! m_pData
->m_pTypeCollection
)
2115 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
2117 if (! m_pData
->m_pTypeCollection
)
2119 if ( m_pData
->m_nStorageType
== embed::StorageFormats::PACKAGE
)
2121 if ( m_pData
->m_bIsRoot
)
2123 m_pData
->m_pTypeCollection
.reset(new ::cppu::OTypeCollection
2124 ( cppu::UnoType
<lang::XTypeProvider
>::get()
2125 , cppu::UnoType
<embed::XStorage
>::get()
2126 , cppu::UnoType
<embed::XStorage2
>::get()
2127 , cppu::UnoType
<embed::XStorageRawAccess
>::get()
2128 , cppu::UnoType
<embed::XTransactedObject
>::get()
2129 , cppu::UnoType
<embed::XTransactionBroadcaster
>::get()
2130 , cppu::UnoType
<util::XModifiable
>::get()
2131 , cppu::UnoType
<embed::XEncryptionProtectedStorage
>::get()
2132 , cppu::UnoType
<embed::XEncryptionProtectedSource2
>::get()
2133 , cppu::UnoType
<embed::XEncryptionProtectedSource
>::get()
2134 , cppu::UnoType
<beans::XPropertySet
>::get()));
2138 m_pData
->m_pTypeCollection
.reset(new ::cppu::OTypeCollection
2139 ( cppu::UnoType
<lang::XTypeProvider
>::get()
2140 , cppu::UnoType
<embed::XStorage
>::get()
2141 , cppu::UnoType
<embed::XStorage2
>::get()
2142 , cppu::UnoType
<embed::XStorageRawAccess
>::get()
2143 , cppu::UnoType
<embed::XTransactedObject
>::get()
2144 , cppu::UnoType
<embed::XTransactionBroadcaster
>::get()
2145 , cppu::UnoType
<util::XModifiable
>::get()
2146 , cppu::UnoType
<beans::XPropertySet
>::get()));
2149 else if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
)
2151 m_pData
->m_pTypeCollection
.reset(new ::cppu::OTypeCollection
2152 ( cppu::UnoType
<lang::XTypeProvider
>::get()
2153 , cppu::UnoType
<embed::XStorage
>::get()
2154 , cppu::UnoType
<embed::XTransactedObject
>::get()
2155 , cppu::UnoType
<embed::XTransactionBroadcaster
>::get()
2156 , cppu::UnoType
<util::XModifiable
>::get()
2157 , cppu::UnoType
<embed::XRelationshipAccess
>::get()
2158 , cppu::UnoType
<beans::XPropertySet
>::get()));
2162 m_pData
->m_pTypeCollection
.reset(new ::cppu::OTypeCollection
2163 ( cppu::UnoType
<lang::XTypeProvider
>::get()
2164 , cppu::UnoType
<embed::XStorage
>::get()
2165 , cppu::UnoType
<embed::XTransactedObject
>::get()
2166 , cppu::UnoType
<embed::XTransactionBroadcaster
>::get()
2167 , cppu::UnoType
<util::XModifiable
>::get()
2168 , cppu::UnoType
<beans::XPropertySet
>::get()));
2173 return m_pData
->m_pTypeCollection
->getTypes() ;
2176 uno::Sequence
< sal_Int8
> SAL_CALL
OStorage::getImplementationId()
2178 static ::cppu::OImplementationId lcl_ImplId
;
2179 return lcl_ImplId
.getImplementationId();
2183 void SAL_CALL
OStorage::copyToStorage( const uno::Reference
< embed::XStorage
>& xDest
)
2185 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
2189 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2190 throw lang::DisposedException( THROW_WHERE
);
2193 if ( !xDest
.is() || xDest
== uno::Reference
< uno::XInterface
>( static_cast< OWeakObject
*> ( this ), uno::UNO_QUERY
) )
2194 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 );
2197 m_pImpl
->CopyToStorage( xDest
, false );
2199 catch( const embed::InvalidStorageException
& )
2201 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2204 catch( const lang::IllegalArgumentException
& )
2206 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2209 catch( const embed::StorageWrappedTargetException
& )
2211 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2214 catch( const io::IOException
& )
2216 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2219 catch( const uno::RuntimeException
& )
2221 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2224 catch( const uno::Exception
& )
2226 uno::Any
aCaught( ::cppu::getCaughtException() );
2227 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2229 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy storage!",
2230 uno::Reference
< io::XInputStream
>(),
2235 uno::Reference
< io::XStream
> SAL_CALL
OStorage::openStreamElement(
2236 const OUString
& aStreamName
, sal_Int32 nOpenMode
)
2238 osl::ClearableMutexGuard
aGuard(m_pData
->m_xSharedMutex
->GetMutex());
2242 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2243 throw lang::DisposedException( THROW_WHERE
);
2246 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
2247 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2249 if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStreamName
== "_rels" )
2250 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable element name
2252 if ( ( nOpenMode
& embed::ElementModes::WRITE
) && m_pData
->m_bReadOnlyWrap
)
2253 throw io::IOException( THROW_WHERE
); // TODO: access denied
2255 uno::Reference
< io::XStream
> xResult
;
2258 SotElement_Impl
*pElement
= OpenStreamElement_Impl( aStreamName
, nOpenMode
, false );
2259 OSL_ENSURE(pElement
&& pElement
->m_xStream
, "In case element can not be created an exception must be thrown!");
2261 xResult
= pElement
->m_xStream
->GetStream(nOpenMode
, false);
2262 SAL_WARN_IF( !xResult
.is(), "package.xstor", "The method must throw exception instead of removing empty result!" );
2264 if ( m_pData
->m_bReadOnlyWrap
)
2266 // before the storage disposes the stream it must deregister itself as listener
2267 uno::Reference
< lang::XComponent
> xStreamComponent( xResult
, uno::UNO_QUERY_THROW
);
2268 MakeLinkToSubComponent_Impl( xStreamComponent
);
2271 catch( const embed::InvalidStorageException
& )
2273 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2276 catch( const lang::IllegalArgumentException
& )
2278 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2281 catch( const packages::WrongPasswordException
& )
2283 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2286 catch( const embed::StorageWrappedTargetException
& )
2288 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2291 catch( const io::IOException
& )
2293 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2296 catch( const uno::RuntimeException
& )
2298 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2301 catch( const uno::Exception
& )
2303 uno::Any
aCaught( ::cppu::getCaughtException() );
2304 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2306 throw embed::StorageWrappedTargetException(THROW_WHERE
"Can't open stream element!",
2307 uno::Reference
< io::XInputStream
>(),
2313 BroadcastModifiedIfNecessary();
2318 uno::Reference
< io::XStream
> SAL_CALL
OStorage::openEncryptedStreamElement(
2319 const OUString
& aStreamName
, sal_Int32 nOpenMode
, const OUString
& aPass
)
2321 return openEncryptedStream( aStreamName
, nOpenMode
, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass
) );
2324 uno::Reference
< embed::XStorage
> SAL_CALL
OStorage::openStorageElement(
2325 const OUString
& aStorName
, sal_Int32 nStorageMode
)
2327 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
2331 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2332 throw lang::DisposedException( THROW_WHERE
);
2335 if ( aStorName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName
, false ) )
2336 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2338 if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStorName
== "_rels" )
2339 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable storage name
2341 if ( ( nStorageMode
& embed::ElementModes::WRITE
) && m_pData
->m_bReadOnlyWrap
)
2342 throw io::IOException( THROW_WHERE
); // TODO: access denied
2344 if ( ( nStorageMode
& embed::ElementModes::TRUNCATE
)
2345 && !( nStorageMode
& embed::ElementModes::WRITE
) )
2346 throw io::IOException( THROW_WHERE
); // TODO: access denied
2348 // it's always possible to read written storage in this implementation
2349 nStorageMode
|= embed::ElementModes::READ
;
2351 uno::Reference
< embed::XStorage
> xResult
;
2354 SotElement_Impl
*pElement
= m_pImpl
->FindElement( aStorName
);
2357 // element does not exist, check if creation is allowed
2358 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
)
2359 || (( nStorageMode
& embed::ElementModes::WRITE
) != embed::ElementModes::WRITE
)
2360 || ( nStorageMode
& embed::ElementModes::NOCREATE
) == embed::ElementModes::NOCREATE
)
2361 throw io::IOException( THROW_WHERE
); // TODO: access_denied
2363 // create a new StorageElement and insert it into the list
2364 pElement
= m_pImpl
->InsertStorage( aStorName
, nStorageMode
);
2366 else if ( !pElement
->m_bIsStorage
)
2368 throw io::IOException( THROW_WHERE
);
2370 else if (pElement
->m_xStorage
)
2372 // storage has already been opened; it may be opened another time, if it the mode allows to do so
2373 if (pElement
->m_xStorage
->m_pAntiImpl
)
2375 throw io::IOException( THROW_WHERE
); // TODO: access_denied
2377 else if ( !pElement
->m_xStorage
->m_aReadOnlyWrapVector
.empty()
2378 && ( nStorageMode
& embed::ElementModes::WRITE
) )
2380 throw io::IOException( THROW_WHERE
); // TODO: access_denied
2384 // in case parent storage allows writing the readonly mode of the child storage is
2385 // virtual, that means that it is just enough to change the flag to let it be writable
2386 // and since there is no AntiImpl nobody should be notified about it
2387 pElement
->m_xStorage
->m_nStorageMode
= nStorageMode
| embed::ElementModes::READ
;
2389 if ( nStorageMode
& embed::ElementModes::TRUNCATE
)
2391 for (const auto & rPair
: pElement
->m_xStorage
->m_aChildrenMap
)
2392 for (auto pElementToDel
: rPair
.second
)
2393 m_pImpl
->RemoveElement( /*aName*/rPair
.first
, pElementToDel
);
2398 if (!pElement
->m_xStorage
)
2399 m_pImpl
->OpenSubStorage(pElement
, nStorageMode
);
2401 if (!pElement
->m_xStorage
)
2402 throw io::IOException( THROW_WHERE
); // TODO: general_error
2404 bool bReadOnlyWrap
= ( ( nStorageMode
& embed::ElementModes::WRITE
) != embed::ElementModes::WRITE
);
2405 rtl::Reference
<OStorage
> pResultStorage
= new OStorage(pElement
->m_xStorage
.get(), bReadOnlyWrap
);
2406 xResult
= pResultStorage
;
2408 if ( bReadOnlyWrap
)
2410 // Before this call is done the object must be refcounted already
2411 pElement
->m_xStorage
->SetReadOnlyWrap(*pResultStorage
);
2413 // before the storage disposes the stream it must deregister itself as listener
2414 uno::Reference
< lang::XComponent
> xStorageComponent( xResult
, uno::UNO_QUERY_THROW
);
2415 MakeLinkToSubComponent_Impl( xStorageComponent
);
2418 catch( const embed::InvalidStorageException
& )
2420 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2423 catch( const lang::IllegalArgumentException
& )
2425 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2428 catch( const embed::StorageWrappedTargetException
& )
2430 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2433 catch( const io::IOException
& )
2435 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2438 catch( const uno::RuntimeException
& )
2440 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2443 catch( const uno::Exception
& )
2445 uno::Any
aCaught( ::cppu::getCaughtException() );
2446 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2448 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't open storage!",
2449 uno::Reference
< io::XInputStream
>(),
2456 uno::Reference
< io::XStream
> SAL_CALL
OStorage::cloneStreamElement( const OUString
& aStreamName
)
2458 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
2462 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2463 throw lang::DisposedException( THROW_WHERE
);
2466 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
2467 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2469 if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStreamName
== "_rels" )
2470 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable storage name
2474 uno::Reference
< io::XStream
> xResult
;
2475 m_pImpl
->CloneStreamElement( aStreamName
, false, ::comphelper::SequenceAsHashMap(), xResult
);
2476 if ( !xResult
.is() )
2477 throw uno::RuntimeException( THROW_WHERE
);
2480 catch( const embed::InvalidStorageException
& )
2482 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2485 catch( const lang::IllegalArgumentException
& )
2487 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2490 catch( const packages::WrongPasswordException
& )
2492 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2495 catch( const io::IOException
& )
2497 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2500 catch( const embed::StorageWrappedTargetException
& )
2502 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2505 catch( const uno::RuntimeException
& )
2507 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2510 catch( const uno::Exception
& )
2512 uno::Any
aCaught( ::cppu::getCaughtException() );
2513 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2515 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't clone stream!",
2516 uno::Reference
< io::XInputStream
>(),
2521 uno::Reference
< io::XStream
> SAL_CALL
OStorage::cloneEncryptedStreamElement(
2522 const OUString
& aStreamName
,
2523 const OUString
& aPass
)
2525 return cloneEncryptedStream( aStreamName
, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass
) );
2528 void SAL_CALL
OStorage::copyLastCommitTo(
2529 const uno::Reference
< embed::XStorage
>& xTargetStorage
)
2531 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
2535 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2536 throw lang::DisposedException( THROW_WHERE
);
2541 m_pImpl
->CopyLastCommitTo( xTargetStorage
);
2543 catch( const embed::InvalidStorageException
& )
2545 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2548 catch( const lang::IllegalArgumentException
& )
2550 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2553 catch( const embed::StorageWrappedTargetException
& )
2555 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2558 catch( const io::IOException
& )
2560 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2563 catch( const uno::RuntimeException
& )
2565 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2568 catch( const uno::Exception
& )
2570 uno::Any
aCaught( ::cppu::getCaughtException() );
2571 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2573 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy last commit version!",
2574 uno::Reference
< io::XInputStream
>(),
2580 void SAL_CALL
OStorage::copyStorageElementLastCommitTo(
2581 const OUString
& aStorName
,
2582 const uno::Reference
< embed::XStorage
>& xTargetStorage
)
2584 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
2588 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2589 throw lang::DisposedException( THROW_WHERE
);
2592 if ( aStorName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName
, false ) )
2593 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2595 if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStorName
== "_rels" )
2596 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable storage name
2600 SotElement_Impl
*pElement
= m_pImpl
->FindElement( aStorName
);
2603 // element does not exist, throw exception
2604 throw io::IOException( THROW_WHERE
); // TODO: access_denied
2606 else if ( !pElement
->m_bIsStorage
)
2608 throw io::IOException( THROW_WHERE
);
2611 if (!pElement
->m_xStorage
)
2612 m_pImpl
->OpenSubStorage( pElement
, embed::ElementModes::READ
);
2614 if (!pElement
->m_xStorage
)
2615 throw io::IOException( THROW_WHERE
); // TODO: general_error
2617 // the existence of m_pAntiImpl of the child is not interesting,
2618 // the copy will be created internally
2620 pElement
->m_xStorage
->CopyLastCommitTo(xTargetStorage
);
2622 catch( const embed::InvalidStorageException
& )
2624 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2627 catch( const lang::IllegalArgumentException
& )
2629 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2632 catch( const io::IOException
& )
2634 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2637 catch( const embed::StorageWrappedTargetException
& )
2639 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2642 catch( const uno::RuntimeException
& )
2644 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2647 catch( const uno::Exception
& )
2649 uno::Any
aCaught( ::cppu::getCaughtException() );
2650 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2652 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy last commit element version!",
2653 uno::Reference
< io::XInputStream
>(),
2658 sal_Bool SAL_CALL
OStorage::isStreamElement( const OUString
& aElementName
)
2660 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
2664 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2665 throw lang::DisposedException( THROW_WHERE
);
2668 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false ) )
2669 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2671 if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aElementName
== "_rels" )
2672 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable name
2674 SotElement_Impl
* pElement
= nullptr;
2678 pElement
= m_pImpl
->FindElement( aElementName
);
2680 catch( const embed::InvalidStorageException
& )
2682 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2685 catch( const lang::IllegalArgumentException
& )
2687 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2690 catch( const container::NoSuchElementException
& )
2692 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2695 catch( const uno::RuntimeException
& )
2697 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2700 catch( const uno::Exception
& )
2702 uno::Any
aCaught( ::cppu::getCaughtException() );
2703 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2705 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can't detect whether it is a stream!",
2706 uno::Reference
< io::XInputStream
>(),
2711 throw container::NoSuchElementException( THROW_WHERE
); //???
2713 return !pElement
->m_bIsStorage
;
2716 sal_Bool SAL_CALL
OStorage::isStorageElement( const OUString
& aElementName
)
2718 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
2722 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2723 throw lang::DisposedException( THROW_WHERE
);
2726 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false ) )
2727 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2729 if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aElementName
== "_rels" )
2730 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 );
2732 SotElement_Impl
* pElement
= nullptr;
2736 pElement
= m_pImpl
->FindElement( aElementName
);
2738 catch( const embed::InvalidStorageException
& )
2740 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2743 catch( const lang::IllegalArgumentException
& )
2745 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2748 catch( const container::NoSuchElementException
& )
2750 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2753 catch( const uno::RuntimeException
& )
2755 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2758 catch( const uno::Exception
& )
2760 uno::Any
aCaught( ::cppu::getCaughtException() );
2761 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2763 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"can't detect whether it is a storage",
2764 uno::Reference
< io::XInputStream
>(),
2769 throw container::NoSuchElementException( THROW_WHERE
); //???
2771 return pElement
->m_bIsStorage
;
2774 void SAL_CALL
OStorage::removeElement( const OUString
& aElementName
)
2777 osl::MutexGuard
aGuard(m_pData
->m_xSharedMutex
->GetMutex());
2781 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2782 throw lang::DisposedException(THROW_WHERE
);
2785 if (aElementName
.isEmpty()
2786 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aElementName
, false))
2787 throw lang::IllegalArgumentException(THROW_WHERE
"Unexpected entry name syntax.",
2788 uno::Reference
<uno::XInterface
>(), 1);
2790 if (m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aElementName
== "_rels")
2791 throw lang::IllegalArgumentException(THROW_WHERE
, uno::Reference
<uno::XInterface
>(),
2792 1); // TODO: unacceptable name
2794 if (!(m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
))
2795 throw io::IOException(THROW_WHERE
); // TODO: access denied
2799 auto pElement
= m_pImpl
->FindElement(aElementName
);
2801 throw container::NoSuchElementException(THROW_WHERE
); //???
2803 m_pImpl
->RemoveElement(aElementName
, pElement
);
2805 m_pImpl
->m_bIsModified
= true;
2806 m_pImpl
->m_bBroadcastModified
= true;
2808 catch (const embed::InvalidStorageException
&)
2810 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2813 catch (const lang::IllegalArgumentException
&)
2815 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2818 catch (const container::NoSuchElementException
&)
2820 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2823 catch (const io::IOException
&)
2825 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2828 catch (const embed::StorageWrappedTargetException
&)
2830 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2833 catch (const uno::RuntimeException
&)
2835 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2838 catch (const uno::Exception
&)
2840 uno::Any
aCaught(::cppu::getCaughtException());
2841 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2843 throw embed::StorageWrappedTargetException(THROW_WHERE
"Can't remove element!",
2844 uno::Reference
<io::XInputStream
>(), aCaught
);
2848 BroadcastModifiedIfNecessary();
2851 void SAL_CALL
OStorage::renameElement( const OUString
& aElementName
, const OUString
& aNewName
)
2854 osl::MutexGuard
aGuard(m_pData
->m_xSharedMutex
->GetMutex());
2858 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2859 throw lang::DisposedException(THROW_WHERE
);
2862 if (aElementName
.isEmpty()
2863 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aElementName
, false)
2864 || aNewName
.isEmpty()
2865 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aNewName
, false))
2866 throw lang::IllegalArgumentException(THROW_WHERE
"Unexpected entry name syntax.",
2867 uno::Reference
<uno::XInterface
>(), 1);
2869 if (m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
2870 && (aElementName
== "_rels" || aNewName
== "_rels"))
2871 throw lang::IllegalArgumentException(THROW_WHERE
, uno::Reference
<uno::XInterface
>(),
2872 0); // TODO: unacceptable element name
2874 if (!(m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
))
2875 throw io::IOException(THROW_WHERE
); // TODO: access denied
2879 SotElement_Impl
* pRefElement
= m_pImpl
->FindElement(aNewName
);
2881 throw container::ElementExistException(THROW_WHERE
); //???
2883 auto pElement
= m_pImpl
->FindElement( aElementName
);
2885 throw container::NoSuchElementException(THROW_WHERE
); //???
2887 auto mapIt
= m_pImpl
->m_aChildrenMap
.find(aElementName
);
2888 auto rVec
= mapIt
->second
;
2889 for (auto it
= rVec
.begin(); it
!= rVec
.end(); ++it
)
2890 if (pElement
== *it
)
2892 rVec
.erase(std::remove(rVec
.begin(), rVec
.end(), pElement
), rVec
.end());
2894 m_pImpl
->m_aChildrenMap
.erase(mapIt
);
2897 m_pImpl
->m_aChildrenMap
[aNewName
].push_back(pElement
);
2898 m_pImpl
->m_bIsModified
= true;
2899 m_pImpl
->m_bBroadcastModified
= true;
2901 catch (const embed::InvalidStorageException
&)
2903 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2906 catch (const lang::IllegalArgumentException
&)
2908 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2911 catch (const container::NoSuchElementException
&)
2913 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2916 catch (const container::ElementExistException
&)
2918 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2921 catch (const io::IOException
&)
2923 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2926 catch (const embed::StorageWrappedTargetException
&)
2928 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2931 catch (const uno::RuntimeException
&)
2933 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2936 catch (const uno::Exception
&)
2938 uno::Any
aCaught(::cppu::getCaughtException());
2939 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
2941 throw embed::StorageWrappedTargetException(THROW_WHERE
"Can't rename element!",
2942 uno::Reference
<io::XInputStream
>(), aCaught
);
2946 BroadcastModifiedIfNecessary();
2949 void SAL_CALL
OStorage::copyElementTo( const OUString
& aElementName
,
2950 const uno::Reference
< embed::XStorage
>& xDest
,
2951 const OUString
& aNewName
)
2953 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
2957 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
2958 throw lang::DisposedException( THROW_WHERE
);
2961 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false )
2962 || aNewName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName
, false ) )
2963 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
2966 // || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
2967 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
2969 if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& ( aElementName
== "_rels" || aNewName
== "_rels" ) )
2970 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 ); // unacceptable element name
2974 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aElementName
);
2976 throw container::NoSuchElementException( THROW_WHERE
);
2978 uno::Reference
< XNameAccess
> xNameAccess( xDest
, uno::UNO_QUERY_THROW
);
2979 if ( xNameAccess
->hasByName( aNewName
) )
2980 throw container::ElementExistException( THROW_WHERE
);
2982 m_pImpl
->CopyStorageElement( pElement
, xDest
, aNewName
, false );
2984 catch( const embed::InvalidStorageException
& )
2986 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2989 catch( const lang::IllegalArgumentException
& )
2991 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2994 catch( const container::NoSuchElementException
& )
2996 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2999 catch( const container::ElementExistException
& )
3001 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3004 catch( const embed::StorageWrappedTargetException
& )
3006 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3009 catch( const io::IOException
& )
3011 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3014 catch( const uno::RuntimeException
& )
3016 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3019 catch( const uno::Exception
& )
3021 uno::Any
aCaught( ::cppu::getCaughtException() );
3022 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3024 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy element!",
3025 uno::Reference
< io::XInputStream
>(),
3030 void SAL_CALL
OStorage::moveElementTo( const OUString
& aElementName
,
3031 const uno::Reference
< embed::XStorage
>& xDest
,
3032 const OUString
& aNewName
)
3035 osl::MutexGuard
aGuard(m_pData
->m_xSharedMutex
->GetMutex());
3039 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3040 throw lang::DisposedException(THROW_WHERE
);
3043 if (aElementName
.isEmpty()
3044 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aElementName
, false)
3045 || aNewName
.isEmpty()
3046 || !::comphelper::OStorageHelper::IsValidZipEntryFileName(aNewName
, false))
3047 throw lang::IllegalArgumentException(THROW_WHERE
"Unexpected entry name syntax.",
3048 uno::Reference
<uno::XInterface
>(), 1);
3052 == uno::Reference
<uno::XInterface
>(static_cast<OWeakObject
*>(this),
3054 throw lang::IllegalArgumentException(THROW_WHERE
, uno::Reference
<uno::XInterface
>(), 2);
3056 if (m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
3057 && (aElementName
== "_rels" || aNewName
== "_rels"))
3058 throw lang::IllegalArgumentException(THROW_WHERE
, uno::Reference
<uno::XInterface
>(),
3059 0); // unacceptable element name
3061 if (!(m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
))
3062 throw io::IOException(THROW_WHERE
); // TODO: access denied
3066 auto pElement
= m_pImpl
->FindElement( aElementName
);
3068 throw container::NoSuchElementException(THROW_WHERE
); //???
3070 uno::Reference
<XNameAccess
> xNameAccess(xDest
, uno::UNO_QUERY_THROW
);
3071 if (xNameAccess
->hasByName(aNewName
))
3072 throw container::ElementExistException(THROW_WHERE
);
3074 m_pImpl
->CopyStorageElement(pElement
, xDest
, aNewName
, false);
3076 m_pImpl
->RemoveElement(aElementName
, pElement
);
3078 m_pImpl
->m_bIsModified
= true;
3079 m_pImpl
->m_bBroadcastModified
= true;
3081 catch (const embed::InvalidStorageException
&)
3083 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3086 catch (const lang::IllegalArgumentException
&)
3088 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3091 catch (const container::NoSuchElementException
&)
3093 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3096 catch (const container::ElementExistException
&)
3098 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3101 catch (const embed::StorageWrappedTargetException
&)
3103 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3106 catch (const io::IOException
&)
3108 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3111 catch (const uno::RuntimeException
&)
3113 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3116 catch (const uno::Exception
&)
3118 uno::Any
aCaught(::cppu::getCaughtException());
3119 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3121 throw embed::StorageWrappedTargetException(THROW_WHERE
"Can't move element!",
3122 uno::Reference
<io::XInputStream
>(), aCaught
);
3126 BroadcastModifiedIfNecessary();
3130 uno::Reference
< io::XStream
> SAL_CALL
OStorage::openEncryptedStream(
3131 const OUString
& aStreamName
, sal_Int32 nOpenMode
, const uno::Sequence
< beans::NamedValue
>& aEncryptionData
)
3133 osl::ClearableMutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3137 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3138 throw lang::DisposedException( THROW_WHERE
);
3141 if ( ( nOpenMode
& embed::ElementModes::WRITE
) && m_pData
->m_bReadOnlyWrap
)
3142 throw io::IOException( THROW_WHERE
); // TODO: access denied
3144 if ( !aEncryptionData
.hasElements() )
3145 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 3 );
3147 uno::Reference
< io::XStream
> xResult
;
3150 SotElement_Impl
*pElement
= OpenStreamElement_Impl( aStreamName
, nOpenMode
, true );
3151 OSL_ENSURE(pElement
&& pElement
->m_xStream
, "In case element can not be created an exception must be thrown!");
3153 xResult
= pElement
->m_xStream
->GetStream(nOpenMode
, aEncryptionData
, false);
3154 SAL_WARN_IF( !xResult
.is(), "package.xstor", "The method must throw exception instead of removing empty result!" );
3156 if ( m_pData
->m_bReadOnlyWrap
)
3158 // before the storage disposes the stream it must deregister itself as listener
3159 uno::Reference
< lang::XComponent
> xStreamComponent( xResult
, uno::UNO_QUERY_THROW
);
3160 MakeLinkToSubComponent_Impl( xStreamComponent
);
3163 catch( const embed::InvalidStorageException
& )
3165 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3168 catch( const lang::IllegalArgumentException
& )
3170 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3173 catch( const packages::NoEncryptionException
& )
3175 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3178 catch( const packages::WrongPasswordException
& )
3180 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3183 catch( const embed::StorageWrappedTargetException
& )
3185 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3188 catch( const io::IOException
& )
3190 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3193 catch( const uno::RuntimeException
& )
3195 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3198 catch( const uno::Exception
& )
3200 uno::Any
aCaught( ::cppu::getCaughtException() );
3201 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3203 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't open encrypted stream!",
3204 uno::Reference
< io::XInputStream
>(),
3210 BroadcastModifiedIfNecessary();
3215 uno::Reference
< io::XStream
> SAL_CALL
OStorage::cloneEncryptedStream(
3216 const OUString
& aStreamName
,
3217 const uno::Sequence
< beans::NamedValue
>& aEncryptionData
)
3219 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3223 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3224 throw lang::DisposedException( THROW_WHERE
);
3227 if ( !aEncryptionData
.hasElements() )
3228 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
3232 uno::Reference
< io::XStream
> xResult
;
3233 m_pImpl
->CloneStreamElement( aStreamName
, true, aEncryptionData
, xResult
);
3234 if ( !xResult
.is() )
3235 throw uno::RuntimeException( THROW_WHERE
);
3238 catch( const embed::InvalidStorageException
& )
3240 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3243 catch( const lang::IllegalArgumentException
& )
3245 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3248 catch( const packages::NoEncryptionException
& )
3250 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3253 catch( const packages::WrongPasswordException
& )
3255 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3258 catch( const io::IOException
& )
3260 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3263 catch( const embed::StorageWrappedTargetException
& )
3265 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3268 catch( const uno::RuntimeException
& )
3270 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3273 catch( const uno::Exception
& )
3275 uno::Any
aCaught( ::cppu::getCaughtException() );
3276 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3278 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't clone encrypted stream!",
3279 uno::Reference
< io::XInputStream
>(),
3284 // XStorageRawAccess
3285 uno::Reference
< io::XInputStream
> SAL_CALL
OStorage::getPlainRawStreamElement(
3286 const OUString
& sStreamName
)
3288 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3292 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3293 throw lang::DisposedException( THROW_WHERE
);
3296 if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
)
3297 throw uno::RuntimeException( THROW_WHERE
); // the interface is not supported and must not be accessible
3299 if ( sStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName
, false ) )
3300 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
3302 uno::Reference
< io::XInputStream
> xTempIn
;
3305 SotElement_Impl
* pElement
= m_pImpl
->FindElement( sStreamName
);
3307 throw container::NoSuchElementException( THROW_WHERE
);
3309 if (!pElement
->m_xStream
)
3311 m_pImpl
->OpenSubStream( pElement
);
3312 if (!pElement
->m_xStream
)
3313 throw io::IOException( THROW_WHERE
);
3316 uno::Reference
<io::XInputStream
> xRawInStream
= pElement
->m_xStream
->GetPlainRawInStream();
3317 if ( !xRawInStream
.is() )
3318 throw io::IOException( THROW_WHERE
);
3320 uno::Reference
< io::XTempFile
> xTempFile
= io::TempFile::create( m_pImpl
->m_xContext
);
3321 uno::Reference
< io::XOutputStream
> xTempOut
= xTempFile
->getOutputStream();
3322 xTempIn
= xTempFile
->getInputStream();
3323 uno::Reference
< io::XSeekable
> xSeek( xTempOut
, uno::UNO_QUERY
);
3325 if ( !xTempOut
.is() || !xTempIn
.is() || !xSeek
.is() )
3326 throw io::IOException( THROW_WHERE
);
3328 // Copy temporary file to a new one
3329 ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream
, xTempOut
);
3330 xTempOut
->closeOutput();
3333 catch( const embed::InvalidStorageException
& )
3335 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3338 catch( const lang::IllegalArgumentException
& )
3340 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3343 catch( const container::NoSuchElementException
& )
3345 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3348 catch( const embed::StorageWrappedTargetException
& )
3350 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3353 catch( const io::IOException
& )
3355 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3358 catch( const uno::RuntimeException
& )
3360 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3363 catch( const uno::Exception
& )
3365 uno::Any
aCaught( ::cppu::getCaughtException() );
3366 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3368 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't get plain raw stream!",
3369 uno::Reference
< io::XInputStream
>(),
3376 uno::Reference
< io::XInputStream
> SAL_CALL
OStorage::getRawEncrStreamElement(
3377 const OUString
& sStreamName
)
3379 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3383 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3384 throw lang::DisposedException( THROW_WHERE
);
3387 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
3388 throw packages::NoEncryptionException( THROW_WHERE
);
3390 if ( sStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName
, false ) )
3391 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
3393 uno::Reference
< io::XInputStream
> xTempIn
;
3396 SotElement_Impl
* pElement
= m_pImpl
->FindElement( sStreamName
);
3398 throw container::NoSuchElementException( THROW_WHERE
);
3400 if (!pElement
->m_xStream
)
3402 m_pImpl
->OpenSubStream( pElement
);
3403 if (!pElement
->m_xStream
)
3404 throw io::IOException( THROW_WHERE
);
3407 if (!pElement
->m_xStream
->IsEncrypted())
3408 throw packages::NoEncryptionException( THROW_WHERE
);
3410 uno::Reference
< io::XInputStream
> xRawInStream
= pElement
->m_xStream
->GetRawInStream();
3411 if ( !xRawInStream
.is() )
3412 throw io::IOException( THROW_WHERE
);
3414 uno::Reference
< io::XTempFile
> xTempFile
= io::TempFile::create(m_pImpl
->m_xContext
);
3415 uno::Reference
< io::XOutputStream
> xTempOut
= xTempFile
->getOutputStream();
3416 xTempIn
= xTempFile
->getInputStream();
3417 uno::Reference
< io::XSeekable
> xSeek( xTempOut
, uno::UNO_QUERY
);
3419 if ( !xTempOut
.is() || !xTempIn
.is() || !xSeek
.is() )
3420 throw io::IOException( THROW_WHERE
);
3422 // Copy temporary file to a new one
3423 ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream
, xTempOut
);
3424 xTempOut
->closeOutput();
3428 catch( const embed::InvalidStorageException
& )
3430 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3433 catch( const lang::IllegalArgumentException
& )
3435 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3438 catch( const packages::NoEncryptionException
& )
3440 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3443 catch( const container::NoSuchElementException
& )
3445 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3448 catch( const embed::StorageWrappedTargetException
& )
3450 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3453 catch( const io::IOException
& )
3455 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3458 catch( const uno::RuntimeException
& )
3460 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3463 catch( const uno::Exception
& )
3465 uno::Any
aCaught( ::cppu::getCaughtException() );
3466 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3468 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't get raw stream!",
3469 uno::Reference
< io::XInputStream
>(),
3476 void SAL_CALL
OStorage::insertRawEncrStreamElement( const OUString
& aStreamName
,
3477 const uno::Reference
< io::XInputStream
>& xInStream
)
3479 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3483 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3484 throw lang::DisposedException( THROW_WHERE
);
3487 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
3488 throw embed::InvalidStorageException( THROW_WHERE
);
3490 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
3491 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
3493 if ( !xInStream
.is() )
3494 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
3496 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
) )
3497 throw io::IOException( THROW_WHERE
); // TODO: access denied
3501 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aStreamName
);
3503 throw container::ElementExistException( THROW_WHERE
);
3505 m_pImpl
->InsertRawStream( aStreamName
, xInStream
);
3507 catch( const embed::InvalidStorageException
& )
3509 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3512 catch( const lang::IllegalArgumentException
& )
3514 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3517 catch( const packages::NoRawFormatException
& )
3519 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3522 catch( const container::ElementExistException
& )
3524 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3527 catch( const embed::StorageWrappedTargetException
& )
3529 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3532 catch( const io::IOException
& )
3534 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3537 catch( const uno::RuntimeException
& )
3539 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3542 catch( const uno::Exception
& )
3544 uno::Any
aCaught( ::cppu::getCaughtException() );
3545 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3547 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't insert raw stream!",
3548 uno::Reference
< io::XInputStream
>(),
3553 // XTransactedObject
3554 void SAL_CALL
OStorage::commit()
3556 uno::Reference
< util::XModifiable
> xParentModif
;
3559 BroadcastTransaction( STOR_MESS_PRECOMMIT
);
3561 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3565 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3566 throw lang::DisposedException( THROW_WHERE
);
3569 if ( m_pData
->m_bReadOnlyWrap
)
3570 throw io::IOException( THROW_WHERE
); // TODO: access_denied
3572 m_pImpl
->Commit(); // the root storage initiates the storing to source
3574 // when the storage is committed the parent is modified
3575 if ( m_pImpl
->m_pParent
&& m_pImpl
->m_pParent
->m_pAntiImpl
)
3576 xParentModif
= static_cast<util::XModifiable
*>(m_pImpl
->m_pParent
->m_pAntiImpl
);
3578 catch( const io::IOException
& )
3580 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3583 catch( const embed::StorageWrappedTargetException
& )
3585 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3588 catch( const uno::RuntimeException
& )
3590 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3593 catch( const uno::Exception
& )
3595 uno::Any
aCaught( ::cppu::getCaughtException() );
3596 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3598 throw embed::StorageWrappedTargetException( THROW_WHERE
"Problems on commit!",
3599 static_cast< ::cppu::OWeakObject
* >( this ),
3603 setModified( false );
3604 if ( xParentModif
.is() )
3605 xParentModif
->setModified( true );
3607 BroadcastTransaction( STOR_MESS_COMMITTED
);
3610 void SAL_CALL
OStorage::revert()
3612 // the method removes all the changes done after last commit
3614 BroadcastTransaction( STOR_MESS_PREREVERT
);
3617 osl::MutexGuard
aGuard(m_pData
->m_xSharedMutex
->GetMutex());
3621 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3622 throw lang::DisposedException(THROW_WHERE
);
3625 for (const auto & rPair
: m_pImpl
->m_aChildrenMap
)
3626 for (auto pElement
: rPair
.second
)
3628 bool bThrow
= (pElement
->m_xStorage
3629 && (pElement
->m_xStorage
->m_pAntiImpl
3630 || !pElement
->m_xStorage
->m_aReadOnlyWrapVector
.empty()))
3631 || (pElement
->m_xStream
3632 && (pElement
->m_xStream
->m_pAntiImpl
3633 || !pElement
->m_xStream
->m_aInputStreamsVector
.empty()));
3635 throw io::IOException(THROW_WHERE
); // TODO: access denied
3638 if (m_pData
->m_bReadOnlyWrap
|| !m_pImpl
->m_bListCreated
)
3639 return; // nothing to do
3644 m_pImpl
->m_bIsModified
= false;
3645 m_pImpl
->m_bBroadcastModified
= true;
3647 catch (const io::IOException
&)
3649 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3652 catch (const embed::StorageWrappedTargetException
&)
3654 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3657 catch (const uno::RuntimeException
&)
3659 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3662 catch (const uno::Exception
&)
3664 uno::Any
aCaught(::cppu::getCaughtException());
3665 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3667 throw embed::StorageWrappedTargetException(THROW_WHERE
"Problems on revert!",
3668 static_cast<::cppu::OWeakObject
*>(this),
3673 setModified( false );
3674 BroadcastTransaction( STOR_MESS_REVERTED
);
3677 // XTransactionBroadcaster
3678 void SAL_CALL
OStorage::addTransactionListener( const uno::Reference
< embed::XTransactionListener
>& aListener
)
3680 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3684 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3685 throw lang::DisposedException( THROW_WHERE
);
3688 m_pData
->m_aListenersContainer
.addInterface( cppu::UnoType
<embed::XTransactionListener
>::get(),
3692 void SAL_CALL
OStorage::removeTransactionListener( const uno::Reference
< embed::XTransactionListener
>& aListener
)
3694 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3698 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3699 throw lang::DisposedException( THROW_WHERE
);
3702 m_pData
->m_aListenersContainer
.removeInterface( cppu::UnoType
<embed::XTransactionListener
>::get(),
3707 // TODO: if there will be no demand on this interface it will be removed from implementation,
3708 // I do not want to remove it now since it is still possible that it will be inserted
3709 // to the service back.
3711 sal_Bool SAL_CALL
OStorage::isModified()
3713 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3717 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3718 throw lang::DisposedException( THROW_WHERE
);
3721 return m_pImpl
->m_bIsModified
;
3724 void SAL_CALL
OStorage::setModified( sal_Bool bModified
)
3727 osl::MutexGuard
aGuard(m_pData
->m_xSharedMutex
->GetMutex());
3731 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3732 throw lang::DisposedException(THROW_WHERE
);
3735 if (m_pData
->m_bReadOnlyWrap
)
3736 throw beans::PropertyVetoException(THROW_WHERE
); // TODO: access denied
3738 if (m_pImpl
->m_bIsModified
!= bool(bModified
))
3739 m_pImpl
->m_bIsModified
= bModified
;
3744 m_pImpl
->m_bBroadcastModified
= true;
3745 BroadcastModifiedIfNecessary();
3749 void SAL_CALL
OStorage::addModifyListener(
3750 const uno::Reference
< util::XModifyListener
>& aListener
)
3752 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3756 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3757 throw lang::DisposedException( THROW_WHERE
);
3760 osl_atomic_increment( &m_pImpl
->m_nModifiedListenerCount
);
3761 m_pData
->m_aListenersContainer
.addInterface(
3762 cppu::UnoType
<util::XModifyListener
>::get(), aListener
);
3765 void SAL_CALL
OStorage::removeModifyListener(
3766 const uno::Reference
< util::XModifyListener
>& aListener
)
3768 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3772 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3773 throw lang::DisposedException( THROW_WHERE
);
3776 osl_atomic_decrement( &m_pImpl
->m_nModifiedListenerCount
);
3777 m_pData
->m_aListenersContainer
.removeInterface(
3778 cppu::UnoType
<util::XModifyListener
>::get(), aListener
);
3783 uno::Any SAL_CALL
OStorage::getByName( const OUString
& aName
)
3785 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3789 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3790 throw lang::DisposedException( THROW_WHERE
);
3793 if ( aName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aName
, false ) )
3794 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
3796 if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aName
== "_rels" )
3797 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable element name
3802 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aName
);
3804 throw container::NoSuchElementException( THROW_WHERE
);
3806 if ( pElement
->m_bIsStorage
)
3807 aResult
<<= openStorageElement( aName
, embed::ElementModes::READ
);
3809 aResult
<<= openStreamElement( aName
, embed::ElementModes::READ
);
3811 catch( const container::NoSuchElementException
& )
3813 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3816 catch( const lang::WrappedTargetException
& )
3818 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3821 catch( const uno::RuntimeException
& )
3823 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3826 catch( const uno::Exception
& )
3828 uno::Any
aCaught( ::cppu::getCaughtException() );
3829 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3831 throw lang::WrappedTargetException( THROW_WHERE
"Can not open storage!",
3832 static_cast< OWeakObject
* >( this ),
3839 uno::Sequence
< OUString
> SAL_CALL
OStorage::getElementNames()
3841 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3845 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3846 throw lang::DisposedException( THROW_WHERE
);
3851 return m_pImpl
->GetElementNames();
3853 catch( const uno::RuntimeException
& )
3855 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3858 catch ( const uno::Exception
& )
3860 uno::Any
aCaught( ::cppu::getCaughtException() );
3861 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3863 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open storage!",
3864 static_cast< OWeakObject
* >( this ),
3869 sal_Bool SAL_CALL
OStorage::hasByName( const OUString
& aName
)
3871 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3875 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3876 throw lang::DisposedException( THROW_WHERE
);
3879 if ( aName
.isEmpty() )
3882 if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aName
== "_rels" )
3885 SotElement_Impl
* pElement
= nullptr;
3888 pElement
= m_pImpl
->FindElement( aName
);
3890 catch( const uno::RuntimeException
& )
3892 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3895 catch ( const uno::Exception
& )
3897 uno::Any
aCaught( ::cppu::getCaughtException() );
3898 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3900 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open storage!",
3901 static_cast< OWeakObject
* >( this ),
3905 return ( pElement
!= nullptr );
3908 uno::Type SAL_CALL
OStorage::getElementType()
3910 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3914 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3915 throw lang::DisposedException( THROW_WHERE
);
3918 // it is a multitype container
3922 sal_Bool SAL_CALL
OStorage::hasElements()
3924 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3928 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3929 throw lang::DisposedException( THROW_WHERE
);
3934 return m_pImpl
->HasChildren();
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 ),
3953 void SAL_CALL
OStorage::dispose()
3955 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3959 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3960 throw lang::DisposedException( THROW_WHERE
);
3965 InternalDispose( true );
3967 catch( const uno::RuntimeException
& )
3969 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3972 catch( const uno::Exception
& )
3974 uno::Any
aCaught( ::cppu::getCaughtException() );
3975 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
3977 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open storage!",
3978 static_cast< OWeakObject
* >( this ),
3983 void SAL_CALL
OStorage::addEventListener(
3984 const uno::Reference
< lang::XEventListener
>& xListener
)
3986 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
3990 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
3991 throw lang::DisposedException( THROW_WHERE
);
3994 m_pData
->m_aListenersContainer
.addInterface(
3995 cppu::UnoType
<lang::XEventListener
>::get(), xListener
);
3998 void SAL_CALL
OStorage::removeEventListener(
3999 const uno::Reference
< lang::XEventListener
>& xListener
)
4001 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4005 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4006 throw lang::DisposedException( THROW_WHERE
);
4009 m_pData
->m_aListenersContainer
.removeInterface(
4010 cppu::UnoType
<lang::XEventListener
>::get(), xListener
);
4013 // XEncryptionProtectedSource
4015 void SAL_CALL
OStorage::setEncryptionPassword( const OUString
& aPass
)
4017 setEncryptionData( ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass
) );
4020 void SAL_CALL
OStorage::removeEncryption()
4022 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4026 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4027 throw lang::DisposedException( THROW_WHERE
);
4030 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4031 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4033 SAL_WARN_IF( !m_pData
->m_bIsRoot
, "package.xstor", "removeEncryption() method is not available for nonroot storages!" );
4034 if ( !m_pData
->m_bIsRoot
)
4038 m_pImpl
->ReadContents();
4040 catch ( const uno::RuntimeException
& )
4042 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4045 catch ( const uno::Exception
& )
4047 uno::Any
aCaught( ::cppu::getCaughtException() );
4048 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4050 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4051 static_cast< OWeakObject
* >( this ),
4055 // TODO: check if the password is valid
4056 // update all streams that was encrypted with old password
4058 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4061 xPackPropSet
->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY
,
4062 uno::makeAny( uno::Sequence
< beans::NamedValue
>() ) );
4064 m_pImpl
->m_bHasCommonEncryptionData
= false;
4065 m_pImpl
->m_aCommonEncryptionData
.clear();
4067 catch( const uno::RuntimeException
& )
4069 TOOLS_WARN_EXCEPTION( "package.xstor", "The call must not fail, it is pretty simple!" );
4072 catch( const uno::Exception
& )
4074 TOOLS_WARN_EXCEPTION( "package.xstor", "The call must not fail, it is pretty simple!" );
4075 throw io::IOException( THROW_WHERE
);
4079 // XEncryptionProtectedSource2
4081 void SAL_CALL
OStorage::setEncryptionData( const uno::Sequence
< beans::NamedValue
>& aEncryptionData
)
4083 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4087 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4088 throw lang::DisposedException( THROW_WHERE
);
4091 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4092 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4094 if ( !aEncryptionData
.hasElements() )
4095 throw uno::RuntimeException( THROW_WHERE
"Unexpected empty encryption data!" );
4097 SAL_WARN_IF( !m_pData
->m_bIsRoot
, "package.xstor", "setEncryptionData() method is not available for nonroot storages!" );
4098 if ( !m_pData
->m_bIsRoot
)
4102 m_pImpl
->ReadContents();
4104 catch ( const uno::RuntimeException
& )
4106 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4109 catch ( const uno::Exception
& )
4111 uno::Any
aCaught( ::cppu::getCaughtException() );
4112 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4114 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4115 static_cast< OWeakObject
* >( this ),
4119 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4122 ::comphelper::SequenceAsHashMap
aEncryptionMap( aEncryptionData
);
4123 xPackPropSet
->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY
,
4124 uno::makeAny( aEncryptionMap
.getAsConstNamedValueList() ) );
4126 m_pImpl
->m_bHasCommonEncryptionData
= true;
4127 m_pImpl
->m_aCommonEncryptionData
= aEncryptionMap
;
4129 catch( const uno::Exception
& )
4131 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:" );
4133 throw io::IOException( THROW_WHERE
);
4137 sal_Bool SAL_CALL
OStorage::hasEncryptionData()
4139 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4141 return m_pImpl
&& m_pImpl
->m_bHasCommonEncryptionData
;
4144 // XEncryptionProtectedStorage
4146 void SAL_CALL
OStorage::setEncryptionAlgorithms( const uno::Sequence
< beans::NamedValue
>& aAlgorithms
)
4148 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4152 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4153 throw lang::DisposedException( THROW_WHERE
);
4156 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4157 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4159 if ( !aAlgorithms
.hasElements() )
4160 throw uno::RuntimeException( THROW_WHERE
"Unexpected empty encryption algorithms list!" );
4162 SAL_WARN_IF( !m_pData
->m_bIsRoot
, "package.xstor", "setEncryptionAlgorithms() method is not available for nonroot storages!" );
4163 if ( !m_pData
->m_bIsRoot
)
4167 m_pImpl
->ReadContents();
4169 catch ( const uno::RuntimeException
& )
4171 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4174 catch ( const uno::Exception
& )
4176 uno::Any
aCaught( ::cppu::getCaughtException() );
4177 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4179 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4180 static_cast< OWeakObject
* >( this ),
4184 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4187 xPackPropSet
->setPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY
,
4188 uno::makeAny( aAlgorithms
) );
4190 catch ( const uno::RuntimeException
& )
4192 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4195 catch( const uno::Exception
& )
4197 uno::Any
aCaught( ::cppu::getCaughtException() );
4198 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4200 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4201 static_cast< OWeakObject
* >( this ),
4206 void SAL_CALL
OStorage::setGpgProperties( const uno::Sequence
< uno::Sequence
< beans::NamedValue
> >& aProps
)
4208 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4212 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4213 throw lang::DisposedException( THROW_WHERE
);
4216 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4217 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4219 if ( !aProps
.hasElements() )
4220 throw uno::RuntimeException( THROW_WHERE
"Unexpected empty encryption algorithms list!" );
4222 SAL_WARN_IF( !m_pData
->m_bIsRoot
, "package.xstor", "setGpgProperties() method is not available for nonroot storages!" );
4223 if ( !m_pData
->m_bIsRoot
)
4227 m_pImpl
->ReadContents();
4229 catch ( const uno::RuntimeException
& aRuntimeException
)
4231 SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException
.Message
);
4234 catch ( const uno::Exception
& )
4236 uno::Any
aCaught( ::cppu::getCaughtException() );
4237 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4239 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4240 static_cast< OWeakObject
* >( this ),
4244 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4247 xPackPropSet
->setPropertyValue( ENCRYPTION_GPG_PROPERTIES
,
4248 uno::makeAny( aProps
) );
4250 catch ( const uno::RuntimeException
& aRuntimeException
)
4252 SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException
.Message
);
4255 catch( const uno::Exception
& )
4257 uno::Any
aCaught( ::cppu::getCaughtException() );
4258 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4260 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4261 static_cast< OWeakObject
* >( this ),
4266 uno::Sequence
< beans::NamedValue
> SAL_CALL
OStorage::getEncryptionAlgorithms()
4268 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4272 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4273 throw lang::DisposedException( THROW_WHERE
);
4276 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
4277 throw uno::RuntimeException( THROW_WHERE
); // the interface must be visible only for package storage
4279 uno::Sequence
< beans::NamedValue
> aResult
;
4280 SAL_WARN_IF( !m_pData
->m_bIsRoot
, "package.xstor", "getEncryptionAlgorithms() method is not available for nonroot storages!" );
4281 if ( m_pData
->m_bIsRoot
)
4284 m_pImpl
->ReadContents();
4286 catch ( const uno::RuntimeException
& )
4288 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4291 catch ( const uno::Exception
& )
4293 uno::Any
aCaught( ::cppu::getCaughtException() );
4294 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4296 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4297 static_cast< OWeakObject
* >( this ),
4301 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4304 xPackPropSet
->getPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY
) >>= aResult
;
4306 catch ( const uno::RuntimeException
& )
4308 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4311 catch( const uno::Exception
& )
4313 uno::Any
aCaught( ::cppu::getCaughtException() );
4314 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4316 throw lang::WrappedTargetRuntimeException( THROW_WHERE
"Can not open package!",
4317 static_cast< OWeakObject
* >( this ),
4327 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
OStorage::getPropertySetInfo()
4329 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4333 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4334 throw lang::DisposedException( THROW_WHERE
);
4338 return uno::Reference
< beans::XPropertySetInfo
>();
4341 void SAL_CALL
OStorage::setPropertyValue( const OUString
& aPropertyName
, const uno::Any
& aValue
)
4343 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4347 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4348 throw lang::DisposedException( THROW_WHERE
);
4351 //TODO: think about interaction handler
4354 // The old document might have no version in the manifest.xml, so we have to allow to set the version
4355 // even for readonly storages, so that the version from content.xml can be used.
4356 if ( m_pData
->m_bReadOnlyWrap
&& aPropertyName
!= "Version" )
4357 throw uno::RuntimeException( THROW_WHERE
); // TODO: Access denied
4359 if ( m_pData
->m_nStorageType
== embed::StorageFormats::ZIP
)
4360 throw beans::UnknownPropertyException( aPropertyName
);
4361 else if ( m_pData
->m_nStorageType
== embed::StorageFormats::PACKAGE
)
4363 if ( aPropertyName
== "MediaType" )
4365 aValue
>>= m_pImpl
->m_aMediaType
;
4366 m_pImpl
->m_bControlMediaType
= true;
4368 m_pImpl
->m_bBroadcastModified
= true;
4369 m_pImpl
->m_bIsModified
= true;
4371 else if ( aPropertyName
== "Version" )
4373 aValue
>>= m_pImpl
->m_aVersion
;
4374 m_pImpl
->m_bControlVersion
= true;
4376 // this property can be set even for readonly storage
4377 if ( !m_pData
->m_bReadOnlyWrap
)
4379 m_pImpl
->m_bBroadcastModified
= true;
4380 m_pImpl
->m_bIsModified
= true;
4383 else if ( ( m_pData
->m_bIsRoot
&& ( aPropertyName
== HAS_ENCRYPTED_ENTRIES_PROPERTY
4384 || aPropertyName
== HAS_NONENCRYPTED_ENTRIES_PROPERTY
4385 || aPropertyName
== IS_INCONSISTENT_PROPERTY
4386 || aPropertyName
== "URL"
4387 || aPropertyName
== "RepairPackage"
4388 || aPropertyName
== ENCRYPTION_GPG_PROPERTIES
) )
4389 || aPropertyName
== "IsRoot"
4390 || aPropertyName
== MEDIATYPE_FALLBACK_USED_PROPERTY
)
4391 throw beans::PropertyVetoException( THROW_WHERE
);
4393 throw beans::UnknownPropertyException( aPropertyName
);
4395 else if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
)
4397 if ( aPropertyName
== "RelationsInfoStream" )
4399 uno::Reference
< io::XInputStream
> xInRelStream
;
4400 if ( !( aValue
>>= xInRelStream
) || !xInRelStream
.is() )
4401 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
4403 uno::Reference
< io::XSeekable
> xSeek( xInRelStream
, uno::UNO_QUERY
);
4406 // currently this is an internal property that is used for optimization
4407 // and the stream must support XSeekable interface
4408 // TODO/LATER: in future it can be changed if property is used from outside
4409 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
4412 m_pImpl
->m_xNewRelInfoStream
= xInRelStream
;
4413 m_pImpl
->m_aRelInfo
= uno::Sequence
< uno::Sequence
< beans::StringPair
> >();
4414 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED_STREAM
;
4415 m_pImpl
->m_bBroadcastModified
= true;
4416 m_pImpl
->m_bIsModified
= true;
4418 else if ( aPropertyName
== "RelationsInfo" )
4420 if ( !(aValue
>>= m_pImpl
->m_aRelInfo
) )
4421 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
4423 m_pImpl
->m_xNewRelInfoStream
.clear();
4424 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4425 m_pImpl
->m_bBroadcastModified
= true;
4426 m_pImpl
->m_bIsModified
= true;
4428 else if ( ( m_pData
->m_bIsRoot
&& ( aPropertyName
== "URL" || aPropertyName
== "RepairPackage") )
4429 || aPropertyName
== "IsRoot" )
4430 throw beans::PropertyVetoException( THROW_WHERE
);
4432 throw beans::UnknownPropertyException( aPropertyName
);
4435 throw beans::UnknownPropertyException( aPropertyName
);
4437 BroadcastModifiedIfNecessary();
4440 uno::Any SAL_CALL
OStorage::getPropertyValue( const OUString
& aPropertyName
)
4442 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4446 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4447 throw lang::DisposedException( THROW_WHERE
);
4450 if ( m_pData
->m_nStorageType
== embed::StorageFormats::PACKAGE
4451 && ( aPropertyName
== "MediaType" || aPropertyName
== MEDIATYPE_FALLBACK_USED_PROPERTY
|| aPropertyName
== "Version" ) )
4455 m_pImpl
->ReadContents();
4457 catch ( const uno::RuntimeException
& )
4459 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4462 catch ( const uno::Exception
& )
4464 uno::Any
aCaught( ::cppu::getCaughtException() );
4465 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4467 throw lang::WrappedTargetException(
4468 "Can't read contents!",
4469 static_cast< OWeakObject
* >( this ),
4473 if ( aPropertyName
== "MediaType" )
4474 return uno::makeAny( m_pImpl
->m_aMediaType
);
4475 else if ( aPropertyName
== "Version" )
4476 return uno::makeAny( m_pImpl
->m_aVersion
);
4478 return uno::makeAny( m_pImpl
->m_bMTFallbackUsed
);
4480 else if ( aPropertyName
== "IsRoot" )
4482 return uno::makeAny( m_pData
->m_bIsRoot
);
4484 else if ( aPropertyName
== "OpenMode" )
4486 return uno::makeAny( m_pImpl
->m_nStorageMode
);
4488 else if ( m_pData
->m_bIsRoot
)
4490 if ( aPropertyName
== "URL"
4491 || aPropertyName
== "RepairPackage" )
4493 auto pProp
= std::find_if(std::cbegin(m_pImpl
->m_xProperties
), std::cend(m_pImpl
->m_xProperties
),
4494 [&aPropertyName
](const css::beans::PropertyValue
& rProp
) { return rProp
.Name
== aPropertyName
; });
4495 if (pProp
!= std::cend(m_pImpl
->m_xProperties
))
4496 return pProp
->Value
;
4498 if ( aPropertyName
== "URL" )
4499 return uno::makeAny( OUString() );
4501 return uno::makeAny( false ); // RepairPackage
4503 else if ( m_pData
->m_nStorageType
== embed::StorageFormats::PACKAGE
4504 && ( aPropertyName
== HAS_ENCRYPTED_ENTRIES_PROPERTY
4505 || aPropertyName
== HAS_NONENCRYPTED_ENTRIES_PROPERTY
4506 || aPropertyName
== ENCRYPTION_GPG_PROPERTIES
4507 || aPropertyName
== IS_INCONSISTENT_PROPERTY
) )
4510 m_pImpl
->ReadContents();
4511 uno::Reference
< beans::XPropertySet
> xPackPropSet( m_pImpl
->m_xPackage
, uno::UNO_QUERY_THROW
);
4512 return xPackPropSet
->getPropertyValue( aPropertyName
);
4514 catch ( const uno::RuntimeException
& )
4516 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4519 catch ( const uno::Exception
& )
4521 uno::Any
aCaught( ::cppu::getCaughtException() );
4522 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
4524 throw lang::WrappedTargetException( THROW_WHERE
"Can not open package!",
4525 static_cast< OWeakObject
* >( this ),
4531 throw beans::UnknownPropertyException(aPropertyName
);
4534 void SAL_CALL
OStorage::addPropertyChangeListener(
4535 const OUString
& /*aPropertyName*/,
4536 const uno::Reference
< beans::XPropertyChangeListener
>& /*xListener*/ )
4538 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4542 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4543 throw lang::DisposedException( THROW_WHERE
);
4549 void SAL_CALL
OStorage::removePropertyChangeListener(
4550 const OUString
& /*aPropertyName*/,
4551 const uno::Reference
< beans::XPropertyChangeListener
>& /*aListener*/ )
4553 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4557 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4558 throw lang::DisposedException( THROW_WHERE
);
4564 void SAL_CALL
OStorage::addVetoableChangeListener(
4565 const OUString
& /*PropertyName*/,
4566 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
4568 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4572 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4573 throw lang::DisposedException( THROW_WHERE
);
4579 void SAL_CALL
OStorage::removeVetoableChangeListener(
4580 const OUString
& /*PropertyName*/,
4581 const uno::Reference
< beans::XVetoableChangeListener
>& /*aListener*/ )
4583 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4587 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4588 throw lang::DisposedException( THROW_WHERE
);
4594 // XRelationshipAccess
4596 // TODO/LATER: the storage and stream implementations of this interface are very similar, they could use a helper class
4598 sal_Bool SAL_CALL
OStorage::hasByID( const OUString
& sID
)
4600 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4604 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4605 throw lang::DisposedException( THROW_WHERE
);
4608 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4609 throw uno::RuntimeException( THROW_WHERE
);
4613 getRelationshipByID( sID
);
4616 catch( const container::NoSuchElementException
& )
4618 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4627 const beans::StringPair
* lcl_findPairByName(const uno::Sequence
<beans::StringPair
>& rSeq
, const OUString
& rName
)
4629 return std::find_if(rSeq
.begin(), rSeq
.end(), [&rName
](const beans::StringPair
& rPair
) { return rPair
.First
== rName
; });
4634 OUString SAL_CALL
OStorage::getTargetByID( const OUString
& sID
)
4636 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4640 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4641 throw lang::DisposedException( THROW_WHERE
);
4644 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4645 throw uno::RuntimeException( THROW_WHERE
);
4647 const uno::Sequence
< beans::StringPair
> aSeq
= getRelationshipByID( sID
);
4648 auto pRel
= lcl_findPairByName(aSeq
, "Target");
4649 if (pRel
!= aSeq
.end())
4650 return pRel
->Second
;
4655 OUString SAL_CALL
OStorage::getTypeByID( const OUString
& sID
)
4657 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4661 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4662 throw lang::DisposedException( THROW_WHERE
);
4665 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4666 throw uno::RuntimeException( THROW_WHERE
);
4668 const uno::Sequence
< beans::StringPair
> aSeq
= getRelationshipByID( sID
);
4669 auto pRel
= lcl_findPairByName(aSeq
, "Type");
4670 if (pRel
!= aSeq
.end())
4671 return pRel
->Second
;
4676 uno::Sequence
< beans::StringPair
> SAL_CALL
OStorage::getRelationshipByID( const OUString
& sID
)
4678 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4682 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4683 throw lang::DisposedException( THROW_WHERE
);
4686 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4687 throw uno::RuntimeException( THROW_WHERE
);
4689 // TODO/LATER: in future the unification of the ID could be checked
4690 const uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4691 const beans::StringPair
aIDRel("Id", sID
);
4693 auto pRel
= std::find_if(aSeq
.begin(), aSeq
.end(),
4694 [&aIDRel
](const uno::Sequence
<beans::StringPair
>& rRel
) {
4695 return std::find(rRel
.begin(), rRel
.end(), aIDRel
) != rRel
.end(); });
4696 if (pRel
!= aSeq
.end())
4699 throw container::NoSuchElementException( THROW_WHERE
);
4702 uno::Sequence
< uno::Sequence
< beans::StringPair
> > SAL_CALL
OStorage::getRelationshipsByType( const OUString
& sType
)
4704 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4708 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4709 throw lang::DisposedException( THROW_WHERE
);
4712 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4713 throw uno::RuntimeException( THROW_WHERE
);
4715 // TODO/LATER: in future the unification of the ID could be checked
4716 const uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4717 std::vector
< uno::Sequence
< beans::StringPair
> > aResult
;
4718 aResult
.reserve(aSeq
.getLength());
4720 std::copy_if(aSeq
.begin(), aSeq
.end(), std::back_inserter(aResult
),
4721 [&sType
](const uno::Sequence
<beans::StringPair
>& rRel
) {
4722 auto pRel
= lcl_findPairByName(rRel
, "Type");
4723 return pRel
!= rRel
.end()
4724 // the type is usually a URL, so the check should be case insensitive
4725 && pRel
->Second
.equalsIgnoreAsciiCase( sType
);
4728 return comphelper::containerToSequence(aResult
);
4731 uno::Sequence
< uno::Sequence
< beans::StringPair
> > SAL_CALL
OStorage::getAllRelationships()
4733 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4737 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4738 throw lang::DisposedException( THROW_WHERE
);
4741 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4742 throw uno::RuntimeException( THROW_WHERE
);
4744 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aRet
;
4747 aRet
= m_pImpl
->GetAllRelationshipsIfAny();
4749 catch (const io::IOException
&)
4753 catch (const uno::RuntimeException
&)
4757 catch (const uno::Exception
&)
4759 uno::Any
aCaught( ::cppu::getCaughtException() );
4760 throw lang::WrappedTargetRuntimeException(THROW_WHERE
"Can't getAllRelationships!",
4761 uno::Reference
< uno::XInterface
>(),
4768 void SAL_CALL
OStorage::insertRelationshipByID( const OUString
& sID
, const uno::Sequence
< beans::StringPair
>& aEntry
, sal_Bool bReplace
)
4770 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4774 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4775 throw lang::DisposedException( THROW_WHERE
);
4778 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4779 throw uno::RuntimeException( THROW_WHERE
);
4781 const beans::StringPair
aIDRel("Id", sID
);
4783 sal_Int32 nIDInd
= -1;
4785 // TODO/LATER: in future the unification of the ID could be checked
4786 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4787 for ( sal_Int32 nInd
= 0; nInd
< aSeq
.getLength(); nInd
++ )
4789 const auto& rRel
= aSeq
[nInd
];
4790 if (std::find(rRel
.begin(), rRel
.end(), aIDRel
) != rRel
.end())
4794 if ( nIDInd
!= -1 && !bReplace
)
4795 throw container::ElementExistException( THROW_WHERE
);
4799 nIDInd
= aSeq
.getLength();
4800 aSeq
.realloc( nIDInd
+ 1 );
4803 std::vector
<beans::StringPair
> aResult
;
4804 aResult
.reserve(aEntry
.getLength() + 1);
4806 aResult
.push_back(aIDRel
);
4807 std::copy_if(aEntry
.begin(), aEntry
.end(), std::back_inserter(aResult
),
4808 [](const beans::StringPair
& rPair
) { return rPair
.First
!= "Id"; });
4810 aSeq
[nIDInd
] = comphelper::containerToSequence(aResult
);
4812 m_pImpl
->m_aRelInfo
= aSeq
;
4813 m_pImpl
->m_xNewRelInfoStream
.clear();
4814 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4817 void SAL_CALL
OStorage::removeRelationshipByID( const OUString
& sID
)
4819 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4823 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4824 throw lang::DisposedException( THROW_WHERE
);
4827 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4828 throw uno::RuntimeException( THROW_WHERE
);
4830 uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4831 const beans::StringPair
aIDRel("Id", sID
);
4832 auto pRel
= std::find_if(std::cbegin(aSeq
), std::cend(aSeq
),
4833 [&aIDRel
](const uno::Sequence
< beans::StringPair
>& rRel
) {
4834 return std::find(rRel
.begin(), rRel
.end(), aIDRel
) != rRel
.end(); });
4835 if (pRel
!= std::cend(aSeq
))
4837 auto nInd
= static_cast<sal_Int32
>(std::distance(std::cbegin(aSeq
), pRel
));
4838 comphelper::removeElementAt(aSeq
, nInd
);
4840 m_pImpl
->m_aRelInfo
= aSeq
;
4841 m_pImpl
->m_xNewRelInfoStream
.clear();
4842 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4844 // TODO/LATER: in future the unification of the ID could be checked
4848 throw container::NoSuchElementException( THROW_WHERE
);
4851 void SAL_CALL
OStorage::insertRelationships( const uno::Sequence
< uno::Sequence
< beans::StringPair
> >& aEntries
, sal_Bool bReplace
)
4853 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4857 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4858 throw lang::DisposedException( THROW_WHERE
);
4861 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4862 throw uno::RuntimeException( THROW_WHERE
);
4864 OUString
aIDTag( "Id" );
4865 const uno::Sequence
< uno::Sequence
< beans::StringPair
> > aSeq
= getAllRelationships();
4866 std::vector
< uno::Sequence
<beans::StringPair
> > aResultVec
;
4867 aResultVec
.reserve(aSeq
.getLength() + aEntries
.getLength());
4869 std::copy_if(aSeq
.begin(), aSeq
.end(), std::back_inserter(aResultVec
),
4870 [&aIDTag
, &aEntries
, bReplace
](const uno::Sequence
<beans::StringPair
>& rTargetRel
) {
4871 auto pTargetPair
= lcl_findPairByName(rTargetRel
, aIDTag
);
4872 if (pTargetPair
== rTargetRel
.end())
4875 bool bIsSourceSame
= std::any_of(aEntries
.begin(), aEntries
.end(),
4876 [&pTargetPair
](const uno::Sequence
<beans::StringPair
>& rSourceEntry
) {
4877 return std::find(rSourceEntry
.begin(), rSourceEntry
.end(), *pTargetPair
) != rSourceEntry
.end(); });
4879 if ( bIsSourceSame
&& !bReplace
)
4880 throw container::ElementExistException( THROW_WHERE
);
4882 // if no such element in the provided sequence
4883 return !bIsSourceSame
;
4886 std::transform(aEntries
.begin(), aEntries
.end(), std::back_inserter(aResultVec
),
4887 [&aIDTag
](const uno::Sequence
<beans::StringPair
>& rEntry
) -> uno::Sequence
<beans::StringPair
> {
4888 auto pPair
= lcl_findPairByName(rEntry
, aIDTag
);
4889 if (pPair
== rEntry
.end())
4890 throw io::IOException( THROW_WHERE
); // TODO: illegal relation ( no ID )
4892 auto aResult
= comphelper::sequenceToContainer
<std::vector
<beans::StringPair
>>(rEntry
);
4893 auto nIDInd
= std::distance(rEntry
.begin(), pPair
);
4894 std::rotate(aResult
.begin(), std::next(aResult
.begin(), nIDInd
), std::next(aResult
.begin(), nIDInd
+ 1));
4896 return comphelper::containerToSequence(aResult
);
4899 m_pImpl
->m_aRelInfo
= comphelper::containerToSequence(aResultVec
);
4900 m_pImpl
->m_xNewRelInfoStream
.clear();
4901 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4904 void SAL_CALL
OStorage::clearRelationships()
4906 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4910 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4911 throw lang::DisposedException( THROW_WHERE
);
4914 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::OFOPXML
)
4915 throw uno::RuntimeException( THROW_WHERE
);
4917 m_pImpl
->m_aRelInfo
.realloc( 0 );
4918 m_pImpl
->m_xNewRelInfoStream
.clear();
4919 m_pImpl
->m_nRelInfoStatus
= RELINFO_CHANGED
;
4922 // XOptimizedStorage
4923 void SAL_CALL
OStorage::insertRawNonEncrStreamElementDirect(
4924 const OUString
& /*sStreamName*/,
4925 const uno::Reference
< io::XInputStream
>& /*xInStream*/ )
4927 // not implemented currently because there is still no demand
4928 // might need to be implemented if direct copying of compressed streams is used
4929 throw io::IOException( THROW_WHERE
);
4932 void SAL_CALL
OStorage::insertStreamElementDirect(
4933 const OUString
& aStreamName
,
4934 const uno::Reference
< io::XInputStream
>& xInStream
,
4935 const uno::Sequence
< beans::PropertyValue
>& aProps
)
4937 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
4941 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
4942 throw lang::DisposedException( THROW_WHERE
);
4945 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
4946 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
4948 if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStreamName
== "_rels" )
4949 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable storage name
4951 if ( m_pData
->m_bReadOnlyWrap
)
4952 throw io::IOException( THROW_WHERE
); // TODO: access denied
4956 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aStreamName
);
4959 throw container::ElementExistException( THROW_WHERE
);
4961 pElement
= OpenStreamElement_Impl( aStreamName
, embed::ElementModes::READWRITE
, false );
4962 OSL_ENSURE(pElement
&& pElement
->m_xStream
, "In case element can not be created an exception must be thrown!");
4964 pElement
->m_xStream
->InsertStreamDirectly(xInStream
, aProps
);
4966 catch( const embed::InvalidStorageException
& )
4968 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4971 catch( const lang::IllegalArgumentException
& )
4973 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4976 catch( const container::ElementExistException
& )
4978 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4981 catch( const embed::StorageWrappedTargetException
& )
4983 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4986 catch( const io::IOException
& )
4988 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4991 catch( const uno::RuntimeException
& )
4993 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4996 catch( const uno::Exception
& )
4998 uno::Any
aCaught( ::cppu::getCaughtException() );
4999 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5001 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't insert stream directly!",
5002 uno::Reference
< io::XInputStream
>(),
5007 void SAL_CALL
OStorage::copyElementDirectlyTo(
5008 const OUString
& aElementName
,
5009 const uno::Reference
< embed::XOptimizedStorage
>& xDest
,
5010 const OUString
& aNewName
)
5012 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
5016 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5017 throw lang::DisposedException( THROW_WHERE
);
5020 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false )
5021 || aNewName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName
, false ) )
5022 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5024 if ( !xDest
.is() || xDest
== uno::Reference
< uno::XInterface
>( static_cast< OWeakObject
* >( this ), uno::UNO_QUERY
) )
5025 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
5027 if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& ( aElementName
== "_rels" || aNewName
== "_rels" ) )
5028 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 ); // unacceptable name
5032 SotElement_Impl
* pElement
= m_pImpl
->FindElement( aElementName
);
5034 throw container::NoSuchElementException( THROW_WHERE
);
5036 uno::Reference
< XNameAccess
> xNameAccess( xDest
, uno::UNO_QUERY_THROW
);
5037 if ( xNameAccess
->hasByName( aNewName
) )
5038 throw container::ElementExistException( THROW_WHERE
);
5040 // let the element be copied directly
5041 uno::Reference
< embed::XStorage
> xStorDest( xDest
, uno::UNO_QUERY_THROW
);
5042 m_pImpl
->CopyStorageElement( pElement
, xStorDest
, aNewName
, true );
5044 catch( const embed::InvalidStorageException
& )
5046 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5049 catch( const lang::IllegalArgumentException
& )
5051 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5054 catch( const container::NoSuchElementException
& )
5056 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5059 catch( const container::ElementExistException
& )
5061 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5064 catch( const embed::StorageWrappedTargetException
& )
5066 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5069 catch( const io::IOException
& )
5071 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5074 catch( const uno::RuntimeException
& )
5076 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5079 catch( const uno::Exception
& )
5081 uno::Any
aCaught( ::cppu::getCaughtException() );
5082 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5084 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy element directly!",
5085 uno::Reference
< io::XInputStream
>(),
5090 void SAL_CALL
OStorage::writeAndAttachToStream( const uno::Reference
< io::XStream
>& xStream
)
5092 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
5096 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5097 throw lang::DisposedException( THROW_WHERE
);
5100 if ( !m_pData
->m_bIsRoot
)
5101 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
5103 if ( !m_pImpl
->m_pSwitchStream
)
5104 throw uno::RuntimeException( THROW_WHERE
);
5108 m_pImpl
->m_pSwitchStream
->CopyAndSwitchPersistenceTo( xStream
);
5110 catch( const embed::InvalidStorageException
& )
5112 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5115 catch( const lang::IllegalArgumentException
& )
5117 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5120 catch( const embed::StorageWrappedTargetException
& )
5122 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5125 catch( const io::IOException
& )
5127 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:" );
5130 catch( const uno::RuntimeException
& )
5132 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5135 catch( const uno::Exception
& )
5137 uno::Any
aCaught( ::cppu::getCaughtException() );
5138 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5140 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't write and attach to stream!",
5141 uno::Reference
< io::XInputStream
>(),
5147 void SAL_CALL
OStorage::attachToURL( const OUString
& sURL
,
5148 sal_Bool bReadOnly
)
5150 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
5154 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5155 throw lang::DisposedException( THROW_WHERE
);
5158 if ( !m_pData
->m_bIsRoot
)
5159 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 0 );
5161 if ( !m_pImpl
->m_pSwitchStream
)
5162 throw uno::RuntimeException( THROW_WHERE
);
5164 uno::Reference
< ucb::XSimpleFileAccess3
> xAccess(
5165 ucb::SimpleFileAccess::create( m_pImpl
->m_xContext
) );
5171 uno::Reference
< io::XInputStream
> xInputStream
= xAccess
->openFileRead( sURL
);
5172 m_pImpl
->m_pSwitchStream
->SwitchPersistenceTo( xInputStream
);
5176 uno::Reference
< io::XStream
> xStream
= xAccess
->openFileReadWrite( sURL
);
5177 m_pImpl
->m_pSwitchStream
->SwitchPersistenceTo( xStream
);
5180 catch( const embed::InvalidStorageException
& )
5182 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5185 catch( const lang::IllegalArgumentException
& )
5187 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5190 catch( const embed::StorageWrappedTargetException
& )
5192 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5195 catch( const io::IOException
& )
5197 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5200 catch( const uno::RuntimeException
& )
5202 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5205 catch( const uno::Exception
& )
5207 uno::Any
aCaught( ::cppu::getCaughtException() );
5208 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5210 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't attach to URL!",
5211 uno::Reference
< io::XInputStream
>(),
5216 uno::Any SAL_CALL
OStorage::getElementPropertyValue( const OUString
& aElementName
, const OUString
& aPropertyName
)
5218 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
5222 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5223 throw lang::DisposedException( THROW_WHERE
);
5226 if ( aElementName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName
, false ) )
5227 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5229 if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aElementName
== "_rels" )
5230 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // TODO: unacceptable name
5234 SotElement_Impl
*pElement
= m_pImpl
->FindElement( aElementName
);
5236 throw container::NoSuchElementException( THROW_WHERE
);
5238 // TODO/LATER: Currently it is only implemented for MediaType property of substorages, might be changed in future
5239 if ( !pElement
->m_bIsStorage
|| m_pData
->m_nStorageType
!= embed::StorageFormats::PACKAGE
|| aPropertyName
!= "MediaType" )
5240 throw beans::PropertyVetoException( THROW_WHERE
);
5242 if (!pElement
->m_xStorage
)
5243 m_pImpl
->OpenSubStorage( pElement
, embed::ElementModes::READ
);
5245 if (!pElement
->m_xStorage
)
5246 throw io::IOException( THROW_WHERE
); // TODO: general_error
5248 pElement
->m_xStorage
->ReadContents();
5249 return uno::makeAny(pElement
->m_xStorage
->m_aMediaType
);
5251 catch( const embed::InvalidStorageException
& )
5253 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5256 catch( const lang::IllegalArgumentException
& )
5258 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5261 catch( const container::NoSuchElementException
& )
5263 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5266 catch( const beans::UnknownPropertyException
& )
5268 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5271 catch( const beans::PropertyVetoException
& )
5273 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5276 catch( const embed::StorageWrappedTargetException
& )
5278 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5281 catch( const io::IOException
& )
5283 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5286 catch( const uno::RuntimeException
& )
5288 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5291 catch( const uno::Exception
& )
5293 uno::Any
aCaught( ::cppu::getCaughtException() );
5294 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5296 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't get element property!",
5297 uno::Reference
< io::XInputStream
>(),
5302 void SAL_CALL
OStorage::copyStreamElementData( const OUString
& aStreamName
, const uno::Reference
< io::XStream
>& xTargetStream
)
5304 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
5308 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5309 throw lang::DisposedException( THROW_WHERE
);
5312 if ( aStreamName
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName
, false ) )
5313 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5315 if ( m_pData
->m_nStorageType
== embed::StorageFormats::OFOPXML
&& aStreamName
== "_rels" )
5316 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 1 ); // unacceptable name
5318 if ( !xTargetStream
.is() )
5319 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 2 );
5323 uno::Reference
< io::XStream
> xNonconstRef
= xTargetStream
;
5324 m_pImpl
->CloneStreamElement( aStreamName
, false, ::comphelper::SequenceAsHashMap(), xNonconstRef
);
5326 SAL_WARN_IF( xNonconstRef
!= xTargetStream
, "package.xstor", "The provided stream reference seems not be filled in correctly!" );
5327 if ( xNonconstRef
!= xTargetStream
)
5328 throw uno::RuntimeException( THROW_WHERE
); // if the stream reference is set it must not be changed!
5330 catch( const embed::InvalidStorageException
& )
5332 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5335 catch( const lang::IllegalArgumentException
& )
5337 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5340 catch( const packages::WrongPasswordException
& )
5342 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5345 catch( const io::IOException
& )
5347 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5350 catch( const embed::StorageWrappedTargetException
& )
5352 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5355 catch( const uno::RuntimeException
& )
5357 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5360 catch( const uno::Exception
& )
5362 uno::Any
aCaught( ::cppu::getCaughtException() );
5363 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught
));
5365 throw embed::StorageWrappedTargetException( THROW_WHERE
"Can't copy stream data!",
5366 uno::Reference
< io::XInputStream
>(),
5372 // XHierarchicalStorageAccess
5373 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
OStorage::openStreamElementByHierarchicalName( const OUString
& aStreamPath
, ::sal_Int32 nOpenMode
)
5375 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
5379 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5380 throw lang::DisposedException( THROW_WHERE
);
5383 if ( aStreamPath
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath
, true ) )
5384 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5386 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
)
5387 && ( nOpenMode
& embed::ElementModes::WRITE
) )
5388 throw io::IOException( THROW_WHERE
); // Access denied
5390 std::vector
<OUString
> aListPath
= OHierarchyHolder_Impl::GetListPathFromString( aStreamPath
);
5391 OSL_ENSURE( aListPath
.size(), "The result list must not be empty!" );
5393 uno::Reference
< embed::XExtendedStorageStream
> xResult
;
5394 if ( aListPath
.size() == 1 )
5398 // that must be a direct request for a stream
5399 // the transacted version of the stream should be opened
5401 SotElement_Impl
*pElement
= OpenStreamElement_Impl( aStreamPath
, nOpenMode
, false );
5402 assert(pElement
&& pElement
->m_xStream
&& "In case element can not be created an exception must be thrown!");
5404 xResult
.set(pElement
->m_xStream
->GetStream(nOpenMode
, true),
5405 uno::UNO_QUERY_THROW
);
5407 catch ( const container::NoSuchElementException
& )
5409 throw io::IOException( THROW_WHERE
); // file not found
5414 // there are still storages in between
5415 if ( !m_pData
->m_rHierarchyHolder
.is() )
5416 m_pData
->m_rHierarchyHolder
= new OHierarchyHolder_Impl(
5417 uno::Reference
< embed::XStorage
>( static_cast< embed::XStorage
* >( this ) ) );
5419 xResult
= m_pData
->m_rHierarchyHolder
->GetStreamHierarchically(
5420 ( m_pImpl
->m_nStorageMode
& embed::ElementModes::READWRITE
),
5425 if ( !xResult
.is() )
5426 throw uno::RuntimeException( THROW_WHERE
);
5431 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
OStorage::openEncryptedStreamElementByHierarchicalName( const OUString
& aStreamPath
, ::sal_Int32 nOpenMode
, const OUString
& sPassword
)
5433 return openEncryptedStreamByHierarchicalName( aStreamPath
, nOpenMode
, ::comphelper::OStorageHelper::CreatePackageEncryptionData( sPassword
) );
5436 void SAL_CALL
OStorage::removeStreamElementByHierarchicalName( const OUString
& aStreamPath
)
5438 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
5442 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5443 throw lang::DisposedException( 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 ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
) )
5450 throw io::IOException( THROW_WHERE
); // Access denied
5452 std::vector
<OUString
> aListPath
= OHierarchyHolder_Impl::GetListPathFromString( aStreamPath
);
5453 OSL_ENSURE( aListPath
.size(), "The result list must not be empty!" );
5455 if ( !m_pData
->m_rHierarchyHolder
.is() )
5456 m_pData
->m_rHierarchyHolder
= new OHierarchyHolder_Impl(
5457 uno::Reference
< embed::XStorage
>( static_cast< embed::XStorage
* >( this ) ) );
5459 m_pData
->m_rHierarchyHolder
->RemoveStreamHierarchically( aListPath
);
5462 // XHierarchicalStorageAccess2
5463 uno::Reference
< embed::XExtendedStorageStream
> SAL_CALL
OStorage::openEncryptedStreamByHierarchicalName( const OUString
& aStreamPath
, ::sal_Int32 nOpenMode
, const uno::Sequence
< beans::NamedValue
>& aEncryptionData
)
5465 ::osl::MutexGuard
aGuard( m_pData
->m_xSharedMutex
->GetMutex() );
5469 SAL_INFO("package.xstor", THROW_WHERE
"Disposed!");
5470 throw lang::DisposedException( THROW_WHERE
);
5473 if ( m_pData
->m_nStorageType
!= embed::StorageFormats::PACKAGE
)
5474 throw packages::NoEncryptionException( THROW_WHERE
);
5476 if ( aStreamPath
.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath
, true ) )
5477 throw lang::IllegalArgumentException( THROW_WHERE
"Unexpected entry name syntax.", uno::Reference
< uno::XInterface
>(), 1 );
5479 if ( !aEncryptionData
.hasElements() )
5480 throw lang::IllegalArgumentException( THROW_WHERE
, uno::Reference
< uno::XInterface
>(), 3 );
5482 if ( !( m_pImpl
->m_nStorageMode
& embed::ElementModes::WRITE
)
5483 && ( nOpenMode
& embed::ElementModes::WRITE
) )
5484 throw io::IOException( THROW_WHERE
); // Access denied
5486 std::vector
<OUString
> aListPath
= OHierarchyHolder_Impl::GetListPathFromString( aStreamPath
);
5487 OSL_ENSURE( aListPath
.size(), "The result list must not be empty!" );
5489 uno::Reference
< embed::XExtendedStorageStream
> xResult
;
5490 if ( aListPath
.size() == 1 )
5492 // that must be a direct request for a stream
5493 // the transacted version of the stream should be opened
5495 SotElement_Impl
*pElement
= OpenStreamElement_Impl( aStreamPath
, nOpenMode
, true );
5496 OSL_ENSURE(pElement
&& pElement
->m_xStream
, "In case element can not be created an exception must be thrown!");
5498 xResult
.set(pElement
->m_xStream
->GetStream(nOpenMode
, aEncryptionData
, true),
5499 uno::UNO_QUERY_THROW
);
5503 // there are still storages in between
5504 if ( !m_pData
->m_rHierarchyHolder
.is() )
5505 m_pData
->m_rHierarchyHolder
= new OHierarchyHolder_Impl(
5506 uno::Reference
< embed::XStorage
>( static_cast< embed::XStorage
* >( this ) ) );
5508 xResult
= m_pData
->m_rHierarchyHolder
->GetStreamHierarchically(
5509 ( m_pImpl
->m_nStorageMode
& embed::ElementModes::READWRITE
),
5515 if ( !xResult
.is() )
5516 throw uno::RuntimeException( THROW_WHERE
);
5521 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */