Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / package / source / xstor / xstorage.cxx
blob0a43a07869f973d561dd30312d4eb2285b2293d9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <memory>
21 #include <sal/config.h>
23 #include <cassert>
25 #include <com/sun/star/beans/PropertyValue.hpp>
26 #include <com/sun/star/embed/ElementModes.hpp>
27 #include <com/sun/star/embed/InvalidStorageException.hpp>
28 #include <com/sun/star/embed/UseBackupException.hpp>
29 #include <com/sun/star/embed/StorageFormats.hpp>
30 #include <com/sun/star/embed/StorageWrappedTargetException.hpp>
31 #include <com/sun/star/packages/NoRawFormatException.hpp>
32 #include <com/sun/star/packages/WrongPasswordException.hpp>
33 #include <com/sun/star/ucb/XProgressHandler.hpp>
34 #include <com/sun/star/io/TempFile.hpp>
35 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
36 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
37 #include <com/sun/star/container/XEnumerationAccess.hpp>
38 #include <com/sun/star/container/XNamed.hpp>
39 #include <com/sun/star/util/XChangesBatch.hpp>
40 #include <com/sun/star/util/XCloneable.hpp>
42 #include <com/sun/star/lang/XUnoTunnel.hpp>
43 #include <com/sun/star/lang/XComponent.hpp>
44 #include <com/sun/star/lang/DisposedException.hpp>
45 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
46 #include <com/sun/star/beans/NamedValue.hpp>
48 #include <PackageConstants.hxx>
50 #include <cppuhelper/queryinterface.hxx>
51 #include <cppuhelper/typeprovider.hxx>
52 #include <cppuhelper/exc_hlp.hxx>
53 #include <rtl/instance.hxx>
55 #include <comphelper/storagehelper.hxx>
56 #include <comphelper/ofopxmlhelper.hxx>
58 #include "xstorage.hxx"
59 #include "owriteablestream.hxx"
60 #include "disposelistener.hxx"
61 #include "switchpersistencestream.hxx"
62 #include "ohierarchyholder.hxx"
64 using namespace ::com::sun::star;
66 #if OSL_DEBUG_LEVEL > 0
67 #define THROW_WHERE SAL_WHERE
68 #else
69 #define THROW_WHERE ""
70 #endif
72 typedef ::std::vector< uno::WeakReference< lang::XComponent > > WeakComponentVector;
74 struct StorInternalData_Impl
76 rtl::Reference<comphelper::RefCountedMutex> m_xSharedMutex;
77 ::cppu::OMultiTypeInterfaceContainerHelper m_aListenersContainer; // list of listeners
78 ::std::unique_ptr< ::cppu::OTypeCollection> m_pTypeCollection;
79 bool m_bIsRoot;
80 sal_Int32 m_nStorageType; // the mode in which the storage is used
81 bool m_bReadOnlyWrap;
83 ::rtl::Reference<OChildDispListener_Impl> m_pSubElDispListener;
85 WeakComponentVector m_aOpenSubComponentsVector;
87 ::rtl::Reference< OHierarchyHolder_Impl > m_rHierarchyHolder;
89 // the mutex reference MUST NOT be empty
90 StorInternalData_Impl( const rtl::Reference<comphelper::RefCountedMutex>& rMutexRef, bool bRoot, sal_Int32 nStorageType, bool bReadOnlyWrap )
91 : m_xSharedMutex( rMutexRef )
92 , m_aListenersContainer( rMutexRef->GetMutex() )
93 , m_pTypeCollection()
94 , m_bIsRoot( bRoot )
95 , m_nStorageType( nStorageType )
96 , m_bReadOnlyWrap( bReadOnlyWrap )
97 , m_pSubElDispListener()
101 // static
102 void OStorage_Impl::completeStorageStreamCopy_Impl(
103 const uno::Reference< io::XStream >& xSource,
104 const uno::Reference< io::XStream >& xDest,
105 sal_Int32 nStorageType,
106 const uno::Sequence< uno::Sequence< beans::StringPair > >& aRelInfo )
108 uno::Reference< beans::XPropertySet > xSourceProps( xSource, uno::UNO_QUERY_THROW );
109 uno::Reference< beans::XPropertySet > xDestProps( xDest, uno::UNO_QUERY_THROW );
111 uno::Reference< io::XOutputStream > xDestOutStream = xDest->getOutputStream();
112 if ( !xDestOutStream.is() )
113 throw io::IOException( THROW_WHERE );
115 uno::Reference< io::XInputStream > xSourceInStream = xSource->getInputStream();
116 if ( !xSourceInStream.is() )
117 throw io::IOException( THROW_WHERE );
119 // TODO: headers of encrypted streams should be copied also
120 ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInStream, xDestOutStream );
122 uno::Sequence<OUString> aPropNames { "Compressed" };
124 if ( nStorageType == embed::StorageFormats::PACKAGE )
126 aPropNames.realloc( 3 );
127 aPropNames[1] = "MediaType";
128 aPropNames[2] = "UseCommonStoragePasswordEncryption";
130 else if ( nStorageType == embed::StorageFormats::OFOPXML )
132 // TODO/LATER: in future it might make sense to provide the stream if there is one
133 uno::Reference< embed::XRelationshipAccess > xRelAccess( xDest, uno::UNO_QUERY_THROW );
134 xRelAccess->clearRelationships();
135 xRelAccess->insertRelationships( aRelInfo, false );
137 aPropNames.realloc( 2 );
138 aPropNames[1] = "MediaType";
141 for ( int ind = 0; ind < aPropNames.getLength(); ind++ )
142 xDestProps->setPropertyValue( aPropNames[ind], xSourceProps->getPropertyValue( aPropNames[ind] ) );
145 uno::Reference< io::XInputStream > GetSeekableTempCopy( const uno::Reference< io::XInputStream >& xInStream,
146 const uno::Reference< uno::XComponentContext >& xContext )
148 uno::Reference < io::XTempFile > xTempFile = io::TempFile::create(xContext);
149 uno::Reference < io::XOutputStream > xTempOut = xTempFile->getOutputStream();
150 uno::Reference < io::XInputStream > xTempIn = xTempFile->getInputStream();
152 if ( !xTempOut.is() || !xTempIn.is() )
153 throw io::IOException( THROW_WHERE );
155 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOut );
156 xTempOut->closeOutput();
158 return xTempIn;
161 SotElement_Impl::SotElement_Impl(const OUString& rName, bool bStor, bool bNew)
162 : m_aName(rName)
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,
172 sal_Int32 nMode,
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 )
182 , m_bIsRoot( true )
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_pSwitchStream( nullptr )
193 , m_nStorageType( nStorageType )
194 , m_pRelStorElement( nullptr )
195 , m_nRelInfoStatus( RELINFO_NO_INIT )
197 // all the checks done below by assertion statements must be done by factory
198 SAL_WARN_IF( !xInputStream.is(), "package.xstor", "No input stream is provided!" );
199 assert(xContext.is());
201 m_pSwitchStream = new SwitchablePersistenceStream(xContext, xInputStream);
202 m_xInputStream = m_pSwitchStream->getInputStream();
204 if ( m_nStorageMode & embed::ElementModes::WRITE )
206 // check that the stream allows to write
207 SAL_WARN( "package.xstor", "No stream for writing is provided!" );
211 // most of properties are holt by the storage but are not used
212 OStorage_Impl::OStorage_Impl( uno::Reference< io::XStream > const & xStream,
213 sal_Int32 nMode,
214 const uno::Sequence< beans::PropertyValue >& xProperties,
215 uno::Reference< uno::XComponentContext > const & xContext,
216 sal_Int32 nStorageType )
217 : m_xMutex( new comphelper::RefCountedMutex )
218 , m_pAntiImpl( nullptr )
219 , m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
220 , m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
221 , m_bBroadcastModified( false )
222 , m_bCommited( false )
223 , m_bIsRoot( true )
224 , m_bListCreated( false )
225 , m_nModifiedListenerCount( 0 )
226 , m_xContext( xContext )
227 , m_xProperties( xProperties )
228 , m_bHasCommonEncryptionData( false )
229 , m_pParent( nullptr )
230 , m_bControlMediaType( false )
231 , m_bMTFallbackUsed( false )
232 , m_bControlVersion( false )
233 , m_pSwitchStream( nullptr )
234 , m_nStorageType( nStorageType )
235 , m_pRelStorElement( nullptr )
236 , m_nRelInfoStatus( RELINFO_NO_INIT )
238 // all the checks done below by assertion statements must be done by factory
239 SAL_WARN_IF( !xStream.is(), "package.xstor", "No stream is provided!" );
240 assert(xContext.is());
242 if ( m_nStorageMode & embed::ElementModes::WRITE )
244 m_pSwitchStream = new SwitchablePersistenceStream(xContext, xStream);
245 m_xStream = static_cast< io::XStream* >( m_pSwitchStream );
247 else
249 m_pSwitchStream = new SwitchablePersistenceStream(xContext, xStream->getInputStream());
250 m_xInputStream = m_pSwitchStream->getInputStream();
254 OStorage_Impl::OStorage_Impl( OStorage_Impl* pParent,
255 sal_Int32 nMode,
256 uno::Reference< container::XNameContainer > const & xPackageFolder,
257 uno::Reference< lang::XSingleServiceFactory > const & xPackage,
258 uno::Reference< uno::XComponentContext > const & xContext,
259 sal_Int32 nStorageType )
260 : m_xMutex( new comphelper::RefCountedMutex )
261 , m_pAntiImpl( nullptr )
262 , m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
263 , m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
264 , m_bBroadcastModified( false )
265 , m_bCommited( false )
266 , m_bIsRoot( false )
267 , m_bListCreated( false )
268 , m_nModifiedListenerCount( 0 )
269 , m_xPackageFolder( xPackageFolder )
270 , m_xPackage( xPackage )
271 , m_xContext( xContext )
272 , m_bHasCommonEncryptionData( false )
273 , m_pParent( pParent ) // can be empty in case of temporary readonly substorages and relation storage
274 , m_bControlMediaType( false )
275 , m_bMTFallbackUsed( false )
276 , m_bControlVersion( false )
277 , m_pSwitchStream( nullptr )
278 , m_nStorageType( nStorageType )
279 , m_pRelStorElement( nullptr )
280 , m_nRelInfoStatus( RELINFO_NO_INIT )
282 SAL_WARN_IF( !xPackageFolder.is(), "package.xstor", "No package folder!" );
283 assert(xContext.is());
286 OStorage_Impl::~OStorage_Impl()
289 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
290 if ( m_pAntiImpl ) // root storage wrapper must set this member to NULL before destruction of object
292 SAL_WARN_IF( m_bIsRoot, "package.xstor", "The root storage wrapper must be disposed already" );
294 try {
295 m_pAntiImpl->InternalDispose( false );
297 catch ( const uno::Exception& rException )
299 SAL_INFO("package.xstor", "Quiet exception: " << rException);
301 m_pAntiImpl = nullptr;
303 else if ( !m_aReadOnlyWrapVector.empty() )
305 for ( StorageHoldersType::iterator pStorageIter = m_aReadOnlyWrapVector.begin();
306 pStorageIter != m_aReadOnlyWrapVector.end(); ++pStorageIter )
308 uno::Reference< embed::XStorage > xTmp = pStorageIter->m_xWeakRef;
309 if ( xTmp.is() )
310 try {
311 pStorageIter->m_pPointer->InternalDispose( false );
312 } catch( const uno::Exception& rException )
314 SAL_INFO("package.xstor", "Quiet exception: " << rException);
318 m_aReadOnlyWrapVector.clear();
321 m_pParent = nullptr;
324 std::for_each(m_aChildrenVector.begin(), m_aChildrenVector.end(), std::default_delete<SotElement_Impl>());
325 m_aChildrenVector.clear();
327 std::for_each(m_aDeletedVector.begin(), m_aDeletedVector.end(), std::default_delete<SotElement_Impl>());
328 m_aDeletedVector.clear();
330 if ( m_nStorageType == embed::StorageFormats::OFOPXML && m_pRelStorElement )
332 delete m_pRelStorElement;
333 m_pRelStorElement = nullptr;
336 m_xPackageFolder.clear();
337 m_xPackage.clear();
339 OUString aPropertyName = "URL";
340 for ( sal_Int32 aInd = 0; aInd < m_xProperties.getLength(); ++aInd )
342 if ( m_xProperties[aInd].Name == aPropertyName )
344 // the storage is URL based so all the streams are opened by factory and should be closed
347 if ( m_xInputStream.is() )
349 m_xInputStream->closeInput();
350 m_xInputStream.clear();
353 if ( m_xStream.is() )
355 uno::Reference< io::XInputStream > xInStr = m_xStream->getInputStream();
356 if ( xInStr.is() )
357 xInStr->closeInput();
359 uno::Reference< io::XOutputStream > xOutStr = m_xStream->getOutputStream();
360 if ( xOutStr.is() )
361 xOutStr->closeOutput();
363 m_xStream.clear();
366 catch (const uno::Exception& rException)
368 SAL_INFO("package.xstor", "Quiet exception: " << rException);
374 void OStorage_Impl::SetReadOnlyWrap( OStorage& aStorage )
376 // Weak reference is used inside the holder so the refcount must not be zero at this point
377 OSL_ENSURE( aStorage.GetRefCount_Impl(), "There must be a reference alive to use this method!" );
378 m_aReadOnlyWrapVector.emplace_back( &aStorage );
381 void OStorage_Impl::RemoveReadOnlyWrap( OStorage& aStorage )
383 for ( StorageHoldersType::iterator pStorageIter = m_aReadOnlyWrapVector.begin();
384 pStorageIter != m_aReadOnlyWrapVector.end();)
386 uno::Reference< embed::XStorage > xTmp = pStorageIter->m_xWeakRef;
387 if ( !xTmp.is() || pStorageIter->m_pPointer == &aStorage )
389 try {
390 pStorageIter->m_pPointer->InternalDispose( false );
391 } catch( const uno::Exception& rException )
393 SAL_INFO("package.xstor", "Quiet exception: " << rException);
396 pStorageIter = m_aReadOnlyWrapVector.erase(pStorageIter);
398 else
399 ++pStorageIter;
403 void OStorage_Impl::OpenOwnPackage()
405 SAL_WARN_IF( !m_bIsRoot, "package.xstor", "Opening of the package has no sense!" );
407 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
409 if ( !m_xPackageFolder.is() )
411 if ( !m_xPackage.is() )
413 uno::Sequence< uno::Any > aArguments( 2 );
414 if ( m_nStorageMode & embed::ElementModes::WRITE )
415 aArguments[ 0 ] <<= m_xStream;
416 else
418 SAL_WARN_IF( !m_xInputStream.is(), "package.xstor", "Input stream must be set for readonly access!" );
419 aArguments[ 0 ] <<= m_xInputStream;
420 // TODO: if input stream is not seekable or XSeekable interface is supported
421 // on XStream object a wrapper must be used
424 // do not allow elements to remove themself from the old container in case of insertion to another container
425 aArguments[ 1 ] <<= beans::NamedValue( "AllowRemoveOnInsert",
426 uno::makeAny( false ) );
428 sal_Int32 nArgNum = 2;
429 for ( sal_Int32 aInd = 0; aInd < m_xProperties.getLength(); aInd++ )
431 if ( m_xProperties[aInd].Name == "RepairPackage"
432 || m_xProperties[aInd].Name == "ProgressHandler"
433 || m_xProperties[aInd].Name == "NoFileSync" )
435 // Forward these to the package.
436 beans::NamedValue aNamedValue( m_xProperties[aInd].Name,
437 m_xProperties[aInd].Value );
438 aArguments.realloc( ++nArgNum );
439 aArguments[nArgNum-1] <<= aNamedValue;
441 else if ( m_xProperties[aInd].Name == "Password" )
443 // TODO: implement password setting for documents
444 // the password entry must be removed after setting
448 if ( m_nStorageType == embed::StorageFormats::ZIP )
450 // let the package support only plain zip format
451 beans::NamedValue aNamedValue;
452 aNamedValue.Name = "StorageFormat";
453 aNamedValue.Value <<= OUString( "ZipFormat" );
454 aArguments.realloc( ++nArgNum );
455 aArguments[nArgNum-1] <<= aNamedValue;
457 else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
459 // let the package support OFOPXML media type handling
460 beans::NamedValue aNamedValue;
461 aNamedValue.Name = "StorageFormat";
462 aNamedValue.Value <<= OUString( "OFOPXMLFormat" );
463 aArguments.realloc( ++nArgNum );
464 aArguments[nArgNum-1] <<= aNamedValue;
467 m_xPackage.set( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
468 "com.sun.star.packages.comp.ZipPackage", aArguments, m_xContext),
469 uno::UNO_QUERY );
472 uno::Reference< container::XHierarchicalNameAccess > xHNameAccess( m_xPackage, uno::UNO_QUERY );
473 SAL_WARN_IF( !xHNameAccess.is(), "package.xstor", "The package could not be created!" );
475 if ( xHNameAccess.is() )
477 uno::Any aFolder = xHNameAccess->getByHierarchicalName("/");
478 aFolder >>= m_xPackageFolder;
482 SAL_WARN_IF( !m_xPackageFolder.is(), "package.xstor", "The package root folder can not be opened!" );
483 if ( !m_xPackageFolder.is() )
484 throw embed::InvalidStorageException( THROW_WHERE );
487 SotElementVector_Impl& OStorage_Impl::GetChildrenVector()
489 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
491 ReadContents();
492 return m_aChildrenVector;
495 void OStorage_Impl::GetStorageProperties()
497 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
499 uno::Reference< beans::XPropertySet > xProps( m_xPackageFolder, uno::UNO_QUERY_THROW );
501 if ( !m_bControlMediaType )
503 uno::Reference< beans::XPropertySet > xPackageProps( m_xPackage, uno::UNO_QUERY_THROW );
504 xPackageProps->getPropertyValue( MEDIATYPE_FALLBACK_USED_PROPERTY ) >>= m_bMTFallbackUsed;
506 xProps->getPropertyValue( "MediaType" ) >>= m_aMediaType;
507 m_bControlMediaType = true;
510 if ( !m_bControlVersion )
512 xProps->getPropertyValue( "Version" ) >>= m_aVersion;
513 m_bControlVersion = true;
517 // the properties of OFOPXML will be handled directly
520 void OStorage_Impl::ReadRelInfoIfNecessary()
522 if ( m_nStorageType != embed::StorageFormats::OFOPXML )
523 return;
525 if ( m_nRelInfoStatus == RELINFO_NO_INIT )
527 // Init from original stream
528 uno::Reference< io::XInputStream > xRelInfoStream = GetRelInfoStreamForName( OUString() );
531 if ( xRelInfoStream.is() )
532 m_aRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
533 xRelInfoStream,
534 "_rels/.rels",
535 m_xContext );
536 m_nRelInfoStatus = RELINFO_READ;
538 catch (css::uno::Exception & e)
540 SAL_INFO("package.xstor", "caught " << e);
543 else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
545 // Init from the new stream
548 if ( m_xNewRelInfoStream.is() )
549 m_aRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
550 m_xNewRelInfoStream,
551 "_rels/.rels",
552 m_xContext );
554 m_nRelInfoStatus = RELINFO_CHANGED_STREAM_READ;
556 catch( const uno::Exception& )
558 m_nRelInfoStatus = RELINFO_CHANGED_BROKEN;
563 void OStorage_Impl::ReadContents()
565 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
567 if ( m_bListCreated )
568 return;
570 if ( m_bIsRoot )
571 OpenOwnPackage();
573 uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xPackageFolder, uno::UNO_QUERY_THROW );
574 uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration();
575 if ( !xEnum.is() )
576 throw uno::RuntimeException( THROW_WHERE );
578 m_bListCreated = true;
580 while( xEnum->hasMoreElements() )
582 try {
583 uno::Reference< container::XNamed > xNamed;
584 xEnum->nextElement() >>= xNamed;
586 if ( !xNamed.is() )
588 SAL_WARN( "package.xstor", "XNamed is not supported!" );
589 throw uno::RuntimeException( THROW_WHERE );
592 OUString aName = xNamed->getName();
593 SAL_WARN_IF( aName.isEmpty(), "package.xstor", "Empty name!" );
595 uno::Reference< container::XNameContainer > xNameContainer( xNamed, uno::UNO_QUERY );
597 std::unique_ptr<SotElement_Impl> xNewElement(new SotElement_Impl(aName, xNameContainer.is(), false));
598 if ( m_nStorageType == embed::StorageFormats::OFOPXML && aName == "_rels" )
600 if (!xNewElement->m_bIsStorage)
601 throw io::IOException( THROW_WHERE ); // TODO: Unexpected format
603 m_pRelStorElement = xNewElement.release();
604 CreateRelStorage();
606 else
608 if ( ( m_nStorageMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE )
610 // if a storage is truncated all of it elements are marked as deleted
611 xNewElement->m_bIsRemoved = true;
614 m_aChildrenVector.push_back(xNewElement.release());
617 catch( const container::NoSuchElementException& rNoSuchElementException )
619 SAL_WARN( "package.xstor", "hasMoreElements() implementation has problems! " << rNoSuchElementException);
620 break;
623 if ( ( m_nStorageMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE )
625 // if a storage is truncated the relations information should be cleaned
626 m_xNewRelInfoStream.clear();
627 m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
628 m_nRelInfoStatus = RELINFO_CHANGED;
631 // cache changeable folder properties
632 GetStorageProperties();
635 void OStorage_Impl::CopyToStorage( const uno::Reference< embed::XStorage >& xDest, bool bDirect )
637 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
639 uno::Reference< beans::XPropertySet > xPropSet( xDest, uno::UNO_QUERY );
640 if ( !xPropSet.is() )
641 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 );
643 sal_Int32 nDestMode = embed::ElementModes::READ;
644 xPropSet->getPropertyValue( "OpenMode" ) >>= nDestMode;
646 if ( !( nDestMode & embed::ElementModes::WRITE ) )
647 throw io::IOException( THROW_WHERE ); // TODO: access_denied
649 ReadContents();
651 if ( !m_xPackageFolder.is() )
652 throw embed::InvalidStorageException( THROW_WHERE );
654 for ( SotElementVector_Impl::iterator pElementIter = m_aChildrenVector.begin();
655 pElementIter != m_aChildrenVector.end(); ++pElementIter )
657 if ( !(*pElementIter)->m_bIsRemoved )
658 CopyStorageElement( *pElementIter, xDest, (*pElementIter)->m_aName, bDirect );
661 // move storage properties to the destination one ( means changeable properties )
662 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
664 OUString aMediaTypeString = "MediaType";
665 OUString aVersionString = "Version";
666 xPropSet->setPropertyValue( aMediaTypeString, uno::makeAny( m_aMediaType ) );
667 xPropSet->setPropertyValue( aVersionString, uno::makeAny( m_aVersion ) );
670 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
672 // if this is a root storage, the common key from current one should be moved there
673 bool bIsRoot = false;
674 OUString aRootString = "IsRoot";
675 if ( ( xPropSet->getPropertyValue( aRootString ) >>= bIsRoot ) && bIsRoot )
679 uno::Reference< embed::XEncryptionProtectedStorage > xEncr( xDest, uno::UNO_QUERY );
680 if ( xEncr.is() )
682 xEncr->setEncryptionData( GetCommonRootEncryptionData().getAsConstNamedValueList() );
684 uno::Sequence< beans::NamedValue > aAlgorithms;
685 uno::Reference< beans::XPropertySet > xPackPropSet( m_xPackage, uno::UNO_QUERY_THROW );
686 xPackPropSet->getPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY )
687 >>= aAlgorithms;
688 xEncr->setEncryptionAlgorithms( aAlgorithms );
691 catch( const packages::NoEncryptionException& rNoEncryptionException )
693 SAL_INFO("package.xstor", "No Encryption: " << rNoEncryptionException);
697 else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
700 // TODO/LATER: currently the optimization is not active
701 // uno::Reference< io::XInputStream > xRelInfoStream = GetRelInfoStreamForName( OUString() ); // own stream
702 // if ( xRelInfoStream.is() )
703 // {
704 // // Relations info stream is a writeonly property, introduced only to optimize copying
705 // // Should be used carefully since no check for stream consistency is done, and the stream must not stay locked
707 // OUString aRelInfoString = "RelationsInfoStream";
708 // xPropSet->setPropertyValue( aRelInfoString, uno::makeAny( GetSeekableTempCopy( xRelInfoStream, m_xFactory ) ) );
709 // }
711 uno::Reference< embed::XRelationshipAccess > xRels( xDest, uno::UNO_QUERY );
712 if ( !xRels.is() )
713 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 );
715 xRels->insertRelationships( GetAllRelationshipsIfAny(), false );
718 // if possible the destination storage should be committed after successful copying
719 uno::Reference< embed::XTransactedObject > xObjToCommit( xDest, uno::UNO_QUERY );
720 if ( xObjToCommit.is() )
721 xObjToCommit->commit();
724 void OStorage_Impl::CopyStorageElement( SotElement_Impl* pElement,
725 const uno::Reference< embed::XStorage >& xDest,
726 const OUString& aName,
727 bool bDirect )
729 SAL_WARN_IF( !xDest.is(), "package.xstor", "No destination storage!" );
730 SAL_WARN_IF( aName.isEmpty(), "package.xstor", "Empty element name!" );
732 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
734 uno::Reference< container::XNameAccess > xDestAccess( xDest, uno::UNO_QUERY_THROW );
735 if ( xDestAccess->hasByName( aName )
736 && !( pElement->m_bIsStorage && xDest->isStorageElement( aName ) ) )
737 xDest->removeElement( aName );
739 if ( pElement->m_bIsStorage )
741 uno::Reference< embed::XStorage > xSubDest =
742 xDest->openStorageElement( aName,
743 embed::ElementModes::WRITE );
745 SAL_WARN_IF( !xSubDest.is(), "package.xstor", "No destination substorage!" );
747 if (!pElement->m_xStorage)
749 OpenSubStorage( pElement, embed::ElementModes::READ );
750 if (!pElement->m_xStorage)
751 throw io::IOException( THROW_WHERE );
754 pElement->m_xStorage->CopyToStorage(xSubDest, bDirect);
756 else
758 if (!pElement->m_xStream)
760 OpenSubStream( pElement );
761 if (!pElement->m_xStream)
762 throw io::IOException( THROW_WHERE );
765 if (!pElement->m_xStream->IsEncrypted())
767 if ( bDirect )
769 // fill in the properties for the stream
770 uno::Sequence< beans::PropertyValue > aStrProps(0);
771 uno::Sequence< beans::PropertyValue > aSrcPkgProps = pElement->m_xStream->GetStreamProperties();
772 sal_Int32 nNum = 0;
773 for ( int ind = 0; ind < aSrcPkgProps.getLength(); ind++ )
775 if ( aSrcPkgProps[ind].Name == "MediaType" || aSrcPkgProps[ind].Name == "Compressed" )
777 aStrProps.realloc( ++nNum );
778 aStrProps[nNum-1].Name = aSrcPkgProps[ind].Name;
779 aStrProps[nNum-1].Value = aSrcPkgProps[ind].Value;
783 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
785 aStrProps.realloc( ++nNum );
786 aStrProps[nNum-1].Name = "UseCommonStoragePasswordEncryption";
787 aStrProps[nNum-1].Value <<= pElement->m_xStream->UsesCommonEncryption_Impl();
789 else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
791 // TODO/LATER: currently the optimization is not active
792 // uno::Reference< io::XInputStream > xInStream = GetRelInfoStreamForName( OUString() ); // own rels stream
793 // if ( xInStream.is() )
794 // {
795 // aStrProps.realloc( ++nNum );
796 // aStrProps[nNum-1].Name = "RelationsInfoStream";
797 // aStrProps[nNum-1].Value <<= GetSeekableTempCopy( xInStream, m_xFactory );
798 // }
800 uno::Reference< embed::XRelationshipAccess > xRels( xDest, uno::UNO_QUERY );
801 if ( !xRels.is() )
802 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
804 xRels->insertRelationships( GetAllRelationshipsIfAny(), false );
807 uno::Reference< embed::XOptimizedStorage > xOptDest( xDest, uno::UNO_QUERY_THROW );
808 uno::Reference < io::XInputStream > xInputToInsert;
810 if (pElement->m_xStream->HasTempFile_Impl() || !pElement->m_xStream->m_xPackageStream.is())
812 SAL_WARN_IF(!pElement->m_xStream->m_xPackageStream.is(), "package.xstor", "No package stream!");
814 // if the stream is modified - the temporary file must be used for insertion
815 xInputToInsert = pElement->m_xStream->GetTempFileAsInputStream();
817 else
819 // for now get just nonseekable access to the stream
820 // TODO/LATER: the raw stream can be used
822 xInputToInsert = pElement->m_xStream->m_xPackageStream->getDataStream();
825 if ( !xInputToInsert.is() )
826 throw io::IOException( THROW_WHERE );
828 xOptDest->insertStreamElementDirect( aName, xInputToInsert, aStrProps );
830 else
832 uno::Reference< io::XStream > xSubStr =
833 xDest->openStreamElement( aName,
834 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
835 SAL_WARN_IF( !xSubStr.is(), "package.xstor", "No destination substream!" );
837 pElement->m_xStream->CopyInternallyTo_Impl(xSubStr);
840 else if ( m_nStorageType != embed::StorageFormats::PACKAGE )
842 SAL_WARN( "package.xstor", "Encryption is only supported in package storage!" );
843 throw io::IOException( THROW_WHERE );
845 else if ( pElement->m_xStream->HasCachedEncryptionData()
846 && ( pElement->m_xStream->IsModified() || pElement->m_xStream->HasWriteOwner_Impl() ) )
848 ::comphelper::SequenceAsHashMap aCommonEncryptionData;
849 bool bHasCommonEncryptionData = false;
852 aCommonEncryptionData = GetCommonRootEncryptionData();
853 bHasCommonEncryptionData = true;
855 catch( const packages::NoEncryptionException& rNoEncryptionException )
857 SAL_INFO("package.xstor", "No Encryption: " << rNoEncryptionException);
860 if (bHasCommonEncryptionData && ::package::PackageEncryptionDatasEqual(pElement->m_xStream->GetCachedEncryptionData(), aCommonEncryptionData))
862 // If the stream can be opened with the common storage password
863 // it must be stored with the common storage password as well
864 uno::Reference< io::XStream > xDestStream =
865 xDest->openStreamElement( aName,
866 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
868 pElement->m_xStream->CopyInternallyTo_Impl( xDestStream );
870 uno::Reference< beans::XPropertySet > xProps( xDestStream, uno::UNO_QUERY_THROW );
871 xProps->setPropertyValue(
872 "UseCommonStoragePasswordEncryption",
873 uno::Any( true ) );
875 else
877 // the stream is already opened for writing or was changed
878 uno::Reference< embed::XStorage2 > xDest2( xDest, uno::UNO_QUERY_THROW );
879 uno::Reference< io::XStream > xSubStr =
880 xDest2->openEncryptedStream( aName,
881 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE,
882 pElement->m_xStream->GetCachedEncryptionData().getAsConstNamedValueList() );
883 SAL_WARN_IF( !xSubStr.is(), "package.xstor", "No destination substream!" );
885 pElement->m_xStream->CopyInternallyTo_Impl(xSubStr, pElement->m_xStream->GetCachedEncryptionData());
888 else
890 // the stream is not opened at all, so it can be just opened for reading
893 // If the stream can be opened with the common storage password
894 // it must be stored with the common storage password as well
896 uno::Reference< io::XStream > xOwnStream = pElement->m_xStream->GetStream(embed::ElementModes::READ,
897 false);
898 uno::Reference< io::XStream > xDestStream =
899 xDest->openStreamElement( aName,
900 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
901 SAL_WARN_IF( !xDestStream.is(), "package.xstor", "No destination substream!" );
902 completeStorageStreamCopy_Impl( xOwnStream, xDestStream, m_nStorageType, GetAllRelationshipsIfAny() );
904 uno::Reference< beans::XPropertySet > xProps( xDestStream, uno::UNO_QUERY_THROW );
905 xProps->setPropertyValue(
906 "UseCommonStoragePasswordEncryption",
907 uno::Any( true ) );
909 catch( const packages::WrongPasswordException& rWrongPasswordException )
911 SAL_INFO("package.xstor", "Handled exception: " << rWrongPasswordException);
913 // If the common storage password does not allow to open the stream
914 // it could be copied in raw way, the problem is that the StartKey should be the same
915 // in the ODF1.2 package, so an invalid package could be produced if the stream
916 // is copied from ODF1.1 package, where it is allowed to have different StartKeys
917 uno::Reference< embed::XStorageRawAccess > xRawDest( xDest, uno::UNO_QUERY_THROW );
918 uno::Reference< io::XInputStream > xRawInStream = pElement->m_xStream->GetRawInStream();
919 xRawDest->insertRawEncrStreamElement( aName, xRawInStream );
925 uno::Sequence< uno::Sequence< beans::StringPair > > OStorage_Impl::GetAllRelationshipsIfAny()
927 if ( m_nStorageType != embed::StorageFormats::OFOPXML )
928 return uno::Sequence< uno::Sequence< beans::StringPair > >();
930 ReadRelInfoIfNecessary();
932 if ( m_nRelInfoStatus != RELINFO_READ
933 && m_nRelInfoStatus != RELINFO_CHANGED_STREAM_READ
934 && m_nRelInfoStatus != RELINFO_CHANGED )
935 throw io::IOException( THROW_WHERE "Wrong relinfo stream!" );
936 // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
937 return m_aRelInfo;
940 void OStorage_Impl::CopyLastCommitTo( const uno::Reference< embed::XStorage >& xNewStor )
942 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
944 SAL_WARN_IF( !m_xPackageFolder.is(), "package.xstor", "A committed storage is incomplete!" );
945 if ( !m_xPackageFolder.is() )
946 throw uno::RuntimeException( THROW_WHERE );
948 OStorage_Impl aTempRepresent( nullptr,
949 embed::ElementModes::READ,
950 m_xPackageFolder,
951 m_xPackage,
952 m_xContext,
953 m_nStorageType);
955 // TODO/LATER: could use direct copying
956 aTempRepresent.CopyToStorage( xNewStor, false );
959 void OStorage_Impl::InsertIntoPackageFolder( const OUString& aName,
960 const uno::Reference< container::XNameContainer >& xParentPackageFolder )
962 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
964 SAL_WARN_IF( !m_xPackageFolder.is(), "package.xstor", "An inserted storage is incomplete!" );
965 uno::Reference< lang::XUnoTunnel > xTunnel( m_xPackageFolder, uno::UNO_QUERY_THROW );
966 xParentPackageFolder->insertByName( aName, uno::makeAny( xTunnel ) );
968 m_bCommited = false;
971 void OStorage_Impl::Commit()
973 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
975 if ( !m_bIsModified )
976 return;
978 // in case of a new empty storage it is possible that the contents are still not read
979 // ( the storage of course has no contents, but the initialization is postponed till the first use,
980 // thus if a new storage was created and committed immediately it must be initialized here )
981 ReadContents();
983 // if storage is committed it should have a valid Package representation
984 SAL_WARN_IF( !m_xPackageFolder.is(), "package.xstor", "The package representation should exist!" );
985 if ( !m_xPackageFolder.is() )
986 throw embed::InvalidStorageException( THROW_WHERE );
988 OSL_ENSURE( m_nStorageMode & embed::ElementModes::WRITE,
989 "Commit of readonly storage, should be detected before!" );
991 uno::Reference< container::XNameContainer > xNewPackageFolder;
993 // here the storage will switch to the temporary package folder
994 // if the storage was already committed and the parent was not committed after that
995 // the switch should not be done since the package folder in use is a temporary one;
996 // it can be detected by m_bCommited flag ( root storage doesn't need temporary representation )
997 if ( !m_bCommited && !m_bIsRoot )
999 uno::Sequence< uno::Any > aSeq( 1 );
1000 aSeq[0] <<= true;
1002 xNewPackageFolder.set( m_xPackage->createInstanceWithArguments( aSeq ),
1003 uno::UNO_QUERY );
1005 else
1006 xNewPackageFolder = m_xPackageFolder;
1008 // remove replaced removed elements
1009 for ( SotElementVector_Impl::iterator pDeletedIter = m_aDeletedVector.begin();
1010 pDeletedIter != m_aDeletedVector.end();
1011 ++pDeletedIter )
1014 if ( m_nStorageType == embed::StorageFormats::OFOPXML && !(*pDeletedIter)->m_bIsStorage )
1015 RemoveStreamRelInfo( (*pDeletedIter)->m_aOriginalName );
1017 // the removed elements are not in new temporary storage
1018 if ( m_bCommited || m_bIsRoot )
1019 xNewPackageFolder->removeByName( (*pDeletedIter)->m_aOriginalName );
1020 delete *pDeletedIter;
1021 *pDeletedIter = nullptr;
1023 m_aDeletedVector.clear();
1025 // remove removed elements
1026 SotElementVector_Impl::iterator pElementIter = m_aChildrenVector.begin();
1027 while ( pElementIter != m_aChildrenVector.end() )
1029 // renamed and inserted elements must be really inserted to package later
1030 // since thay can conflict with removed elements
1032 if ( (*pElementIter)->m_bIsRemoved )
1034 if ( m_nStorageType == embed::StorageFormats::OFOPXML && !(*pElementIter)->m_bIsStorage )
1035 RemoveStreamRelInfo( (*pElementIter)->m_aOriginalName );
1037 // the removed elements are not in new temporary storage
1038 if ( m_bCommited || m_bIsRoot )
1039 xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1041 delete *pElementIter;
1042 pElementIter = m_aChildrenVector.erase(pElementIter);
1044 else
1045 ++pElementIter;
1048 // there should be no more deleted elements
1049 for ( pElementIter = m_aChildrenVector.begin(); pElementIter != m_aChildrenVector.end(); ++pElementIter )
1051 // if it is a 'duplicate commit' inserted elements must be really inserted to package later
1052 // since thay can conflict with renamed elements
1054 if ( !(*pElementIter)->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 ( !(*pElementIter)->m_bIsStorage && (*pElementIter)->m_xStream
1062 && !(*pElementIter)->m_xStream->IsTransacted() )
1063 (*pElementIter)->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 ((*pElementIter)->m_bIsStorage && (*pElementIter)->m_xStorage && (*pElementIter)->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( (*pElementIter)->m_aOriginalName );
1076 (*pElementIter)->m_xStorage->InsertIntoPackageFolder((*pElementIter)->m_aName, xNewPackageFolder);
1078 else if (!(*pElementIter)->m_bIsStorage && (*pElementIter)->m_xStream && (*pElementIter)->m_xStream->m_bFlushed)
1080 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1081 CommitStreamRelInfo( *pElementIter );
1083 // the renamed elements are not in new temporary storage
1084 if ( m_bCommited || m_bIsRoot )
1085 xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1087 (*pElementIter)->m_xStream->InsertIntoPackageFolder((*pElementIter)->m_aName, 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( (*pElementIter)->m_aOriginalName );
1095 xNewPackageFolder->insertByName( (*pElementIter)->m_aName, aPackageElement );
1097 else if ( (*pElementIter)->m_aName != (*pElementIter)->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( (*pElementIter)->m_aOriginalName );
1102 xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1103 xNewPackageFolder->insertByName( (*pElementIter)->m_aName, aPackageElement );
1105 if ( m_nStorageType == embed::StorageFormats::OFOPXML && !(*pElementIter)->m_bIsStorage )
1107 if (!(*pElementIter)->m_xStream)
1109 OpenSubStream( *pElementIter );
1110 if (!(*pElementIter)->m_xStream)
1111 throw uno::RuntimeException( THROW_WHERE );
1114 CommitStreamRelInfo( *pElementIter );
1118 (*pElementIter)->m_aOriginalName = (*pElementIter)->m_aName;
1122 for ( pElementIter = m_aChildrenVector.begin(); pElementIter != m_aChildrenVector.end(); ++pElementIter )
1124 // now inserted elements can be inserted to the package
1125 if ( (*pElementIter)->m_bIsInserted )
1127 (*pElementIter)->m_aOriginalName = (*pElementIter)->m_aName;
1129 if ( (*pElementIter)->m_bIsStorage )
1131 if ((*pElementIter)->m_xStorage->m_bCommited)
1133 OSL_ENSURE((*pElementIter)->m_xStorage, "An inserted storage is incomplete!");
1134 if (!(*pElementIter)->m_xStorage)
1135 throw uno::RuntimeException( THROW_WHERE );
1137 (*pElementIter)->m_xStorage->InsertIntoPackageFolder((*pElementIter)->m_aName, xNewPackageFolder);
1139 (*pElementIter)->m_bIsInserted = false;
1142 else
1144 OSL_ENSURE((*pElementIter)->m_xStream, "An inserted stream is incomplete!");
1145 if (!(*pElementIter)->m_xStream)
1146 throw uno::RuntimeException( THROW_WHERE );
1148 if (!(*pElementIter)->m_xStream->IsTransacted())
1149 (*pElementIter)->m_xStream->Commit();
1151 if ((*pElementIter)->m_xStream->m_bFlushed)
1153 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1154 CommitStreamRelInfo( *pElementIter );
1156 (*pElementIter)->m_xStream->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
1158 (*pElementIter)->m_bIsInserted = false;
1164 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
1166 // move properties to the destination package folder
1167 uno::Reference< beans::XPropertySet > xProps( xNewPackageFolder, uno::UNO_QUERY_THROW );
1168 xProps->setPropertyValue( "MediaType", uno::makeAny( m_aMediaType ) );
1169 xProps->setPropertyValue( "Version", uno::makeAny( m_aVersion ) );
1172 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1173 CommitRelInfo( xNewPackageFolder ); // store own relations and commit complete relations storage
1175 if ( m_bIsRoot )
1177 uno::Reference< util::XChangesBatch > xChangesBatch( m_xPackage, uno::UNO_QUERY_THROW );
1180 xChangesBatch->commitChanges();
1182 catch( const lang::WrappedTargetException& r )
1184 // the wrapped UseBackupException means that the target medium can be corrupted
1185 embed::UseBackupException aException;
1186 if ( r.TargetException >>= aException )
1188 m_xStream.clear();
1189 m_xInputStream.clear();
1190 throw aException;
1193 SAL_INFO("package.xstor", "Rethrow: " << aException);
1194 throw;
1197 else if ( !m_bCommited )
1199 m_xPackageFolder = xNewPackageFolder;
1200 m_bCommited = true;
1203 // after commit the mediatype treated as the correct one
1204 m_bMTFallbackUsed = false;
1207 void OStorage_Impl::Revert()
1209 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
1211 if ( !( m_nStorageMode & embed::ElementModes::WRITE ) )
1212 return; // nothing to do
1214 // all the children must be removed
1215 // they will be created later on demand
1217 SotElementVector_Impl::iterator pElementIter = m_aChildrenVector.begin();
1218 while ( pElementIter != m_aChildrenVector.end() )
1220 if ( (*pElementIter)->m_bIsInserted )
1222 delete *pElementIter;
1223 pElementIter = m_aChildrenVector.erase(pElementIter);
1225 else
1227 ClearElement( *pElementIter );
1229 (*pElementIter)->m_aName = (*pElementIter)->m_aOriginalName;
1230 (*pElementIter)->m_bIsRemoved = false;
1232 ++pElementIter;
1236 // return replaced removed elements
1237 for ( SotElementVector_Impl::iterator pDeletedIter = m_aDeletedVector.begin();
1238 pDeletedIter != m_aDeletedVector.end();
1239 ++pDeletedIter )
1241 m_aChildrenVector.push_back( *pDeletedIter );
1243 ClearElement( *pDeletedIter );
1245 (*pDeletedIter)->m_aName = (*pDeletedIter)->m_aOriginalName;
1246 (*pDeletedIter)->m_bIsRemoved = false;
1248 m_aDeletedVector.clear();
1250 m_bControlMediaType = false;
1251 m_bControlVersion = false;
1253 GetStorageProperties();
1255 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1257 // currently the relations storage is changed only on commit
1258 m_xNewRelInfoStream.clear();
1259 m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
1260 m_nRelInfoStatus = RELINFO_NO_INIT;
1264 ::comphelper::SequenceAsHashMap OStorage_Impl::GetCommonRootEncryptionData()
1266 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() ) ;
1268 if ( m_nStorageType != embed::StorageFormats::PACKAGE )
1269 throw packages::NoEncryptionException( THROW_WHERE );
1271 if ( m_bIsRoot )
1273 if ( !m_bHasCommonEncryptionData )
1274 throw packages::NoEncryptionException( THROW_WHERE );
1276 return m_aCommonEncryptionData;
1278 else
1280 if ( !m_pParent )
1281 throw packages::NoEncryptionException( THROW_WHERE );
1283 return m_pParent->GetCommonRootEncryptionData();
1287 SotElement_Impl* OStorage_Impl::FindElement( const OUString& rName )
1289 SAL_WARN_IF( rName.isEmpty(), "package.xstor", "Name is empty!" );
1291 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
1293 ReadContents();
1295 for ( SotElementVector_Impl::iterator pElementIter = m_aChildrenVector.begin();
1296 pElementIter != m_aChildrenVector.end(); ++pElementIter )
1298 if ( (*pElementIter)->m_aName == rName && !(*pElementIter)->m_bIsRemoved )
1299 return *pElementIter;
1302 return nullptr;
1305 SotElement_Impl* OStorage_Impl::InsertStream( const OUString& aName, bool bEncr )
1307 SAL_WARN_IF( !m_xPackage.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1308 if ( !m_xPackage.is() )
1309 throw embed::InvalidStorageException( THROW_WHERE);
1311 uno::Sequence< uno::Any > aSeq( 1 );
1312 aSeq[0] <<= false;
1313 uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1314 uno::UNO_QUERY );
1316 SAL_WARN_IF( !xNewElement.is(), "package.xstor", "Not possible to create a new stream!" );
1317 if ( !xNewElement.is() )
1318 throw io::IOException( THROW_WHERE );
1320 uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xNewElement, uno::UNO_QUERY_THROW );
1322 OSL_ENSURE( m_nStorageType == embed::StorageFormats::PACKAGE || !bEncr, "Only package storage supports encryption!" );
1323 if ( m_nStorageType != embed::StorageFormats::PACKAGE && bEncr )
1324 throw packages::NoEncryptionException( THROW_WHERE );
1326 // the mode is not needed for storage stream internal implementation
1327 SotElement_Impl* pNewElement = InsertElement( aName, false );
1328 pNewElement->m_xStream.reset(new OWriteStream_Impl(this, xPackageSubStream, m_xPackage, m_xContext, bEncr, m_nStorageType, true));
1330 m_aChildrenVector.push_back( pNewElement );
1331 m_bIsModified = true;
1332 m_bBroadcastModified = true;
1334 return pNewElement;
1337 void OStorage_Impl::InsertRawStream( const OUString& aName, const uno::Reference< io::XInputStream >& xInStream )
1339 // insert of raw stream means insert and commit
1340 SAL_WARN_IF( !m_xPackage.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1341 if ( !m_xPackage.is() )
1342 throw embed::InvalidStorageException( THROW_WHERE );
1344 if ( m_nStorageType != embed::StorageFormats::PACKAGE )
1345 throw packages::NoEncryptionException( THROW_WHERE );
1347 uno::Reference< io::XSeekable > xSeek( xInStream, uno::UNO_QUERY );
1348 uno::Reference< io::XInputStream > xInStrToInsert = xSeek.is() ? xInStream :
1349 GetSeekableTempCopy( xInStream, m_xContext );
1351 uno::Sequence< uno::Any > aSeq( 1 );
1352 aSeq[0] <<= false;
1353 uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1354 uno::UNO_QUERY );
1356 SAL_WARN_IF( !xNewElement.is(), "package.xstor", "Not possible to create a new stream!" );
1357 if ( !xNewElement.is() )
1358 throw io::IOException( THROW_WHERE );
1360 uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xNewElement, uno::UNO_QUERY_THROW );
1361 xPackageSubStream->setRawStream( xInStrToInsert );
1363 // the mode is not needed for storage stream internal implementation
1364 SotElement_Impl* pNewElement = InsertElement( aName, false );
1365 pNewElement->m_xStream.reset(new OWriteStream_Impl(this, xPackageSubStream, m_xPackage, m_xContext, true, m_nStorageType, false));
1366 // the stream is inserted and must be treated as a committed one
1367 pNewElement->m_xStream->SetToBeCommited();
1369 m_aChildrenVector.push_back( pNewElement );
1370 m_bIsModified = true;
1371 m_bBroadcastModified = true;
1374 OStorage_Impl* OStorage_Impl::CreateNewStorageImpl( sal_Int32 nStorageMode )
1376 SAL_WARN_IF( !m_xPackage.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1377 if ( !m_xPackage.is() )
1378 throw embed::InvalidStorageException( THROW_WHERE );
1380 uno::Sequence< uno::Any > aSeq( 1 );
1381 aSeq[0] <<= true;
1382 uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1383 uno::UNO_QUERY );
1385 SAL_WARN_IF( !xNewElement.is(), "package.xstor", "Not possible to create a new storage!" );
1386 if ( !xNewElement.is() )
1387 throw io::IOException( THROW_WHERE );
1389 uno::Reference< container::XNameContainer > xPackageSubFolder( xNewElement, uno::UNO_QUERY_THROW );
1390 OStorage_Impl* pResult =
1391 new OStorage_Impl( this, nStorageMode, xPackageSubFolder, m_xPackage, m_xContext, m_nStorageType );
1392 pResult->m_bIsModified = true;
1394 return pResult;
1397 SotElement_Impl* OStorage_Impl::InsertStorage( const OUString& aName, sal_Int32 nStorageMode )
1399 SotElement_Impl* pNewElement = InsertElement( aName, true );
1401 pNewElement->m_xStorage.reset(CreateNewStorageImpl(nStorageMode));
1403 m_aChildrenVector.push_back( pNewElement );
1405 return pNewElement;
1408 SotElement_Impl* OStorage_Impl::InsertElement( const OUString& aName, bool bIsStorage )
1410 OSL_ENSURE( FindElement( aName ) == nullptr, "Should not try to insert existing element" );
1412 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
1414 SotElement_Impl* pDeletedElm = nullptr;
1416 for ( SotElementVector_Impl::iterator pElementIter = m_aChildrenVector.begin();
1417 pElementIter != m_aChildrenVector.end(); ++pElementIter )
1419 if ( (*pElementIter)->m_aName == aName )
1421 SAL_WARN_IF( !(*pElementIter)->m_bIsRemoved, "package.xstor", "Try to insert an element instead of existing one!" );
1422 if ( (*pElementIter)->m_bIsRemoved )
1424 SAL_WARN_IF( (*pElementIter)->m_bIsInserted, "package.xstor", "Inserted elements must be deleted immediately!" );
1425 pDeletedElm = *pElementIter;
1426 break;
1431 if ( pDeletedElm )
1433 if ( pDeletedElm->m_bIsStorage )
1434 OpenSubStorage( pDeletedElm, embed::ElementModes::READWRITE );
1435 else
1436 OpenSubStream( pDeletedElm );
1438 m_aChildrenVector.erase(
1439 std::remove(m_aChildrenVector.begin(), m_aChildrenVector.end(), pDeletedElm),
1440 m_aChildrenVector.end());
1441 m_aDeletedVector.push_back( pDeletedElm );
1444 // create new element
1445 return new SotElement_Impl( aName, bIsStorage, true );
1448 void OStorage_Impl::OpenSubStorage( SotElement_Impl* pElement, sal_Int32 nStorageMode )
1450 SAL_WARN_IF( !pElement, "package.xstor", "pElement is not set!" );
1451 SAL_WARN_IF( !pElement->m_bIsStorage, "package.xstor", "Storage flag is not set!" );
1453 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
1455 if (!pElement->m_xStorage)
1457 SAL_WARN_IF( pElement->m_bIsInserted, "package.xstor", "Inserted element must be created already!" );
1459 uno::Reference< lang::XUnoTunnel > xTunnel;
1460 m_xPackageFolder->getByName( pElement->m_aOriginalName ) >>= xTunnel;
1461 if ( !xTunnel.is() )
1462 throw container::NoSuchElementException( THROW_WHERE );
1464 uno::Reference< container::XNameContainer > xPackageSubFolder( xTunnel, uno::UNO_QUERY_THROW );
1465 pElement->m_xStorage.reset(new OStorage_Impl(this, nStorageMode, xPackageSubFolder, m_xPackage, m_xContext, m_nStorageType));
1469 void OStorage_Impl::OpenSubStream( SotElement_Impl* pElement )
1471 SAL_WARN_IF( !pElement, "package.xstor", "pElement is not set!" );
1472 SAL_WARN_IF( pElement->m_bIsStorage, "package.xstor", "Storage flag is set!" );
1474 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
1476 if (!pElement->m_xStream)
1478 SAL_WARN_IF( pElement->m_bIsInserted, "package.xstor", "Inserted element must be created already!" );
1480 uno::Reference< lang::XUnoTunnel > xTunnel;
1481 m_xPackageFolder->getByName( pElement->m_aOriginalName ) >>= xTunnel;
1482 if ( !xTunnel.is() )
1483 throw container::NoSuchElementException( THROW_WHERE );
1485 uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xTunnel, uno::UNO_QUERY_THROW );
1487 // the stream can never be inserted here, because inserted stream element holds the stream till commit or destruction
1488 pElement->m_xStream.reset(new OWriteStream_Impl(this, xPackageSubStream, m_xPackage, m_xContext, false, m_nStorageType, false, GetRelInfoStreamForName(pElement->m_aOriginalName)));
1492 uno::Sequence< OUString > OStorage_Impl::GetElementNames()
1494 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
1496 ReadContents();
1498 sal_uInt32 nSize = m_aChildrenVector.size();
1499 uno::Sequence< OUString > aElementNames( nSize );
1501 sal_uInt32 nInd = 0;
1502 for ( SotElementVector_Impl::iterator pElementIter = m_aChildrenVector.begin();
1503 pElementIter != m_aChildrenVector.end(); ++pElementIter )
1505 if ( !(*pElementIter)->m_bIsRemoved )
1506 aElementNames[nInd++] = (*pElementIter)->m_aName;
1509 aElementNames.realloc( nInd );
1510 return aElementNames;
1513 void OStorage_Impl::RemoveElement( SotElement_Impl* pElement )
1515 SAL_WARN_IF( !pElement, "package.xstor", "Element must be provided!" );
1517 if ( !pElement )
1518 return;
1520 if ( (pElement->m_xStorage && ( pElement->m_xStorage->m_pAntiImpl || !pElement->m_xStorage->m_aReadOnlyWrapVector.empty() ))
1521 || (pElement->m_xStream && ( pElement->m_xStream->m_pAntiImpl || !pElement->m_xStream->m_aInputStreamsVector.empty() )) )
1522 throw io::IOException( THROW_WHERE ); // TODO: Access denied
1524 if ( pElement->m_bIsInserted )
1526 delete pElement;
1527 m_aChildrenVector.erase(std::remove(m_aChildrenVector.begin(), m_aChildrenVector.end(), pElement), m_aChildrenVector.end());
1529 else
1531 pElement->m_bIsRemoved = true;
1532 ClearElement( pElement );
1535 // TODO/OFOPXML: the rel stream should be removed as well
1538 void OStorage_Impl::ClearElement( SotElement_Impl* pElement )
1540 pElement->m_xStorage.reset();
1541 pElement->m_xStream.reset();
1544 void OStorage_Impl::CloneStreamElement( const OUString& aStreamName,
1545 bool bEncryptionDataProvided,
1546 const ::comphelper::SequenceAsHashMap& aEncryptionData,
1547 uno::Reference< io::XStream >& xTargetStream )
1549 SotElement_Impl *pElement = FindElement( aStreamName );
1550 if ( !pElement )
1552 // element does not exist, throw exception
1553 throw io::IOException( THROW_WHERE ); // TODO: access_denied
1555 else if ( pElement->m_bIsStorage )
1556 throw io::IOException( THROW_WHERE );
1558 if (!pElement->m_xStream)
1559 OpenSubStream( pElement );
1561 if (!pElement->m_xStream || !pElement->m_xStream->m_xPackageStream.is())
1562 throw io::IOException( THROW_WHERE ); // TODO: general_error
1564 // the existence of m_pAntiImpl of the child is not interesting,
1565 // the copy will be created internally
1567 // usual copying is not applicable here, only last flushed version of the
1568 // child stream should be used for copiing. Probably the children m_xPackageStream
1569 // can be used as a base of a new stream, that would be copied to result
1570 // storage. The only problem is that some package streams can be accessed from outside
1571 // at the same time (now solved by wrappers that remember own position).
1573 if (bEncryptionDataProvided)
1574 pElement->m_xStream->GetCopyOfLastCommit(xTargetStream, aEncryptionData);
1575 else
1576 pElement->m_xStream->GetCopyOfLastCommit(xTargetStream);
1579 void OStorage_Impl::RemoveStreamRelInfo( const OUString& aOriginalName )
1581 // this method should be used only in OStorage_Impl::Commit() method
1582 // the aOriginalName can be empty, in this case the storage relation info should be removed
1584 if ( m_nStorageType == embed::StorageFormats::OFOPXML && m_xRelStorage.is() )
1586 OUString aRelStreamName = aOriginalName;
1587 aRelStreamName += ".rels";
1589 if ( m_xRelStorage->hasByName( aRelStreamName ) )
1590 m_xRelStorage->removeElement( aRelStreamName );
1594 void OStorage_Impl::CreateRelStorage()
1596 if ( m_nStorageType != embed::StorageFormats::OFOPXML )
1597 return;
1599 if ( !m_xRelStorage.is() )
1601 if ( !m_pRelStorElement )
1603 m_pRelStorElement = new SotElement_Impl( "_rels", true, true );
1604 m_pRelStorElement->m_xStorage.reset(CreateNewStorageImpl(embed::ElementModes::WRITE));
1605 if (m_pRelStorElement->m_xStorage)
1606 m_pRelStorElement->m_xStorage->m_pParent = nullptr; // the relation storage is completely controlled by parent
1609 if (!m_pRelStorElement->m_xStorage)
1610 OpenSubStorage( m_pRelStorElement, embed::ElementModes::WRITE );
1612 if (!m_pRelStorElement->m_xStorage)
1613 throw uno::RuntimeException( THROW_WHERE );
1615 OStorage* pResultStorage = new OStorage(m_pRelStorElement->m_xStorage.get(), false);
1616 m_xRelStorage.set( static_cast<embed::XStorage*>(pResultStorage) );
1620 void OStorage_Impl::CommitStreamRelInfo( SotElement_Impl const * pStreamElement )
1622 // this method should be used only in OStorage_Impl::Commit() method
1624 // the stream element must be provided
1625 if ( !pStreamElement )
1626 throw uno::RuntimeException( THROW_WHERE );
1628 if (m_nStorageType == embed::StorageFormats::OFOPXML && pStreamElement->m_xStream)
1630 SAL_WARN_IF( pStreamElement->m_aName.isEmpty(), "package.xstor", "The name must not be empty!" );
1632 if ( !m_xRelStorage.is() )
1634 // Create new rels storage, this is commit scenario so it must be possible
1635 CreateRelStorage();
1638 pStreamElement->m_xStream->CommitStreamRelInfo(m_xRelStorage, pStreamElement->m_aOriginalName, pStreamElement->m_aName);
1642 uno::Reference< io::XInputStream > OStorage_Impl::GetRelInfoStreamForName( const OUString& aName )
1644 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1646 ReadContents();
1647 if ( m_xRelStorage.is() )
1649 OUString aRelStreamName = aName;
1650 aRelStreamName += ".rels";
1651 if ( m_xRelStorage->hasByName( aRelStreamName ) )
1653 uno::Reference< io::XStream > xStream = m_xRelStorage->openStreamElement( aRelStreamName, embed::ElementModes::READ );
1654 if ( xStream.is() )
1655 return xStream->getInputStream();
1660 return uno::Reference< io::XInputStream >();
1663 void OStorage_Impl::CommitRelInfo( const uno::Reference< container::XNameContainer >& xNewPackageFolder )
1665 // this method should be used only in OStorage_Impl::Commit() method
1666 OUString aRelsStorName("_rels");
1668 if ( !xNewPackageFolder.is() )
1669 throw uno::RuntimeException( THROW_WHERE );
1671 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
1677 || m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
1678 || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1680 if ( m_nRelInfoStatus == RELINFO_CHANGED )
1682 if ( m_aRelInfo.getLength() )
1684 CreateRelStorage();
1686 uno::Reference< io::XStream > xRelsStream =
1687 m_xRelStorage->openStreamElement( ".rels" ,
1688 embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
1690 uno::Reference< io::XOutputStream > xOutStream = xRelsStream->getOutputStream();
1691 if ( !xOutStream.is() )
1692 throw uno::RuntimeException( THROW_WHERE );
1694 ::comphelper::OFOPXMLHelper::WriteRelationsInfoSequence( xOutStream, m_aRelInfo, m_xContext );
1696 // set the mediatype
1697 uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
1698 xPropSet->setPropertyValue(
1699 "MediaType",
1700 uno::makeAny( OUString( "application/vnd.openxmlformats-package.relationships+xml" ) ) );
1702 m_nRelInfoStatus = RELINFO_READ;
1704 else if ( m_xRelStorage.is() )
1705 RemoveStreamRelInfo( OUString() ); // remove own rel info
1707 else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
1708 || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1710 CreateRelStorage();
1712 uno::Reference< io::XStream > xRelsStream =
1713 m_xRelStorage->openStreamElement( ".rels",
1714 embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
1716 uno::Reference< io::XOutputStream > xOutputStream = xRelsStream->getOutputStream();
1717 if ( !xOutputStream.is() )
1718 throw uno::RuntimeException( THROW_WHERE );
1720 uno::Reference< io::XSeekable > xSeek( m_xNewRelInfoStream, uno::UNO_QUERY_THROW );
1721 xSeek->seek( 0 );
1722 ::comphelper::OStorageHelper::CopyInputToOutput( m_xNewRelInfoStream, xOutputStream );
1724 // set the mediatype
1725 uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
1726 xPropSet->setPropertyValue(
1727 "MediaType",
1728 uno::makeAny( OUString( "application/vnd.openxmlformats-package.relationships+xml" ) ) );
1730 m_xNewRelInfoStream.clear();
1731 if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1733 m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
1734 m_nRelInfoStatus = RELINFO_NO_INIT;
1736 else
1737 m_nRelInfoStatus = RELINFO_READ;
1741 if ( m_xRelStorage.is() )
1743 if ( m_xRelStorage->hasElements() )
1745 uno::Reference< embed::XTransactedObject > xTrans( m_xRelStorage, uno::UNO_QUERY_THROW );
1746 if ( xTrans.is() )
1747 xTrans->commit();
1750 if ( xNewPackageFolder.is() && xNewPackageFolder->hasByName( aRelsStorName ) )
1751 xNewPackageFolder->removeByName( aRelsStorName );
1753 if ( !m_xRelStorage->hasElements() )
1755 // the empty relations storage should not be created
1756 delete m_pRelStorElement;
1757 m_pRelStorElement = nullptr;
1758 m_xRelStorage.clear();
1760 else if ( m_pRelStorElement && m_pRelStorElement->m_xStorage && xNewPackageFolder.is() )
1761 m_pRelStorElement->m_xStorage->InsertIntoPackageFolder( aRelsStorName, xNewPackageFolder );
1766 // OStorage implementation
1768 OStorage::OStorage( uno::Reference< io::XInputStream > const & xInputStream,
1769 sal_Int32 nMode,
1770 const uno::Sequence< beans::PropertyValue >& xProperties,
1771 uno::Reference< uno::XComponentContext > const & xContext,
1772 sal_Int32 nStorageType )
1773 : m_pImpl( new OStorage_Impl( xInputStream, nMode, xProperties, xContext, nStorageType ) )
1775 m_pImpl->m_pAntiImpl = this;
1776 m_pData.reset(new StorInternalData_Impl( m_pImpl->m_xMutex, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, false));
1779 OStorage::OStorage( uno::Reference< io::XStream > const & xStream,
1780 sal_Int32 nMode,
1781 const uno::Sequence< beans::PropertyValue >& xProperties,
1782 uno::Reference< uno::XComponentContext > const & xContext,
1783 sal_Int32 nStorageType )
1784 : m_pImpl( new OStorage_Impl( xStream, nMode, xProperties, xContext, nStorageType ) )
1786 m_pImpl->m_pAntiImpl = this;
1787 m_pData.reset(new StorInternalData_Impl( m_pImpl->m_xMutex, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, false));
1790 OStorage::OStorage( OStorage_Impl* pImpl, bool bReadOnlyWrap )
1791 : m_pImpl( pImpl )
1793 // this call can be done only from OStorage_Impl implementation to create child storage
1794 OSL_ENSURE( m_pImpl && m_pImpl->m_xMutex.is(), "The provided pointer & mutex MUST NOT be empty!" );
1796 m_pData.reset(new StorInternalData_Impl( m_pImpl->m_xMutex, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, bReadOnlyWrap));
1798 OSL_ENSURE( ( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) == embed::ElementModes::WRITE ||
1799 m_pData->m_bReadOnlyWrap,
1800 "The wrapper can not allow writing in case implementation does not!" );
1802 if ( !bReadOnlyWrap )
1803 m_pImpl->m_pAntiImpl = this;
1806 OStorage::~OStorage()
1808 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
1809 if ( m_pImpl )
1811 m_refCount++; // to call dispose
1812 try {
1813 dispose();
1815 catch( const uno::RuntimeException& rRuntimeException )
1817 SAL_INFO("package.xstor", "Handled exception: " << rRuntimeException);
1822 void OStorage::InternalDispose( bool bNotifyImpl )
1824 if ( !m_pImpl )
1826 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
1827 throw lang::DisposedException( THROW_WHERE );
1830 // the source object is also a kind of locker for the current object
1831 // since the listeners could dispose the object while being notified
1832 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
1833 m_pData->m_aListenersContainer.disposeAndClear( aSource );
1835 if ( !m_pImpl )
1837 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
1838 throw lang::DisposedException( THROW_WHERE );
1841 m_pImpl->m_nModifiedListenerCount = 0;
1843 if ( m_pData->m_bReadOnlyWrap )
1845 OSL_ENSURE( !m_pData->m_aOpenSubComponentsVector.size() || m_pData->m_pSubElDispListener.get(),
1846 "If any subelements are open the listener must exist!" );
1848 if (m_pData->m_pSubElDispListener.get())
1850 m_pData->m_pSubElDispListener->OwnerIsDisposed();
1852 // iterate through m_pData->m_aOpenSubComponentsVector
1853 // deregister m_pData->m_pSubElDispListener and dispose all of them
1854 if ( !m_pData->m_aOpenSubComponentsVector.empty() )
1856 for ( WeakComponentVector::iterator pCompIter = m_pData->m_aOpenSubComponentsVector.begin();
1857 pCompIter != m_pData->m_aOpenSubComponentsVector.end(); ++pCompIter )
1859 uno::Reference< lang::XComponent > xTmp = (*pCompIter);
1860 if ( xTmp.is() )
1862 xTmp->removeEventListener( uno::Reference< lang::XEventListener >(
1863 static_cast< lang::XEventListener* >( m_pData->m_pSubElDispListener.get())));
1865 try {
1866 xTmp->dispose();
1867 } catch( const uno::Exception& rException )
1869 SAL_INFO("package.xstor", "Quiet exception: " << rException);
1874 m_pData->m_aOpenSubComponentsVector.clear();
1878 if ( bNotifyImpl )
1879 m_pImpl->RemoveReadOnlyWrap( *this );
1881 else
1883 m_pImpl->m_pAntiImpl = nullptr;
1885 if ( bNotifyImpl )
1887 if ( m_pData->m_bIsRoot )
1888 delete m_pImpl;
1889 else
1891 // the non-committed changes for the storage must be removed
1892 m_pImpl->Revert();
1897 m_pImpl = nullptr;
1900 void OStorage::ChildIsDisposed( const uno::Reference< uno::XInterface >& xChild )
1902 // this method can only be called by child disposing listener
1904 // this method must not contain any locking
1905 // the locking is done in the listener
1907 if ( !m_pData->m_aOpenSubComponentsVector.empty() )
1909 for ( WeakComponentVector::iterator pCompIter = m_pData->m_aOpenSubComponentsVector.begin();
1910 pCompIter != m_pData->m_aOpenSubComponentsVector.end(); )
1912 uno::Reference< lang::XComponent > xTmp = (*pCompIter);
1913 if ( !xTmp.is() || xTmp == xChild )
1915 pCompIter = m_pData->m_aOpenSubComponentsVector.erase(pCompIter);
1917 else
1918 ++pCompIter;
1923 void OStorage::BroadcastModifiedIfNecessary()
1925 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
1926 if ( !m_pImpl )
1928 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
1929 throw lang::DisposedException( THROW_WHERE );
1932 if ( !m_pImpl->m_bBroadcastModified )
1933 return;
1935 m_pImpl->m_bBroadcastModified = false;
1937 SAL_WARN_IF( m_pData->m_bReadOnlyWrap, "package.xstor", "The storage can not be modified at all!" );
1939 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
1941 ::cppu::OInterfaceContainerHelper* pContainer =
1942 m_pData->m_aListenersContainer.getContainer(
1943 cppu::UnoType<util::XModifyListener>::get());
1944 if ( pContainer )
1946 ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
1947 while ( pIterator.hasMoreElements( ) )
1949 static_cast<util::XModifyListener*>( pIterator.next( ) )->modified( aSource );
1954 void OStorage::BroadcastTransaction( sal_Int8 nMessage )
1956 1 - preCommit
1957 2 - committed
1958 3 - preRevert
1959 4 - reverted
1962 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
1963 if ( !m_pImpl )
1965 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
1966 throw lang::DisposedException( THROW_WHERE );
1969 SAL_WARN_IF( m_pData->m_bReadOnlyWrap, "package.xstor", "The storage can not be modified at all!" );
1971 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
1973 ::cppu::OInterfaceContainerHelper* pContainer =
1974 m_pData->m_aListenersContainer.getContainer(
1975 cppu::UnoType<embed::XTransactionListener>::get());
1976 if ( pContainer )
1978 ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
1979 while ( pIterator.hasMoreElements( ) )
1981 OSL_ENSURE( nMessage >= 1 && nMessage <= 4, "Wrong internal notification code is used!" );
1983 switch( nMessage )
1985 case STOR_MESS_PRECOMMIT:
1986 static_cast<embed::XTransactionListener*>( pIterator.next( ) )->preCommit( aSource );
1987 break;
1988 case STOR_MESS_COMMITED:
1989 static_cast<embed::XTransactionListener*>( pIterator.next( ) )->commited( aSource );
1990 break;
1991 case STOR_MESS_PREREVERT:
1992 static_cast<embed::XTransactionListener*>( pIterator.next( ) )->preRevert( aSource );
1993 break;
1994 case STOR_MESS_REVERTED:
1995 static_cast<embed::XTransactionListener*>( pIterator.next( ) )->reverted( aSource );
1996 break;
2002 SotElement_Impl* OStorage::OpenStreamElement_Impl( const OUString& aStreamName, sal_Int32 nOpenMode, bool bEncr )
2004 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
2006 OSL_ENSURE( !m_pData->m_bReadOnlyWrap || ( nOpenMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE,
2007 "An element can not be opened for writing in readonly storage!" );
2009 SotElement_Impl *pElement = m_pImpl->FindElement( aStreamName );
2010 if ( !pElement )
2012 // element does not exist, check if creation is allowed
2013 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
2014 || (( nOpenMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
2015 || ( nOpenMode & embed::ElementModes::NOCREATE ) == embed::ElementModes::NOCREATE )
2017 throw io::IOException("Element does not exist and cannot be "
2018 "created: \"" + aStreamName + "\""); // TODO: access_denied
2021 // create a new StreamElement and insert it into the list
2022 pElement = m_pImpl->InsertStream( aStreamName, bEncr );
2024 else if ( pElement->m_bIsStorage )
2026 throw io::IOException( THROW_WHERE );
2029 SAL_WARN_IF( !pElement, "package.xstor", "In case element can not be created an exception must be thrown!" );
2031 if (!pElement->m_xStream)
2032 m_pImpl->OpenSubStream( pElement );
2034 if (!pElement->m_xStream)
2035 throw io::IOException( THROW_WHERE );
2037 return pElement;
2040 void OStorage::MakeLinkToSubComponent_Impl( const uno::Reference< lang::XComponent >& xComponent )
2042 if ( !xComponent.is() )
2043 throw uno::RuntimeException( THROW_WHERE );
2045 if (!m_pData->m_pSubElDispListener.get())
2047 m_pData->m_pSubElDispListener = new OChildDispListener_Impl( *this );
2050 xComponent->addEventListener( uno::Reference< lang::XEventListener >(
2051 static_cast< ::cppu::OWeakObject* >(m_pData->m_pSubElDispListener.get()), uno::UNO_QUERY));
2053 m_pData->m_aOpenSubComponentsVector.emplace_back(xComponent );
2056 // XInterface
2058 uno::Any SAL_CALL OStorage::queryInterface( const uno::Type& rType )
2060 uno::Any aReturn;
2062 // common interfaces
2063 aReturn = ::cppu::queryInterface
2064 ( rType
2065 , static_cast<lang::XTypeProvider*> ( this )
2066 , static_cast<embed::XStorage*> ( this )
2067 , static_cast<embed::XStorage2*> ( this )
2068 , static_cast<embed::XTransactedObject*> ( this )
2069 , static_cast<embed::XTransactionBroadcaster*> ( this )
2070 , static_cast<util::XModifiable*> ( this )
2071 , static_cast<container::XNameAccess*> ( this )
2072 , static_cast<container::XElementAccess*> ( this )
2073 , static_cast<lang::XComponent*> ( this )
2074 , static_cast<beans::XPropertySet*> ( this )
2075 , static_cast<embed::XOptimizedStorage*> ( this ) );
2077 if ( aReturn.hasValue() )
2078 return aReturn ;
2080 aReturn = ::cppu::queryInterface
2081 ( rType
2082 , static_cast<embed::XHierarchicalStorageAccess*> ( this )
2083 , static_cast<embed::XHierarchicalStorageAccess2*> ( this ) );
2085 if ( aReturn.hasValue() )
2086 return aReturn ;
2088 if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
2090 if ( m_pData->m_bIsRoot )
2092 aReturn = ::cppu::queryInterface
2093 ( rType
2094 , static_cast<embed::XStorageRawAccess*> ( this )
2095 , static_cast<embed::XEncryptionProtectedSource*> ( this )
2096 , static_cast<embed::XEncryptionProtectedSource2*> ( this )
2097 , static_cast<embed::XEncryptionProtectedStorage*> ( this ) );
2099 else
2101 aReturn = ::cppu::queryInterface
2102 ( rType
2103 , static_cast<embed::XStorageRawAccess*> ( this ) );
2106 else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
2108 aReturn = ::cppu::queryInterface
2109 ( rType
2110 , static_cast<embed::XRelationshipAccess*> ( this ) );
2113 if ( aReturn.hasValue() )
2114 return aReturn ;
2116 return OWeakObject::queryInterface( rType );
2119 void SAL_CALL OStorage::acquire() throw()
2121 OWeakObject::acquire();
2124 void SAL_CALL OStorage::release() throw()
2126 OWeakObject::release();
2129 // XTypeProvider
2130 uno::Sequence< uno::Type > SAL_CALL OStorage::getTypes()
2132 if (! m_pData->m_pTypeCollection)
2134 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
2136 if (! m_pData->m_pTypeCollection)
2138 if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
2140 if ( m_pData->m_bIsRoot )
2142 m_pData->m_pTypeCollection.reset(new ::cppu::OTypeCollection
2143 ( cppu::UnoType<lang::XTypeProvider>::get()
2144 , cppu::UnoType<embed::XStorage>::get()
2145 , cppu::UnoType<embed::XStorage2>::get()
2146 , cppu::UnoType<embed::XStorageRawAccess>::get()
2147 , cppu::UnoType<embed::XTransactedObject>::get()
2148 , cppu::UnoType<embed::XTransactionBroadcaster>::get()
2149 , cppu::UnoType<util::XModifiable>::get()
2150 , cppu::UnoType<embed::XEncryptionProtectedStorage>::get()
2151 , cppu::UnoType<embed::XEncryptionProtectedSource2>::get()
2152 , cppu::UnoType<embed::XEncryptionProtectedSource>::get()
2153 , cppu::UnoType<beans::XPropertySet>::get()));
2155 else
2157 m_pData->m_pTypeCollection.reset(new ::cppu::OTypeCollection
2158 ( cppu::UnoType<lang::XTypeProvider>::get()
2159 , cppu::UnoType<embed::XStorage>::get()
2160 , cppu::UnoType<embed::XStorage2>::get()
2161 , cppu::UnoType<embed::XStorageRawAccess>::get()
2162 , cppu::UnoType<embed::XTransactedObject>::get()
2163 , cppu::UnoType<embed::XTransactionBroadcaster>::get()
2164 , cppu::UnoType<util::XModifiable>::get()
2165 , cppu::UnoType<beans::XPropertySet>::get()));
2168 else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
2170 m_pData->m_pTypeCollection.reset(new ::cppu::OTypeCollection
2171 ( cppu::UnoType<lang::XTypeProvider>::get()
2172 , cppu::UnoType<embed::XStorage>::get()
2173 , cppu::UnoType<embed::XTransactedObject>::get()
2174 , cppu::UnoType<embed::XTransactionBroadcaster>::get()
2175 , cppu::UnoType<util::XModifiable>::get()
2176 , cppu::UnoType<embed::XRelationshipAccess>::get()
2177 , cppu::UnoType<beans::XPropertySet>::get()));
2179 else
2181 m_pData->m_pTypeCollection.reset(new ::cppu::OTypeCollection
2182 ( cppu::UnoType<lang::XTypeProvider>::get()
2183 , cppu::UnoType<embed::XStorage>::get()
2184 , cppu::UnoType<embed::XTransactedObject>::get()
2185 , cppu::UnoType<embed::XTransactionBroadcaster>::get()
2186 , cppu::UnoType<util::XModifiable>::get()
2187 , cppu::UnoType<beans::XPropertySet>::get()));
2192 return m_pData->m_pTypeCollection->getTypes() ;
2195 namespace { struct lcl_ImplId : public rtl::Static< ::cppu::OImplementationId, lcl_ImplId > {}; }
2197 uno::Sequence< sal_Int8 > SAL_CALL OStorage::getImplementationId()
2199 return css::uno::Sequence<sal_Int8>();
2202 // XStorage
2203 void SAL_CALL OStorage::copyToStorage( const uno::Reference< embed::XStorage >& xDest )
2205 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
2207 if ( !m_pImpl )
2209 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2210 throw lang::DisposedException( THROW_WHERE );
2213 if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject*> ( this ), uno::UNO_QUERY ) )
2214 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 );
2216 try {
2217 m_pImpl->CopyToStorage( xDest, false );
2219 catch( const embed::InvalidStorageException& rInvalidStorageException )
2221 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
2222 throw;
2224 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2226 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
2227 throw;
2229 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
2231 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
2232 throw;
2234 catch( const io::IOException& rIOException )
2236 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
2237 throw;
2239 catch( const uno::RuntimeException& rRuntimeException )
2241 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
2242 throw;
2244 catch( const uno::Exception& rException )
2246 SAL_INFO("package.xstor", "Rethrow: " << rException);
2248 uno::Any aCaught( ::cppu::getCaughtException() );
2249 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't copy storage!",
2250 uno::Reference< io::XInputStream >(),
2251 aCaught );
2255 uno::Reference< io::XStream > SAL_CALL OStorage::openStreamElement(
2256 const OUString& aStreamName, sal_Int32 nOpenMode )
2258 ::osl::ResettableMutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
2260 if ( !m_pImpl )
2262 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2263 throw lang::DisposedException( THROW_WHERE );
2266 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, false ) )
2267 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2269 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aStreamName == "_rels" )
2270 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable element name
2272 if ( ( nOpenMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
2273 throw io::IOException( THROW_WHERE ); // TODO: access denied
2275 uno::Reference< io::XStream > xResult;
2278 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamName, nOpenMode, false );
2279 OSL_ENSURE(pElement && pElement->m_xStream, "In case element can not be created an exception must be thrown!");
2281 xResult = pElement->m_xStream->GetStream(nOpenMode, false);
2282 SAL_WARN_IF( !xResult.is(), "package.xstor", "The method must throw exception instead of removing empty result!" );
2284 if ( m_pData->m_bReadOnlyWrap )
2286 // before the storage disposes the stream it must deregister itself as listener
2287 uno::Reference< lang::XComponent > xStreamComponent( xResult, uno::UNO_QUERY_THROW );
2288 MakeLinkToSubComponent_Impl( xStreamComponent );
2291 catch( const embed::InvalidStorageException& rInvalidStorageException )
2293 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
2294 throw;
2296 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2298 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
2299 throw;
2301 catch( const packages::WrongPasswordException& rWrongPasswordException )
2303 SAL_INFO("package.xstor", "Rethrow: " << rWrongPasswordException);
2304 throw;
2306 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
2308 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
2309 throw;
2311 catch( const io::IOException& rIOException )
2313 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
2314 throw;
2316 catch( const uno::RuntimeException& rRuntimeException )
2318 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
2319 throw;
2321 catch( const uno::Exception& rException )
2323 SAL_INFO("package.xstor", "Rethrow: " << rException);
2325 uno::Any aCaught( ::cppu::getCaughtException() );
2326 throw embed::StorageWrappedTargetException(THROW_WHERE "Can't open stream element!",
2327 uno::Reference< io::XInputStream >(),
2328 aCaught );
2331 aGuard.clear();
2333 BroadcastModifiedIfNecessary();
2335 return xResult;
2338 uno::Reference< io::XStream > SAL_CALL OStorage::openEncryptedStreamElement(
2339 const OUString& aStreamName, sal_Int32 nOpenMode, const OUString& aPass )
2341 return openEncryptedStream( aStreamName, nOpenMode, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass ) );
2344 uno::Reference< embed::XStorage > SAL_CALL OStorage::openStorageElement(
2345 const OUString& aStorName, sal_Int32 nStorageMode )
2347 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
2349 if ( !m_pImpl )
2351 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2352 throw lang::DisposedException( THROW_WHERE );
2355 if ( aStorName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName, false ) )
2356 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2358 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aStorName == "_rels" )
2359 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2361 if ( ( nStorageMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
2362 throw io::IOException( THROW_WHERE ); // TODO: access denied
2364 if ( ( nStorageMode & embed::ElementModes::TRUNCATE )
2365 && !( nStorageMode & embed::ElementModes::WRITE ) )
2366 throw io::IOException( THROW_WHERE ); // TODO: access denied
2368 // it's always possible to read written storage in this implementation
2369 nStorageMode |= embed::ElementModes::READ;
2371 uno::Reference< embed::XStorage > xResult;
2374 SotElement_Impl *pElement = m_pImpl->FindElement( aStorName );
2375 if ( !pElement )
2377 // element does not exist, check if creation is allowed
2378 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
2379 || (( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
2380 || ( nStorageMode & embed::ElementModes::NOCREATE ) == embed::ElementModes::NOCREATE )
2381 throw io::IOException( THROW_WHERE ); // TODO: access_denied
2383 // create a new StorageElement and insert it into the list
2384 pElement = m_pImpl->InsertStorage( aStorName, nStorageMode );
2386 else if ( !pElement->m_bIsStorage )
2388 throw io::IOException( THROW_WHERE );
2390 else if (pElement->m_xStorage)
2392 // storage has already been opened; it may be opened another time, if it the mode allows to do so
2393 if (pElement->m_xStorage->m_pAntiImpl)
2395 throw io::IOException( THROW_WHERE ); // TODO: access_denied
2397 else if ( !pElement->m_xStorage->m_aReadOnlyWrapVector.empty()
2398 && ( nStorageMode & embed::ElementModes::WRITE ) )
2400 throw io::IOException( THROW_WHERE ); // TODO: access_denied
2402 else
2404 // in case parent storage allows writing the readonly mode of the child storage is
2405 // virtual, that means that it is just enough to change the flag to let it be writable
2406 // and since there is no AntiImpl nobody should be notified about it
2407 pElement->m_xStorage->m_nStorageMode = nStorageMode | embed::ElementModes::READ;
2409 if ( nStorageMode & embed::ElementModes::TRUNCATE )
2411 for ( SotElementVector_Impl::iterator pElementIter = pElement->m_xStorage->m_aChildrenVector.begin();
2412 pElementIter != pElement->m_xStorage->m_aChildrenVector.end(); )
2414 SotElement_Impl* pElementToDel = (*pElementIter);
2415 ++pElementIter;
2417 m_pImpl->RemoveElement( pElementToDel );
2423 if (!pElement->m_xStorage)
2424 m_pImpl->OpenSubStorage(pElement, nStorageMode);
2426 if (!pElement->m_xStorage)
2427 throw io::IOException( THROW_WHERE ); // TODO: general_error
2429 bool bReadOnlyWrap = ( ( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE );
2430 OStorage* pResultStorage = new OStorage(pElement->m_xStorage.get(), bReadOnlyWrap);
2431 xResult.set( static_cast<embed::XStorage*>(pResultStorage) );
2433 if ( bReadOnlyWrap )
2435 // Before this call is done the object must be refcounted already
2436 pElement->m_xStorage->SetReadOnlyWrap(*pResultStorage);
2438 // before the storage disposes the stream it must deregister itself as listener
2439 uno::Reference< lang::XComponent > xStorageComponent( xResult, uno::UNO_QUERY_THROW );
2440 MakeLinkToSubComponent_Impl( xStorageComponent );
2443 catch( const embed::InvalidStorageException& rInvalidStorageException )
2445 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
2446 throw;
2448 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2450 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
2451 throw;
2453 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
2455 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
2456 throw;
2458 catch( const io::IOException& rIOException )
2460 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
2461 throw;
2463 catch( const uno::RuntimeException& rRuntimeException )
2465 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
2466 throw;
2468 catch( const uno::Exception& rException )
2470 SAL_INFO("package.xstor", "Rethrow: " << rException);
2472 uno::Any aCaught( ::cppu::getCaughtException() );
2473 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't open storage!",
2474 uno::Reference< io::XInputStream >(),
2475 aCaught );
2478 return xResult;
2481 uno::Reference< io::XStream > SAL_CALL OStorage::cloneStreamElement( const OUString& aStreamName )
2483 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
2485 if ( !m_pImpl )
2487 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2488 throw lang::DisposedException( THROW_WHERE );
2491 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, false ) )
2492 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2494 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aStreamName == "_rels" )
2495 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2499 uno::Reference< io::XStream > xResult;
2500 m_pImpl->CloneStreamElement( aStreamName, false, ::comphelper::SequenceAsHashMap(), xResult );
2501 if ( !xResult.is() )
2502 throw uno::RuntimeException( THROW_WHERE );
2503 return xResult;
2505 catch( const embed::InvalidStorageException& rInvalidStorageException )
2507 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
2508 throw;
2510 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2512 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
2513 throw;
2515 catch( const packages::WrongPasswordException& rWrongPasswordException )
2517 SAL_INFO("package.xstor", "Rethrow: " << rWrongPasswordException);
2518 throw;
2520 catch( const io::IOException& rIOException )
2522 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
2523 throw;
2525 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
2527 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
2528 throw;
2530 catch( const uno::RuntimeException& rRuntimeException )
2532 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
2533 throw;
2535 catch( const uno::Exception& rException )
2537 SAL_INFO("package.xstor", "Rethrow: " << rException);
2539 uno::Any aCaught( ::cppu::getCaughtException() );
2540 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't clone stream!",
2541 uno::Reference< io::XInputStream >(),
2542 aCaught );
2546 uno::Reference< io::XStream > SAL_CALL OStorage::cloneEncryptedStreamElement(
2547 const OUString& aStreamName,
2548 const OUString& aPass )
2550 return cloneEncryptedStream( aStreamName, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass ) );
2553 void SAL_CALL OStorage::copyLastCommitTo(
2554 const uno::Reference< embed::XStorage >& xTargetStorage )
2556 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
2558 if ( !m_pImpl )
2560 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2561 throw lang::DisposedException( THROW_WHERE );
2566 m_pImpl->CopyLastCommitTo( xTargetStorage );
2568 catch( const embed::InvalidStorageException& rInvalidStorageException )
2570 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
2571 throw;
2573 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2575 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
2576 throw;
2578 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
2580 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
2581 throw;
2583 catch( const io::IOException& rIOException )
2585 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
2586 throw;
2588 catch( const uno::RuntimeException& rRuntimeException )
2590 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
2591 throw;
2593 catch( const uno::Exception& rException )
2595 SAL_INFO("package.xstor", "Rethrow: " << rException);
2597 uno::Any aCaught( ::cppu::getCaughtException() );
2598 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't copy last commit version!",
2599 uno::Reference< io::XInputStream >(),
2600 aCaught );
2605 void SAL_CALL OStorage::copyStorageElementLastCommitTo(
2606 const OUString& aStorName,
2607 const uno::Reference< embed::XStorage >& xTargetStorage )
2609 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
2611 if ( !m_pImpl )
2613 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2614 throw lang::DisposedException( THROW_WHERE );
2617 if ( aStorName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName, false ) )
2618 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2620 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aStorName == "_rels" )
2621 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2625 SotElement_Impl *pElement = m_pImpl->FindElement( aStorName );
2626 if ( !pElement )
2628 // element does not exist, throw exception
2629 throw io::IOException( THROW_WHERE ); // TODO: access_denied
2631 else if ( !pElement->m_bIsStorage )
2633 throw io::IOException( THROW_WHERE );
2636 if (!pElement->m_xStorage)
2637 m_pImpl->OpenSubStorage( pElement, embed::ElementModes::READ );
2639 if (!pElement->m_xStorage)
2640 throw io::IOException( THROW_WHERE ); // TODO: general_error
2642 // the existence of m_pAntiImpl of the child is not interesting,
2643 // the copy will be created internally
2645 pElement->m_xStorage->CopyLastCommitTo(xTargetStorage);
2647 catch( const embed::InvalidStorageException& rInvalidStorageException )
2649 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
2650 throw;
2652 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2654 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
2655 throw;
2657 catch( const io::IOException& rIOException )
2659 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
2660 throw;
2662 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
2664 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
2665 throw;
2667 catch( const uno::RuntimeException& rRuntimeException )
2669 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
2670 throw;
2672 catch( const uno::Exception& rException )
2674 SAL_INFO("package.xstor", "Rethrow: " << rException);
2676 uno::Any aCaught( ::cppu::getCaughtException() );
2677 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't copy last commit element version!",
2678 uno::Reference< io::XInputStream >(),
2679 aCaught );
2683 sal_Bool SAL_CALL OStorage::isStreamElement( const OUString& aElementName )
2685 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
2687 if ( !m_pImpl )
2689 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2690 throw lang::DisposedException( THROW_WHERE );
2693 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, false ) )
2694 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2696 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aElementName == "_rels" )
2697 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable name
2699 SotElement_Impl* pElement = nullptr;
2703 pElement = m_pImpl->FindElement( aElementName );
2705 catch( const embed::InvalidStorageException& rInvalidStorageException )
2707 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
2708 throw;
2710 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2712 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
2713 throw;
2715 catch( const container::NoSuchElementException& rNoSuchElementException )
2717 SAL_INFO("package.xstor", "Rethrow: " << rNoSuchElementException);
2718 throw;
2720 catch( const uno::RuntimeException& rRuntimeException )
2722 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
2723 throw;
2725 catch( const uno::Exception& rException )
2727 SAL_INFO("package.xstor", "Rethrow: " << rException);
2729 uno::Any aCaught( ::cppu::getCaughtException() );
2730 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can't detect whether it is a stream!",
2731 uno::Reference< io::XInputStream >(),
2732 aCaught );
2735 if ( !pElement )
2736 throw container::NoSuchElementException( THROW_WHERE ); //???
2738 return !pElement->m_bIsStorage;
2741 sal_Bool SAL_CALL OStorage::isStorageElement( const OUString& aElementName )
2743 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
2745 if ( !m_pImpl )
2747 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2748 throw lang::DisposedException( THROW_WHERE );
2751 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, false ) )
2752 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2754 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aElementName == "_rels" )
2755 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 );
2757 SotElement_Impl* pElement = nullptr;
2761 pElement = m_pImpl->FindElement( aElementName );
2763 catch( const embed::InvalidStorageException& rInvalidStorageException )
2765 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
2766 throw;
2768 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2770 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
2771 throw;
2773 catch( const container::NoSuchElementException& rNoSuchElementException )
2775 SAL_INFO("package.xstor", "Rethrow: " << rNoSuchElementException);
2776 throw;
2778 catch( const uno::RuntimeException& rRuntimeException )
2780 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
2781 throw;
2783 catch( const uno::Exception& rException )
2785 SAL_INFO("package.xstor", "Rethrow: " << rException);
2787 uno::Any aCaught( ::cppu::getCaughtException() );
2788 throw lang::WrappedTargetRuntimeException( THROW_WHERE "can't detect whether it is a storage",
2789 uno::Reference< io::XInputStream >(),
2790 aCaught );
2793 if ( !pElement )
2794 throw container::NoSuchElementException( THROW_WHERE ); //???
2796 return pElement->m_bIsStorage;
2799 void SAL_CALL OStorage::removeElement( const OUString& aElementName )
2801 ::osl::ResettableMutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
2803 if ( !m_pImpl )
2805 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2806 throw lang::DisposedException( THROW_WHERE );
2809 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, false ) )
2810 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2812 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aElementName == "_rels" )
2813 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // TODO: unacceptable name
2815 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
2816 throw io::IOException( THROW_WHERE ); // TODO: access denied
2820 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
2822 if ( !pElement )
2823 throw container::NoSuchElementException( THROW_WHERE ); //???
2825 m_pImpl->RemoveElement( pElement );
2827 m_pImpl->m_bIsModified = true;
2828 m_pImpl->m_bBroadcastModified = true;
2830 catch( const embed::InvalidStorageException& rInvalidStorageException )
2832 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
2833 throw;
2835 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2837 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
2838 throw;
2840 catch( const container::NoSuchElementException& rNoSuchElementException )
2842 SAL_INFO("package.xstor", "Rethrow: " << rNoSuchElementException);
2843 throw;
2845 catch( const io::IOException& rIOException )
2847 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
2848 throw;
2850 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
2852 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
2853 throw;
2855 catch( const uno::RuntimeException& rRuntimeException )
2857 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
2858 throw;
2860 catch( const uno::Exception& rException )
2862 SAL_INFO("package.xstor", "Rethrow: " << rException);
2864 uno::Any aCaught( ::cppu::getCaughtException() );
2865 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't remove element!",
2866 uno::Reference< io::XInputStream >(),
2867 aCaught );
2870 aGuard.clear();
2872 BroadcastModifiedIfNecessary();
2875 void SAL_CALL OStorage::renameElement( const OUString& aElementName, const OUString& aNewName )
2877 ::osl::ResettableMutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
2879 if ( !m_pImpl )
2881 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2882 throw lang::DisposedException( THROW_WHERE );
2885 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, false )
2886 || aNewName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, false ) )
2887 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2889 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && ( aElementName == "_rels" || aNewName == "_rels" ) )
2890 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 ); // TODO: unacceptable element name
2892 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
2893 throw io::IOException( THROW_WHERE ); // TODO: access denied
2897 SotElement_Impl* pRefElement = m_pImpl->FindElement( aNewName );
2898 if ( pRefElement )
2899 throw container::ElementExistException( THROW_WHERE ); //???
2901 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
2902 if ( !pElement )
2903 throw container::NoSuchElementException( THROW_WHERE ); //???
2905 pElement->m_aName = aNewName;
2907 m_pImpl->m_bIsModified = true;
2908 m_pImpl->m_bBroadcastModified = true;
2910 catch( const embed::InvalidStorageException& rInvalidStorageException )
2912 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
2913 throw;
2915 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2917 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
2918 throw;
2920 catch( const container::NoSuchElementException& rNoSuchElementException )
2922 SAL_INFO("package.xstor", "Rethrow: " << rNoSuchElementException);
2923 throw;
2925 catch( const container::ElementExistException& rElementExistException )
2927 SAL_INFO("package.xstor", "Rethrow: " << rElementExistException);
2928 throw;
2930 catch( const io::IOException& rIOException )
2932 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
2933 throw;
2935 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
2937 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
2938 throw;
2940 catch( const uno::RuntimeException& rRuntimeException )
2942 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
2943 throw;
2945 catch( const uno::Exception& rException )
2947 SAL_INFO("package.xstor", "Rethrow: " << rException);
2949 uno::Any aCaught( ::cppu::getCaughtException() );
2950 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't rename element!",
2951 uno::Reference< io::XInputStream >(),
2952 aCaught );
2955 aGuard.clear();
2957 BroadcastModifiedIfNecessary();
2960 void SAL_CALL OStorage::copyElementTo( const OUString& aElementName,
2961 const uno::Reference< embed::XStorage >& xDest,
2962 const OUString& aNewName )
2964 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
2966 if ( !m_pImpl )
2968 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2969 throw lang::DisposedException( THROW_WHERE );
2972 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, false )
2973 || aNewName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, false ) )
2974 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2976 if ( !xDest.is() )
2977 // || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
2978 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 2 );
2980 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && ( aElementName == "_rels" || aNewName == "_rels" ) )
2981 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 ); // unacceptable element name
2985 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
2986 if ( !pElement )
2987 throw container::NoSuchElementException( THROW_WHERE );
2989 uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY_THROW );
2990 if ( xNameAccess->hasByName( aNewName ) )
2991 throw container::ElementExistException( THROW_WHERE );
2993 m_pImpl->CopyStorageElement( pElement, xDest, aNewName, false );
2995 catch( const embed::InvalidStorageException& rInvalidStorageException )
2997 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
2998 throw;
3000 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3002 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
3003 throw;
3005 catch( const container::NoSuchElementException& rNoSuchElementException )
3007 SAL_INFO("package.xstor", "Rethrow: " << rNoSuchElementException);
3008 throw;
3010 catch( const container::ElementExistException& rElementExistException )
3012 SAL_INFO("package.xstor", "Rethrow: " << rElementExistException);
3013 throw;
3015 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3017 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
3018 throw;
3020 catch( const io::IOException& rIOException )
3022 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
3023 throw;
3025 catch( const uno::RuntimeException& rRuntimeException )
3027 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
3028 throw;
3030 catch( const uno::Exception& rException )
3032 SAL_INFO("package.xstor", "Rethrow: " << rException);
3034 uno::Any aCaught( ::cppu::getCaughtException() );
3035 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't copy element!",
3036 uno::Reference< io::XInputStream >(),
3037 aCaught );
3041 void SAL_CALL OStorage::moveElementTo( const OUString& aElementName,
3042 const uno::Reference< embed::XStorage >& xDest,
3043 const OUString& aNewName )
3045 ::osl::ResettableMutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3047 if ( !m_pImpl )
3049 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3050 throw lang::DisposedException( THROW_WHERE );
3053 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, false )
3054 || aNewName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, false ) )
3055 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3057 if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
3058 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 2 );
3060 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && ( aElementName == "_rels" || aNewName == "_rels" ) )
3061 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 ); // unacceptable element name
3063 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3064 throw io::IOException( THROW_WHERE ); // TODO: access denied
3068 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3069 if ( !pElement )
3070 throw container::NoSuchElementException( THROW_WHERE ); //???
3072 uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY_THROW );
3073 if ( xNameAccess->hasByName( aNewName ) )
3074 throw container::ElementExistException( THROW_WHERE );
3076 m_pImpl->CopyStorageElement( pElement, xDest, aNewName, false );
3078 m_pImpl->RemoveElement( pElement );
3080 m_pImpl->m_bIsModified = true;
3081 m_pImpl->m_bBroadcastModified = true;
3083 catch( const embed::InvalidStorageException& rInvalidStorageException )
3085 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
3086 throw;
3088 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3090 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
3091 throw;
3093 catch( const container::NoSuchElementException& rNoSuchElementException )
3095 SAL_INFO("package.xstor", "Rethrow: " << rNoSuchElementException);
3096 throw;
3098 catch( const container::ElementExistException& rElementExistException )
3100 SAL_INFO("package.xstor", "Rethrow: " << rElementExistException);
3101 throw;
3103 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3105 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
3106 throw;
3108 catch( const io::IOException& rIOException )
3110 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
3111 throw;
3113 catch( const uno::RuntimeException& rRuntimeException )
3115 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
3116 throw;
3118 catch( const uno::Exception& rException )
3120 SAL_INFO("package.xstor", "Rethrow: " << rException);
3122 uno::Any aCaught( ::cppu::getCaughtException() );
3123 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't move element!",
3124 uno::Reference< io::XInputStream >(),
3125 aCaught );
3128 aGuard.clear();
3130 BroadcastModifiedIfNecessary();
3133 // XStorage2
3134 uno::Reference< io::XStream > SAL_CALL OStorage::openEncryptedStream(
3135 const OUString& aStreamName, sal_Int32 nOpenMode, const uno::Sequence< beans::NamedValue >& aEncryptionData )
3137 ::osl::ResettableMutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3139 if ( !m_pImpl )
3141 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3142 throw lang::DisposedException( THROW_WHERE );
3145 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
3146 packages::NoEncryptionException();
3148 if ( ( nOpenMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
3149 throw io::IOException( THROW_WHERE ); // TODO: access denied
3151 if ( !aEncryptionData.getLength() )
3152 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 3 );
3154 uno::Reference< io::XStream > xResult;
3157 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamName, nOpenMode, true );
3158 OSL_ENSURE(pElement && pElement->m_xStream, "In case element can not be created an exception must be thrown!");
3160 xResult = pElement->m_xStream->GetStream(nOpenMode, aEncryptionData, false);
3161 SAL_WARN_IF( !xResult.is(), "package.xstor", "The method must throw exception instead of removing empty result!" );
3163 if ( m_pData->m_bReadOnlyWrap )
3165 // before the storage disposes the stream it must deregister itself as listener
3166 uno::Reference< lang::XComponent > xStreamComponent( xResult, uno::UNO_QUERY_THROW );
3167 MakeLinkToSubComponent_Impl( xStreamComponent );
3170 catch( const embed::InvalidStorageException& rInvalidStorageException )
3172 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
3173 throw;
3175 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3177 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
3178 throw;
3180 catch( const packages::NoEncryptionException& rNoEncryptionException )
3182 SAL_INFO("package.xstor", "Rethrow: " << rNoEncryptionException);
3183 throw;
3185 catch( const packages::WrongPasswordException& rWrongPasswordException )
3187 SAL_INFO("package.xstor", "Rethrow: " << rWrongPasswordException);
3188 throw;
3190 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3192 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
3193 throw;
3195 catch( const io::IOException& rIOException )
3197 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
3198 throw;
3200 catch( const uno::RuntimeException& rRuntimeException )
3202 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
3203 throw;
3205 catch( const uno::Exception& rException )
3207 SAL_INFO("package.xstor", "Rethrow: " << rException);
3209 uno::Any aCaught( ::cppu::getCaughtException() );
3210 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't open encrypted stream!",
3211 uno::Reference< io::XInputStream >(),
3212 aCaught );
3215 aGuard.clear();
3217 BroadcastModifiedIfNecessary();
3219 return xResult;
3222 uno::Reference< io::XStream > SAL_CALL OStorage::cloneEncryptedStream(
3223 const OUString& aStreamName,
3224 const uno::Sequence< beans::NamedValue >& aEncryptionData )
3226 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3228 if ( !m_pImpl )
3230 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3231 throw lang::DisposedException( THROW_WHERE );
3234 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
3235 packages::NoEncryptionException();
3237 if ( !aEncryptionData.getLength() )
3238 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 2 );
3242 uno::Reference< io::XStream > xResult;
3243 m_pImpl->CloneStreamElement( aStreamName, true, aEncryptionData, xResult );
3244 if ( !xResult.is() )
3245 throw uno::RuntimeException( THROW_WHERE );
3246 return xResult;
3248 catch( const embed::InvalidStorageException& rInvalidStorageException )
3250 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
3251 throw;
3253 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3255 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
3256 throw;
3258 catch( const packages::NoEncryptionException& rNoEncryptionException )
3260 SAL_INFO("package.xstor", "Rethrow: " << rNoEncryptionException);
3261 throw;
3263 catch( const packages::WrongPasswordException& rWrongPasswordException )
3265 SAL_INFO("package.xstor", "Rethrow: " << rWrongPasswordException);
3266 throw;
3268 catch( const io::IOException& rIOException )
3270 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
3271 throw;
3273 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3275 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
3276 throw;
3278 catch( const uno::RuntimeException& rRuntimeException )
3280 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
3281 throw;
3283 catch( const uno::Exception& rException )
3285 SAL_INFO("package.xstor", "Rethrow: " << rException);
3287 uno::Any aCaught( ::cppu::getCaughtException() );
3288 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't clone encrypted stream!",
3289 uno::Reference< io::XInputStream >(),
3290 aCaught );
3294 // XStorageRawAccess
3295 uno::Reference< io::XInputStream > SAL_CALL OStorage::getPlainRawStreamElement(
3296 const OUString& sStreamName )
3298 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3300 if ( !m_pImpl )
3302 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3303 throw lang::DisposedException( THROW_WHERE );
3306 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
3307 throw uno::RuntimeException( THROW_WHERE ); // the interface is not supported and must not be accessible
3309 if ( sStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName, false ) )
3310 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3312 uno::Reference < io::XInputStream > xTempIn;
3315 SotElement_Impl* pElement = m_pImpl->FindElement( sStreamName );
3316 if ( !pElement )
3317 throw container::NoSuchElementException( THROW_WHERE );
3319 if (!pElement->m_xStream)
3321 m_pImpl->OpenSubStream( pElement );
3322 if (!pElement->m_xStream)
3323 throw io::IOException( THROW_WHERE );
3326 uno::Reference<io::XInputStream> xRawInStream = pElement->m_xStream->GetPlainRawInStream();
3327 if ( !xRawInStream.is() )
3328 throw io::IOException( THROW_WHERE );
3330 uno::Reference < io::XTempFile > xTempFile = io::TempFile::create( m_pImpl->m_xContext );
3331 uno::Reference < io::XOutputStream > xTempOut = xTempFile->getOutputStream();
3332 xTempIn = xTempFile->getInputStream();
3333 uno::Reference < io::XSeekable > xSeek( xTempOut, uno::UNO_QUERY );
3335 if ( !xTempOut.is() || !xTempIn.is() || !xSeek.is() )
3336 throw io::IOException( THROW_WHERE );
3338 // Copy temporary file to a new one
3339 ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
3340 xTempOut->closeOutput();
3341 xSeek->seek( 0 );
3343 catch( const embed::InvalidStorageException& rInvalidStorageException )
3345 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
3346 throw;
3348 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3350 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
3351 throw;
3353 catch( const container::NoSuchElementException& rNoSuchElementException )
3355 SAL_INFO("package.xstor", "Rethrow: " << rNoSuchElementException);
3356 throw;
3358 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3360 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
3361 throw;
3363 catch( const io::IOException& rIOException )
3365 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
3366 throw;
3368 catch( const uno::RuntimeException& rRuntimeException )
3370 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
3371 throw;
3373 catch( const uno::Exception& rException )
3375 SAL_INFO("package.xstor", "Rethrow: " << rException);
3377 uno::Any aCaught( ::cppu::getCaughtException() );
3378 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't get plain raw stream!",
3379 uno::Reference< io::XInputStream >(),
3380 aCaught );
3383 return xTempIn;
3386 uno::Reference< io::XInputStream > SAL_CALL OStorage::getRawEncrStreamElement(
3387 const OUString& sStreamName )
3389 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3391 if ( !m_pImpl )
3393 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3394 throw lang::DisposedException( THROW_WHERE );
3397 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
3398 throw packages::NoEncryptionException( THROW_WHERE );
3400 if ( sStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName, false ) )
3401 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3403 uno::Reference < io::XInputStream > xTempIn;
3406 SotElement_Impl* pElement = m_pImpl->FindElement( sStreamName );
3407 if ( !pElement )
3408 throw container::NoSuchElementException( THROW_WHERE );
3410 if (!pElement->m_xStream)
3412 m_pImpl->OpenSubStream( pElement );
3413 if (!pElement->m_xStream)
3414 throw io::IOException( THROW_WHERE );
3417 if (!pElement->m_xStream->IsEncrypted())
3418 throw packages::NoEncryptionException( THROW_WHERE );
3420 uno::Reference< io::XInputStream > xRawInStream = pElement->m_xStream->GetRawInStream();
3421 if ( !xRawInStream.is() )
3422 throw io::IOException( THROW_WHERE );
3424 uno::Reference < io::XTempFile > xTempFile = io::TempFile::create(m_pImpl->m_xContext);
3425 uno::Reference < io::XOutputStream > xTempOut = xTempFile->getOutputStream();
3426 xTempIn = xTempFile->getInputStream();
3427 uno::Reference < io::XSeekable > xSeek( xTempOut, uno::UNO_QUERY );
3429 if ( !xTempOut.is() || !xTempIn.is() || !xSeek.is() )
3430 throw io::IOException( THROW_WHERE );
3432 // Copy temporary file to a new one
3433 ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
3434 xTempOut->closeOutput();
3435 xSeek->seek( 0 );
3438 catch( const embed::InvalidStorageException& rInvalidStorageException )
3440 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
3441 throw;
3443 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3445 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
3446 throw;
3448 catch( const packages::NoEncryptionException& rNoEncryptionException )
3450 SAL_INFO("package.xstor", "Rethrow: " << rNoEncryptionException);
3451 throw;
3453 catch( const container::NoSuchElementException& rNoSuchElementException )
3455 SAL_INFO("package.xstor", "Rethrow: " << rNoSuchElementException);
3456 throw;
3458 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3460 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
3461 throw;
3463 catch( const io::IOException& rIOException )
3465 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
3466 throw;
3468 catch( const uno::RuntimeException& rRuntimeException )
3470 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
3471 throw;
3473 catch( const uno::Exception& rException )
3475 SAL_INFO("package.xstor", "Rethrow: " << rException);
3477 uno::Any aCaught( ::cppu::getCaughtException() );
3478 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't get raw stream!",
3479 uno::Reference< io::XInputStream >(),
3480 aCaught );
3483 return xTempIn;
3486 void SAL_CALL OStorage::insertRawEncrStreamElement( const OUString& aStreamName,
3487 const uno::Reference< io::XInputStream >& xInStream )
3489 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3491 if ( !m_pImpl )
3493 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3494 throw lang::DisposedException( THROW_WHERE );
3497 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
3498 throw embed::InvalidStorageException( THROW_WHERE );
3500 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, false ) )
3501 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3503 if ( !xInStream.is() )
3504 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 2 );
3506 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3507 throw io::IOException( THROW_WHERE ); // TODO: access denied
3511 SotElement_Impl* pElement = m_pImpl->FindElement( aStreamName );
3512 if ( pElement )
3513 throw container::ElementExistException( THROW_WHERE );
3515 m_pImpl->InsertRawStream( aStreamName, xInStream );
3517 catch( const embed::InvalidStorageException& rInvalidStorageException )
3519 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
3520 throw;
3522 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3524 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
3525 throw;
3527 catch( const packages::NoRawFormatException& rNoRawFormatException )
3529 SAL_INFO("package.xstor", "Rethrow: " << rNoRawFormatException);
3530 throw;
3532 catch( const container::ElementExistException& rElementExistException )
3534 SAL_INFO("package.xstor", "Rethrow: " << rElementExistException);
3535 throw;
3537 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3539 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
3540 throw;
3542 catch( const io::IOException& rIOException )
3544 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
3545 throw;
3547 catch( const uno::RuntimeException& rRuntimeException )
3549 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
3550 throw;
3552 catch( const uno::Exception& rException )
3554 SAL_INFO("package.xstor", "Rethrow: " << rException);
3556 uno::Any aCaught( ::cppu::getCaughtException() );
3557 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't insert raw stream!",
3558 uno::Reference< io::XInputStream >(),
3559 aCaught );
3563 // XTransactedObject
3564 void SAL_CALL OStorage::commit()
3566 uno::Reference< util::XModifiable > xParentModif;
3568 try {
3569 BroadcastTransaction( STOR_MESS_PRECOMMIT );
3571 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3573 if ( !m_pImpl )
3575 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3576 throw lang::DisposedException( THROW_WHERE );
3579 if ( m_pData->m_bReadOnlyWrap )
3580 throw io::IOException( THROW_WHERE ); // TODO: access_denied
3582 m_pImpl->Commit(); // the root storage initiates the storing to source
3584 // when the storage is committed the parent is modified
3585 if ( m_pImpl->m_pParent && m_pImpl->m_pParent->m_pAntiImpl )
3586 xParentModif = static_cast<util::XModifiable*>(m_pImpl->m_pParent->m_pAntiImpl);
3588 catch( const io::IOException& rIOException )
3590 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
3591 throw;
3593 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3595 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
3596 throw;
3598 catch( const uno::RuntimeException& rRuntimeException )
3600 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
3601 throw;
3603 catch( const uno::Exception& rException )
3605 SAL_INFO("package.xstor", "Rethrow: " << rException);
3607 uno::Any aCaught( ::cppu::getCaughtException() );
3608 throw embed::StorageWrappedTargetException( THROW_WHERE "Problems on commit!",
3609 static_cast< ::cppu::OWeakObject* >( this ),
3610 aCaught );
3613 setModified( false );
3614 if ( xParentModif.is() )
3615 xParentModif->setModified( true );
3617 BroadcastTransaction( STOR_MESS_COMMITED );
3620 void SAL_CALL OStorage::revert()
3622 // the method removes all the changes done after last commit
3624 BroadcastTransaction( STOR_MESS_PREREVERT );
3626 ::osl::ResettableMutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3628 if ( !m_pImpl )
3630 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3631 throw lang::DisposedException( THROW_WHERE );
3634 for ( SotElementVector_Impl::iterator pElementIter = m_pImpl->m_aChildrenVector.begin();
3635 pElementIter != m_pImpl->m_aChildrenVector.end(); ++pElementIter )
3637 if ( ((*pElementIter)->m_xStorage
3638 && ( (*pElementIter)->m_xStorage->m_pAntiImpl || !(*pElementIter)->m_xStorage->m_aReadOnlyWrapVector.empty() ))
3639 || ((*pElementIter)->m_xStream
3640 && ( (*pElementIter)->m_xStream->m_pAntiImpl || !(*pElementIter)->m_xStream->m_aInputStreamsVector.empty()) ) )
3641 throw io::IOException( THROW_WHERE ); // TODO: access denied
3644 if ( m_pData->m_bReadOnlyWrap || !m_pImpl->m_bListCreated )
3645 return; // nothing to do
3647 try {
3648 m_pImpl->Revert();
3649 m_pImpl->m_bIsModified = false;
3650 m_pImpl->m_bBroadcastModified = true;
3652 catch( const io::IOException& rIOException )
3654 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
3655 throw;
3657 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3659 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
3660 throw;
3662 catch( const uno::RuntimeException& rRuntimeException )
3664 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
3665 throw;
3667 catch( const uno::Exception& rException )
3669 SAL_INFO("package.xstor", "Rethrow: " << rException);
3671 uno::Any aCaught( ::cppu::getCaughtException() );
3672 throw embed::StorageWrappedTargetException( THROW_WHERE "Problems on revert!",
3673 static_cast< ::cppu::OWeakObject* >( this ),
3674 aCaught );
3677 aGuard.clear();
3679 setModified( false );
3680 BroadcastTransaction( STOR_MESS_REVERTED );
3683 // XTransactionBroadcaster
3684 void SAL_CALL OStorage::addTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
3686 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3688 if ( !m_pImpl )
3690 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3691 throw lang::DisposedException( THROW_WHERE );
3694 m_pData->m_aListenersContainer.addInterface( cppu::UnoType<embed::XTransactionListener>::get(),
3695 aListener );
3698 void SAL_CALL OStorage::removeTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
3700 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3702 if ( !m_pImpl )
3704 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3705 throw lang::DisposedException( THROW_WHERE );
3708 m_pData->m_aListenersContainer.removeInterface( cppu::UnoType<embed::XTransactionListener>::get(),
3709 aListener );
3712 // XModifiable
3713 // TODO: if there will be no demand on this interface it will be removed from implementation,
3714 // I do not want to remove it now since it is still possible that it will be inserted
3715 // to the service back.
3717 sal_Bool SAL_CALL OStorage::isModified()
3719 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3721 if ( !m_pImpl )
3723 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3724 throw lang::DisposedException( THROW_WHERE );
3727 return m_pImpl->m_bIsModified;
3730 void SAL_CALL OStorage::setModified( sal_Bool bModified )
3732 ::osl::ResettableMutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3734 if ( !m_pImpl )
3736 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3737 throw lang::DisposedException( THROW_WHERE );
3740 if ( m_pData->m_bReadOnlyWrap )
3741 throw beans::PropertyVetoException( THROW_WHERE ); // TODO: access denied
3743 if ( m_pImpl->m_bIsModified != bool(bModified) )
3744 m_pImpl->m_bIsModified = bModified;
3746 aGuard.clear();
3747 if ( bModified )
3749 m_pImpl->m_bBroadcastModified = true;
3750 BroadcastModifiedIfNecessary();
3754 void SAL_CALL OStorage::addModifyListener(
3755 const uno::Reference< util::XModifyListener >& aListener )
3757 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3759 if ( !m_pImpl )
3761 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3762 throw lang::DisposedException( THROW_WHERE );
3765 osl_atomic_increment( &m_pImpl->m_nModifiedListenerCount );
3766 m_pData->m_aListenersContainer.addInterface(
3767 cppu::UnoType<util::XModifyListener>::get(), aListener );
3770 void SAL_CALL OStorage::removeModifyListener(
3771 const uno::Reference< util::XModifyListener >& aListener )
3773 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3775 if ( !m_pImpl )
3777 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3778 throw lang::DisposedException( THROW_WHERE );
3781 osl_atomic_decrement( &m_pImpl->m_nModifiedListenerCount );
3782 m_pData->m_aListenersContainer.removeInterface(
3783 cppu::UnoType<util::XModifyListener>::get(), aListener );
3786 // XNameAccess
3788 uno::Any SAL_CALL OStorage::getByName( const OUString& aName )
3790 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3792 if ( !m_pImpl )
3794 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3795 throw lang::DisposedException( THROW_WHERE );
3798 if ( aName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aName, false ) )
3799 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3801 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aName == "_rels" )
3802 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable element name
3804 uno::Any aResult;
3807 SotElement_Impl* pElement = m_pImpl->FindElement( aName );
3808 if ( !pElement )
3809 throw container::NoSuchElementException( THROW_WHERE );
3811 if ( pElement->m_bIsStorage )
3812 aResult <<= openStorageElement( aName, embed::ElementModes::READ );
3813 else
3814 aResult <<= openStreamElement( aName, embed::ElementModes::READ );
3816 catch( const container::NoSuchElementException& rNoSuchElementException )
3818 SAL_INFO("package.xstor", "Rethrow: " << rNoSuchElementException);
3819 throw;
3821 catch( const lang::WrappedTargetException& rWrappedTargetException )
3823 SAL_INFO("package.xstor", "Rethrow: " << rWrappedTargetException);
3824 throw;
3826 catch( const uno::RuntimeException& rRuntimeException )
3828 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
3829 throw;
3831 catch( const uno::Exception& rException )
3833 SAL_INFO("package.xstor", "Rethrow: " << rException);
3835 uno::Any aCaught( ::cppu::getCaughtException() );
3836 throw lang::WrappedTargetException( THROW_WHERE "Can not open storage!",
3837 static_cast< OWeakObject* >( this ),
3838 aCaught );
3841 return aResult;
3844 uno::Sequence< OUString > SAL_CALL OStorage::getElementNames()
3846 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3848 if ( !m_pImpl )
3850 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3851 throw lang::DisposedException( THROW_WHERE );
3856 return m_pImpl->GetElementNames();
3858 catch( const uno::RuntimeException& rRuntimeException )
3860 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
3861 throw;
3863 catch ( const uno::Exception& rException )
3865 SAL_INFO("package.xstor", "Rethrow: " << rException);
3867 uno::Any aCaught( ::cppu::getCaughtException() );
3868 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open storage!",
3869 static_cast< OWeakObject* >( this ),
3870 aCaught );
3874 sal_Bool SAL_CALL OStorage::hasByName( const OUString& aName )
3876 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3878 if ( !m_pImpl )
3880 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3881 throw lang::DisposedException( THROW_WHERE );
3884 if ( aName.isEmpty() )
3885 return false;
3887 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aName == "_rels" )
3888 return false;
3890 SotElement_Impl* pElement = nullptr;
3893 pElement = m_pImpl->FindElement( aName );
3895 catch( const uno::RuntimeException& rRuntimeException )
3897 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
3898 throw;
3900 catch ( const uno::Exception& rException )
3902 SAL_INFO("package.xstor", "Rethrow: " << rException);
3904 uno::Any aCaught( ::cppu::getCaughtException() );
3905 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open storage!",
3906 static_cast< OWeakObject* >( this ),
3907 aCaught );
3910 return ( pElement != nullptr );
3913 uno::Type SAL_CALL OStorage::getElementType()
3915 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3917 if ( !m_pImpl )
3919 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3920 throw lang::DisposedException( THROW_WHERE );
3923 // it is a multitype container
3924 return uno::Type();
3927 sal_Bool SAL_CALL OStorage::hasElements()
3929 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3931 if ( !m_pImpl )
3933 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3934 throw lang::DisposedException( THROW_WHERE );
3939 return ( m_pImpl->GetChildrenVector().size() != 0 );
3941 catch( const uno::RuntimeException& rRuntimeException )
3943 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
3944 throw;
3946 catch( const uno::Exception& rException )
3948 SAL_INFO("package.xstor", "Rethrow: " << rException);
3950 uno::Any aCaught( ::cppu::getCaughtException() );
3951 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open storage!",
3952 static_cast< OWeakObject* >( this ),
3953 aCaught );
3957 // XComponent
3958 void SAL_CALL OStorage::dispose()
3960 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3962 if ( !m_pImpl )
3964 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3965 throw lang::DisposedException( THROW_WHERE );
3970 InternalDispose( true );
3972 catch( const uno::RuntimeException& rRuntimeException )
3974 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
3975 throw;
3977 catch( const uno::Exception& rException )
3979 SAL_INFO("package.xstor", "Rethrow: " << rException);
3981 uno::Any aCaught( ::cppu::getCaughtException() );
3982 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open storage!",
3983 static_cast< OWeakObject* >( this ),
3984 aCaught );
3988 void SAL_CALL OStorage::addEventListener(
3989 const uno::Reference< lang::XEventListener >& xListener )
3991 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
3993 if ( !m_pImpl )
3995 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3996 throw lang::DisposedException( THROW_WHERE );
3999 m_pData->m_aListenersContainer.addInterface(
4000 cppu::UnoType<lang::XEventListener>::get(), xListener );
4003 void SAL_CALL OStorage::removeEventListener(
4004 const uno::Reference< lang::XEventListener >& xListener )
4006 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4008 if ( !m_pImpl )
4010 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4011 throw lang::DisposedException( THROW_WHERE );
4014 m_pData->m_aListenersContainer.removeInterface(
4015 cppu::UnoType<lang::XEventListener>::get(), xListener );
4018 // XEncryptionProtectedSource
4020 void SAL_CALL OStorage::setEncryptionPassword( const OUString& aPass )
4022 setEncryptionData( ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass ) );
4025 void SAL_CALL OStorage::removeEncryption()
4027 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4029 if ( !m_pImpl )
4031 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4032 throw lang::DisposedException( THROW_WHERE );
4035 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4036 throw uno::RuntimeException( THROW_WHERE ); // the interface must be visible only for package storage
4038 SAL_WARN_IF( !m_pData->m_bIsRoot, "package.xstor", "removeEncryption() method is not available for nonroot storages!" );
4039 if ( m_pData->m_bIsRoot )
4041 try {
4042 m_pImpl->ReadContents();
4044 catch ( const uno::RuntimeException& rRuntimeException )
4046 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
4047 throw;
4049 catch ( const uno::Exception& rException )
4051 SAL_INFO("package.xstor", "Rethrow: " << rException);
4053 uno::Any aCaught( ::cppu::getCaughtException() );
4054 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4055 static_cast< OWeakObject* >( this ),
4056 aCaught );
4059 // TODO: check if the password is valid
4060 // update all streams that was encrypted with old password
4062 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4065 xPackPropSet->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY,
4066 uno::makeAny( uno::Sequence< beans::NamedValue >() ) );
4068 m_pImpl->m_bHasCommonEncryptionData = false;
4069 m_pImpl->m_aCommonEncryptionData.clear();
4071 catch( const uno::RuntimeException& rRException )
4073 SAL_INFO("package.xstor", "Rethrow: " << rRException);
4075 SAL_WARN( "package.xstor", "The call must not fail, it is pretty simple!" );
4076 throw;
4078 catch( const uno::Exception& rException )
4080 SAL_INFO("package.xstor", "Rethrow: " << rException);
4082 SAL_WARN( "package.xstor", "The call must not fail, it is pretty simple!" );
4083 throw io::IOException( THROW_WHERE );
4088 // XEncryptionProtectedSource2
4090 void SAL_CALL OStorage::setEncryptionData( const uno::Sequence< beans::NamedValue >& aEncryptionData )
4092 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4094 if ( !m_pImpl )
4096 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4097 throw lang::DisposedException( THROW_WHERE );
4100 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4101 throw uno::RuntimeException( THROW_WHERE ); // the interface must be visible only for package storage
4103 if ( !aEncryptionData.getLength() )
4104 throw uno::RuntimeException( THROW_WHERE "Unexpected empty encryption data!" );
4106 SAL_WARN_IF( !m_pData->m_bIsRoot, "package.xstor", "setEncryptionData() method is not available for nonroot storages!" );
4107 if ( m_pData->m_bIsRoot )
4109 try {
4110 m_pImpl->ReadContents();
4112 catch ( const uno::RuntimeException& rRuntimeException )
4114 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
4115 throw;
4117 catch ( const uno::Exception& rException )
4119 SAL_INFO("package.xstor", "Rethrow: " << rException);
4121 uno::Any aCaught( ::cppu::getCaughtException() );
4122 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4123 static_cast< OWeakObject* >( this ),
4124 aCaught );
4127 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4130 ::comphelper::SequenceAsHashMap aEncryptionMap( aEncryptionData );
4131 xPackPropSet->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY,
4132 uno::makeAny( aEncryptionMap.getAsConstNamedValueList() ) );
4134 m_pImpl->m_bHasCommonEncryptionData = true;
4135 m_pImpl->m_aCommonEncryptionData = aEncryptionMap;
4137 catch( const uno::Exception& rException )
4139 SAL_INFO("package.xstor", "Rethrow: " << rException);
4141 throw io::IOException( THROW_WHERE );
4146 sal_Bool SAL_CALL OStorage::hasEncryptionData()
4148 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4150 return m_pImpl && m_pImpl->m_bHasCommonEncryptionData;
4153 // XEncryptionProtectedStorage
4155 void SAL_CALL OStorage::setEncryptionAlgorithms( const uno::Sequence< beans::NamedValue >& aAlgorithms )
4157 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4159 if ( !m_pImpl )
4161 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4162 throw lang::DisposedException( THROW_WHERE );
4165 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4166 throw uno::RuntimeException( THROW_WHERE ); // the interface must be visible only for package storage
4168 if ( !aAlgorithms.getLength() )
4169 throw uno::RuntimeException( THROW_WHERE "Unexpected empty encryption algorithms list!" );
4171 SAL_WARN_IF( !m_pData->m_bIsRoot, "package.xstor", "setEncryptionAlgorithms() method is not available for nonroot storages!" );
4172 if ( m_pData->m_bIsRoot )
4174 try {
4175 m_pImpl->ReadContents();
4177 catch ( const uno::RuntimeException& aRuntimeException )
4179 SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException);
4180 throw;
4182 catch ( const uno::Exception& aException )
4184 SAL_INFO("package.xstor", "Rethrow: " << aException);
4186 uno::Any aCaught( ::cppu::getCaughtException() );
4187 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4188 static_cast< OWeakObject* >( this ),
4189 aCaught );
4192 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4195 xPackPropSet->setPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY,
4196 uno::makeAny( aAlgorithms ) );
4198 catch ( const uno::RuntimeException& aRuntimeException )
4200 SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException);
4201 throw;
4203 catch( const uno::Exception& aException )
4205 SAL_INFO("package.xstor", "Rethrow: " << aException);
4207 uno::Any aCaught( ::cppu::getCaughtException() );
4208 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4209 static_cast< OWeakObject* >( this ),
4210 aCaught );
4215 void SAL_CALL OStorage::setGpgProperties( const uno::Sequence< uno::Sequence< beans::NamedValue > >& aProps )
4217 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4219 if ( !m_pImpl )
4221 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4222 throw lang::DisposedException( THROW_WHERE );
4225 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4226 throw uno::RuntimeException( THROW_WHERE ); // the interface must be visible only for package storage
4228 if ( !aProps.getLength() )
4229 throw uno::RuntimeException( THROW_WHERE "Unexpected empty encryption algorithms list!" );
4231 SAL_WARN_IF( !m_pData->m_bIsRoot, "package.xstor", "setGpgProperties() method is not available for nonroot storages!" );
4232 if ( m_pData->m_bIsRoot )
4234 try {
4235 m_pImpl->ReadContents();
4237 catch ( const uno::RuntimeException& aRuntimeException )
4239 SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException.Message);
4240 throw;
4242 catch ( const uno::Exception& aException )
4244 SAL_INFO("package.xstor", "Rethrow: " << aException.Message);
4246 uno::Any aCaught( ::cppu::getCaughtException() );
4247 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4248 static_cast< OWeakObject* >( this ),
4249 aCaught );
4252 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4255 xPackPropSet->setPropertyValue( ENCRYPTION_GPG_PROPERTIES,
4256 uno::makeAny( aProps ) );
4258 catch ( const uno::RuntimeException& aRuntimeException )
4260 SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException.Message);
4261 throw;
4263 catch( const uno::Exception& aException )
4265 SAL_INFO("package.xstor", "Rethrow: " << aException.Message);
4267 uno::Any aCaught( ::cppu::getCaughtException() );
4268 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4269 static_cast< OWeakObject* >( this ),
4270 aCaught );
4275 uno::Sequence< beans::NamedValue > SAL_CALL OStorage::getEncryptionAlgorithms()
4277 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4279 if ( !m_pImpl )
4281 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4282 throw lang::DisposedException( THROW_WHERE );
4285 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4286 throw uno::RuntimeException( THROW_WHERE ); // the interface must be visible only for package storage
4288 uno::Sequence< beans::NamedValue > aResult;
4289 SAL_WARN_IF( !m_pData->m_bIsRoot, "package.xstor", "getEncryptionAlgorithms() method is not available for nonroot storages!" );
4290 if ( m_pData->m_bIsRoot )
4292 try {
4293 m_pImpl->ReadContents();
4295 catch ( const uno::RuntimeException& aRuntimeException )
4297 SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException);
4298 throw;
4300 catch ( const uno::Exception& aException )
4302 SAL_INFO("package.xstor", "Rethrow: " << aException);
4304 uno::Any aCaught( ::cppu::getCaughtException() );
4305 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4306 static_cast< OWeakObject* >( this ),
4307 aCaught );
4310 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4313 xPackPropSet->getPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY ) >>= aResult;
4315 catch ( const uno::RuntimeException& aRuntimeException )
4317 SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException);
4318 throw;
4320 catch( const uno::Exception& aException )
4322 SAL_INFO("package.xstor", "Rethrow: " << aException);
4324 uno::Any aCaught( ::cppu::getCaughtException() );
4325 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4326 static_cast< OWeakObject* >( this ),
4327 aCaught );
4331 return aResult;
4334 // XPropertySet
4336 uno::Reference< beans::XPropertySetInfo > SAL_CALL OStorage::getPropertySetInfo()
4338 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4340 if ( !m_pImpl )
4342 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4343 throw lang::DisposedException( THROW_WHERE );
4346 //TODO:
4347 return uno::Reference< beans::XPropertySetInfo >();
4350 void SAL_CALL OStorage::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
4352 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4354 if ( !m_pImpl )
4356 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4357 throw lang::DisposedException( THROW_WHERE );
4360 //TODO: think about interaction handler
4362 // WORKAROUND:
4363 // The old document might have no version in the manifest.xml, so we have to allow to set the version
4364 // even for readonly storages, so that the version from content.xml can be used.
4365 if ( m_pData->m_bReadOnlyWrap && aPropertyName != "Version" )
4366 throw uno::RuntimeException( THROW_WHERE ); // TODO: Access denied
4368 if ( m_pData->m_nStorageType == embed::StorageFormats::ZIP )
4369 throw beans::UnknownPropertyException( THROW_WHERE );
4370 else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
4372 if ( aPropertyName == "MediaType" )
4374 aValue >>= m_pImpl->m_aMediaType;
4375 m_pImpl->m_bControlMediaType = true;
4377 m_pImpl->m_bBroadcastModified = true;
4378 m_pImpl->m_bIsModified = true;
4380 else if ( aPropertyName == "Version" )
4382 aValue >>= m_pImpl->m_aVersion;
4383 m_pImpl->m_bControlVersion = true;
4385 // this property can be set even for readonly storage
4386 if ( !m_pData->m_bReadOnlyWrap )
4388 m_pImpl->m_bBroadcastModified = true;
4389 m_pImpl->m_bIsModified = true;
4392 else if ( ( m_pData->m_bIsRoot && ( aPropertyName == HAS_ENCRYPTED_ENTRIES_PROPERTY
4393 || aPropertyName == HAS_NONENCRYPTED_ENTRIES_PROPERTY
4394 || aPropertyName == IS_INCONSISTENT_PROPERTY
4395 || aPropertyName == "URL"
4396 || aPropertyName == "RepairPackage"
4397 || aPropertyName == ENCRYPTION_GPG_PROPERTIES) )
4398 || aPropertyName == "IsRoot"
4399 || aPropertyName == MEDIATYPE_FALLBACK_USED_PROPERTY )
4400 throw beans::PropertyVetoException( THROW_WHERE );
4401 else
4402 throw beans::UnknownPropertyException( THROW_WHERE );
4404 else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
4406 if ( aPropertyName == "RelationsInfoStream" )
4408 uno::Reference< io::XInputStream > xInRelStream;
4409 if ( !( aValue >>= xInRelStream ) || !xInRelStream.is() )
4410 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
4412 uno::Reference< io::XSeekable > xSeek( xInRelStream, uno::UNO_QUERY );
4413 if ( !xSeek.is() )
4415 // currently this is an internal property that is used for optimization
4416 // and the stream must support XSeekable interface
4417 // TODO/LATER: in future it can be changed if property is used from outside
4418 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
4421 m_pImpl->m_xNewRelInfoStream = xInRelStream;
4422 m_pImpl->m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
4423 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED_STREAM;
4424 m_pImpl->m_bBroadcastModified = true;
4425 m_pImpl->m_bIsModified = true;
4427 else if ( aPropertyName == "RelationsInfo" )
4429 if ( !(aValue >>= m_pImpl->m_aRelInfo) )
4430 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
4432 m_pImpl->m_xNewRelInfoStream.clear();
4433 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
4434 m_pImpl->m_bBroadcastModified = true;
4435 m_pImpl->m_bIsModified = true;
4437 else if ( ( m_pData->m_bIsRoot && ( aPropertyName == "URL" || aPropertyName == "RepairPackage") )
4438 || aPropertyName == "IsRoot" )
4439 throw beans::PropertyVetoException( THROW_WHERE );
4440 else
4441 throw beans::UnknownPropertyException( THROW_WHERE );
4443 else
4444 throw beans::UnknownPropertyException( THROW_WHERE );
4446 BroadcastModifiedIfNecessary();
4449 uno::Any SAL_CALL OStorage::getPropertyValue( const OUString& aPropertyName )
4451 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4453 if ( !m_pImpl )
4455 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4456 throw lang::DisposedException( THROW_WHERE );
4459 if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
4460 && ( aPropertyName == "MediaType" || aPropertyName == MEDIATYPE_FALLBACK_USED_PROPERTY || aPropertyName == "Version" ) )
4464 m_pImpl->ReadContents();
4466 catch ( const uno::RuntimeException& rRuntimeException )
4468 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
4469 throw;
4471 catch ( const uno::Exception& rException )
4473 SAL_INFO("package.xstor", "Rethrow: " << rException);
4475 uno::Any aCaught( ::cppu::getCaughtException() );
4476 throw lang::WrappedTargetException(
4477 "Can't read contents!",
4478 static_cast< OWeakObject* >( this ),
4479 aCaught );
4482 if ( aPropertyName == "MediaType" )
4483 return uno::makeAny( m_pImpl->m_aMediaType );
4484 else if ( aPropertyName == "Version" )
4485 return uno::makeAny( m_pImpl->m_aVersion );
4486 else
4487 return uno::makeAny( m_pImpl->m_bMTFallbackUsed );
4489 else if ( aPropertyName == "IsRoot" )
4491 return uno::makeAny( m_pData->m_bIsRoot );
4493 else if ( aPropertyName == "OpenMode" )
4495 return uno::makeAny( m_pImpl->m_nStorageMode );
4497 else if ( m_pData->m_bIsRoot )
4499 if ( aPropertyName == "URL"
4500 || aPropertyName == "RepairPackage" )
4502 for ( sal_Int32 aInd = 0; aInd < m_pImpl->m_xProperties.getLength(); aInd++ )
4504 if ( m_pImpl->m_xProperties[aInd].Name == aPropertyName )
4505 return m_pImpl->m_xProperties[aInd].Value;
4508 if ( aPropertyName == "URL" )
4509 return uno::makeAny( OUString() );
4511 return uno::makeAny( false ); // RepairPackage
4513 else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
4514 && ( aPropertyName == HAS_ENCRYPTED_ENTRIES_PROPERTY
4515 || aPropertyName == HAS_NONENCRYPTED_ENTRIES_PROPERTY
4516 || aPropertyName == ENCRYPTION_GPG_PROPERTIES
4517 || aPropertyName == IS_INCONSISTENT_PROPERTY ) )
4519 try {
4520 m_pImpl->ReadContents();
4521 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4522 return xPackPropSet->getPropertyValue( aPropertyName );
4524 catch ( const uno::RuntimeException& rRuntimeException )
4526 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
4527 throw;
4529 catch ( const uno::Exception& rException )
4531 SAL_INFO("package.xstor", "Rethrow: " << rException);
4533 uno::Any aCaught( ::cppu::getCaughtException() );
4534 throw lang::WrappedTargetException( THROW_WHERE "Can not open package!",
4535 static_cast< OWeakObject* >( this ),
4536 aCaught );
4541 throw beans::UnknownPropertyException( THROW_WHERE );
4544 void SAL_CALL OStorage::addPropertyChangeListener(
4545 const OUString& /*aPropertyName*/,
4546 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
4548 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4550 if ( !m_pImpl )
4552 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4553 throw lang::DisposedException( THROW_WHERE );
4556 //TODO:
4559 void SAL_CALL OStorage::removePropertyChangeListener(
4560 const OUString& /*aPropertyName*/,
4561 const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
4563 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4565 if ( !m_pImpl )
4567 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4568 throw lang::DisposedException( THROW_WHERE );
4571 //TODO:
4574 void SAL_CALL OStorage::addVetoableChangeListener(
4575 const OUString& /*PropertyName*/,
4576 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
4578 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4580 if ( !m_pImpl )
4582 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4583 throw lang::DisposedException( THROW_WHERE );
4586 //TODO:
4589 void SAL_CALL OStorage::removeVetoableChangeListener(
4590 const OUString& /*PropertyName*/,
4591 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
4593 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4595 if ( !m_pImpl )
4597 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4598 throw lang::DisposedException( THROW_WHERE );
4601 //TODO:
4604 // XRelationshipAccess
4606 // TODO/LATER: the storage and stream implementations of this interface are very similar, they could use a helper class
4608 sal_Bool SAL_CALL OStorage::hasByID( const OUString& sID )
4610 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4612 if ( !m_pImpl )
4614 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4615 throw lang::DisposedException( THROW_WHERE );
4618 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
4619 throw uno::RuntimeException( THROW_WHERE );
4623 getRelationshipByID( sID );
4624 return true;
4626 catch( const container::NoSuchElementException& rNoSuchElementException )
4628 SAL_INFO("package.xstor", "Rethrow: " << rNoSuchElementException);
4631 return false;
4634 OUString SAL_CALL OStorage::getTargetByID( const OUString& sID )
4636 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4638 if ( !m_pImpl )
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 uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
4648 for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
4649 if ( aSeq[nInd].First == "Target" )
4650 return aSeq[nInd].Second;
4652 return OUString();
4655 OUString SAL_CALL OStorage::getTypeByID( const OUString& sID )
4657 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4659 if ( !m_pImpl )
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 uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
4669 for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
4670 if ( aSeq[nInd].First == "Type" )
4671 return aSeq[nInd].Second;
4673 return OUString();
4676 uno::Sequence< beans::StringPair > SAL_CALL OStorage::getRelationshipByID( const OUString& sID )
4678 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4680 if ( !m_pImpl )
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 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4691 for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
4692 for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
4693 if ( aSeq[nInd1][nInd2].First == "Id" )
4695 if ( aSeq[nInd1][nInd2].Second == sID )
4696 return aSeq[nInd1];
4697 break;
4700 throw container::NoSuchElementException( THROW_WHERE );
4703 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OStorage::getRelationshipsByType( const OUString& sType )
4705 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4707 if ( !m_pImpl )
4709 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4710 throw lang::DisposedException( THROW_WHERE );
4713 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
4714 throw uno::RuntimeException( THROW_WHERE );
4716 uno::Sequence< uno::Sequence< beans::StringPair > > aResult;
4717 sal_Int32 nEntriesNum = 0;
4719 // TODO/LATER: in future the unification of the ID could be checked
4720 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4721 for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
4722 for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
4723 if ( aSeq[nInd1][nInd2].First == "Type" )
4725 // the type is usually an URL, so the check should be case insensitive
4726 if ( aSeq[nInd1][nInd2].Second.equalsIgnoreAsciiCase( sType ) )
4728 aResult.realloc( ++nEntriesNum );
4729 aResult[nEntriesNum-1] = aSeq[nInd1];
4731 break;
4734 return aResult;
4737 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OStorage::getAllRelationships()
4739 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4741 if ( !m_pImpl )
4743 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4744 throw lang::DisposedException( THROW_WHERE );
4747 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
4748 throw uno::RuntimeException( THROW_WHERE );
4750 uno::Sequence< uno::Sequence< beans::StringPair > > aRet;
4753 aRet = m_pImpl->GetAllRelationshipsIfAny();
4755 catch (const io::IOException&)
4757 throw;
4759 catch (const uno::RuntimeException&)
4761 throw;
4763 catch (const uno::Exception &)
4765 uno::Any aCaught( ::cppu::getCaughtException() );
4766 throw lang::WrappedTargetRuntimeException(THROW_WHERE "Can't getAllRelationships!",
4767 uno::Reference< uno::XInterface >(),
4768 aCaught);
4771 return aRet;
4774 void SAL_CALL OStorage::insertRelationshipByID( const OUString& sID, const uno::Sequence< beans::StringPair >& aEntry, sal_Bool bReplace )
4776 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4778 if ( !m_pImpl )
4780 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4781 throw lang::DisposedException( THROW_WHERE );
4784 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
4785 throw uno::RuntimeException( THROW_WHERE );
4787 OUString aIDTag( "Id" );
4789 sal_Int32 nIDInd = -1;
4791 // TODO/LATER: in future the unification of the ID could be checked
4792 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4793 for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
4794 for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
4795 if ( aSeq[nInd1][nInd2].First == aIDTag )
4797 if ( aSeq[nInd1][nInd2].Second == sID )
4798 nIDInd = nInd1;
4800 break;
4803 if ( nIDInd != -1 && !bReplace )
4804 throw container::ElementExistException( THROW_WHERE );
4806 if ( nIDInd == -1 )
4808 nIDInd = aSeq.getLength();
4809 aSeq.realloc( nIDInd + 1 );
4812 aSeq[nIDInd].realloc( aEntry.getLength() + 1 );
4814 aSeq[nIDInd][0].First = aIDTag;
4815 aSeq[nIDInd][0].Second = sID;
4816 sal_Int32 nIndTarget = 1;
4817 for ( sal_Int32 nIndOrig = 0;
4818 nIndOrig < aEntry.getLength();
4819 nIndOrig++ )
4821 if ( aEntry[nIndOrig].First != aIDTag )
4822 aSeq[nIDInd][nIndTarget++] = aEntry[nIndOrig];
4825 aSeq[nIDInd].realloc( nIndTarget );
4827 m_pImpl->m_aRelInfo = aSeq;
4828 m_pImpl->m_xNewRelInfoStream.clear();
4829 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
4832 void SAL_CALL OStorage::removeRelationshipByID( const OUString& sID )
4834 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4836 if ( !m_pImpl )
4838 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4839 throw lang::DisposedException( THROW_WHERE );
4842 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
4843 throw uno::RuntimeException( THROW_WHERE );
4845 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4846 for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
4847 for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
4848 if ( aSeq[nInd1][nInd2].First == "Id" )
4850 if ( aSeq[nInd1][nInd2].Second == sID )
4852 sal_Int32 nLength = aSeq.getLength();
4853 aSeq[nInd1] = aSeq[nLength-1];
4854 aSeq.realloc( nLength - 1 );
4856 m_pImpl->m_aRelInfo = aSeq;
4857 m_pImpl->m_xNewRelInfoStream.clear();
4858 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
4860 // TODO/LATER: in future the unification of the ID could be checked
4861 return;
4864 break;
4867 throw container::NoSuchElementException( THROW_WHERE );
4870 void SAL_CALL OStorage::insertRelationships( const uno::Sequence< uno::Sequence< beans::StringPair > >& aEntries, sal_Bool bReplace )
4872 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4874 if ( !m_pImpl )
4876 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4877 throw lang::DisposedException( THROW_WHERE );
4880 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
4881 throw uno::RuntimeException( THROW_WHERE );
4883 OUString aIDTag( "Id" );
4884 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4885 uno::Sequence< uno::Sequence< beans::StringPair > > aResultSeq( aSeq.getLength() + aEntries.getLength() );
4886 sal_Int32 nResultInd = 0;
4888 for ( sal_Int32 nIndTarget1 = 0; nIndTarget1 < aSeq.getLength(); nIndTarget1++ )
4889 for ( sal_Int32 nIndTarget2 = 0; nIndTarget2 < aSeq[nIndTarget1].getLength(); nIndTarget2++ )
4890 if ( aSeq[nIndTarget1][nIndTarget2].First == aIDTag )
4892 sal_Int32 nIndSourceSame = -1;
4894 for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
4895 for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
4897 if ( aEntries[nIndSource1][nIndSource2].First == aIDTag )
4899 if ( aEntries[nIndSource1][nIndSource2].Second == aSeq[nIndTarget1][nIndTarget2].Second )
4901 if ( !bReplace )
4902 throw container::ElementExistException( THROW_WHERE );
4904 nIndSourceSame = nIndSource1;
4907 break;
4911 if ( nIndSourceSame == -1 )
4913 // no such element in the provided sequence
4914 aResultSeq[nResultInd++] = aSeq[nIndTarget1];
4917 break;
4920 for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
4922 aResultSeq[nResultInd].realloc( aEntries[nIndSource1].getLength() );
4923 bool bHasID = false;
4924 sal_Int32 nResInd2 = 1;
4926 for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
4927 if ( aEntries[nIndSource1][nIndSource2].First == aIDTag )
4929 aResultSeq[nResultInd][0] = aEntries[nIndSource1][nIndSource2];
4930 bHasID = true;
4932 else if ( nResInd2 < aResultSeq[nResultInd].getLength() )
4933 aResultSeq[nResultInd][nResInd2++] = aEntries[nIndSource1][nIndSource2];
4934 else
4935 throw io::IOException( THROW_WHERE ); // TODO: illegal relation ( no ID )
4937 if ( !bHasID )
4938 throw io::IOException( THROW_WHERE ); // TODO: illegal relations
4940 nResultInd++;
4943 aResultSeq.realloc( nResultInd );
4944 m_pImpl->m_aRelInfo = aResultSeq;
4945 m_pImpl->m_xNewRelInfoStream.clear();
4946 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
4949 void SAL_CALL OStorage::clearRelationships()
4951 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4953 if ( !m_pImpl )
4955 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4956 throw lang::DisposedException( THROW_WHERE );
4959 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
4960 throw uno::RuntimeException( THROW_WHERE );
4962 m_pImpl->m_aRelInfo.realloc( 0 );
4963 m_pImpl->m_xNewRelInfoStream.clear();
4964 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
4967 // XOptimizedStorage
4968 void SAL_CALL OStorage::insertRawNonEncrStreamElementDirect(
4969 const OUString& /*sStreamName*/,
4970 const uno::Reference< io::XInputStream >& /*xInStream*/ )
4972 // not implemented currently because there is still no demand
4973 // might need to be implemented if direct copying of compressed streams is used
4974 throw io::IOException( THROW_WHERE );
4977 void SAL_CALL OStorage::insertStreamElementDirect(
4978 const OUString& aStreamName,
4979 const uno::Reference< io::XInputStream >& xInStream,
4980 const uno::Sequence< beans::PropertyValue >& aProps )
4982 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
4984 if ( !m_pImpl )
4986 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4987 throw lang::DisposedException( THROW_WHERE );
4990 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, false ) )
4991 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
4993 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aStreamName == "_rels" )
4994 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
4996 if ( m_pData->m_bReadOnlyWrap )
4997 throw io::IOException( THROW_WHERE ); // TODO: access denied
5001 SotElement_Impl* pElement = m_pImpl->FindElement( aStreamName );
5003 if ( pElement )
5004 throw container::ElementExistException( THROW_WHERE );
5006 pElement = OpenStreamElement_Impl( aStreamName, embed::ElementModes::READWRITE, false );
5007 OSL_ENSURE(pElement && pElement->m_xStream, "In case element can not be created an exception must be thrown!");
5009 pElement->m_xStream->InsertStreamDirectly(xInStream, aProps);
5011 catch( const embed::InvalidStorageException& rInvalidStorageException )
5013 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
5014 throw;
5016 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
5018 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
5019 throw;
5021 catch( const container::ElementExistException& rElementExistException )
5023 SAL_INFO("package.xstor", "Rethrow: " << rElementExistException);
5024 throw;
5026 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
5028 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
5029 throw;
5031 catch( const io::IOException& rIOException )
5033 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
5034 throw;
5036 catch( const uno::RuntimeException& rRuntimeException )
5038 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
5039 throw;
5041 catch( const uno::Exception& rException )
5043 SAL_INFO("package.xstor", "Rethrow: " << rException);
5045 uno::Any aCaught( ::cppu::getCaughtException() );
5046 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't insert stream directly!",
5047 uno::Reference< io::XInputStream >(),
5048 aCaught );
5052 void SAL_CALL OStorage::copyElementDirectlyTo(
5053 const OUString& aElementName,
5054 const uno::Reference< embed::XOptimizedStorage >& xDest,
5055 const OUString& aNewName )
5057 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
5059 if ( !m_pImpl )
5061 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5062 throw lang::DisposedException( THROW_WHERE );
5065 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, false )
5066 || aNewName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, false ) )
5067 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
5069 if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
5070 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 2 );
5072 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && ( aElementName == "_rels" || aNewName == "_rels" ) )
5073 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 ); // unacceptable name
5077 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
5078 if ( !pElement )
5079 throw container::NoSuchElementException( THROW_WHERE );
5081 uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY_THROW );
5082 if ( xNameAccess->hasByName( aNewName ) )
5083 throw container::ElementExistException( THROW_WHERE );
5085 // let the element be copied directly
5086 uno::Reference< embed::XStorage > xStorDest( xDest, uno::UNO_QUERY_THROW );
5087 m_pImpl->CopyStorageElement( pElement, xStorDest, aNewName, true );
5089 catch( const embed::InvalidStorageException& rInvalidStorageException )
5091 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
5092 throw;
5094 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
5096 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
5097 throw;
5099 catch( const container::NoSuchElementException& rNoSuchElementException )
5101 SAL_INFO("package.xstor", "Rethrow: " << rNoSuchElementException);
5102 throw;
5104 catch( const container::ElementExistException& rElementExistException )
5106 SAL_INFO("package.xstor", "Rethrow: " << rElementExistException);
5107 throw;
5109 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
5111 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
5112 throw;
5114 catch( const io::IOException& rIOException )
5116 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
5117 throw;
5119 catch( const uno::RuntimeException& rRuntimeException )
5121 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
5122 throw;
5124 catch( const uno::Exception& rException )
5126 SAL_INFO("package.xstor", "Rethrow: " << rException);
5128 uno::Any aCaught( ::cppu::getCaughtException() );
5129 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't copy element direcly!",
5130 uno::Reference< io::XInputStream >(),
5131 aCaught );
5135 void SAL_CALL OStorage::writeAndAttachToStream( const uno::Reference< io::XStream >& xStream )
5137 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
5139 if ( !m_pImpl )
5141 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5142 throw lang::DisposedException( THROW_WHERE );
5145 if ( !m_pData->m_bIsRoot )
5146 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
5148 if ( !m_pImpl->m_pSwitchStream )
5149 throw uno::RuntimeException( THROW_WHERE );
5153 m_pImpl->m_pSwitchStream->CopyAndSwitchPersistenceTo( xStream );
5155 catch( const embed::InvalidStorageException& rInvalidStorageException )
5157 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
5158 throw;
5160 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
5162 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
5163 throw;
5165 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
5167 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
5168 throw;
5170 catch( const io::IOException& rIOException )
5172 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
5173 throw;
5175 catch( const uno::RuntimeException& rRuntimeException )
5177 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
5178 throw;
5180 catch( const uno::Exception& rException )
5182 SAL_INFO("package.xstor", "Rethrow: " << rException);
5184 uno::Any aCaught( ::cppu::getCaughtException() );
5185 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't write and attach to stream!",
5186 uno::Reference< io::XInputStream >(),
5187 aCaught );
5192 void SAL_CALL OStorage::attachToURL( const OUString& sURL,
5193 sal_Bool bReadOnly )
5195 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
5197 if ( !m_pImpl )
5199 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5200 throw lang::DisposedException( THROW_WHERE );
5203 if ( !m_pData->m_bIsRoot )
5204 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
5206 if ( !m_pImpl->m_pSwitchStream )
5207 throw uno::RuntimeException( THROW_WHERE );
5209 uno::Reference < ucb::XSimpleFileAccess3 > xAccess(
5210 ucb::SimpleFileAccess::create( m_pImpl->m_xContext ) );
5214 if ( bReadOnly )
5216 uno::Reference< io::XInputStream > xInputStream = xAccess->openFileRead( sURL );
5217 m_pImpl->m_pSwitchStream->SwitchPersistenceTo( xInputStream );
5219 else
5221 uno::Reference< io::XStream > xStream = xAccess->openFileReadWrite( sURL );
5222 m_pImpl->m_pSwitchStream->SwitchPersistenceTo( xStream );
5225 catch( const embed::InvalidStorageException& rInvalidStorageException )
5227 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
5228 throw;
5230 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
5232 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
5233 throw;
5235 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
5237 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
5238 throw;
5240 catch( const io::IOException& rIOException )
5242 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
5243 throw;
5245 catch( const uno::RuntimeException& rRuntimeException )
5247 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
5248 throw;
5250 catch( const uno::Exception& rException )
5252 SAL_INFO("package.xstor", "Rethrow: " << rException);
5254 uno::Any aCaught( ::cppu::getCaughtException() );
5255 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't attach to URL!",
5256 uno::Reference< io::XInputStream >(),
5257 aCaught );
5261 uno::Any SAL_CALL OStorage::getElementPropertyValue( const OUString& aElementName, const OUString& aPropertyName )
5263 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
5265 if ( !m_pImpl )
5267 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5268 throw lang::DisposedException( THROW_WHERE );
5271 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, false ) )
5272 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
5274 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aElementName == "_rels" )
5275 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // TODO: unacceptable name
5279 SotElement_Impl *pElement = m_pImpl->FindElement( aElementName );
5280 if ( !pElement )
5281 throw container::NoSuchElementException( THROW_WHERE );
5283 // TODO/LATER: Currently it is only implemented for MediaType property of substorages, might be changed in future
5284 if ( !pElement->m_bIsStorage || m_pData->m_nStorageType != embed::StorageFormats::PACKAGE || aPropertyName != "MediaType" )
5285 throw beans::PropertyVetoException( THROW_WHERE );
5287 if (!pElement->m_xStorage)
5288 m_pImpl->OpenSubStorage( pElement, embed::ElementModes::READ );
5290 if (!pElement->m_xStorage)
5291 throw io::IOException( THROW_WHERE ); // TODO: general_error
5293 pElement->m_xStorage->ReadContents();
5294 return uno::makeAny(pElement->m_xStorage->m_aMediaType);
5296 catch( const embed::InvalidStorageException& rInvalidStorageException )
5298 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
5299 throw;
5301 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
5303 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
5304 throw;
5306 catch( const container::NoSuchElementException& rNoSuchElementException )
5308 SAL_INFO("package.xstor", "Rethrow: " << rNoSuchElementException);
5309 throw;
5311 catch( const beans::UnknownPropertyException& rUnknownPropertyException )
5313 SAL_INFO("package.xstor", "Rethrow: " << rUnknownPropertyException);
5314 throw;
5316 catch( const beans::PropertyVetoException& rPropertyVetoException )
5318 SAL_INFO("package.xstor", "Rethrow: " << rPropertyVetoException);
5319 throw;
5321 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
5323 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
5324 throw;
5326 catch( const io::IOException& rIOException )
5328 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
5329 throw;
5331 catch( const uno::RuntimeException& rRuntimeException )
5333 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
5334 throw;
5336 catch( const uno::Exception& rException )
5338 SAL_INFO("package.xstor", "Rethrow: " << rException);
5340 uno::Any aCaught( ::cppu::getCaughtException() );
5341 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't get element property!",
5342 uno::Reference< io::XInputStream >(),
5343 aCaught );
5347 void SAL_CALL OStorage::copyStreamElementData( const OUString& aStreamName, const uno::Reference< io::XStream >& xTargetStream )
5349 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
5351 if ( !m_pImpl )
5353 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5354 throw lang::DisposedException( THROW_WHERE );
5357 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, false ) )
5358 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
5360 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aStreamName == "_rels" )
5361 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable name
5363 if ( !xTargetStream.is() )
5364 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 2 );
5368 uno::Reference< io::XStream > xNonconstRef = xTargetStream;
5369 m_pImpl->CloneStreamElement( aStreamName, false, ::comphelper::SequenceAsHashMap(), xNonconstRef );
5371 SAL_WARN_IF( xNonconstRef != xTargetStream, "package.xstor", "The provided stream reference seems not be filled in correctly!" );
5372 if ( xNonconstRef != xTargetStream )
5373 throw uno::RuntimeException( THROW_WHERE ); // if the stream reference is set it must not be changed!
5375 catch( const embed::InvalidStorageException& rInvalidStorageException )
5377 SAL_INFO("package.xstor", "Rethrow: " << rInvalidStorageException);
5378 throw;
5380 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
5382 SAL_INFO("package.xstor", "Rethrow: " << rIllegalArgumentException);
5383 throw;
5385 catch( const packages::WrongPasswordException& rWrongPasswordException )
5387 SAL_INFO("package.xstor", "Rethrow: " << rWrongPasswordException);
5388 throw;
5390 catch( const io::IOException& rIOException )
5392 SAL_INFO("package.xstor", "Rethrow: " << rIOException);
5393 throw;
5395 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
5397 SAL_INFO("package.xstor", "Rethrow: " << rStorageWrappedTargetException);
5398 throw;
5400 catch( const uno::RuntimeException& rRuntimeException )
5402 SAL_INFO("package.xstor", "Rethrow: " << rRuntimeException);
5403 throw;
5405 catch( const uno::Exception& rException )
5407 SAL_INFO("package.xstor", "Rethrow: " << rException);
5409 uno::Any aCaught( ::cppu::getCaughtException() );
5410 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't copy stream data!",
5411 uno::Reference< io::XInputStream >(),
5412 aCaught );
5417 // XHierarchicalStorageAccess
5418 uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openStreamElementByHierarchicalName( const OUString& aStreamPath, ::sal_Int32 nOpenMode )
5420 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
5422 if ( !m_pImpl )
5424 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5425 throw lang::DisposedException( THROW_WHERE );
5428 if ( aStreamPath.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, true ) )
5429 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
5431 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
5432 && ( nOpenMode & embed::ElementModes::WRITE ) )
5433 throw io::IOException( THROW_WHERE ); // Access denied
5435 OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
5436 OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
5438 uno::Reference< embed::XExtendedStorageStream > xResult;
5439 if ( aListPath.size() == 1 )
5443 // that must be a direct request for a stream
5444 // the transacted version of the stream should be opened
5446 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamPath, nOpenMode, false );
5447 assert(pElement && pElement->m_xStream && "In case element can not be created an exception must be thrown!");
5449 xResult.set(pElement->m_xStream->GetStream(nOpenMode, true),
5450 uno::UNO_QUERY_THROW);
5452 catch ( const container::NoSuchElementException & )
5454 throw io::IOException( THROW_WHERE ); // file not found
5457 else
5459 // there are still storages in between
5460 if ( !m_pData->m_rHierarchyHolder.is() )
5461 m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
5462 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
5464 xResult = m_pData->m_rHierarchyHolder->GetStreamHierarchically(
5465 ( m_pImpl->m_nStorageMode & embed::ElementModes::READWRITE ),
5466 aListPath,
5467 nOpenMode );
5470 if ( !xResult.is() )
5471 throw uno::RuntimeException( THROW_WHERE );
5473 return xResult;
5476 uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openEncryptedStreamElementByHierarchicalName( const OUString& aStreamPath, ::sal_Int32 nOpenMode, const OUString& sPassword )
5478 return openEncryptedStreamByHierarchicalName( aStreamPath, nOpenMode, ::comphelper::OStorageHelper::CreatePackageEncryptionData( sPassword ) );
5481 void SAL_CALL OStorage::removeStreamElementByHierarchicalName( const OUString& aStreamPath )
5483 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
5485 if ( !m_pImpl )
5487 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5488 throw lang::DisposedException( THROW_WHERE );
5491 if ( aStreamPath.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, true ) )
5492 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
5494 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
5495 throw io::IOException( THROW_WHERE ); // Access denied
5497 OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
5498 OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
5500 if ( !m_pData->m_rHierarchyHolder.is() )
5501 m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
5502 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
5504 m_pData->m_rHierarchyHolder->RemoveStreamHierarchically( aListPath );
5507 // XHierarchicalStorageAccess2
5508 uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openEncryptedStreamByHierarchicalName( const OUString& aStreamPath, ::sal_Int32 nOpenMode, const uno::Sequence< beans::NamedValue >& aEncryptionData )
5510 ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
5512 if ( !m_pImpl )
5514 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5515 throw lang::DisposedException( THROW_WHERE );
5518 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
5519 throw packages::NoEncryptionException( THROW_WHERE );
5521 if ( aStreamPath.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, true ) )
5522 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
5524 if ( !aEncryptionData.getLength() )
5525 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 3 );
5527 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
5528 && ( nOpenMode & embed::ElementModes::WRITE ) )
5529 throw io::IOException( THROW_WHERE ); // Access denied
5531 OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
5532 OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
5534 uno::Reference< embed::XExtendedStorageStream > xResult;
5535 if ( aListPath.size() == 1 )
5537 // that must be a direct request for a stream
5538 // the transacted version of the stream should be opened
5540 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamPath, nOpenMode, true );
5541 OSL_ENSURE(pElement && pElement->m_xStream, "In case element can not be created an exception must be thrown!");
5543 xResult.set(pElement->m_xStream->GetStream(nOpenMode, aEncryptionData, true),
5544 uno::UNO_QUERY_THROW);
5546 else
5548 // there are still storages in between
5549 if ( !m_pData->m_rHierarchyHolder.is() )
5550 m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
5551 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
5553 xResult = m_pData->m_rHierarchyHolder->GetStreamHierarchically(
5554 ( m_pImpl->m_nStorageMode & embed::ElementModes::READWRITE ),
5555 aListPath,
5556 nOpenMode,
5557 aEncryptionData );
5560 if ( !xResult.is() )
5561 throw uno::RuntimeException( THROW_WHERE );
5563 return xResult;
5566 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */