update credits
[LibreOffice.git] / package / source / xstor / xstorage.cxx
blobd95e418675121d575ab833e322d4b4d9a4d7b2f0
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 <com/sun/star/beans/PropertyValue.hpp>
21 #include <com/sun/star/embed/ElementModes.hpp>
22 #include <com/sun/star/embed/UseBackupException.hpp>
23 #include <com/sun/star/embed/StorageFormats.hpp>
24 #include <com/sun/star/ucb/XProgressHandler.hpp>
25 #include <com/sun/star/io/TempFile.hpp>
26 #include <com/sun/star/logging/DocumentIOLogRing.hpp>
27 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
28 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
29 #include <com/sun/star/container/XEnumerationAccess.hpp>
30 #include <com/sun/star/container/XNamed.hpp>
31 #include <com/sun/star/util/XChangesBatch.hpp>
32 #include <com/sun/star/util/XCloneable.hpp>
35 #include <com/sun/star/lang/XUnoTunnel.hpp>
36 #include <com/sun/star/lang/XComponent.hpp>
37 #include <com/sun/star/lang/DisposedException.hpp>
38 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
39 #include <com/sun/star/beans/NamedValue.hpp>
41 #include <PackageConstants.hxx>
43 #include <cppuhelper/typeprovider.hxx>
44 #include <cppuhelper/exc_hlp.hxx>
45 #include <rtl/logfile.hxx>
46 #include <rtl/instance.hxx>
48 #include <comphelper/processfactory.hxx>
49 #include <comphelper/componentcontext.hxx>
50 #include <comphelper/storagehelper.hxx>
51 #include <comphelper/ofopxmlhelper.hxx>
53 #include "xstorage.hxx"
54 #include "owriteablestream.hxx"
55 #include "disposelistener.hxx"
56 #include "switchpersistencestream.hxx"
57 #include "ohierarchyholder.hxx"
59 using namespace ::com::sun::star;
61 //=========================================================
63 typedef ::std::list< uno::WeakReference< lang::XComponent > > WeakComponentList;
65 struct StorInternalData_Impl
67 SotMutexHolderRef m_rSharedMutexRef;
68 ::cppu::OMultiTypeInterfaceContainerHelper m_aListenersContainer; // list of listeners
69 ::cppu::OTypeCollection* m_pTypeCollection;
70 sal_Bool m_bIsRoot;
71 sal_Int32 m_nStorageType; // the mode in which the storage is used
72 sal_Bool m_bReadOnlyWrap;
74 OChildDispListener_Impl* m_pSubElDispListener;
76 WeakComponentList m_aOpenSubComponentsList;
78 ::rtl::Reference< OHierarchyHolder_Impl > m_rHierarchyHolder;
80 // the mutex reference MUST NOT be empty
81 StorInternalData_Impl( const SotMutexHolderRef& rMutexRef, sal_Bool bRoot, sal_Int32 nStorageType, sal_Bool bReadOnlyWrap )
82 : m_rSharedMutexRef( rMutexRef )
83 , m_aListenersContainer( rMutexRef->GetMutex() )
84 , m_pTypeCollection( NULL )
85 , m_bIsRoot( bRoot )
86 , m_nStorageType( nStorageType )
87 , m_bReadOnlyWrap( bReadOnlyWrap )
88 , m_pSubElDispListener( NULL )
91 ~StorInternalData_Impl();
94 //=========================================================
95 OUString GetNewTempFileURL( const uno::Reference< uno::XComponentContext > xContext );
97 // static
98 void OStorage_Impl::completeStorageStreamCopy_Impl(
99 const uno::Reference< io::XStream >& xSource,
100 const uno::Reference< io::XStream >& xDest,
101 sal_Int32 nStorageType,
102 const uno::Sequence< uno::Sequence< beans::StringPair > >& aRelInfo )
104 uno::Reference< beans::XPropertySet > xSourceProps( xSource, uno::UNO_QUERY );
105 uno::Reference< beans::XPropertySet > xDestProps( xDest, uno::UNO_QUERY );
106 if ( !xSourceProps.is() || !xDestProps.is() )
107 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
109 uno::Reference< io::XOutputStream > xDestOutStream = xDest->getOutputStream();
110 if ( !xDestOutStream.is() )
111 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
113 uno::Reference< io::XInputStream > xSourceInStream = xSource->getInputStream();
114 if ( !xSourceInStream.is() )
115 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
117 // TODO: headers of encripted streams should be copied also
118 ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInStream, xDestOutStream );
120 uno::Sequence< OUString > aPropNames( 1 );
121 aPropNames[0] = "Compressed";
123 if ( nStorageType == embed::StorageFormats::PACKAGE )
125 aPropNames.realloc( 3 );
126 aPropNames[1] = "MediaType";
127 aPropNames[2] = "UseCommonStoragePasswordEncryption";
129 else if ( nStorageType == embed::StorageFormats::OFOPXML )
131 // TODO/LATER: in future it might make sence to provide the stream if there is one
132 uno::Reference< embed::XRelationshipAccess > xRelAccess( xDest, uno::UNO_QUERY_THROW );
133 xRelAccess->clearRelationships();
134 xRelAccess->insertRelationships( aRelInfo, sal_False );
136 aPropNames.realloc( 2 );
137 aPropNames[1] = "MediaType";
140 for ( int ind = 0; ind < aPropNames.getLength(); ind++ )
141 xDestProps->setPropertyValue( aPropNames[ind], xSourceProps->getPropertyValue( aPropNames[ind] ) );
144 uno::Reference< io::XInputStream > GetSeekableTempCopy( uno::Reference< io::XInputStream > xInStream,
145 uno::Reference< uno::XComponentContext > xContext )
147 uno::Reference < io::XTempFile > xTempFile = io::TempFile::create(xContext);
148 uno::Reference < io::XOutputStream > xTempOut = xTempFile->getOutputStream();
149 uno::Reference < io::XInputStream > xTempIn = xTempFile->getInputStream();
151 if ( !xTempOut.is() || !xTempIn.is() )
152 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
154 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOut );
155 xTempOut->closeOutput();
157 return xTempIn;
160 StorInternalData_Impl::~StorInternalData_Impl()
162 if ( m_pTypeCollection )
163 delete m_pTypeCollection;
167 SotElement_Impl::SotElement_Impl( const OUString& rName, sal_Bool bStor, sal_Bool bNew )
168 : m_aName( rName )
169 , m_aOriginalName( rName )
170 , m_bIsRemoved( sal_False )
171 , m_bIsInserted( bNew )
172 , m_bIsStorage( bStor )
173 , m_pStorage( NULL )
174 , m_pStream( NULL )
178 SotElement_Impl::~SotElement_Impl()
180 if ( m_pStorage )
181 delete m_pStorage;
183 if ( m_pStream )
184 delete m_pStream;
187 //-----------------------------------------------
188 // most of properties are holt by the storage but are not used
189 OStorage_Impl::OStorage_Impl( uno::Reference< io::XInputStream > xInputStream,
190 sal_Int32 nMode,
191 uno::Sequence< beans::PropertyValue > xProperties,
192 uno::Reference< uno::XComponentContext > xContext,
193 sal_Int32 nStorageType )
194 : m_rMutexRef( new SotMutexHolder )
195 , m_pAntiImpl( NULL )
196 , m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
197 , m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
198 , m_bBroadcastModified( sal_False )
199 , m_bCommited( sal_False )
200 , m_bIsRoot( sal_True )
201 , m_bListCreated( sal_False )
202 , m_xContext( xContext )
203 , m_xProperties( xProperties )
204 , m_bHasCommonEncryptionData( sal_False )
205 , m_pParent( NULL )
206 , m_bControlMediaType( sal_False )
207 , m_bMTFallbackUsed( sal_False )
208 , m_bControlVersion( sal_False )
209 , m_pSwitchStream( NULL )
210 , m_nStorageType( nStorageType )
211 , m_pRelStorElement( NULL )
212 , m_nRelInfoStatus( RELINFO_NO_INIT )
214 // all the checks done below by assertion statements must be done by factory
215 OSL_ENSURE( xInputStream.is(), "No input stream is provided!\n" );
217 m_pSwitchStream = (SwitchablePersistenceStream*) new SwitchablePersistenceStream( xContext, xInputStream );
218 m_xInputStream = m_pSwitchStream->getInputStream();
220 if ( m_nStorageMode & embed::ElementModes::WRITE )
222 // check that the stream allows to write
223 OSL_FAIL( "No stream for writing is provided!\n" );
227 //-----------------------------------------------
228 // most of properties are holt by the storage but are not used
229 OStorage_Impl::OStorage_Impl( uno::Reference< io::XStream > xStream,
230 sal_Int32 nMode,
231 uno::Sequence< beans::PropertyValue > xProperties,
232 uno::Reference< uno::XComponentContext > xContext,
233 sal_Int32 nStorageType )
234 : m_rMutexRef( new SotMutexHolder )
235 , m_pAntiImpl( NULL )
236 , m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
237 , m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
238 , m_bBroadcastModified( sal_False )
239 , m_bCommited( sal_False )
240 , m_bIsRoot( sal_True )
241 , m_bListCreated( sal_False )
242 , m_xContext( xContext )
243 , m_xProperties( xProperties )
244 , m_bHasCommonEncryptionData( sal_False )
245 , m_pParent( NULL )
246 , m_bControlMediaType( sal_False )
247 , m_bMTFallbackUsed( sal_False )
248 , m_bControlVersion( sal_False )
249 , m_pSwitchStream( NULL )
250 , m_nStorageType( nStorageType )
251 , m_pRelStorElement( NULL )
252 , m_nRelInfoStatus( RELINFO_NO_INIT )
254 // all the checks done below by assertion statements must be done by factory
255 OSL_ENSURE( xStream.is(), "No stream is provided!\n" );
257 if ( m_nStorageMode & embed::ElementModes::WRITE )
259 m_pSwitchStream = (SwitchablePersistenceStream*) new SwitchablePersistenceStream( xContext, xStream );
260 m_xStream = static_cast< io::XStream* >( m_pSwitchStream );
262 else
264 m_pSwitchStream = (SwitchablePersistenceStream*) new SwitchablePersistenceStream( xContext,
265 xStream->getInputStream() );
266 m_xInputStream = m_pSwitchStream->getInputStream();
270 //-----------------------------------------------
271 OStorage_Impl::OStorage_Impl( OStorage_Impl* pParent,
272 sal_Int32 nMode,
273 uno::Reference< container::XNameContainer > xPackageFolder,
274 uno::Reference< lang::XSingleServiceFactory > xPackage,
275 uno::Reference< uno::XComponentContext > xContext,
276 sal_Int32 nStorageType )
277 : m_rMutexRef( new SotMutexHolder )
278 , m_pAntiImpl( NULL )
279 , m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
280 , m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
281 , m_bBroadcastModified( sal_False )
282 , m_bCommited( sal_False )
283 , m_bIsRoot( sal_False )
284 , m_bListCreated( sal_False )
285 , m_xPackageFolder( xPackageFolder )
286 , m_xPackage( xPackage )
287 , m_xContext( xContext )
288 , m_bHasCommonEncryptionData( sal_False )
289 , m_pParent( pParent ) // can be empty in case of temporary readonly substorages and relation storage
290 , m_bControlMediaType( sal_False )
291 , m_bMTFallbackUsed( sal_False )
292 , m_bControlVersion( sal_False )
293 , m_pSwitchStream( NULL )
294 , m_nStorageType( nStorageType )
295 , m_pRelStorElement( NULL )
296 , m_nRelInfoStatus( RELINFO_NO_INIT )
298 OSL_ENSURE( xPackageFolder.is(), "No package folder!\n" );
301 //-----------------------------------------------
302 OStorage_Impl::~OStorage_Impl()
305 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
306 if ( m_pAntiImpl ) // root storage wrapper must set this member to NULL before destruction of object
308 OSL_ENSURE( !m_bIsRoot, "The root storage wrapper must be disposed already" );
310 try {
311 m_pAntiImpl->InternalDispose( sal_False );
313 catch ( const uno::Exception& rException )
315 AddLog( rException.Message );
316 AddLog( OSL_LOG_PREFIX "Quiet exception" );
318 m_pAntiImpl = NULL;
320 else if ( !m_aReadOnlyWrapList.empty() )
322 for ( OStorageList_Impl::iterator pStorageIter = m_aReadOnlyWrapList.begin();
323 pStorageIter != m_aReadOnlyWrapList.end(); ++pStorageIter )
325 uno::Reference< embed::XStorage > xTmp = pStorageIter->m_xWeakRef;
326 if ( xTmp.is() )
327 try {
328 pStorageIter->m_pPointer->InternalDispose( sal_False );
329 } catch( const uno::Exception& rException )
331 AddLog( rException.Message );
332 AddLog( OSL_LOG_PREFIX "Quiet exception" );
336 m_aReadOnlyWrapList.clear();
339 m_pParent = NULL;
342 for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
343 pElementIter != m_aChildrenList.end(); ++pElementIter )
344 delete *pElementIter;
346 m_aChildrenList.clear();
348 for ( SotElementList_Impl::iterator pDeletedIter = m_aDeletedList.begin();
349 pDeletedIter != m_aDeletedList.end(); ++pDeletedIter )
350 delete *pDeletedIter;
352 m_aDeletedList.clear();
354 if ( m_nStorageType == embed::StorageFormats::OFOPXML && m_pRelStorElement )
356 delete m_pRelStorElement;
357 m_pRelStorElement = NULL;
360 m_xPackageFolder = uno::Reference< container::XNameContainer >();
361 m_xPackage = uno::Reference< lang::XSingleServiceFactory >();
363 OUString aPropertyName = "URL";
364 for ( sal_Int32 aInd = 0; aInd < m_xProperties.getLength(); ++aInd )
366 if ( m_xProperties[aInd].Name.equals( aPropertyName ) )
368 // the storage is URL based so all the streams are opened by factory and should be closed
371 if ( m_xInputStream.is() )
373 m_xInputStream->closeInput();
374 m_xInputStream = uno::Reference< io::XInputStream >();
377 if ( m_xStream.is() )
379 uno::Reference< io::XInputStream > xInStr = m_xStream->getInputStream();
380 if ( xInStr.is() )
381 xInStr->closeInput();
383 uno::Reference< io::XOutputStream > xOutStr = m_xStream->getOutputStream();
384 if ( xOutStr.is() )
385 xOutStr->closeOutput();
387 m_xStream = uno::Reference< io::XStream >();
390 catch( const uno::Exception& rException )
392 AddLog( OSL_LOG_PREFIX "Quiet exception" );
393 AddLog( rException.Message );
399 //-----------------------------------------------
400 void OStorage_Impl::AddLog( const OUString& aMessage )
402 if ( !m_xLogRing.is() )
406 uno::Reference<uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
407 m_xLogRing = logging::DocumentIOLogRing::get(xContext);
409 catch( const uno::Exception& )
411 // No log
415 if ( m_xLogRing.is() )
416 m_xLogRing->logString( aMessage );
419 //-----------------------------------------------
420 void OStorage_Impl::SetReadOnlyWrap( OStorage& aStorage )
422 // Weak reference is used inside the holder so the refcount must not be zero at this point
423 OSL_ENSURE( aStorage.GetRefCount_Impl(), "There must be a reference alive to use this method!\n" );
424 m_aReadOnlyWrapList.push_back( StorageHolder_Impl( &aStorage ) );
427 //-----------------------------------------------
428 void OStorage_Impl::RemoveReadOnlyWrap( OStorage& aStorage )
430 for ( OStorageList_Impl::iterator pStorageIter = m_aReadOnlyWrapList.begin();
431 pStorageIter != m_aReadOnlyWrapList.end();)
433 uno::Reference< embed::XStorage > xTmp = pStorageIter->m_xWeakRef;
434 if ( !xTmp.is() || pStorageIter->m_pPointer == &aStorage )
436 try {
437 pStorageIter->m_pPointer->InternalDispose( sal_False );
438 } catch( const uno::Exception& rException )
440 AddLog( OSL_LOG_PREFIX "Quiet exception" );
441 AddLog( rException.Message );
444 OStorageList_Impl::iterator pIterToDelete( pStorageIter );
445 ++pStorageIter;
446 m_aReadOnlyWrapList.erase( pIterToDelete );
448 else
449 ++pStorageIter;
453 //-----------------------------------------------
454 void OStorage_Impl::OpenOwnPackage()
456 OSL_ENSURE( m_bIsRoot, "Opening of the package has no sence!\n" );
458 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
460 if ( !m_xPackageFolder.is() )
462 if ( !m_xPackage.is() )
464 uno::Sequence< uno::Any > aArguments( 2 );
465 if ( m_nStorageMode & embed::ElementModes::WRITE )
466 aArguments[ 0 ] <<= m_xStream;
467 else
469 OSL_ENSURE( m_xInputStream.is(), "Input stream must be set for readonly access!\n" );
470 aArguments[ 0 ] <<= m_xInputStream;
471 // TODO: if input stream is not seekable or XSeekable interface is supported
472 // on XStream object a wrapper must be used
475 // do not allow elements to remove themself from the old container in case of insertion to another container
476 aArguments[ 1 ] <<= beans::NamedValue( "AllowRemoveOnInsert",
477 uno::makeAny( (sal_Bool)sal_False ) );
479 sal_Int32 nArgNum = 2;
480 for ( sal_Int32 aInd = 0; aInd < m_xProperties.getLength(); aInd++ )
482 if ( m_xProperties[aInd].Name == "RepairPackage"
483 || m_xProperties[aInd].Name == "ProgressHandler" )
485 beans::NamedValue aNamedValue( m_xProperties[aInd].Name,
486 m_xProperties[aInd].Value );
487 aArguments.realloc( ++nArgNum );
488 aArguments[nArgNum-1] <<= aNamedValue;
490 else if ( m_xProperties[aInd].Name == "Password" )
492 // TODO: implement password setting for documents
493 // the password entry must be removed after setting
497 if ( m_nStorageType == embed::StorageFormats::ZIP )
499 // let the package support only plain zip format
500 beans::NamedValue aNamedValue;
501 aNamedValue.Name = "StorageFormat";
502 aNamedValue.Value <<= OUString( "ZipFormat" );
503 aArguments.realloc( ++nArgNum );
504 aArguments[nArgNum-1] <<= aNamedValue;
506 else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
508 // let the package support OFOPXML media type handling
509 beans::NamedValue aNamedValue;
510 aNamedValue.Name = OUString( "StorageFormat" );
511 aNamedValue.Value <<= OUString( "OFOPXMLFormat" );
512 aArguments.realloc( ++nArgNum );
513 aArguments[nArgNum-1] <<= aNamedValue;
516 m_xPackage = uno::Reference< lang::XSingleServiceFactory > (
517 GetComponentContext()->getServiceManager()->createInstanceWithArgumentsAndContext(
518 "com.sun.star.packages.comp.ZipPackage", aArguments, GetComponentContext()),
519 uno::UNO_QUERY );
522 uno::Reference< container::XHierarchicalNameAccess > xHNameAccess( m_xPackage, uno::UNO_QUERY );
523 OSL_ENSURE( xHNameAccess.is(), "The package could not be created!\n" );
525 if ( xHNameAccess.is() )
527 uno::Any aFolder = xHNameAccess->getByHierarchicalName("/");
528 aFolder >>= m_xPackageFolder;
532 OSL_ENSURE( m_xPackageFolder.is(), "The package root folder can not be opened!\n" );
533 if ( !m_xPackageFolder.is() )
534 throw embed::InvalidStorageException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
537 //-----------------------------------------------
538 uno::Reference< uno::XComponentContext > OStorage_Impl::GetComponentContext()
540 if ( m_xContext.is() )
541 return m_xContext;
543 return ::comphelper::getProcessComponentContext();
546 //-----------------------------------------------
547 SotElementList_Impl& OStorage_Impl::GetChildrenList()
549 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
551 ReadContents();
552 return m_aChildrenList;
555 //-----------------------------------------------
556 void OStorage_Impl::GetStorageProperties()
558 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
560 uno::Reference< beans::XPropertySet > xProps( m_xPackageFolder, uno::UNO_QUERY_THROW );
562 if ( !m_bControlMediaType )
564 uno::Reference< beans::XPropertySet > xPackageProps( m_xPackage, uno::UNO_QUERY_THROW );
565 xPackageProps->getPropertyValue( MEDIATYPE_FALLBACK_USED_PROPERTY ) >>= m_bMTFallbackUsed;
567 xProps->getPropertyValue( "MediaType" ) >>= m_aMediaType;
568 m_bControlMediaType = sal_True;
571 if ( !m_bControlVersion )
573 xProps->getPropertyValue( "Version" ) >>= m_aVersion;
574 m_bControlVersion = sal_True;
578 // the properties of OFOPXML will be handled directly
581 //-----------------------------------------------
582 void OStorage_Impl::ReadRelInfoIfNecessary()
584 if ( m_nStorageType != embed::StorageFormats::OFOPXML )
585 return;
587 if ( m_nRelInfoStatus == RELINFO_NO_INIT )
589 // Init from original stream
590 uno::Reference< io::XInputStream > xRelInfoStream = GetRelInfoStreamForName( OUString() );
591 if ( xRelInfoStream.is() )
592 m_aRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
593 xRelInfoStream,
594 "_rels/.rels",
595 m_xContext );
597 m_nRelInfoStatus = RELINFO_READ;
599 else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
601 // Init from the new stream
604 if ( m_xNewRelInfoStream.is() )
605 m_aRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
606 m_xNewRelInfoStream,
607 "_rels/.rels",
608 m_xContext );
610 m_nRelInfoStatus = RELINFO_CHANGED_STREAM_READ;
612 catch( const uno::Exception& )
614 m_nRelInfoStatus = RELINFO_CHANGED_BROKEN;
619 //-----------------------------------------------
620 void OStorage_Impl::ReadContents()
622 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
624 if ( m_bListCreated )
625 return;
627 if ( m_bIsRoot )
628 OpenOwnPackage();
630 uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xPackageFolder, uno::UNO_QUERY );
631 if ( !xEnumAccess.is() )
632 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
634 uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration();
635 if ( !xEnum.is() )
636 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
638 m_bListCreated = sal_True;
640 while( xEnum->hasMoreElements() )
642 try {
643 uno::Reference< container::XNamed > xNamed;
644 xEnum->nextElement() >>= xNamed;
646 if ( !xNamed.is() )
648 OSL_FAIL( "XNamed is not supported!\n" );
649 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
652 OUString aName = xNamed->getName();
653 OSL_ENSURE( !aName.isEmpty(), "Empty name!\n" );
655 uno::Reference< container::XNameContainer > xNameContainer( xNamed, uno::UNO_QUERY );
657 SotElement_Impl* pNewElement = new SotElement_Impl( aName, xNameContainer.is(), sal_False );
658 if ( m_nStorageType == embed::StorageFormats::OFOPXML && aName == "_rels" )
660 if ( !pNewElement->m_bIsStorage )
661 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: Unexpected format
663 m_pRelStorElement = pNewElement;
664 CreateRelStorage();
666 else
668 if ( ( m_nStorageMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE )
670 // if a storage is truncated all of it elements are marked as deleted
671 pNewElement->m_bIsRemoved = sal_True;
674 m_aChildrenList.push_back( pNewElement );
677 catch( const container::NoSuchElementException& rNoSuchElementException )
679 AddLog( rNoSuchElementException.Message );
680 AddLog( OSL_LOG_PREFIX "NoSuchElement" );
682 OSL_FAIL( "hasMoreElements() implementation has problems!\n" );
683 break;
686 if ( ( m_nStorageMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE )
688 // if a storage is truncated the relations information should be cleaned
689 m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
690 m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
691 m_nRelInfoStatus = RELINFO_CHANGED;
694 // cache changeable folder properties
695 GetStorageProperties();
698 //-----------------------------------------------
699 void OStorage_Impl::CopyToStorage( const uno::Reference< embed::XStorage >& xDest, sal_Bool bDirect )
701 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
703 uno::Reference< beans::XPropertySet > xPropSet( xDest, uno::UNO_QUERY );
704 if ( !xPropSet.is() )
705 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 );
707 sal_Int32 nDestMode = embed::ElementModes::READ;
708 xPropSet->getPropertyValue( "OpenMode" ) >>= nDestMode;
710 if ( !( nDestMode & embed::ElementModes::WRITE ) )
711 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access_denied
713 ReadContents();
715 if ( !m_xPackageFolder.is() )
716 throw embed::InvalidStorageException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
718 for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
719 pElementIter != m_aChildrenList.end(); ++pElementIter )
721 if ( !(*pElementIter)->m_bIsRemoved )
722 CopyStorageElement( *pElementIter, xDest, (*pElementIter)->m_aName, bDirect );
725 // move storage properties to the destination one ( means changeable properties )
726 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
728 OUString aMediaTypeString = "MediaType";
729 OUString aVersionString = "Version";
730 xPropSet->setPropertyValue( aMediaTypeString, uno::makeAny( m_aMediaType ) );
731 xPropSet->setPropertyValue( aVersionString, uno::makeAny( m_aVersion ) );
734 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
736 // if this is a root storage, the common key from current one should be moved there
737 sal_Bool bIsRoot = sal_False;
738 OUString aRootString = "IsRoot";
739 if ( ( xPropSet->getPropertyValue( aRootString ) >>= bIsRoot ) && bIsRoot )
743 uno::Reference< embed::XEncryptionProtectedStorage > xEncr( xDest, uno::UNO_QUERY );
744 if ( xEncr.is() )
746 xEncr->setEncryptionData( GetCommonRootEncryptionData().getAsConstNamedValueList() );
748 uno::Sequence< beans::NamedValue > aAlgorithms;
749 uno::Reference< beans::XPropertySet > xPackPropSet( m_xPackage, uno::UNO_QUERY_THROW );
750 xPackPropSet->getPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY )
751 >>= aAlgorithms;
752 xEncr->setEncryptionAlgorithms( aAlgorithms );
755 catch( const packages::NoEncryptionException& rNoEncryptionException )
757 AddLog( rNoEncryptionException.Message );
758 AddLog( OSL_LOG_PREFIX "No Encryption" );
762 else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
765 // TODO/LATER: currently the optimization is not active
766 // uno::Reference< io::XInputStream > xRelInfoStream = GetRelInfoStreamForName( OUString() ); // own stream
767 // if ( xRelInfoStream.is() )
768 // {
769 // // Relations info stream is a writeonly property, introduced only to optimyze copying
770 // // Should be used carefuly since no check for stream consistency is done, and the stream must not stay locked
772 // OUString aRelInfoString = "RelationsInfoStream";
773 // xPropSet->setPropertyValue( aRelInfoString, uno::makeAny( GetSeekableTempCopy( xRelInfoStream, m_xFactory ) ) );
774 // }
776 uno::Reference< embed::XRelationshipAccess > xRels( xDest, uno::UNO_QUERY );
777 if ( !xRels.is() )
778 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 );
780 xRels->insertRelationships( GetAllRelationshipsIfAny(), sal_False );
783 // if possible the destination storage should be commited after successful copying
784 uno::Reference< embed::XTransactedObject > xObjToCommit( xDest, uno::UNO_QUERY );
785 if ( xObjToCommit.is() )
786 xObjToCommit->commit();
789 //-----------------------------------------------
790 void OStorage_Impl::CopyStorageElement( SotElement_Impl* pElement,
791 uno::Reference< embed::XStorage > xDest,
792 OUString aName,
793 sal_Bool bDirect )
795 OSL_ENSURE( xDest.is(), "No destination storage!\n" );
796 OSL_ENSURE( !aName.isEmpty(), "Empty element name!\n" );
798 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
800 uno::Reference< container::XNameAccess > xDestAccess( xDest, uno::UNO_QUERY );
801 if ( !xDestAccess.is() )
802 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
804 if ( xDestAccess->hasByName( aName )
805 && !( pElement->m_bIsStorage && xDest->isStorageElement( aName ) ) )
806 xDest->removeElement( aName );
808 if ( pElement->m_bIsStorage )
810 uno::Reference< embed::XStorage > xSubDest =
811 xDest->openStorageElement( aName,
812 embed::ElementModes::WRITE );
814 OSL_ENSURE( xSubDest.is(), "No destination substorage!\n" );
816 if ( !pElement->m_pStorage )
818 OpenSubStorage( pElement, embed::ElementModes::READ );
819 if ( !pElement->m_pStorage )
820 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
823 pElement->m_pStorage->CopyToStorage( xSubDest, bDirect );
825 else
827 if ( !pElement->m_pStream )
829 OpenSubStream( pElement );
830 if ( !pElement->m_pStream )
831 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
834 if ( !pElement->m_pStream->IsEncrypted() )
836 if ( bDirect )
838 // fill in the properties for the stream
839 uno::Sequence< beans::PropertyValue > aStrProps(0);
840 uno::Sequence< beans::PropertyValue > aSrcPkgProps = pElement->m_pStream->GetStreamProperties();
841 sal_Int32 nNum = 0;
842 for ( int ind = 0; ind < aSrcPkgProps.getLength(); ind++ )
844 if ( aSrcPkgProps[ind].Name == "MediaType" || aSrcPkgProps[ind].Name == "Compressed" )
846 aStrProps.realloc( ++nNum );
847 aStrProps[nNum-1].Name = aSrcPkgProps[ind].Name;
848 aStrProps[nNum-1].Value = aSrcPkgProps[ind].Value;
852 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
854 aStrProps.realloc( ++nNum );
855 aStrProps[nNum-1].Name = "UseCommonStoragePasswordEncryption";
856 aStrProps[nNum-1].Value <<= (sal_Bool)( pElement->m_pStream->UsesCommonEncryption_Impl() );
858 else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
860 // TODO/LATER: currently the optimization is not active
861 // uno::Reference< io::XInputStream > xInStream = GetRelInfoStreamForName( OUString() ); // own rels stream
862 // if ( xInStream.is() )
863 // {
864 // aStrProps.realloc( ++nNum );
865 // aStrProps[nNum-1].Name = "RelationsInfoStream";
866 // aStrProps[nNum-1].Value <<= GetSeekableTempCopy( xInStream, m_xFactory );
867 // }
869 uno::Reference< embed::XRelationshipAccess > xRels( xDest, uno::UNO_QUERY );
870 if ( !xRels.is() )
871 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 0 );
873 xRels->insertRelationships( GetAllRelationshipsIfAny(), sal_False );
876 uno::Reference< embed::XOptimizedStorage > xOptDest( xDest, uno::UNO_QUERY_THROW );
877 uno::Reference < io::XInputStream > xInputToInsert;
879 if ( pElement->m_pStream->HasTempFile_Impl() || !pElement->m_pStream->m_xPackageStream.is() )
881 OSL_ENSURE( pElement->m_pStream->m_xPackageStream.is(), "No package stream!" );
883 // if the stream is modified - the temporary file must be used for insertion
884 xInputToInsert = pElement->m_pStream->GetTempFileAsInputStream();
886 else
888 // for now get just nonseekable access to the stream
889 // TODO/LATER: the raw stream can be used
891 xInputToInsert = pElement->m_pStream->m_xPackageStream->getDataStream();
894 if ( !xInputToInsert.is() )
895 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
897 xOptDest->insertStreamElementDirect( aName, xInputToInsert, aStrProps );
899 else
901 uno::Reference< io::XStream > xSubStr =
902 xDest->openStreamElement( aName,
903 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
904 OSL_ENSURE( xSubStr.is(), "No destination substream!\n" );
906 pElement->m_pStream->CopyInternallyTo_Impl( xSubStr );
909 else if ( m_nStorageType != embed::StorageFormats::PACKAGE )
911 OSL_FAIL( "Encryption is only supported in package storage!\n" );
912 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
914 else if ( pElement->m_pStream->HasCachedEncryptionData()
915 && ( pElement->m_pStream->IsModified() || pElement->m_pStream->HasWriteOwner_Impl() ) )
917 ::comphelper::SequenceAsHashMap aCommonEncryptionData;
918 sal_Bool bHasCommonEncryptionData = sal_False;
921 aCommonEncryptionData = GetCommonRootEncryptionData();
922 bHasCommonEncryptionData = sal_True;
924 catch( const packages::NoEncryptionException& rNoEncryptionException )
926 AddLog( rNoEncryptionException.Message );
927 AddLog( OSL_LOG_PREFIX "No Encryption" );
930 if ( bHasCommonEncryptionData && ::package::PackageEncryptionDatasEqual( pElement->m_pStream->GetCachedEncryptionData(), aCommonEncryptionData ) )
932 // If the stream can be opened with the common storage password
933 // it must be stored with the common storage password as well
934 uno::Reference< io::XStream > xDestStream =
935 xDest->openStreamElement( aName,
936 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
938 pElement->m_pStream->CopyInternallyTo_Impl( xDestStream );
940 uno::Reference< beans::XPropertySet > xProps( xDestStream, uno::UNO_QUERY_THROW );
941 xProps->setPropertyValue(
942 "UseCommonStoragePasswordEncryption",
943 uno::Any( (sal_Bool) sal_True ) );
945 else
947 // the stream is already opened for writing or was changed
948 uno::Reference< embed::XStorage2 > xDest2( xDest, uno::UNO_QUERY_THROW );
949 uno::Reference< io::XStream > xSubStr =
950 xDest2->openEncryptedStream( aName,
951 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE,
952 pElement->m_pStream->GetCachedEncryptionData().getAsConstNamedValueList() );
953 OSL_ENSURE( xSubStr.is(), "No destination substream!\n" );
955 pElement->m_pStream->CopyInternallyTo_Impl( xSubStr, pElement->m_pStream->GetCachedEncryptionData() );
958 else
960 // the stream is not opened at all, so it can be just opened for reading
963 // If the stream can be opened with the common storage password
964 // it must be stored with the common storage password as well
966 uno::Reference< io::XStream > xOwnStream = pElement->m_pStream->GetStream( embed::ElementModes::READ,
967 sal_False );
968 uno::Reference< io::XStream > xDestStream =
969 xDest->openStreamElement( aName,
970 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
971 OSL_ENSURE( xDestStream.is(), "No destination substream!\n" );
972 completeStorageStreamCopy_Impl( xOwnStream, xDestStream, m_nStorageType, GetAllRelationshipsIfAny() );
974 uno::Reference< beans::XPropertySet > xProps( xDestStream, uno::UNO_QUERY_THROW );
975 xProps->setPropertyValue(
976 "UseCommonStoragePasswordEncryption",
977 uno::Any( (sal_Bool) sal_True ) );
979 catch( const packages::WrongPasswordException& rWrongPasswordException )
981 AddLog( rWrongPasswordException.Message );
982 AddLog( OSL_LOG_PREFIX "Handled exception" );
984 // If the common storage password does not allow to open the stream
985 // it could be copyed in raw way, the problem is that the StartKey should be the same
986 // in the ODF1.2 package, so an invalid package could be produced if the stream
987 // is copied from ODF1.1 package, where it is allowed to have different StartKeys
988 uno::Reference< embed::XStorageRawAccess > xRawDest( xDest, uno::UNO_QUERY_THROW );
989 uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetRawInStream();
990 xRawDest->insertRawEncrStreamElement( aName, xRawInStream );
996 //-----------------------------------------------
997 uno::Sequence< uno::Sequence< beans::StringPair > > OStorage_Impl::GetAllRelationshipsIfAny()
999 if ( m_nStorageType != embed::StorageFormats::OFOPXML )
1000 return uno::Sequence< uno::Sequence< beans::StringPair > >();
1002 ReadRelInfoIfNecessary();
1004 if ( m_nRelInfoStatus == RELINFO_READ
1005 || m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ || m_nRelInfoStatus == RELINFO_CHANGED )
1006 return m_aRelInfo;
1007 else // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
1008 throw io::IOException( OSL_LOG_PREFIX "Wrong relinfo stream!",
1009 uno::Reference< uno::XInterface >() );
1012 //-----------------------------------------------
1013 void OStorage_Impl::CopyLastCommitTo( const uno::Reference< embed::XStorage >& xNewStor )
1015 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1017 OSL_ENSURE( m_xPackageFolder.is(), "A commited storage is incomplete!\n" );
1018 if ( !m_xPackageFolder.is() )
1019 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1021 OStorage_Impl aTempRepresent( NULL,
1022 embed::ElementModes::READ,
1023 m_xPackageFolder,
1024 m_xPackage,
1025 m_xContext,
1026 m_nStorageType);
1028 // TODO/LATER: could use direct copying
1029 aTempRepresent.CopyToStorage( xNewStor, sal_False );
1032 //-----------------------------------------------
1033 void OStorage_Impl::InsertIntoPackageFolder( const OUString& aName,
1034 const uno::Reference< container::XNameContainer >& xParentPackageFolder )
1036 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1038 OSL_ENSURE( m_xPackageFolder.is(), "An inserted storage is incomplete!\n" );
1039 uno::Reference< lang::XUnoTunnel > xTunnel( m_xPackageFolder, uno::UNO_QUERY );
1040 if ( !xTunnel.is() )
1041 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1043 xParentPackageFolder->insertByName( aName, uno::makeAny( xTunnel ) );
1045 m_bCommited = sal_False;
1048 //-----------------------------------------------
1049 void OStorage_Impl::Commit()
1051 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1053 if ( !m_bIsModified )
1054 return;
1056 // in case of a new empty storage it is possible that the contents are still not read
1057 // ( the storage of course has no contents, but the initialization is postponed till the first use,
1058 // thus if a new storage was created and commited immediatelly it must be initialized here )
1059 ReadContents();
1061 // if storage is commited it should have a valid Package representation
1062 OSL_ENSURE( m_xPackageFolder.is(), "The package representation should exist!\n" );
1063 if ( !m_xPackageFolder.is() )
1064 throw embed::InvalidStorageException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1066 OSL_ENSURE( m_nStorageMode & embed::ElementModes::WRITE,
1067 "Commit of readonly storage, should be detected before!\n" );
1069 uno::Reference< container::XNameContainer > xNewPackageFolder;
1071 // here the storage will switch to the temporary package folder
1072 // if the storage was already commited and the parent was not commited after that
1073 // the switch should not be done since the package folder in use is a temporary one;
1074 // it can be detected by m_bCommited flag ( root storage doesn't need temporary representation )
1075 if ( !m_bCommited && !m_bIsRoot )
1077 uno::Sequence< uno::Any > aSeq( 1 );
1078 aSeq[0] <<= sal_True;
1080 xNewPackageFolder = uno::Reference< container::XNameContainer >(
1081 m_xPackage->createInstanceWithArguments( aSeq ),
1082 uno::UNO_QUERY );
1084 else
1085 xNewPackageFolder = m_xPackageFolder;
1087 // remove replaced removed elements
1088 for ( SotElementList_Impl::iterator pDeletedIter = m_aDeletedList.begin();
1089 pDeletedIter != m_aDeletedList.end();
1090 ++pDeletedIter )
1093 if ( m_nStorageType == embed::StorageFormats::OFOPXML && !(*pDeletedIter)->m_bIsStorage )
1094 RemoveStreamRelInfo( (*pDeletedIter)->m_aOriginalName );
1096 // the removed elements are not in new temporary storage
1097 if ( m_bCommited || m_bIsRoot )
1098 xNewPackageFolder->removeByName( (*pDeletedIter)->m_aOriginalName );
1099 delete *pDeletedIter;
1100 *pDeletedIter = NULL;
1102 m_aDeletedList.clear();
1104 // remove removed elements
1105 SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1106 while ( pElementIter != m_aChildrenList.end() )
1108 // renamed and inserted elements must be really inserted to package later
1109 // since thay can conflict with removed elements
1111 if ( (*pElementIter)->m_bIsRemoved )
1113 if ( m_nStorageType == embed::StorageFormats::OFOPXML && !(*pElementIter)->m_bIsStorage )
1114 RemoveStreamRelInfo( (*pElementIter)->m_aOriginalName );
1116 // the removed elements are not in new temporary storage
1117 if ( m_bCommited || m_bIsRoot )
1118 xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1120 SotElement_Impl* pToDelete = *pElementIter;
1122 ++pElementIter; // to let the iterator be valid it should be increased before removing
1124 m_aChildrenList.remove( pToDelete );
1125 delete pToDelete;
1127 else
1128 ++pElementIter;
1131 // there should be no more deleted elements
1132 for ( pElementIter = m_aChildrenList.begin(); pElementIter != m_aChildrenList.end(); ++pElementIter )
1134 // if it is a 'duplicate commit' inserted elements must be really inserted to package later
1135 // since thay can conflict with renamed elements
1137 if ( !(*pElementIter)->m_bIsInserted )
1139 // for now stream is opened in direct mode that means that in case
1140 // storage is commited all the streams from it are commited in current state.
1141 // following two steps are separated to allow easily implement transacted mode
1142 // for streams if we need it in future.
1143 // Only hierarchical access uses transacted streams currently
1144 if ( !(*pElementIter)->m_bIsStorage && (*pElementIter)->m_pStream
1145 && !(*pElementIter)->m_pStream->IsTransacted() )
1146 (*pElementIter)->m_pStream->Commit();
1148 // if the storage was not open, there is no need to commit it ???
1149 // the storage should be checked that it is commited
1150 if ( (*pElementIter)->m_bIsStorage && (*pElementIter)->m_pStorage && (*pElementIter)->m_pStorage->m_bCommited )
1152 // it's temporary PackageFolder should be inserted instead of current one
1153 // also the new copy of PackageFolder should be used by the children storages
1155 // the renamed elements are not in new temporary storage
1156 if ( m_bCommited || m_bIsRoot )
1157 xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1159 (*pElementIter)->m_pStorage->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
1161 else if ( !(*pElementIter)->m_bIsStorage && (*pElementIter)->m_pStream && (*pElementIter)->m_pStream->m_bFlushed )
1163 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1164 CommitStreamRelInfo( *pElementIter );
1166 // the renamed elements are not in new temporary storage
1167 if ( m_bCommited || m_bIsRoot )
1168 xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1170 (*pElementIter)->m_pStream->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
1172 else if ( !m_bCommited && !m_bIsRoot )
1174 // the element must be just copied to the new temporary package folder
1175 // the connection with the original package should not be lost just because
1176 // the element is still refered by the folder in the original hierarchy
1177 uno::Any aPackageElement = m_xPackageFolder->getByName( (*pElementIter)->m_aOriginalName );
1178 xNewPackageFolder->insertByName( (*pElementIter)->m_aName, aPackageElement );
1180 else if ( (*pElementIter)->m_aName.compareTo( (*pElementIter)->m_aOriginalName ) )
1182 // this is the case when xNewPackageFolder refers to m_xPackageFolder
1183 // in case the name was changed and it is not a changed storage - rename the element
1184 uno::Reference< container::XNamed > xNamed;
1185 uno::Any aPackageElement = xNewPackageFolder->getByName( (*pElementIter)->m_aOriginalName );
1186 xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1187 xNewPackageFolder->insertByName( (*pElementIter)->m_aName, aPackageElement );
1189 if ( m_nStorageType == embed::StorageFormats::OFOPXML && !(*pElementIter)->m_bIsStorage )
1191 if ( !(*pElementIter)->m_pStream )
1193 OpenSubStream( *pElementIter );
1194 if ( !(*pElementIter)->m_pStream )
1195 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1198 CommitStreamRelInfo( *pElementIter );
1202 (*pElementIter)->m_aOriginalName = (*pElementIter)->m_aName;
1206 for ( pElementIter = m_aChildrenList.begin(); pElementIter != m_aChildrenList.end(); ++pElementIter )
1208 // now inserted elements can be inserted to the package
1209 if ( (*pElementIter)->m_bIsInserted )
1211 (*pElementIter)->m_aOriginalName = (*pElementIter)->m_aName;
1212 uno::Reference< lang::XUnoTunnel > xNewElement;
1214 if ( (*pElementIter)->m_bIsStorage )
1216 if ( (*pElementIter)->m_pStorage->m_bCommited )
1218 OSL_ENSURE( (*pElementIter)->m_pStorage, "An inserted storage is incomplete!\n" );
1219 if ( !(*pElementIter)->m_pStorage )
1220 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1222 (*pElementIter)->m_pStorage->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
1224 (*pElementIter)->m_bIsInserted = sal_False;
1227 else
1229 OSL_ENSURE( (*pElementIter)->m_pStream, "An inserted stream is incomplete!\n" );
1230 if ( !(*pElementIter)->m_pStream )
1231 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1233 if ( !(*pElementIter)->m_pStream->IsTransacted() )
1234 (*pElementIter)->m_pStream->Commit();
1236 if ( (*pElementIter)->m_pStream->m_bFlushed )
1238 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1239 CommitStreamRelInfo( *pElementIter );
1241 (*pElementIter)->m_pStream->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
1243 (*pElementIter)->m_bIsInserted = sal_False;
1249 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
1251 // move properties to the destination package folder
1252 uno::Reference< beans::XPropertySet > xProps( xNewPackageFolder, uno::UNO_QUERY );
1253 if ( !xProps.is() )
1254 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1256 xProps->setPropertyValue( "MediaType", uno::makeAny( m_aMediaType ) );
1257 xProps->setPropertyValue( "Version", uno::makeAny( m_aVersion ) );
1260 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1261 CommitRelInfo( xNewPackageFolder ); // store own relations and commit complete relations storage
1263 if ( m_bIsRoot )
1265 uno::Reference< util::XChangesBatch > xChangesBatch( m_xPackage, uno::UNO_QUERY );
1267 OSL_ENSURE( xChangesBatch.is(), "Impossible to commit package!\n" );
1268 if ( !xChangesBatch.is() )
1269 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1273 xChangesBatch->commitChanges();
1275 catch( const lang::WrappedTargetException& r )
1277 // the wrapped UseBackupException means that the target medium can be corrupted
1278 embed::UseBackupException aException;
1279 if ( r.TargetException >>= aException )
1281 m_xStream = uno::Reference< io::XStream >();
1282 m_xInputStream = uno::Reference< io::XInputStream >();
1283 throw aException;
1286 AddLog( aException.Message );
1287 AddLog( OSL_LOG_PREFIX "Rethrow" );
1288 throw;
1291 else if ( !m_bCommited )
1293 m_xPackageFolder = xNewPackageFolder;
1294 m_bCommited = sal_True;
1297 // after commit the mediatype treated as the correct one
1298 m_bMTFallbackUsed = sal_False;
1301 //-----------------------------------------------
1302 void OStorage_Impl::Revert()
1304 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1306 if ( !( m_nStorageMode & embed::ElementModes::WRITE ) )
1307 return; // nothing to do
1309 // all the children must be removed
1310 // they will be created later on demand
1312 SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1313 while ( pElementIter != m_aChildrenList.end() )
1315 if ( (*pElementIter)->m_bIsInserted )
1317 SotElement_Impl* pToDelete = *pElementIter;
1319 ++pElementIter; // to let the iterator be valid it should be increased before removing
1321 m_aChildrenList.remove( pToDelete );
1322 delete pToDelete;
1324 else
1326 ClearElement( *pElementIter );
1328 (*pElementIter)->m_aName = (*pElementIter)->m_aOriginalName;
1329 (*pElementIter)->m_bIsRemoved = sal_False;
1331 ++pElementIter;
1335 // return replaced removed elements
1336 for ( SotElementList_Impl::iterator pDeletedIter = m_aDeletedList.begin();
1337 pDeletedIter != m_aDeletedList.end();
1338 ++pDeletedIter )
1340 m_aChildrenList.push_back( (*pDeletedIter) );
1342 ClearElement( *pDeletedIter );
1344 (*pDeletedIter)->m_aName = (*pDeletedIter)->m_aOriginalName;
1345 (*pDeletedIter)->m_bIsRemoved = sal_False;
1347 m_aDeletedList.clear();
1349 m_bControlMediaType = sal_False;
1350 m_bControlVersion = sal_False;
1352 GetStorageProperties();
1354 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1356 // currently the relations storage is changed only on commit
1357 m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
1358 m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
1359 m_nRelInfoStatus = RELINFO_NO_INIT;
1363 //-----------------------------------------------
1364 ::comphelper::SequenceAsHashMap OStorage_Impl::GetCommonRootEncryptionData()
1365 throw ( packages::NoEncryptionException )
1367 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
1369 if ( m_nStorageType != embed::StorageFormats::PACKAGE )
1370 throw packages::NoEncryptionException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1372 if ( m_bIsRoot )
1374 if ( !m_bHasCommonEncryptionData )
1375 throw packages::NoEncryptionException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1377 return m_aCommonEncryptionData;
1379 else
1381 if ( !m_pParent )
1382 throw packages::NoEncryptionException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1384 return m_pParent->GetCommonRootEncryptionData();
1388 //-----------------------------------------------
1389 SotElement_Impl* OStorage_Impl::FindElement( const OUString& rName )
1391 OSL_ENSURE( !rName.isEmpty(), "Name is empty!" );
1393 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1395 ReadContents();
1397 for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1398 pElementIter != m_aChildrenList.end(); ++pElementIter )
1400 if ( (*pElementIter)->m_aName == rName && !(*pElementIter)->m_bIsRemoved )
1401 return *pElementIter;
1404 return NULL;
1407 //-----------------------------------------------
1408 SotElement_Impl* OStorage_Impl::InsertStream( OUString aName, sal_Bool bEncr )
1410 OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
1411 if ( !m_xPackage.is() )
1412 throw embed::InvalidStorageException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1414 uno::Sequence< uno::Any > aSeq( 1 );
1415 aSeq[0] <<= sal_False;
1416 uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1417 uno::UNO_QUERY );
1419 OSL_ENSURE( xNewElement.is(), "Not possible to create a new stream!\n" );
1420 if ( !xNewElement.is() )
1421 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1423 uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xNewElement, uno::UNO_QUERY );
1424 if ( !xPackageSubStream.is() )
1425 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1427 OSL_ENSURE( m_nStorageType == embed::StorageFormats::PACKAGE || !bEncr, "Only package storage supports encryption!\n" );
1428 if ( m_nStorageType != embed::StorageFormats::PACKAGE && bEncr )
1429 throw packages::NoEncryptionException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1431 // the mode is not needed for storage stream internal implementation
1432 SotElement_Impl* pNewElement = InsertElement( aName, sal_False );
1433 pNewElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xContext, bEncr, m_nStorageType, sal_True );
1435 m_aChildrenList.push_back( pNewElement );
1436 m_bIsModified = sal_True;
1437 m_bBroadcastModified = sal_True;
1439 return pNewElement;
1442 //-----------------------------------------------
1443 SotElement_Impl* OStorage_Impl::InsertRawStream( OUString aName, const uno::Reference< io::XInputStream >& xInStream )
1445 // insert of raw stream means insert and commit
1446 OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
1447 if ( !m_xPackage.is() )
1448 throw embed::InvalidStorageException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1450 if ( m_nStorageType != embed::StorageFormats::PACKAGE )
1451 throw packages::NoEncryptionException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1453 uno::Reference< io::XSeekable > xSeek( xInStream, uno::UNO_QUERY );
1454 uno::Reference< io::XInputStream > xInStrToInsert = xSeek.is() ? xInStream :
1455 GetSeekableTempCopy( xInStream, GetComponentContext() );
1457 uno::Sequence< uno::Any > aSeq( 1 );
1458 aSeq[0] <<= sal_False;
1459 uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1460 uno::UNO_QUERY );
1462 OSL_ENSURE( xNewElement.is(), "Not possible to create a new stream!\n" );
1463 if ( !xNewElement.is() )
1464 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1466 uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xNewElement, uno::UNO_QUERY );
1467 if ( !xPackageSubStream.is() )
1468 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1470 xPackageSubStream->setRawStream( xInStrToInsert );
1472 // the mode is not needed for storage stream internal implementation
1473 SotElement_Impl* pNewElement = InsertElement( aName, sal_False );
1474 pNewElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xContext, sal_True, m_nStorageType, sal_False );
1475 // the stream is inserted and must be treated as a commited one
1476 pNewElement->m_pStream->SetToBeCommited();
1478 m_aChildrenList.push_back( pNewElement );
1479 m_bIsModified = sal_True;
1480 m_bBroadcastModified = sal_True;
1482 return pNewElement;
1485 //-----------------------------------------------
1486 OStorage_Impl* OStorage_Impl::CreateNewStorageImpl( sal_Int32 nStorageMode )
1488 OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
1489 if ( !m_xPackage.is() )
1490 throw embed::InvalidStorageException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1492 uno::Sequence< uno::Any > aSeq( 1 );
1493 aSeq[0] <<= sal_True;
1494 uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1495 uno::UNO_QUERY );
1497 OSL_ENSURE( xNewElement.is(), "Not possible to create a new storage!\n" );
1498 if ( !xNewElement.is() )
1499 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1501 uno::Reference< container::XNameContainer > xPackageSubFolder( xNewElement, uno::UNO_QUERY );
1502 if ( !xPackageSubFolder.is() )
1503 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1505 OStorage_Impl* pResult =
1506 new OStorage_Impl( this, nStorageMode, xPackageSubFolder, m_xPackage, m_xContext, m_nStorageType );
1507 pResult->m_bIsModified = sal_True;
1509 return pResult;
1512 //-----------------------------------------------
1513 SotElement_Impl* OStorage_Impl::InsertStorage( OUString aName, sal_Int32 nStorageMode )
1515 SotElement_Impl* pNewElement = InsertElement( aName, sal_True );
1517 pNewElement->m_pStorage = CreateNewStorageImpl( nStorageMode );
1519 m_aChildrenList.push_back( pNewElement );
1521 return pNewElement;
1524 //-----------------------------------------------
1525 SotElement_Impl* OStorage_Impl::InsertElement( OUString aName, sal_Bool bIsStorage )
1527 OSL_ENSURE( FindElement( aName ) == NULL, "Should not try to insert existing element" );
1529 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1531 SotElement_Impl* pDeletedElm = NULL;
1533 for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1534 pElementIter != m_aChildrenList.end(); ++pElementIter )
1536 if ( (*pElementIter)->m_aName == aName )
1538 OSL_ENSURE( (*pElementIter)->m_bIsRemoved, "Try to insert an element instead of existing one!\n" );
1539 if ( (*pElementIter)->m_bIsRemoved )
1541 OSL_ENSURE( !(*pElementIter)->m_bIsInserted, "Inserted elements must be deleted immediatelly!\n" );
1542 pDeletedElm = *pElementIter;
1543 break;
1548 if ( pDeletedElm )
1550 if ( pDeletedElm->m_bIsStorage )
1551 OpenSubStorage( pDeletedElm, embed::ElementModes::READWRITE );
1552 else
1553 OpenSubStream( pDeletedElm );
1555 m_aChildrenList.remove( pDeletedElm ); // correct usage of list ???
1556 m_aDeletedList.push_back( pDeletedElm );
1559 // create new element
1560 return new SotElement_Impl( aName, bIsStorage, sal_True );
1563 //-----------------------------------------------
1564 void OStorage_Impl::OpenSubStorage( SotElement_Impl* pElement, sal_Int32 nStorageMode )
1566 OSL_ENSURE( pElement, "pElement is not set!\n" );
1567 OSL_ENSURE( pElement->m_bIsStorage, "Storage flag is not set!\n" );
1569 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1571 if ( !pElement->m_pStorage )
1573 OSL_ENSURE( !pElement->m_bIsInserted, "Inserted element must be created already!\n" );
1575 uno::Reference< lang::XUnoTunnel > xTunnel;
1576 m_xPackageFolder->getByName( pElement->m_aOriginalName ) >>= xTunnel;
1577 if ( !xTunnel.is() )
1578 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1580 uno::Reference< container::XNameContainer > xPackageSubFolder( xTunnel, uno::UNO_QUERY );
1582 OSL_ENSURE( xPackageSubFolder.is(), "Can not get XNameContainer interface from folder!\n" );
1584 if ( !xPackageSubFolder.is() )
1585 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1587 pElement->m_pStorage = new OStorage_Impl( this, nStorageMode, xPackageSubFolder, m_xPackage, m_xContext, m_nStorageType );
1591 //-----------------------------------------------
1592 void OStorage_Impl::OpenSubStream( SotElement_Impl* pElement )
1594 OSL_ENSURE( pElement, "pElement is not set!\n" );
1595 OSL_ENSURE( !pElement->m_bIsStorage, "Storage flag is set!\n" );
1597 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1599 if ( !pElement->m_pStream )
1601 OSL_ENSURE( !pElement->m_bIsInserted, "Inserted element must be created already!\n" );
1603 uno::Reference< lang::XUnoTunnel > xTunnel;
1604 m_xPackageFolder->getByName( pElement->m_aOriginalName ) >>= xTunnel;
1605 if ( !xTunnel.is() )
1606 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1608 uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xTunnel, uno::UNO_QUERY );
1609 if ( !xPackageSubStream.is() )
1610 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1612 // the stream can never be inserted here, because inserted stream element holds the stream till commit or destruction
1613 pElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xContext, sal_False, m_nStorageType, sal_False, GetRelInfoStreamForName( pElement->m_aOriginalName ) );
1617 //-----------------------------------------------
1618 uno::Sequence< OUString > OStorage_Impl::GetElementNames()
1620 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1622 ReadContents();
1624 sal_uInt32 nSize = m_aChildrenList.size();
1625 uno::Sequence< OUString > aElementNames( nSize );
1627 sal_uInt32 nInd = 0;
1628 for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1629 pElementIter != m_aChildrenList.end(); ++pElementIter )
1631 if ( !(*pElementIter)->m_bIsRemoved )
1632 aElementNames[nInd++] = (*pElementIter)->m_aName;
1635 aElementNames.realloc( nInd );
1636 return aElementNames;
1639 //-----------------------------------------------
1640 void OStorage_Impl::RemoveElement( SotElement_Impl* pElement )
1642 OSL_ENSURE( pElement, "Element must be provided!" );
1644 if ( !pElement )
1645 return;
1647 if ( (pElement->m_pStorage && ( pElement->m_pStorage->m_pAntiImpl || !pElement->m_pStorage->m_aReadOnlyWrapList.empty() ))
1648 || (pElement->m_pStream && ( pElement->m_pStream->m_pAntiImpl || !pElement->m_pStream->m_aInputStreamsList.empty() )) )
1649 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: Access denied
1651 if ( pElement->m_bIsInserted )
1653 m_aChildrenList.remove( pElement );
1654 delete pElement; // ???
1656 else
1658 pElement->m_bIsRemoved = sal_True;
1659 ClearElement( pElement );
1662 // TODO/OFOPXML: the rel stream should be removed as well
1665 //-----------------------------------------------
1666 void OStorage_Impl::ClearElement( SotElement_Impl* pElement )
1668 if ( pElement->m_pStorage )
1670 delete pElement->m_pStorage;
1671 pElement->m_pStorage = NULL;
1674 if ( pElement->m_pStream )
1676 delete pElement->m_pStream;
1677 pElement->m_pStream = NULL;
1681 //-----------------------------------------------
1682 void OStorage_Impl::CloneStreamElement( const OUString& aStreamName,
1683 sal_Bool bEncryptionDataProvided,
1684 const ::comphelper::SequenceAsHashMap& aEncryptionData,
1685 uno::Reference< io::XStream >& xTargetStream )
1686 throw ( embed::InvalidStorageException,
1687 lang::IllegalArgumentException,
1688 packages::WrongPasswordException,
1689 io::IOException,
1690 embed::StorageWrappedTargetException,
1691 uno::RuntimeException )
1693 SotElement_Impl *pElement = FindElement( aStreamName );
1694 if ( !pElement )
1696 // element does not exist, throw exception
1697 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access_denied
1699 else if ( pElement->m_bIsStorage )
1700 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1702 if ( !pElement->m_pStream )
1703 OpenSubStream( pElement );
1705 if ( pElement->m_pStream && pElement->m_pStream->m_xPackageStream.is() )
1707 // the existence of m_pAntiImpl of the child is not interesting,
1708 // the copy will be created internally
1710 // usual copying is not applicable here, only last flushed version of the
1711 // child stream should be used for copiing. Probably the children m_xPackageStream
1712 // can be used as a base of a new stream, that would be copied to result
1713 // storage. The only problem is that some package streams can be accessed from outside
1714 // at the same time ( now solwed by wrappers that remember own position ).
1716 if ( bEncryptionDataProvided )
1717 pElement->m_pStream->GetCopyOfLastCommit( xTargetStream, aEncryptionData );
1718 else
1719 pElement->m_pStream->GetCopyOfLastCommit( xTargetStream );
1721 else
1722 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: general_error
1725 //-----------------------------------------------
1726 void OStorage_Impl::RemoveStreamRelInfo( const OUString& aOriginalName )
1728 // this method should be used only in OStorage_Impl::Commit() method
1729 // the aOriginalName can be empty, in this case the storage relation info should be removed
1731 if ( m_nStorageType == embed::StorageFormats::OFOPXML && m_xRelStorage.is() )
1733 OUString aRelStreamName = aOriginalName;
1734 aRelStreamName += ".rels";
1736 if ( m_xRelStorage->hasByName( aRelStreamName ) )
1737 m_xRelStorage->removeElement( aRelStreamName );
1741 //-----------------------------------------------
1742 void OStorage_Impl::CreateRelStorage()
1744 if ( m_nStorageType != embed::StorageFormats::OFOPXML )
1745 return;
1747 if ( !m_xRelStorage.is() )
1749 if ( !m_pRelStorElement )
1751 m_pRelStorElement = new SotElement_Impl( "_rels", sal_True, sal_True );
1752 m_pRelStorElement->m_pStorage = CreateNewStorageImpl( embed::ElementModes::WRITE );
1753 if ( m_pRelStorElement->m_pStorage )
1754 m_pRelStorElement->m_pStorage->m_pParent = NULL; // the relation storage is completely controlled by parent
1757 if ( !m_pRelStorElement->m_pStorage )
1758 OpenSubStorage( m_pRelStorElement, embed::ElementModes::WRITE );
1760 if ( !m_pRelStorElement->m_pStorage )
1761 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1763 OStorage* pResultStorage = new OStorage( m_pRelStorElement->m_pStorage, sal_False );
1764 m_xRelStorage = uno::Reference< embed::XStorage >( (embed::XStorage*) pResultStorage );
1768 //-----------------------------------------------
1769 void OStorage_Impl::CommitStreamRelInfo( SotElement_Impl* pStreamElement )
1771 // this method should be used only in OStorage_Impl::Commit() method
1773 // the stream element must be provided
1774 if ( !pStreamElement )
1775 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1777 if ( m_nStorageType == embed::StorageFormats::OFOPXML && pStreamElement->m_pStream )
1779 OSL_ENSURE( !pStreamElement->m_aName.isEmpty(), "The name must not be empty!\n" );
1781 if ( !m_xRelStorage.is() )
1783 // Create new rels storage, this is commit scenario so it must be possible
1784 CreateRelStorage();
1787 pStreamElement->m_pStream->CommitStreamRelInfo( m_xRelStorage, pStreamElement->m_aOriginalName, pStreamElement->m_aName );
1791 //-----------------------------------------------
1792 uno::Reference< io::XInputStream > OStorage_Impl::GetRelInfoStreamForName( const OUString& aName )
1794 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1796 ReadContents();
1797 if ( m_xRelStorage.is() )
1799 OUString aRelStreamName = aName;
1800 aRelStreamName += ".rels";
1801 if ( m_xRelStorage->hasByName( aRelStreamName ) )
1803 uno::Reference< io::XStream > xStream = m_xRelStorage->openStreamElement( aRelStreamName, embed::ElementModes::READ );
1804 if ( xStream.is() )
1805 return xStream->getInputStream();
1810 return uno::Reference< io::XInputStream >();
1813 //-----------------------------------------------
1814 void OStorage_Impl::CommitRelInfo( const uno::Reference< container::XNameContainer >& xNewPackageFolder )
1816 // this method should be used only in OStorage_Impl::Commit() method
1817 OUString aRelsStorName("_rels");
1819 if ( !xNewPackageFolder.is() )
1820 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1822 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1824 if ( m_nRelInfoStatus == RELINFO_BROKEN || m_nRelInfoStatus == RELINFO_CHANGED_BROKEN )
1825 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1827 if ( m_nRelInfoStatus == RELINFO_CHANGED
1828 || m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
1829 || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1831 if ( m_nRelInfoStatus == RELINFO_CHANGED )
1833 if ( m_aRelInfo.getLength() )
1835 CreateRelStorage();
1837 uno::Reference< io::XStream > xRelsStream =
1838 m_xRelStorage->openStreamElement( ".rels" ,
1839 embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
1841 uno::Reference< io::XOutputStream > xOutStream = xRelsStream->getOutputStream();
1842 if ( !xOutStream.is() )
1843 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1845 ::comphelper::OFOPXMLHelper::WriteRelationsInfoSequence( xOutStream, m_aRelInfo, m_xContext );
1847 // set the mediatype
1848 uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
1849 xPropSet->setPropertyValue(
1850 "MediaType",
1851 uno::makeAny( OUString( "application/vnd.openxmlformats-package.relationships+xml" ) ) );
1853 m_nRelInfoStatus = RELINFO_READ;
1855 else if ( m_xRelStorage.is() )
1856 RemoveStreamRelInfo( OUString() ); // remove own rel info
1858 else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
1859 || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1861 CreateRelStorage();
1863 uno::Reference< io::XStream > xRelsStream =
1864 m_xRelStorage->openStreamElement( ".rels",
1865 embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
1867 uno::Reference< io::XOutputStream > xOutputStream = xRelsStream->getOutputStream();
1868 if ( !xOutputStream.is() )
1869 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
1871 uno::Reference< io::XSeekable > xSeek( m_xNewRelInfoStream, uno::UNO_QUERY_THROW );
1872 xSeek->seek( 0 );
1873 ::comphelper::OStorageHelper::CopyInputToOutput( m_xNewRelInfoStream, xOutputStream );
1875 // set the mediatype
1876 uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
1877 xPropSet->setPropertyValue(
1878 "MediaType",
1879 uno::makeAny( OUString( "application/vnd.openxmlformats-package.relationships+xml" ) ) );
1881 m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
1882 if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1884 m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
1885 m_nRelInfoStatus = RELINFO_NO_INIT;
1887 else
1888 m_nRelInfoStatus = RELINFO_READ;
1892 if ( m_xRelStorage.is() )
1894 if ( m_xRelStorage->hasElements() )
1896 uno::Reference< embed::XTransactedObject > xTrans( m_xRelStorage, uno::UNO_QUERY_THROW );
1897 if ( xTrans.is() )
1898 xTrans->commit();
1901 if ( xNewPackageFolder.is() && xNewPackageFolder->hasByName( aRelsStorName ) )
1902 xNewPackageFolder->removeByName( aRelsStorName );
1904 if ( !m_xRelStorage->hasElements() )
1906 // the empty relations storage should not be created
1907 delete m_pRelStorElement;
1908 m_pRelStorElement = NULL;
1909 m_xRelStorage = uno::Reference< embed::XStorage >();
1911 else if ( m_pRelStorElement && m_pRelStorElement->m_pStorage && xNewPackageFolder.is() )
1912 m_pRelStorElement->m_pStorage->InsertIntoPackageFolder( aRelsStorName, xNewPackageFolder );
1917 //=====================================================
1918 // OStorage implementation
1919 //=====================================================
1921 //-----------------------------------------------
1922 OStorage::OStorage( uno::Reference< io::XInputStream > xInputStream,
1923 sal_Int32 nMode,
1924 uno::Sequence< beans::PropertyValue > xProperties,
1925 uno::Reference< uno::XComponentContext > xContext,
1926 sal_Int32 nStorageType )
1927 : m_pImpl( new OStorage_Impl( xInputStream, nMode, xProperties, xContext, nStorageType ) )
1929 m_pImpl->m_pAntiImpl = this;
1930 m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, sal_False );
1933 //-----------------------------------------------
1934 OStorage::OStorage( uno::Reference< io::XStream > xStream,
1935 sal_Int32 nMode,
1936 uno::Sequence< beans::PropertyValue > xProperties,
1937 uno::Reference< uno::XComponentContext > xContext,
1938 sal_Int32 nStorageType )
1939 : m_pImpl( new OStorage_Impl( xStream, nMode, xProperties, xContext, nStorageType ) )
1941 m_pImpl->m_pAntiImpl = this;
1942 m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, sal_False );
1945 //-----------------------------------------------
1946 OStorage::OStorage( OStorage_Impl* pImpl, sal_Bool bReadOnlyWrap )
1947 : m_pImpl( pImpl )
1949 // this call can be done only from OStorage_Impl implementation to create child storage
1950 OSL_ENSURE( m_pImpl && m_pImpl->m_rMutexRef.Is(), "The provided pointer & mutex MUST NOT be empty!\n" );
1952 m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, bReadOnlyWrap );
1954 OSL_ENSURE( ( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) == embed::ElementModes::WRITE ||
1955 m_pData->m_bReadOnlyWrap,
1956 "The wrapper can not allow writing in case implementation does not!\n" );
1958 if ( !bReadOnlyWrap )
1959 m_pImpl->m_pAntiImpl = this;
1962 //-----------------------------------------------
1963 OStorage::~OStorage()
1966 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
1967 if ( m_pImpl )
1969 m_refCount++; // to call dispose
1970 try {
1971 dispose();
1973 catch( const uno::RuntimeException& rRuntimeException )
1975 m_pImpl->AddLog( rRuntimeException.Message );
1976 m_pImpl->AddLog( OSL_LOG_PREFIX "Handled exception" );
1981 if ( m_pData )
1983 if ( m_pData->m_pSubElDispListener )
1985 m_pData->m_pSubElDispListener->release();
1986 m_pData->m_pSubElDispListener = NULL;
1989 if ( m_pData->m_pTypeCollection )
1991 delete m_pData->m_pTypeCollection;
1992 m_pData->m_pTypeCollection = NULL;
1995 delete m_pData;
1999 //-----------------------------------------------
2000 void SAL_CALL OStorage::InternalDispose( sal_Bool bNotifyImpl )
2002 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::InternalDispose" );
2004 if ( !m_pImpl )
2006 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
2007 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2010 // the source object is also a kind of locker for the current object
2011 // since the listeners could dispose the object while being notified
2012 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
2013 m_pData->m_aListenersContainer.disposeAndClear( aSource );
2015 if ( m_pData->m_bReadOnlyWrap )
2017 OSL_ENSURE( !m_pData->m_aOpenSubComponentsList.size() || m_pData->m_pSubElDispListener,
2018 "If any subelements are open the listener must exist!\n" );
2020 if ( m_pData->m_pSubElDispListener )
2022 m_pData->m_pSubElDispListener->OwnerIsDisposed();
2024 // iterate through m_pData->m_aOpenSubComponentsList
2025 // deregister m_pData->m_pSubElDispListener and dispose all of them
2026 if ( !m_pData->m_aOpenSubComponentsList.empty() )
2028 for ( WeakComponentList::iterator pCompIter = m_pData->m_aOpenSubComponentsList.begin();
2029 pCompIter != m_pData->m_aOpenSubComponentsList.end(); ++pCompIter )
2031 uno::Reference< lang::XComponent > xTmp = (*pCompIter);
2032 if ( xTmp.is() )
2034 xTmp->removeEventListener( uno::Reference< lang::XEventListener >(
2035 static_cast< lang::XEventListener* >( m_pData->m_pSubElDispListener ) ) );
2037 try {
2038 xTmp->dispose();
2039 } catch( const uno::Exception& rException )
2041 m_pImpl->AddLog( rException.Message );
2042 m_pImpl->AddLog( OSL_LOG_PREFIX "Quiet exception" );
2047 m_pData->m_aOpenSubComponentsList.clear();
2051 if ( bNotifyImpl )
2052 m_pImpl->RemoveReadOnlyWrap( *this );
2054 else
2056 m_pImpl->m_pAntiImpl = NULL;
2058 if ( bNotifyImpl )
2060 if ( m_pData->m_bIsRoot )
2061 delete m_pImpl;
2062 else
2064 // the noncommited changes for the storage must be removed
2065 m_pImpl->Revert();
2070 m_pImpl = NULL;
2073 //-----------------------------------------------
2074 void OStorage::ChildIsDisposed( const uno::Reference< uno::XInterface >& xChild )
2076 // this method can only be called by child disposing listener
2078 // this method must not contain any locking
2079 // the locking is done in the listener
2081 if ( !m_pData->m_aOpenSubComponentsList.empty() )
2083 for ( WeakComponentList::iterator pCompIter = m_pData->m_aOpenSubComponentsList.begin();
2084 pCompIter != m_pData->m_aOpenSubComponentsList.end(); )
2086 uno::Reference< lang::XComponent > xTmp = (*pCompIter);
2087 if ( !xTmp.is() || xTmp == xChild )
2089 WeakComponentList::iterator pIterToRemove = pCompIter;
2090 ++pCompIter;
2091 m_pData->m_aOpenSubComponentsList.erase( pIterToRemove );
2093 else
2094 ++pCompIter;
2099 //-----------------------------------------------
2100 void OStorage::BroadcastModifiedIfNecessary()
2102 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
2103 if ( !m_pImpl )
2105 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
2106 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2109 if ( !m_pImpl->m_bBroadcastModified )
2110 return;
2112 m_pImpl->m_bBroadcastModified = sal_False;
2114 OSL_ENSURE( !m_pData->m_bReadOnlyWrap, "The storage can not be modified at all!\n" );
2116 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
2118 ::cppu::OInterfaceContainerHelper* pContainer =
2119 m_pData->m_aListenersContainer.getContainer(
2120 ::getCppuType( ( const uno::Reference< util::XModifyListener >*) NULL ) );
2121 if ( pContainer )
2123 ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
2124 while ( pIterator.hasMoreElements( ) )
2126 ( ( util::XModifyListener* )pIterator.next( ) )->modified( aSource );
2131 //-----------------------------------------------
2132 void OStorage::BroadcastTransaction( sal_Int8 nMessage )
2134 1 - preCommit
2135 2 - commited
2136 3 - preRevert
2137 4 - reverted
2140 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
2141 if ( !m_pImpl )
2143 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
2144 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2147 OSL_ENSURE( !m_pData->m_bReadOnlyWrap, "The storage can not be modified at all!\n" );
2149 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
2151 ::cppu::OInterfaceContainerHelper* pContainer =
2152 m_pData->m_aListenersContainer.getContainer(
2153 ::getCppuType( ( const uno::Reference< embed::XTransactionListener >*) NULL ) );
2154 if ( pContainer )
2156 ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
2157 while ( pIterator.hasMoreElements( ) )
2159 OSL_ENSURE( nMessage >= 1 && nMessage <= 4, "Wrong internal notification code is used!\n" );
2161 switch( nMessage )
2163 case STOR_MESS_PRECOMMIT:
2164 ( ( embed::XTransactionListener* )pIterator.next( ) )->preCommit( aSource );
2165 break;
2166 case STOR_MESS_COMMITED:
2167 ( ( embed::XTransactionListener* )pIterator.next( ) )->commited( aSource );
2168 break;
2169 case STOR_MESS_PREREVERT:
2170 ( ( embed::XTransactionListener* )pIterator.next( ) )->preRevert( aSource );
2171 break;
2172 case STOR_MESS_REVERTED:
2173 ( ( embed::XTransactionListener* )pIterator.next( ) )->reverted( aSource );
2174 break;
2180 //-----------------------------------------------
2181 SotElement_Impl* OStorage::OpenStreamElement_Impl( const OUString& aStreamName, sal_Int32 nOpenMode, sal_Bool bEncr )
2183 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2185 OSL_ENSURE( !m_pData->m_bReadOnlyWrap || ( nOpenMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE,
2186 "An element can not be opened for writing in readonly storage!\n" );
2188 SotElement_Impl *pElement = m_pImpl->FindElement( aStreamName );
2189 if ( !pElement )
2191 // element does not exist, check if creation is allowed
2192 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
2193 || (( nOpenMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
2194 || ( nOpenMode & embed::ElementModes::NOCREATE ) == embed::ElementModes::NOCREATE )
2196 throw io::IOException("Element does not exist and cannot be "
2197 "created: \"" + aStreamName + "\"",
2198 uno::Reference< uno::XInterface >()); // TODO: access_denied
2201 // create a new StreamElement and insert it into the list
2202 pElement = m_pImpl->InsertStream( aStreamName, bEncr );
2204 else if ( pElement->m_bIsStorage )
2206 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2209 OSL_ENSURE( pElement, "In case element can not be created an exception must be thrown!" );
2211 if ( !pElement->m_pStream )
2212 m_pImpl->OpenSubStream( pElement );
2214 if ( !pElement->m_pStream )
2215 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2217 return pElement;
2220 //-----------------------------------------------
2221 void OStorage::MakeLinkToSubComponent_Impl( const uno::Reference< lang::XComponent >& xComponent )
2223 if ( !xComponent.is() )
2224 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2226 if ( !m_pData->m_pSubElDispListener )
2228 m_pData->m_pSubElDispListener = new OChildDispListener_Impl( *this );
2229 m_pData->m_pSubElDispListener->acquire();
2232 xComponent->addEventListener( uno::Reference< lang::XEventListener >(
2233 static_cast< ::cppu::OWeakObject* >( m_pData->m_pSubElDispListener ), uno::UNO_QUERY ) );
2235 m_pData->m_aOpenSubComponentsList.push_back( xComponent );
2238 //____________________________________________________________________________________________________
2239 // XInterface
2240 //____________________________________________________________________________________________________
2242 //-----------------------------------------------
2243 uno::Any SAL_CALL OStorage::queryInterface( const uno::Type& rType )
2244 throw( uno::RuntimeException )
2246 uno::Any aReturn;
2248 // common interfaces
2249 aReturn <<= ::cppu::queryInterface
2250 ( rType
2251 , static_cast<lang::XTypeProvider*> ( this )
2252 , static_cast<embed::XStorage*> ( this )
2253 , static_cast<embed::XStorage2*> ( this )
2254 , static_cast<embed::XTransactedObject*> ( this )
2255 , static_cast<embed::XTransactionBroadcaster*> ( this )
2256 , static_cast<util::XModifiable*> ( this )
2257 , static_cast<container::XNameAccess*> ( this )
2258 , static_cast<container::XElementAccess*> ( this )
2259 , static_cast<lang::XComponent*> ( this )
2260 , static_cast<beans::XPropertySet*> ( this )
2261 , static_cast<embed::XOptimizedStorage*> ( this ) );
2263 if ( aReturn.hasValue() == sal_True )
2264 return aReturn ;
2266 aReturn <<= ::cppu::queryInterface
2267 ( rType
2268 , static_cast<embed::XHierarchicalStorageAccess*> ( this )
2269 , static_cast<embed::XHierarchicalStorageAccess2*> ( this ) );
2271 if ( aReturn.hasValue() == sal_True )
2272 return aReturn ;
2274 if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
2276 if ( m_pData->m_bIsRoot )
2278 aReturn <<= ::cppu::queryInterface
2279 ( rType
2280 , static_cast<embed::XStorageRawAccess*> ( this )
2281 , static_cast<embed::XEncryptionProtectedSource*> ( this )
2282 , static_cast<embed::XEncryptionProtectedSource2*> ( this )
2283 , static_cast<embed::XEncryptionProtectedStorage*> ( this ) );
2285 else
2287 aReturn <<= ::cppu::queryInterface
2288 ( rType
2289 , static_cast<embed::XStorageRawAccess*> ( this ) );
2292 else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
2294 aReturn <<= ::cppu::queryInterface
2295 ( rType
2296 , static_cast<embed::XRelationshipAccess*> ( this ) );
2299 if ( aReturn.hasValue() == sal_True )
2300 return aReturn ;
2302 return OWeakObject::queryInterface( rType );
2305 //-----------------------------------------------
2306 void SAL_CALL OStorage::acquire() throw()
2308 OWeakObject::acquire();
2311 //-----------------------------------------------
2312 void SAL_CALL OStorage::release() throw()
2314 OWeakObject::release();
2317 //____________________________________________________________________________________________________
2318 // XTypeProvider
2319 //____________________________________________________________________________________________________
2321 //-----------------------------------------------
2322 uno::Sequence< uno::Type > SAL_CALL OStorage::getTypes()
2323 throw( uno::RuntimeException )
2325 if ( m_pData->m_pTypeCollection == NULL )
2327 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2329 if ( m_pData->m_pTypeCollection == NULL )
2331 if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
2333 if ( m_pData->m_bIsRoot )
2335 m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2336 ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2337 , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2338 , ::getCppuType( ( const uno::Reference< embed::XStorage2 >* )NULL )
2339 , ::getCppuType( ( const uno::Reference< embed::XStorageRawAccess >* )NULL )
2340 , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2341 , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2342 , ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2343 , ::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedStorage >* )NULL )
2344 , ::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedSource2 >* )NULL )
2345 , ::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedSource >* )NULL )
2346 , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2348 else
2350 m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2351 ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2352 , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2353 , ::getCppuType( ( const uno::Reference< embed::XStorage2 >* )NULL )
2354 , ::getCppuType( ( const uno::Reference< embed::XStorageRawAccess >* )NULL )
2355 , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2356 , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2357 , ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2358 , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2361 else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
2363 m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2364 ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2365 , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2366 , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2367 , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2368 , ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2369 , ::getCppuType( ( const uno::Reference< embed::XRelationshipAccess >* )NULL )
2370 , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2372 else
2374 m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2375 ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2376 , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2377 , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2378 , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2379 , ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2380 , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2385 return m_pData->m_pTypeCollection->getTypes() ;
2388 namespace { struct lcl_ImplId : public rtl::Static< ::cppu::OImplementationId, lcl_ImplId > {}; }
2390 //-----------------------------------------------
2391 uno::Sequence< sal_Int8 > SAL_CALL OStorage::getImplementationId()
2392 throw( uno::RuntimeException )
2394 ::cppu::OImplementationId &rID = lcl_ImplId::get();
2395 return rID.getImplementationId();
2398 //____________________________________________________________________________________________________
2399 // XStorage
2400 //____________________________________________________________________________________________________
2403 //-----------------------------------------------
2404 void SAL_CALL OStorage::copyToStorage( const uno::Reference< embed::XStorage >& xDest )
2405 throw ( embed::InvalidStorageException,
2406 io::IOException,
2407 lang::IllegalArgumentException,
2408 embed::StorageWrappedTargetException,
2409 uno::RuntimeException )
2411 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyToStorage" );
2413 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2415 if ( !m_pImpl )
2417 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
2418 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2421 if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject*> ( this ), uno::UNO_QUERY ) )
2422 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 );
2424 try {
2425 m_pImpl->CopyToStorage( xDest, sal_False );
2427 catch( const embed::InvalidStorageException& rInvalidStorageException )
2429 m_pImpl->AddLog( rInvalidStorageException.Message );
2430 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2431 throw;
2433 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2435 m_pImpl->AddLog( rIllegalArgumentException.Message );
2436 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2437 throw;
2439 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
2441 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
2442 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2443 throw;
2445 catch( const io::IOException& rIOException )
2447 m_pImpl->AddLog( rIOException.Message );
2448 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2449 throw;
2451 catch( const uno::RuntimeException& rRuntimeException )
2453 m_pImpl->AddLog( rRuntimeException.Message );
2454 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2455 throw;
2457 catch( const uno::Exception& rException )
2459 m_pImpl->AddLog( rException.Message );
2460 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2462 uno::Any aCaught( ::cppu::getCaughtException() );
2463 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't copy storage!",
2464 uno::Reference< io::XInputStream >(),
2465 aCaught );
2469 //-----------------------------------------------
2470 uno::Reference< io::XStream > SAL_CALL OStorage::openStreamElement(
2471 const OUString& aStreamName, sal_Int32 nOpenMode )
2472 throw ( embed::InvalidStorageException,
2473 lang::IllegalArgumentException,
2474 packages::WrongPasswordException,
2475 io::IOException,
2476 embed::StorageWrappedTargetException,
2477 uno::RuntimeException )
2479 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openStreamElement" );
2481 ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2483 if ( !m_pImpl )
2485 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
2486 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2489 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
2490 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2492 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aStreamName == "_rels" )
2493 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 ); // unacceptable element name
2495 if ( ( nOpenMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
2496 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access denied
2498 uno::Reference< io::XStream > xResult;
2501 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamName, nOpenMode, sal_False );
2502 OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
2504 xResult = pElement->m_pStream->GetStream( nOpenMode, sal_False );
2505 OSL_ENSURE( xResult.is(), "The method must throw exception instead of removing empty result!\n" );
2507 if ( m_pData->m_bReadOnlyWrap )
2509 // before the storage disposes the stream it must deregister itself as listener
2510 uno::Reference< lang::XComponent > xStreamComponent( xResult, uno::UNO_QUERY );
2511 if ( !xStreamComponent.is() )
2512 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2514 MakeLinkToSubComponent_Impl( xStreamComponent );
2517 catch( const embed::InvalidStorageException& rInvalidStorageException )
2519 m_pImpl->AddLog( rInvalidStorageException.Message );
2520 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2521 throw;
2523 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2525 m_pImpl->AddLog( rIllegalArgumentException.Message );
2526 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2527 throw;
2529 catch( const packages::WrongPasswordException& rWrongPasswordException )
2531 m_pImpl->AddLog( rWrongPasswordException.Message );
2532 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2533 throw;
2535 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
2537 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
2538 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2539 throw;
2541 catch( const io::IOException& rIOException )
2543 m_pImpl->AddLog( rIOException.Message );
2544 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2545 throw;
2547 catch( const uno::RuntimeException& rRuntimeException )
2549 m_pImpl->AddLog( rRuntimeException.Message );
2550 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2551 throw;
2553 catch( const uno::Exception& rException )
2555 m_pImpl->AddLog( rException.Message );
2556 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2558 uno::Any aCaught( ::cppu::getCaughtException() );
2559 throw embed::StorageWrappedTargetException(OSL_LOG_PREFIX "Can't open stream element!",
2560 uno::Reference< io::XInputStream >(),
2561 aCaught );
2564 aGuard.clear();
2566 BroadcastModifiedIfNecessary();
2568 return xResult;
2571 //-----------------------------------------------
2572 uno::Reference< io::XStream > SAL_CALL OStorage::openEncryptedStreamElement(
2573 const OUString& aStreamName, sal_Int32 nOpenMode, const OUString& aPass )
2574 throw ( embed::InvalidStorageException,
2575 lang::IllegalArgumentException,
2576 packages::NoEncryptionException,
2577 packages::WrongPasswordException,
2578 io::IOException,
2579 embed::StorageWrappedTargetException,
2580 uno::RuntimeException )
2582 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openEncryptedStreamElement" );
2584 return openEncryptedStream( aStreamName, nOpenMode, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass ) );
2587 //-----------------------------------------------
2588 uno::Reference< embed::XStorage > SAL_CALL OStorage::openStorageElement(
2589 const OUString& aStorName, sal_Int32 nStorageMode )
2590 throw ( embed::InvalidStorageException,
2591 lang::IllegalArgumentException,
2592 io::IOException,
2593 embed::StorageWrappedTargetException,
2594 uno::RuntimeException )
2596 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openStorageElement" );
2598 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2600 if ( !m_pImpl )
2602 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
2603 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2606 if ( aStorName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName, sal_False ) )
2607 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2609 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aStorName == "_rels" )
2610 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2612 if ( ( nStorageMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
2613 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access denied
2615 if ( ( nStorageMode & embed::ElementModes::TRUNCATE )
2616 && !( nStorageMode & embed::ElementModes::WRITE ) )
2617 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access denied
2619 // it's always possible to read written storage in this implementation
2620 nStorageMode |= embed::ElementModes::READ;
2622 uno::Reference< embed::XStorage > xResult;
2625 SotElement_Impl *pElement = m_pImpl->FindElement( aStorName );
2626 if ( !pElement )
2628 // element does not exist, check if creation is allowed
2629 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
2630 || (( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
2631 || ( nStorageMode & embed::ElementModes::NOCREATE ) == embed::ElementModes::NOCREATE )
2632 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access_denied
2634 // create a new StorageElement and insert it into the list
2635 pElement = m_pImpl->InsertStorage( aStorName, nStorageMode );
2637 else if ( !pElement->m_bIsStorage )
2639 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2641 else if ( pElement->m_pStorage )
2643 // storage has already been opened; it may be opened another time, if it the mode allows to do so
2644 if ( pElement->m_pStorage->m_pAntiImpl )
2646 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access_denied
2648 else if ( !pElement->m_pStorage->m_aReadOnlyWrapList.empty()
2649 && ( nStorageMode & embed::ElementModes::WRITE ) )
2651 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access_denied
2653 else
2655 // in case parent storage allows writing the readonly mode of the child storage is
2656 // virtual, that means that it is just enough to change the flag to let it be writable
2657 // and since there is no AntiImpl nobody should be notified about it
2658 pElement->m_pStorage->m_nStorageMode = nStorageMode | embed::ElementModes::READ;
2660 if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) )
2662 for ( SotElementList_Impl::iterator pElementIter = pElement->m_pStorage->m_aChildrenList.begin();
2663 pElementIter != pElement->m_pStorage->m_aChildrenList.end(); )
2665 SotElement_Impl* pElementToDel = (*pElementIter);
2666 ++pElementIter;
2668 m_pImpl->RemoveElement( pElementToDel );
2674 if ( !pElement->m_pStorage )
2675 m_pImpl->OpenSubStorage( pElement, nStorageMode );
2677 if ( !pElement->m_pStorage )
2678 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: general_error
2680 sal_Bool bReadOnlyWrap = ( ( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE );
2681 OStorage* pResultStorage = new OStorage( pElement->m_pStorage, bReadOnlyWrap );
2682 xResult = uno::Reference< embed::XStorage >( (embed::XStorage*) pResultStorage );
2684 if ( bReadOnlyWrap )
2686 // Before this call is done the object must be refcounted already
2687 pElement->m_pStorage->SetReadOnlyWrap( *pResultStorage );
2689 // before the storage disposes the stream it must deregister itself as listener
2690 uno::Reference< lang::XComponent > xStorageComponent( xResult, uno::UNO_QUERY );
2691 if ( !xStorageComponent.is() )
2692 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2694 MakeLinkToSubComponent_Impl( xStorageComponent );
2697 catch( const embed::InvalidStorageException& rInvalidStorageException )
2699 m_pImpl->AddLog( rInvalidStorageException.Message );
2700 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2701 throw;
2703 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2705 m_pImpl->AddLog( rIllegalArgumentException.Message );
2706 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2707 throw;
2709 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
2711 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
2712 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2713 throw;
2715 catch( const io::IOException& rIOException )
2717 m_pImpl->AddLog( rIOException.Message );
2718 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2719 throw;
2721 catch( const uno::RuntimeException& rRuntimeException )
2723 m_pImpl->AddLog( rRuntimeException.Message );
2724 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2725 throw;
2727 catch( const uno::Exception& rException )
2729 m_pImpl->AddLog( rException.Message );
2730 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2732 uno::Any aCaught( ::cppu::getCaughtException() );
2733 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't open storage!",
2734 uno::Reference< io::XInputStream >(),
2735 aCaught );
2738 return xResult;
2741 //-----------------------------------------------
2742 uno::Reference< io::XStream > SAL_CALL OStorage::cloneStreamElement( const OUString& aStreamName )
2743 throw ( embed::InvalidStorageException,
2744 lang::IllegalArgumentException,
2745 packages::WrongPasswordException,
2746 io::IOException,
2747 embed::StorageWrappedTargetException,
2748 uno::RuntimeException )
2750 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::cloneStreamElement" );
2752 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2754 if ( !m_pImpl )
2756 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
2757 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2760 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
2761 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2763 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aStreamName == "_rels" )
2764 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2768 uno::Reference< io::XStream > xResult;
2769 m_pImpl->CloneStreamElement( aStreamName, sal_False, ::comphelper::SequenceAsHashMap(), xResult );
2770 if ( !xResult.is() )
2771 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2772 return xResult;
2774 catch( const embed::InvalidStorageException& rInvalidStorageException )
2776 m_pImpl->AddLog( rInvalidStorageException.Message );
2777 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2778 throw;
2780 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2782 m_pImpl->AddLog( rIllegalArgumentException.Message );
2783 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2784 throw;
2786 catch( const packages::WrongPasswordException& rWrongPasswordException )
2788 m_pImpl->AddLog( rWrongPasswordException.Message );
2789 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2790 throw;
2792 catch( const io::IOException& rIOException )
2794 m_pImpl->AddLog( rIOException.Message );
2795 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2796 throw;
2798 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
2800 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
2801 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2802 throw;
2804 catch( const uno::RuntimeException& rRuntimeException )
2806 m_pImpl->AddLog( rRuntimeException.Message );
2807 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2808 throw;
2810 catch( const uno::Exception& rException )
2812 m_pImpl->AddLog( rException.Message );
2813 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2815 uno::Any aCaught( ::cppu::getCaughtException() );
2816 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't clone stream!",
2817 uno::Reference< io::XInputStream >(),
2818 aCaught );
2822 //-----------------------------------------------
2823 uno::Reference< io::XStream > SAL_CALL OStorage::cloneEncryptedStreamElement(
2824 const OUString& aStreamName,
2825 const OUString& aPass )
2826 throw ( embed::InvalidStorageException,
2827 lang::IllegalArgumentException,
2828 packages::NoEncryptionException,
2829 packages::WrongPasswordException,
2830 io::IOException,
2831 embed::StorageWrappedTargetException,
2832 uno::RuntimeException )
2834 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::cloneEncryptedStreamElement" );
2836 return cloneEncryptedStream( aStreamName, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass ) );
2839 //-----------------------------------------------
2840 void SAL_CALL OStorage::copyLastCommitTo(
2841 const uno::Reference< embed::XStorage >& xTargetStorage )
2842 throw ( embed::InvalidStorageException,
2843 lang::IllegalArgumentException,
2844 io::IOException,
2845 embed::StorageWrappedTargetException,
2846 uno::RuntimeException )
2848 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyLastCommitTo" );
2850 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2852 if ( !m_pImpl )
2854 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
2855 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2860 m_pImpl->CopyLastCommitTo( xTargetStorage );
2862 catch( const embed::InvalidStorageException& rInvalidStorageException )
2864 m_pImpl->AddLog( rInvalidStorageException.Message );
2865 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2866 throw;
2868 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2870 m_pImpl->AddLog( rIllegalArgumentException.Message );
2871 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2872 throw;
2874 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
2876 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
2877 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2878 throw;
2880 catch( const io::IOException& rIOException )
2882 m_pImpl->AddLog( rIOException.Message );
2883 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2884 throw;
2886 catch( const uno::RuntimeException& rRuntimeException )
2888 m_pImpl->AddLog( rRuntimeException.Message );
2889 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2890 throw;
2892 catch( const uno::Exception& rException )
2894 m_pImpl->AddLog( rException.Message );
2895 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2897 uno::Any aCaught( ::cppu::getCaughtException() );
2898 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't copy last commit version!",
2899 uno::Reference< io::XInputStream >(),
2900 aCaught );
2905 //-----------------------------------------------
2906 void SAL_CALL OStorage::copyStorageElementLastCommitTo(
2907 const OUString& aStorName,
2908 const uno::Reference< embed::XStorage >& xTargetStorage )
2909 throw ( embed::InvalidStorageException,
2910 lang::IllegalArgumentException,
2911 io::IOException,
2912 embed::StorageWrappedTargetException,
2913 uno::RuntimeException )
2915 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyStorageElementLastCommitTo" );
2917 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2919 if ( !m_pImpl )
2921 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!");
2922 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2925 if ( aStorName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName, sal_False ) )
2926 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2928 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aStorName == "_rels" )
2929 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2931 // it's always possible to read written storage in this implementation
2932 sal_Int32 nStorageMode = embed::ElementModes::READ;
2936 SotElement_Impl *pElement = m_pImpl->FindElement( aStorName );
2937 if ( !pElement )
2939 // element does not exist, throw exception
2940 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access_denied
2942 else if ( !pElement->m_bIsStorage )
2944 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
2947 if ( !pElement->m_pStorage )
2948 m_pImpl->OpenSubStorage( pElement, nStorageMode );
2950 uno::Reference< embed::XStorage > xResult;
2951 if ( pElement->m_pStorage )
2953 // the existence of m_pAntiImpl of the child is not interesting,
2954 // the copy will be created internally
2956 pElement->m_pStorage->CopyLastCommitTo( xTargetStorage );
2958 else
2959 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: general_error
2961 catch( const embed::InvalidStorageException& rInvalidStorageException )
2963 m_pImpl->AddLog( rInvalidStorageException.Message );
2964 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2965 throw;
2967 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
2969 m_pImpl->AddLog( rIllegalArgumentException.Message );
2970 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2971 throw;
2973 catch( const io::IOException& rIOException )
2975 m_pImpl->AddLog( rIOException.Message );
2976 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2977 throw;
2979 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
2981 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
2982 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2983 throw;
2985 catch( const uno::RuntimeException& rRuntimeException )
2987 m_pImpl->AddLog( rRuntimeException.Message );
2988 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2989 throw;
2991 catch( const uno::Exception& rException )
2993 m_pImpl->AddLog( rException.Message );
2994 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
2996 uno::Any aCaught( ::cppu::getCaughtException() );
2997 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't copy last commit element version!",
2998 uno::Reference< io::XInputStream >(),
2999 aCaught );
3003 //-----------------------------------------------
3004 sal_Bool SAL_CALL OStorage::isStreamElement( const OUString& aElementName )
3005 throw ( embed::InvalidStorageException,
3006 lang::IllegalArgumentException,
3007 container::NoSuchElementException,
3008 uno::RuntimeException )
3010 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3012 if ( !m_pImpl )
3014 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
3015 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3018 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
3019 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3021 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aElementName == "_rels" )
3022 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 ); // unacceptable name
3024 SotElement_Impl* pElement = NULL;
3028 pElement = m_pImpl->FindElement( aElementName );
3030 catch( const embed::InvalidStorageException& rInvalidStorageException )
3032 m_pImpl->AddLog( rInvalidStorageException.Message );
3033 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3034 throw;
3036 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3038 m_pImpl->AddLog( rIllegalArgumentException.Message );
3039 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3040 throw;
3042 catch( const container::NoSuchElementException& rNoSuchElementException )
3044 m_pImpl->AddLog( rNoSuchElementException.Message );
3045 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3046 throw;
3048 catch( const uno::RuntimeException& rRuntimeException )
3050 m_pImpl->AddLog( rRuntimeException.Message );
3051 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3052 throw;
3054 catch( const uno::Exception& rException )
3056 m_pImpl->AddLog( rException.Message );
3057 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3059 uno::Any aCaught( ::cppu::getCaughtException() );
3060 throw lang::WrappedTargetRuntimeException( OSL_LOG_PREFIX "Can't detect whether it is a stream!",
3061 uno::Reference< io::XInputStream >(),
3062 aCaught );
3065 if ( !pElement )
3066 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); //???
3068 return !pElement->m_bIsStorage;
3071 //-----------------------------------------------
3072 sal_Bool SAL_CALL OStorage::isStorageElement( const OUString& aElementName )
3073 throw ( embed::InvalidStorageException,
3074 lang::IllegalArgumentException,
3075 container::NoSuchElementException,
3076 uno::RuntimeException )
3078 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3080 if ( !m_pImpl )
3082 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
3083 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3086 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
3087 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3089 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aElementName == "_rels" )
3090 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 );
3092 SotElement_Impl* pElement = NULL;
3096 pElement = m_pImpl->FindElement( aElementName );
3098 catch( const embed::InvalidStorageException& rInvalidStorageException )
3100 m_pImpl->AddLog( rInvalidStorageException.Message );
3101 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3102 throw;
3104 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3106 m_pImpl->AddLog( rIllegalArgumentException.Message );
3107 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3108 throw;
3110 catch( const container::NoSuchElementException& rNoSuchElementException )
3112 m_pImpl->AddLog( rNoSuchElementException.Message );
3113 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3114 throw;
3116 catch( const uno::RuntimeException& rRuntimeException )
3118 m_pImpl->AddLog( rRuntimeException.Message );
3119 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3120 throw;
3122 catch( const uno::Exception& rException )
3124 m_pImpl->AddLog( rException.Message );
3125 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3127 uno::Any aCaught( ::cppu::getCaughtException() );
3128 throw lang::WrappedTargetRuntimeException( OSL_LOG_PREFIX "can't detect whether it is a storage",
3129 uno::Reference< io::XInputStream >(),
3130 aCaught );
3133 if ( !pElement )
3134 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); //???
3136 return pElement->m_bIsStorage;
3139 //-----------------------------------------------
3140 void SAL_CALL OStorage::removeElement( const OUString& aElementName )
3141 throw ( embed::InvalidStorageException,
3142 lang::IllegalArgumentException,
3143 container::NoSuchElementException,
3144 io::IOException,
3145 embed::StorageWrappedTargetException,
3146 uno::RuntimeException )
3148 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::removeElement" );
3150 ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3152 if ( !m_pImpl )
3154 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
3155 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3158 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
3159 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3161 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aElementName == "_rels" )
3162 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 ); // TODO: unacceptable name
3164 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3165 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access denied
3169 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3171 if ( !pElement )
3172 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); //???
3174 m_pImpl->RemoveElement( pElement );
3176 m_pImpl->m_bIsModified = sal_True;
3177 m_pImpl->m_bBroadcastModified = sal_True;
3179 catch( const embed::InvalidStorageException& rInvalidStorageException )
3181 m_pImpl->AddLog( rInvalidStorageException.Message );
3182 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3183 throw;
3185 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3187 m_pImpl->AddLog( rIllegalArgumentException.Message );
3188 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3189 throw;
3191 catch( const container::NoSuchElementException& rNoSuchElementException )
3193 m_pImpl->AddLog( rNoSuchElementException.Message );
3194 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3195 throw;
3197 catch( const io::IOException& rIOException )
3199 m_pImpl->AddLog( rIOException.Message );
3200 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3201 throw;
3203 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3205 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
3206 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3207 throw;
3209 catch( const uno::RuntimeException& rRuntimeException )
3211 m_pImpl->AddLog( rRuntimeException.Message );
3212 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3213 throw;
3215 catch( const uno::Exception& rException )
3217 m_pImpl->AddLog( rException.Message );
3218 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3220 uno::Any aCaught( ::cppu::getCaughtException() );
3221 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't remove element!",
3222 uno::Reference< io::XInputStream >(),
3223 aCaught );
3226 aGuard.clear();
3228 BroadcastModifiedIfNecessary();
3231 //-----------------------------------------------
3232 void SAL_CALL OStorage::renameElement( const OUString& aElementName, const OUString& aNewName )
3233 throw ( embed::InvalidStorageException,
3234 lang::IllegalArgumentException,
3235 container::NoSuchElementException,
3236 container::ElementExistException,
3237 io::IOException,
3238 embed::StorageWrappedTargetException,
3239 uno::RuntimeException )
3241 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::renameElement" );
3243 ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3245 if ( !m_pImpl )
3247 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
3248 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3251 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
3252 || aNewName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
3253 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3255 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && ( aElementName == "_rels" || aNewName == "_rels" ) )
3256 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 0 ); // TODO: unacceptable element name
3258 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3259 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access denied
3263 SotElement_Impl* pRefElement = m_pImpl->FindElement( aNewName );
3264 if ( pRefElement )
3265 throw container::ElementExistException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); //???
3267 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3268 if ( !pElement )
3269 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); //???
3271 pElement->m_aName = aNewName;
3273 m_pImpl->m_bIsModified = sal_True;
3274 m_pImpl->m_bBroadcastModified = sal_True;
3276 catch( const embed::InvalidStorageException& rInvalidStorageException )
3278 m_pImpl->AddLog( rInvalidStorageException.Message );
3279 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3280 throw;
3282 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3284 m_pImpl->AddLog( rIllegalArgumentException.Message );
3285 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3286 throw;
3288 catch( const container::NoSuchElementException& rNoSuchElementException )
3290 m_pImpl->AddLog( rNoSuchElementException.Message );
3291 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3292 throw;
3294 catch( const container::ElementExistException& rElementExistException )
3296 m_pImpl->AddLog( rElementExistException.Message );
3297 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3298 throw;
3300 catch( const io::IOException& rIOException )
3302 m_pImpl->AddLog( rIOException.Message );
3303 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3304 throw;
3306 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3308 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
3309 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3310 throw;
3312 catch( const uno::RuntimeException& rRuntimeException )
3314 m_pImpl->AddLog( rRuntimeException.Message );
3315 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3316 throw;
3318 catch( const uno::Exception& rException )
3320 m_pImpl->AddLog( rException.Message );
3321 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3323 uno::Any aCaught( ::cppu::getCaughtException() );
3324 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't rename element!",
3325 uno::Reference< io::XInputStream >(),
3326 aCaught );
3329 aGuard.clear();
3331 BroadcastModifiedIfNecessary();
3334 //-----------------------------------------------
3335 void SAL_CALL OStorage::copyElementTo( const OUString& aElementName,
3336 const uno::Reference< embed::XStorage >& xDest,
3337 const OUString& aNewName )
3338 throw ( embed::InvalidStorageException,
3339 lang::IllegalArgumentException,
3340 container::NoSuchElementException,
3341 container::ElementExistException,
3342 io::IOException,
3343 embed::StorageWrappedTargetException,
3344 uno::RuntimeException )
3346 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyElementTo" );
3348 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3350 if ( !m_pImpl )
3352 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
3353 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3356 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
3357 || aNewName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
3358 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3360 if ( !xDest.is() )
3361 // || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
3362 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 2 );
3364 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && ( aElementName == "_rels" || aNewName == "_rels" ) )
3365 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 0 ); // unacceptable element name
3369 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3370 if ( !pElement )
3371 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3373 uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
3374 if ( !xNameAccess.is() )
3375 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3377 if ( xNameAccess->hasByName( aNewName ) )
3378 throw container::ElementExistException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3380 m_pImpl->CopyStorageElement( pElement, xDest, aNewName, sal_False );
3382 catch( const embed::InvalidStorageException& rInvalidStorageException )
3384 m_pImpl->AddLog( rInvalidStorageException.Message );
3385 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3386 throw;
3388 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3390 m_pImpl->AddLog( rIllegalArgumentException.Message );
3391 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3392 throw;
3394 catch( const container::NoSuchElementException& rNoSuchElementException )
3396 m_pImpl->AddLog( rNoSuchElementException.Message );
3397 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3398 throw;
3400 catch( const container::ElementExistException& rElementExistException )
3402 m_pImpl->AddLog( rElementExistException.Message );
3403 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3404 throw;
3406 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3408 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
3409 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3410 throw;
3412 catch( const io::IOException& rIOException )
3414 m_pImpl->AddLog( rIOException.Message );
3415 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3416 throw;
3418 catch( const uno::RuntimeException& rRuntimeException )
3420 m_pImpl->AddLog( rRuntimeException.Message );
3421 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3422 throw;
3424 catch( const uno::Exception& rException )
3426 m_pImpl->AddLog( rException.Message );
3427 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3429 uno::Any aCaught( ::cppu::getCaughtException() );
3430 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't copy element!",
3431 uno::Reference< io::XInputStream >(),
3432 aCaught );
3437 //-----------------------------------------------
3438 void SAL_CALL OStorage::moveElementTo( const OUString& aElementName,
3439 const uno::Reference< embed::XStorage >& xDest,
3440 const OUString& aNewName )
3441 throw ( embed::InvalidStorageException,
3442 lang::IllegalArgumentException,
3443 container::NoSuchElementException,
3444 container::ElementExistException,
3445 io::IOException,
3446 embed::StorageWrappedTargetException,
3447 uno::RuntimeException )
3449 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::moveElementTo" );
3451 ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3453 if ( !m_pImpl )
3455 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
3456 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3459 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
3460 || aNewName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
3461 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3463 if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
3464 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 2 );
3466 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && ( aElementName == "_rels" || aNewName == "_rels" ) )
3467 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 0 ); // unacceptable element name
3469 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3470 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access denied
3474 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3475 if ( !pElement )
3476 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); //???
3478 uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
3479 if ( !xNameAccess.is() )
3480 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3482 if ( xNameAccess->hasByName( aNewName ) )
3483 throw container::ElementExistException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3485 m_pImpl->CopyStorageElement( pElement, xDest, aNewName, sal_False );
3487 m_pImpl->RemoveElement( pElement );
3489 m_pImpl->m_bIsModified = sal_True;
3490 m_pImpl->m_bBroadcastModified = sal_True;
3492 catch( const embed::InvalidStorageException& rInvalidStorageException )
3494 m_pImpl->AddLog( rInvalidStorageException.Message );
3495 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3496 throw;
3498 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3500 m_pImpl->AddLog( rIllegalArgumentException.Message );
3501 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3502 throw;
3504 catch( const container::NoSuchElementException& rNoSuchElementException )
3506 m_pImpl->AddLog( rNoSuchElementException.Message );
3507 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3508 throw;
3510 catch( const container::ElementExistException& rElementExistException )
3512 m_pImpl->AddLog( rElementExistException.Message );
3513 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3514 throw;
3516 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3518 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
3519 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3520 throw;
3522 catch( const io::IOException& rIOException )
3524 m_pImpl->AddLog( rIOException.Message );
3525 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3526 throw;
3528 catch( const uno::RuntimeException& rRuntimeException )
3530 m_pImpl->AddLog( rRuntimeException.Message );
3531 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3532 throw;
3534 catch( const uno::Exception& rException )
3536 m_pImpl->AddLog( rException.Message );
3537 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3539 uno::Any aCaught( ::cppu::getCaughtException() );
3540 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't move element!",
3541 uno::Reference< io::XInputStream >(),
3542 aCaught );
3545 aGuard.clear();
3547 BroadcastModifiedIfNecessary();
3550 //____________________________________________________________________________________________________
3551 // XStorage2
3552 //____________________________________________________________________________________________________
3554 //-----------------------------------------------
3555 uno::Reference< io::XStream > SAL_CALL OStorage::openEncryptedStream(
3556 const OUString& aStreamName, sal_Int32 nOpenMode, const uno::Sequence< beans::NamedValue >& aEncryptionData )
3557 throw ( embed::InvalidStorageException,
3558 lang::IllegalArgumentException,
3559 packages::NoEncryptionException,
3560 packages::WrongPasswordException,
3561 io::IOException,
3562 embed::StorageWrappedTargetException,
3563 uno::RuntimeException )
3565 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openEncryptedStream" );
3567 ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3569 if ( !m_pImpl )
3571 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
3572 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3575 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
3576 packages::NoEncryptionException();
3578 if ( ( nOpenMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
3579 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access denied
3581 if ( !aEncryptionData.getLength() )
3582 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 3 );
3584 uno::Reference< io::XStream > xResult;
3587 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamName, nOpenMode, sal_True );
3588 OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
3590 xResult = pElement->m_pStream->GetStream( nOpenMode, aEncryptionData, sal_False );
3591 OSL_ENSURE( xResult.is(), "The method must throw exception instead of removing empty result!\n" );
3593 if ( m_pData->m_bReadOnlyWrap )
3595 // before the storage disposes the stream it must deregister itself as listener
3596 uno::Reference< lang::XComponent > xStreamComponent( xResult, uno::UNO_QUERY );
3597 if ( !xStreamComponent.is() )
3598 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3600 MakeLinkToSubComponent_Impl( xStreamComponent );
3603 catch( const embed::InvalidStorageException& rInvalidStorageException )
3605 m_pImpl->AddLog( rInvalidStorageException.Message );
3606 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3607 throw;
3609 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3611 m_pImpl->AddLog( rIllegalArgumentException.Message );
3612 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3613 throw;
3615 catch( const packages::NoEncryptionException& rNoEncryptionException )
3617 m_pImpl->AddLog( rNoEncryptionException.Message );
3618 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3619 throw;
3621 catch( const packages::WrongPasswordException& rWrongPasswordException )
3623 m_pImpl->AddLog( rWrongPasswordException.Message );
3624 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3625 throw;
3627 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3629 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
3630 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3631 throw;
3633 catch( const io::IOException& rIOException )
3635 m_pImpl->AddLog( rIOException.Message );
3636 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3637 throw;
3639 catch( const uno::RuntimeException& rRuntimeException )
3641 m_pImpl->AddLog( rRuntimeException.Message );
3642 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3643 throw;
3645 catch( const uno::Exception& rException )
3647 m_pImpl->AddLog( rException.Message );
3648 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3650 uno::Any aCaught( ::cppu::getCaughtException() );
3651 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't open encrypted stream stream!",
3652 uno::Reference< io::XInputStream >(),
3653 aCaught );
3656 aGuard.clear();
3658 BroadcastModifiedIfNecessary();
3660 return xResult;
3663 //-----------------------------------------------
3664 uno::Reference< io::XStream > SAL_CALL OStorage::cloneEncryptedStream(
3665 const OUString& aStreamName,
3666 const uno::Sequence< beans::NamedValue >& aEncryptionData )
3667 throw ( embed::InvalidStorageException,
3668 lang::IllegalArgumentException,
3669 packages::NoEncryptionException,
3670 packages::WrongPasswordException,
3671 io::IOException,
3672 embed::StorageWrappedTargetException,
3673 uno::RuntimeException )
3675 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::cloneEncryptedStream" );
3677 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3679 if ( !m_pImpl )
3681 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
3682 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3685 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
3686 packages::NoEncryptionException();
3688 if ( !aEncryptionData.getLength() )
3689 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 2 );
3693 uno::Reference< io::XStream > xResult;
3694 m_pImpl->CloneStreamElement( aStreamName, sal_True, aEncryptionData, xResult );
3695 if ( !xResult.is() )
3696 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3697 return xResult;
3699 catch( const embed::InvalidStorageException& rInvalidStorageException )
3701 m_pImpl->AddLog( rInvalidStorageException.Message );
3702 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3703 throw;
3705 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3707 m_pImpl->AddLog( rIllegalArgumentException.Message );
3708 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3709 throw;
3711 catch( const packages::NoEncryptionException& rNoEncryptionException )
3713 m_pImpl->AddLog( rNoEncryptionException.Message );
3714 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3715 throw;
3717 catch( const packages::WrongPasswordException& rWrongPasswordException )
3719 m_pImpl->AddLog( rWrongPasswordException.Message );
3720 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3721 throw;
3723 catch( const io::IOException& rIOException )
3725 m_pImpl->AddLog( rIOException.Message );
3726 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3727 throw;
3729 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3731 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
3732 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3733 throw;
3735 catch( const uno::RuntimeException& rRuntimeException )
3737 m_pImpl->AddLog( rRuntimeException.Message );
3738 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3739 throw;
3741 catch( const uno::Exception& rException )
3743 m_pImpl->AddLog( rException.Message );
3744 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3746 uno::Any aCaught( ::cppu::getCaughtException() );
3747 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't clone encrypted stream!",
3748 uno::Reference< io::XInputStream >(),
3749 aCaught );
3754 //____________________________________________________________________________________________________
3755 // XStorageRawAccess
3756 //____________________________________________________________________________________________________
3758 //-----------------------------------------------
3759 uno::Reference< io::XInputStream > SAL_CALL OStorage::getPlainRawStreamElement(
3760 const OUString& sStreamName )
3761 throw ( embed::InvalidStorageException,
3762 lang::IllegalArgumentException,
3763 container::NoSuchElementException,
3764 io::IOException,
3765 embed::StorageWrappedTargetException,
3766 uno::RuntimeException )
3768 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getPlainRawStreamElement" );
3770 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3772 if ( !m_pImpl )
3774 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
3775 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3778 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
3779 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // the interface is not supported and must not be accessible
3781 if ( sStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName, sal_False ) )
3782 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3784 uno::Reference < io::XInputStream > xTempIn;
3787 SotElement_Impl* pElement = m_pImpl->FindElement( sStreamName );
3788 if ( !pElement )
3789 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3791 if ( !pElement->m_pStream )
3793 m_pImpl->OpenSubStream( pElement );
3794 if ( !pElement->m_pStream )
3795 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3798 uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetPlainRawInStream();
3799 if ( !xRawInStream.is() )
3800 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3802 uno::Reference < io::XTempFile > xTempFile = io::TempFile::create( m_pImpl->GetComponentContext() );
3803 uno::Reference < io::XOutputStream > xTempOut = xTempFile->getOutputStream();
3804 xTempIn = xTempFile->getInputStream();
3805 uno::Reference < io::XSeekable > xSeek( xTempOut, uno::UNO_QUERY );
3807 if ( !xTempOut.is() || !xTempIn.is() || !xSeek.is() )
3808 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3810 // Copy temporary file to a new one
3811 ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
3812 xTempOut->closeOutput();
3813 xSeek->seek( 0 );
3815 catch( const embed::InvalidStorageException& rInvalidStorageException )
3817 m_pImpl->AddLog( rInvalidStorageException.Message );
3818 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3819 throw;
3821 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3823 m_pImpl->AddLog( rIllegalArgumentException.Message );
3824 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3825 throw;
3827 catch( const container::NoSuchElementException& rNoSuchElementException )
3829 m_pImpl->AddLog( rNoSuchElementException.Message );
3830 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3831 throw;
3833 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3835 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
3836 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3837 throw;
3839 catch( const io::IOException& rIOException )
3841 m_pImpl->AddLog( rIOException.Message );
3842 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3843 throw;
3845 catch( const uno::RuntimeException& rRuntimeException )
3847 m_pImpl->AddLog( rRuntimeException.Message );
3848 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3849 throw;
3851 catch( const uno::Exception& rException )
3853 m_pImpl->AddLog( rException.Message );
3854 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3856 uno::Any aCaught( ::cppu::getCaughtException() );
3857 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't get plain raw stream!",
3858 uno::Reference< io::XInputStream >(),
3859 aCaught );
3862 return xTempIn;
3865 //-----------------------------------------------
3866 uno::Reference< io::XInputStream > SAL_CALL OStorage::getRawEncrStreamElement(
3867 const OUString& sStreamName )
3868 throw ( embed::InvalidStorageException,
3869 lang::IllegalArgumentException,
3870 packages::NoEncryptionException,
3871 container::NoSuchElementException,
3872 io::IOException,
3873 embed::StorageWrappedTargetException,
3874 uno::RuntimeException )
3876 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getRawEncrStreamElement" );
3878 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3880 if ( !m_pImpl )
3882 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
3883 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3886 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
3887 throw packages::NoEncryptionException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3889 if ( sStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName, sal_False ) )
3890 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3892 uno::Reference < io::XInputStream > xTempIn;
3895 SotElement_Impl* pElement = m_pImpl->FindElement( sStreamName );
3896 if ( !pElement )
3897 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3899 if ( !pElement->m_pStream )
3901 m_pImpl->OpenSubStream( pElement );
3902 if ( !pElement->m_pStream )
3903 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3906 if ( !pElement->m_pStream->IsEncrypted() )
3907 throw packages::NoEncryptionException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3909 uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetRawInStream();
3910 if ( !xRawInStream.is() )
3911 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3913 uno::Reference < io::XTempFile > xTempFile = io::TempFile::create(m_pImpl->GetComponentContext());
3914 uno::Reference < io::XOutputStream > xTempOut = xTempFile->getOutputStream();
3915 xTempIn = xTempFile->getInputStream();
3916 uno::Reference < io::XSeekable > xSeek( xTempOut, uno::UNO_QUERY );
3918 if ( !xTempOut.is() || !xTempIn.is() || !xSeek.is() )
3919 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
3921 // Copy temporary file to a new one
3922 ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
3923 xTempOut->closeOutput();
3924 xSeek->seek( 0 );
3927 catch( const embed::InvalidStorageException& rInvalidStorageException )
3929 m_pImpl->AddLog( rInvalidStorageException.Message );
3930 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3931 throw;
3933 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
3935 m_pImpl->AddLog( rIllegalArgumentException.Message );
3936 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3937 throw;
3939 catch( const packages::NoEncryptionException& rNoEncryptionException )
3941 m_pImpl->AddLog( rNoEncryptionException.Message );
3942 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3943 throw;
3945 catch( const container::NoSuchElementException& rNoSuchElementException )
3947 m_pImpl->AddLog( rNoSuchElementException.Message );
3948 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3949 throw;
3951 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
3953 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
3954 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3955 throw;
3957 catch( const io::IOException& rIOException )
3959 m_pImpl->AddLog( rIOException.Message );
3960 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3961 throw;
3963 catch( const uno::RuntimeException& rRuntimeException )
3965 m_pImpl->AddLog( rRuntimeException.Message );
3966 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3967 throw;
3969 catch( const uno::Exception& rException )
3971 m_pImpl->AddLog( rException.Message );
3972 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
3974 uno::Any aCaught( ::cppu::getCaughtException() );
3975 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't get raw stream!",
3976 uno::Reference< io::XInputStream >(),
3977 aCaught );
3980 return xTempIn;
3983 //-----------------------------------------------
3984 void SAL_CALL OStorage::insertRawEncrStreamElement( const OUString& aStreamName,
3985 const uno::Reference< io::XInputStream >& xInStream )
3986 throw ( embed::InvalidStorageException,
3987 lang::IllegalArgumentException,
3988 packages::NoRawFormatException,
3989 container::ElementExistException,
3990 io::IOException,
3991 embed::StorageWrappedTargetException,
3992 uno::RuntimeException)
3994 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::insertRawEncrStreamElement" );
3996 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3998 if ( !m_pImpl )
4000 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4001 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4004 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4005 throw packages::NoEncryptionException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4007 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
4008 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
4010 if ( !xInStream.is() )
4011 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 2 );
4013 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
4014 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access denied
4018 SotElement_Impl* pElement = m_pImpl->FindElement( aStreamName );
4019 if ( pElement )
4020 throw container::ElementExistException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4022 m_pImpl->InsertRawStream( aStreamName, xInStream );
4024 catch( const embed::InvalidStorageException& rInvalidStorageException )
4026 m_pImpl->AddLog( rInvalidStorageException.Message );
4027 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4028 throw;
4030 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
4032 m_pImpl->AddLog( rIllegalArgumentException.Message );
4033 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4034 throw;
4036 catch( const packages::NoRawFormatException& rNoRawFormatException )
4038 m_pImpl->AddLog( rNoRawFormatException.Message );
4039 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4040 throw;
4042 catch( const container::ElementExistException& rElementExistException )
4044 m_pImpl->AddLog( rElementExistException.Message );
4045 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4046 throw;
4048 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
4050 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
4051 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4052 throw;
4054 catch( const io::IOException& rIOException )
4056 m_pImpl->AddLog( rIOException.Message );
4057 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4058 throw;
4060 catch( const uno::RuntimeException& rRuntimeException )
4062 m_pImpl->AddLog( rRuntimeException.Message );
4063 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4064 throw;
4066 catch( const uno::Exception& rException )
4068 m_pImpl->AddLog( rException.Message );
4069 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4071 uno::Any aCaught( ::cppu::getCaughtException() );
4072 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't insert raw stream!",
4073 uno::Reference< io::XInputStream >(),
4074 aCaught );
4078 //____________________________________________________________________________________________________
4079 // XTransactedObject
4080 //____________________________________________________________________________________________________
4082 //-----------------------------------------------
4083 void SAL_CALL OStorage::commit()
4084 throw ( io::IOException,
4085 embed::StorageWrappedTargetException,
4086 uno::RuntimeException )
4088 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::commit" );
4090 uno::Reference< util::XModifiable > xParentModif;
4092 try {
4093 BroadcastTransaction( STOR_MESS_PRECOMMIT );
4095 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4097 if ( !m_pImpl )
4099 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4100 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4103 if ( m_pData->m_bReadOnlyWrap )
4104 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access_denied
4106 m_pImpl->Commit(); // the root storage initiates the storing to source
4108 // when the storage is commited the parent is modified
4109 if ( m_pImpl->m_pParent && m_pImpl->m_pParent->m_pAntiImpl )
4110 xParentModif = (util::XModifiable*)m_pImpl->m_pParent->m_pAntiImpl;
4112 catch( const io::IOException& rIOException )
4114 m_pImpl->AddLog( rIOException.Message );
4115 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4116 throw;
4118 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
4120 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
4121 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4122 throw;
4124 catch( const uno::RuntimeException& rRuntimeException )
4126 m_pImpl->AddLog( rRuntimeException.Message );
4127 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4128 throw;
4130 catch( const uno::Exception& rException )
4132 m_pImpl->AddLog( rException.Message );
4133 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4135 uno::Any aCaught( ::cppu::getCaughtException() );
4136 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Problems on commit!",
4137 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ),
4138 aCaught );
4141 setModified( sal_False );
4142 if ( xParentModif.is() )
4143 xParentModif->setModified( sal_True );
4145 BroadcastTransaction( STOR_MESS_COMMITED );
4148 //-----------------------------------------------
4149 void SAL_CALL OStorage::revert()
4150 throw ( io::IOException,
4151 embed::StorageWrappedTargetException,
4152 uno::RuntimeException )
4154 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::revert" );
4156 // the method removes all the changes done after last commit
4158 BroadcastTransaction( STOR_MESS_PREREVERT );
4160 ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4162 if ( !m_pImpl )
4164 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4165 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4168 for ( SotElementList_Impl::iterator pElementIter = m_pImpl->m_aChildrenList.begin();
4169 pElementIter != m_pImpl->m_aChildrenList.end(); ++pElementIter )
4171 if ( ((*pElementIter)->m_pStorage
4172 && ( (*pElementIter)->m_pStorage->m_pAntiImpl || !(*pElementIter)->m_pStorage->m_aReadOnlyWrapList.empty() ))
4173 || ((*pElementIter)->m_pStream
4174 && ( (*pElementIter)->m_pStream->m_pAntiImpl || !(*pElementIter)->m_pStream->m_aInputStreamsList.empty()) ) )
4175 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access denied
4178 if ( m_pData->m_bReadOnlyWrap || !m_pImpl->m_bListCreated )
4179 return; // nothing to do
4181 try {
4182 m_pImpl->Revert();
4183 m_pImpl->m_bIsModified = sal_False;
4184 m_pImpl->m_bBroadcastModified = sal_True;
4186 catch( const io::IOException& rIOException )
4188 m_pImpl->AddLog( rIOException.Message );
4189 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4190 throw;
4192 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
4194 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
4195 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4196 throw;
4198 catch( const uno::RuntimeException& rRuntimeException )
4200 m_pImpl->AddLog( rRuntimeException.Message );
4201 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4202 throw;
4204 catch( const uno::Exception& rException )
4206 m_pImpl->AddLog( rException.Message );
4207 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4209 uno::Any aCaught( ::cppu::getCaughtException() );
4210 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Problems on revert!",
4211 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ),
4212 aCaught );
4215 aGuard.clear();
4217 setModified( sal_False );
4218 BroadcastTransaction( STOR_MESS_REVERTED );
4221 //____________________________________________________________________________________________________
4222 // XTransactionBroadcaster
4223 //____________________________________________________________________________________________________
4225 //-----------------------------------------------
4226 void SAL_CALL OStorage::addTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
4227 throw ( uno::RuntimeException )
4229 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4231 if ( !m_pImpl )
4233 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4234 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4237 m_pData->m_aListenersContainer.addInterface( ::getCppuType((const uno::Reference< embed::XTransactionListener >*)0),
4238 aListener );
4241 //-----------------------------------------------
4242 void SAL_CALL OStorage::removeTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
4243 throw ( uno::RuntimeException )
4245 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4247 if ( !m_pImpl )
4249 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4250 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4253 m_pData->m_aListenersContainer.removeInterface( ::getCppuType((const uno::Reference< embed::XTransactionListener >*)0),
4254 aListener );
4257 //____________________________________________________________________________________________________
4258 // XModifiable
4259 // TODO: if there will be no demand on this interface it will be removed from implementation,
4260 // I do not want to remove it now since it is still possible that it will be inserted
4261 // to the service back.
4262 //____________________________________________________________________________________________________
4264 //-----------------------------------------------
4265 sal_Bool SAL_CALL OStorage::isModified()
4266 throw ( uno::RuntimeException )
4268 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4270 if ( !m_pImpl )
4272 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4273 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4276 return m_pImpl->m_bIsModified;
4280 //-----------------------------------------------
4281 void SAL_CALL OStorage::setModified( sal_Bool bModified )
4282 throw ( beans::PropertyVetoException,
4283 uno::RuntimeException )
4285 ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4287 if ( !m_pImpl )
4289 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4290 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4293 if ( m_pData->m_bReadOnlyWrap )
4294 throw beans::PropertyVetoException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access denied
4296 if ( m_pImpl->m_bIsModified != bModified )
4297 m_pImpl->m_bIsModified = bModified;
4299 aGuard.clear();
4300 if ( bModified )
4302 m_pImpl->m_bBroadcastModified = sal_True;
4303 BroadcastModifiedIfNecessary();
4307 //-----------------------------------------------
4308 void SAL_CALL OStorage::addModifyListener(
4309 const uno::Reference< util::XModifyListener >& aListener )
4310 throw ( uno::RuntimeException )
4312 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4314 if ( !m_pImpl )
4316 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4317 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4320 m_pData->m_aListenersContainer.addInterface(
4321 ::getCppuType( ( const uno::Reference< util::XModifyListener >* )0 ), aListener );
4325 //-----------------------------------------------
4326 void SAL_CALL OStorage::removeModifyListener(
4327 const uno::Reference< util::XModifyListener >& aListener )
4328 throw ( uno::RuntimeException )
4330 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4332 if ( !m_pImpl )
4334 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4335 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4338 m_pData->m_aListenersContainer.removeInterface(
4339 ::getCppuType( ( const uno::Reference< util::XModifyListener >* )0 ), aListener );
4342 //____________________________________________________________________________________________________
4343 // XNameAccess
4344 //____________________________________________________________________________________________________
4346 //-----------------------------------------------
4347 uno::Any SAL_CALL OStorage::getByName( const OUString& aName )
4348 throw ( container::NoSuchElementException,
4349 lang::WrappedTargetException,
4350 uno::RuntimeException )
4352 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getByName" );
4354 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4356 if ( !m_pImpl )
4358 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4359 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4362 if ( aName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aName, sal_False ) )
4363 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
4365 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aName == "_rels" )
4366 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 ); // unacceptable element name
4368 uno::Any aResult;
4371 SotElement_Impl* pElement = m_pImpl->FindElement( aName );
4372 if ( !pElement )
4373 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4375 if ( pElement->m_bIsStorage )
4376 aResult <<= openStorageElement( aName, embed::ElementModes::READ );
4377 else
4378 aResult <<= openStreamElement( aName, embed::ElementModes::READ );
4380 catch( const container::NoSuchElementException& rNoSuchElementException )
4382 m_pImpl->AddLog( rNoSuchElementException.Message );
4383 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4384 throw;
4386 catch( const lang::WrappedTargetException& rWrappedTargetException )
4388 m_pImpl->AddLog( rWrappedTargetException.Message );
4389 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4390 throw;
4392 catch( const uno::RuntimeException& rRuntimeException )
4394 m_pImpl->AddLog( rRuntimeException.Message );
4395 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4396 throw;
4398 catch( const uno::Exception& rException )
4400 m_pImpl->AddLog( rException.Message );
4401 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4403 uno::Any aCaught( ::cppu::getCaughtException() );
4404 throw lang::WrappedTargetException( OSL_LOG_PREFIX "Can not open storage!\n",
4405 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
4406 uno::UNO_QUERY ),
4407 aCaught );
4410 return aResult;
4414 //-----------------------------------------------
4415 uno::Sequence< OUString > SAL_CALL OStorage::getElementNames()
4416 throw ( uno::RuntimeException )
4418 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getElementNames" );
4420 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4422 if ( !m_pImpl )
4424 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4425 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4430 return m_pImpl->GetElementNames();
4432 catch( const uno::RuntimeException& rRuntimeException )
4434 m_pImpl->AddLog( rRuntimeException.Message );
4435 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4436 throw;
4438 catch ( const uno::Exception& rException )
4440 m_pImpl->AddLog( rException.Message );
4441 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4443 uno::Any aCaught( ::cppu::getCaughtException() );
4444 throw lang::WrappedTargetRuntimeException( OSL_LOG_PREFIX "Can not open storage!\n",
4445 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
4446 uno::UNO_QUERY ),
4447 aCaught );
4452 //-----------------------------------------------
4453 sal_Bool SAL_CALL OStorage::hasByName( const OUString& aName )
4454 throw ( uno::RuntimeException )
4456 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::hasByName" );
4458 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4460 if ( !m_pImpl )
4462 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4463 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4466 if ( aName.isEmpty() )
4467 return sal_False;
4469 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aName == "_rels" )
4470 return sal_False;
4472 SotElement_Impl* pElement = NULL;
4475 pElement = m_pImpl->FindElement( aName );
4477 catch( const uno::RuntimeException& rRuntimeException )
4479 m_pImpl->AddLog( rRuntimeException.Message );
4480 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4481 throw;
4483 catch ( const uno::Exception& rException )
4485 m_pImpl->AddLog( rException.Message );
4486 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4488 uno::Any aCaught( ::cppu::getCaughtException() );
4489 throw lang::WrappedTargetRuntimeException( OSL_LOG_PREFIX "Can not open storage!\n",
4490 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
4491 uno::UNO_QUERY ),
4492 aCaught );
4495 return ( pElement != NULL );
4499 //-----------------------------------------------
4500 uno::Type SAL_CALL OStorage::getElementType()
4501 throw ( uno::RuntimeException )
4503 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4505 if ( !m_pImpl )
4507 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4508 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4511 // it is a multitype container
4512 return uno::Type();
4516 //-----------------------------------------------
4517 sal_Bool SAL_CALL OStorage::hasElements()
4518 throw ( uno::RuntimeException )
4520 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::hasElements" );
4522 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4524 if ( !m_pImpl )
4526 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4527 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4532 return ( m_pImpl->GetChildrenList().size() != 0 );
4534 catch( const uno::RuntimeException& rRuntimeException )
4536 m_pImpl->AddLog( rRuntimeException.Message );
4537 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4538 throw;
4540 catch( const uno::Exception& rException )
4542 m_pImpl->AddLog( rException.Message );
4543 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4545 uno::Any aCaught( ::cppu::getCaughtException() );
4546 throw lang::WrappedTargetRuntimeException( OSL_LOG_PREFIX "Can not open storage!\n",
4547 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
4548 uno::UNO_QUERY ),
4549 aCaught );
4554 //____________________________________________________________________________________________________
4555 // XComponent
4556 //____________________________________________________________________________________________________
4558 //-----------------------------------------------
4559 void SAL_CALL OStorage::dispose()
4560 throw ( uno::RuntimeException )
4562 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4564 if ( !m_pImpl )
4566 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4567 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4572 InternalDispose( sal_True );
4574 catch( const uno::RuntimeException& rRuntimeException )
4576 m_pImpl->AddLog( rRuntimeException.Message );
4577 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4578 throw;
4580 catch( const uno::Exception& rException )
4582 m_pImpl->AddLog( rException.Message );
4583 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4585 uno::Any aCaught( ::cppu::getCaughtException() );
4586 throw lang::WrappedTargetRuntimeException( OSL_LOG_PREFIX "Can not open storage!\n",
4587 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
4588 uno::UNO_QUERY ),
4589 aCaught );
4593 //-----------------------------------------------
4594 void SAL_CALL OStorage::addEventListener(
4595 const uno::Reference< lang::XEventListener >& xListener )
4596 throw ( uno::RuntimeException )
4598 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4600 if ( !m_pImpl )
4602 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4603 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4606 m_pData->m_aListenersContainer.addInterface(
4607 ::getCppuType( ( const uno::Reference< lang::XEventListener >* )0 ), xListener );
4610 //-----------------------------------------------
4611 void SAL_CALL OStorage::removeEventListener(
4612 const uno::Reference< lang::XEventListener >& xListener )
4613 throw ( uno::RuntimeException )
4615 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4617 if ( !m_pImpl )
4619 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4620 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4623 m_pData->m_aListenersContainer.removeInterface(
4624 ::getCppuType( ( const uno::Reference< lang::XEventListener >* )0 ), xListener );
4627 //____________________________________________________________________________________________________
4628 // XEncryptionProtectedSource
4629 //____________________________________________________________________________________________________
4631 void SAL_CALL OStorage::setEncryptionPassword( const OUString& aPass )
4632 throw ( uno::RuntimeException,
4633 io::IOException )
4635 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setEncryptionPassword" );
4636 setEncryptionData( ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass ) );
4639 //-----------------------------------------------
4640 void SAL_CALL OStorage::removeEncryption()
4641 throw ( uno::RuntimeException,
4642 io::IOException )
4644 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::removeEncryption" );
4646 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4648 if ( !m_pImpl )
4650 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4651 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4654 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4655 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
4657 OSL_ENSURE( m_pData->m_bIsRoot, "removeEncryption() method is not available for nonroot storages!\n" );
4658 if ( m_pData->m_bIsRoot )
4660 try {
4661 m_pImpl->ReadContents();
4663 catch ( const uno::RuntimeException& rRuntimeException )
4665 m_pImpl->AddLog( rRuntimeException.Message );
4666 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4667 throw;
4669 catch ( const uno::Exception& rException )
4671 m_pImpl->AddLog( rException.Message );
4672 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4674 uno::Any aCaught( ::cppu::getCaughtException() );
4675 throw lang::WrappedTargetRuntimeException( OSL_LOG_PREFIX "Can not open package!\n",
4676 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
4677 uno::UNO_QUERY ),
4678 aCaught );
4681 // TODO: check if the password is valid
4682 // update all streams that was encrypted with old password
4684 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4687 xPackPropSet->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY,
4688 uno::makeAny( uno::Sequence< beans::NamedValue >() ) );
4690 m_pImpl->m_bHasCommonEncryptionData = sal_False;
4691 m_pImpl->m_aCommonEncryptionData.clear();
4693 catch( const uno::RuntimeException& rRException )
4695 m_pImpl->AddLog( rRException.Message );
4696 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4698 OSL_ENSURE( sal_False, "The call must not fail, it is pretty simple!" );
4699 throw;
4701 catch( const uno::Exception& rException )
4703 m_pImpl->AddLog( rException.Message );
4704 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4706 OSL_FAIL( "The call must not fail, it is pretty simple!" );
4707 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4712 //____________________________________________________________________________________________________
4713 // XEncryptionProtectedSource2
4714 //____________________________________________________________________________________________________
4716 void SAL_CALL OStorage::setEncryptionData( const uno::Sequence< beans::NamedValue >& aEncryptionData )
4717 throw ( io::IOException,
4718 uno::RuntimeException )
4720 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setEncryptionData" );
4722 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4724 if ( !m_pImpl )
4726 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4727 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4730 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4731 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
4733 if ( !aEncryptionData.getLength() )
4734 throw uno::RuntimeException( OSL_LOG_PREFIX "Unexpected empty encryption data!", uno::Reference< uno::XInterface >() );
4736 OSL_ENSURE( m_pData->m_bIsRoot, "setEncryptionData() method is not available for nonroot storages!\n" );
4737 if ( m_pData->m_bIsRoot )
4739 try {
4740 m_pImpl->ReadContents();
4742 catch ( const uno::RuntimeException& rRuntimeException )
4744 m_pImpl->AddLog( rRuntimeException.Message );
4745 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4746 throw;
4748 catch ( const uno::Exception& rException )
4750 m_pImpl->AddLog( rException.Message );
4751 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4753 uno::Any aCaught( ::cppu::getCaughtException() );
4754 throw lang::WrappedTargetRuntimeException( OSL_LOG_PREFIX "Can not open package!\n",
4755 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ),
4756 aCaught );
4759 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4762 ::comphelper::SequenceAsHashMap aEncryptionMap( aEncryptionData );
4763 xPackPropSet->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY,
4764 uno::makeAny( aEncryptionMap.getAsConstNamedValueList() ) );
4766 m_pImpl->m_bHasCommonEncryptionData = sal_True;
4767 m_pImpl->m_aCommonEncryptionData = aEncryptionMap;
4769 catch( const uno::Exception& rException )
4771 m_pImpl->AddLog( rException.Message );
4772 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4774 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4779 sal_Bool SAL_CALL OStorage::hasEncryptionData()
4780 throw ( uno::RuntimeException )
4782 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4784 return m_pImpl && m_pImpl->m_bHasCommonEncryptionData;
4788 //____________________________________________________________________________________________________
4789 // XEncryptionProtectedStorage
4790 //____________________________________________________________________________________________________
4792 //-----------------------------------------------
4793 void SAL_CALL OStorage::setEncryptionAlgorithms( const uno::Sequence< beans::NamedValue >& aAlgorithms )
4794 throw (lang::IllegalArgumentException, uno::RuntimeException)
4796 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setEncryptionAlgorithms" );
4798 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4800 if ( !m_pImpl )
4802 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4803 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4806 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4807 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
4809 if ( !aAlgorithms.getLength() )
4810 throw uno::RuntimeException( OSL_LOG_PREFIX "Unexpected empty encryption algorithms list!", uno::Reference< uno::XInterface >() );
4812 OSL_ENSURE( m_pData->m_bIsRoot, "setEncryptionAlgorithms() method is not available for nonroot storages!\n" );
4813 if ( m_pData->m_bIsRoot )
4815 try {
4816 m_pImpl->ReadContents();
4818 catch ( const uno::RuntimeException& aRuntimeException )
4820 m_pImpl->AddLog( aRuntimeException.Message );
4821 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4822 throw;
4824 catch ( const uno::Exception& aException )
4826 m_pImpl->AddLog( aException.Message );
4827 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4829 uno::Any aCaught( ::cppu::getCaughtException() );
4830 throw lang::WrappedTargetException( OSL_LOG_PREFIX "Can not open package!\n",
4831 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
4832 uno::UNO_QUERY ),
4833 aCaught );
4836 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4839 xPackPropSet->setPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY,
4840 uno::makeAny( aAlgorithms ) );
4842 catch ( const uno::RuntimeException& aRuntimeException )
4844 m_pImpl->AddLog( aRuntimeException.Message );
4845 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4846 throw;
4848 catch( const uno::Exception& aException )
4850 m_pImpl->AddLog( aException.Message );
4851 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4853 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4858 //-----------------------------------------------
4859 uno::Sequence< beans::NamedValue > SAL_CALL OStorage::getEncryptionAlgorithms()
4860 throw (uno::RuntimeException)
4862 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getEncryptionAlgorithms" );
4864 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4866 if ( !m_pImpl )
4868 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4869 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4872 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
4873 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // the interface must be visible only for package storage
4875 uno::Sequence< beans::NamedValue > aResult;
4876 OSL_ENSURE( m_pData->m_bIsRoot, "getEncryptionAlgorithms() method is not available for nonroot storages!\n" );
4877 if ( m_pData->m_bIsRoot )
4879 try {
4880 m_pImpl->ReadContents();
4882 catch ( const uno::RuntimeException& aRuntimeException )
4884 m_pImpl->AddLog( aRuntimeException.Message );
4885 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4886 throw;
4888 catch ( const uno::Exception& aException )
4890 m_pImpl->AddLog( aException.Message );
4891 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4893 uno::Any aCaught( ::cppu::getCaughtException() );
4894 throw lang::WrappedTargetException( OSL_LOG_PREFIX "Can not open package!\n",
4895 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
4896 uno::UNO_QUERY ),
4897 aCaught );
4900 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4903 xPackPropSet->getPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY ) >>= aResult;
4905 catch ( const uno::RuntimeException& aRuntimeException )
4907 m_pImpl->AddLog( aRuntimeException.Message );
4908 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4909 throw;
4911 catch( const uno::Exception& aException )
4913 m_pImpl->AddLog( aException.Message );
4914 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
4916 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4920 return aResult;
4924 //____________________________________________________________________________________________________
4925 // XPropertySet
4926 //____________________________________________________________________________________________________
4928 //-----------------------------------------------
4929 uno::Reference< beans::XPropertySetInfo > SAL_CALL OStorage::getPropertySetInfo()
4930 throw ( uno::RuntimeException )
4932 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4934 if ( !m_pImpl )
4936 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4937 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4940 //TODO:
4941 return uno::Reference< beans::XPropertySetInfo >();
4945 //-----------------------------------------------
4946 void SAL_CALL OStorage::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
4947 throw ( beans::UnknownPropertyException,
4948 beans::PropertyVetoException,
4949 lang::IllegalArgumentException,
4950 lang::WrappedTargetException,
4951 uno::RuntimeException )
4953 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setPropertyValue" );
4955 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4957 if ( !m_pImpl )
4959 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
4960 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4963 //TODO: think about interaction handler
4965 // WORKAROUND:
4966 // The old document might have no version in the manifest.xml, so we have to allow to set the version
4967 // even for readonly storages, so that the version from content.xml can be used.
4968 if ( m_pData->m_bReadOnlyWrap && aPropertyName != "Version" )
4969 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: Access denied
4971 if ( m_pData->m_nStorageType == embed::StorageFormats::ZIP )
4972 throw beans::UnknownPropertyException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
4973 else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE )
4975 if ( aPropertyName == "MediaType" )
4977 aValue >>= m_pImpl->m_aMediaType;
4978 m_pImpl->m_bControlMediaType = sal_True;
4980 m_pImpl->m_bBroadcastModified = sal_True;
4981 m_pImpl->m_bIsModified = sal_True;
4983 else if ( aPropertyName == "Version" )
4985 aValue >>= m_pImpl->m_aVersion;
4986 m_pImpl->m_bControlVersion = sal_True;
4988 // this property can be set even for readonly storage
4989 if ( !m_pData->m_bReadOnlyWrap )
4991 m_pImpl->m_bBroadcastModified = sal_True;
4992 m_pImpl->m_bIsModified = sal_True;
4995 else if ( ( m_pData->m_bIsRoot && ( aPropertyName == HAS_ENCRYPTED_ENTRIES_PROPERTY
4996 || aPropertyName == HAS_NONENCRYPTED_ENTRIES_PROPERTY
4997 || aPropertyName == IS_INCONSISTENT_PROPERTY
4998 || aPropertyName == "URL"
4999 || aPropertyName == "RepairPackage" ) )
5000 || aPropertyName == "IsRoot"
5001 || aPropertyName == MEDIATYPE_FALLBACK_USED_PROPERTY )
5002 throw beans::PropertyVetoException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5003 else
5004 throw beans::UnknownPropertyException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5006 else if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML )
5008 if ( aPropertyName == "RelationsInfoStream" )
5010 uno::Reference< io::XInputStream > xInRelStream;
5011 if ( ( aValue >>= xInRelStream ) && xInRelStream.is() )
5013 uno::Reference< io::XSeekable > xSeek( xInRelStream, uno::UNO_QUERY );
5014 if ( !xSeek.is() )
5016 // currently this is an internal property that is used for optimization
5017 // and the stream must support XSeekable interface
5018 // TODO/LATER: in future it can be changed if property is used from outside
5019 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 0 );
5022 m_pImpl->m_xNewRelInfoStream = xInRelStream;
5023 m_pImpl->m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
5024 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED_STREAM;
5025 m_pImpl->m_bBroadcastModified = sal_True;
5026 m_pImpl->m_bIsModified = sal_True;
5028 else
5029 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 0 );
5031 else if ( aPropertyName == "RelationsInfo" )
5033 if ( aValue >>= m_pImpl->m_aRelInfo )
5035 m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
5036 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
5037 m_pImpl->m_bBroadcastModified = sal_True;
5038 m_pImpl->m_bIsModified = sal_True;
5040 else
5041 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 0 );
5043 else if ( ( m_pData->m_bIsRoot && ( aPropertyName == "URL" || aPropertyName == "RepairPackage") )
5044 || aPropertyName == "IsRoot" )
5045 throw beans::PropertyVetoException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5046 else
5047 throw beans::UnknownPropertyException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5049 else
5050 throw beans::UnknownPropertyException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5052 BroadcastModifiedIfNecessary();
5056 //-----------------------------------------------
5057 uno::Any SAL_CALL OStorage::getPropertyValue( const OUString& aPropertyName )
5058 throw ( beans::UnknownPropertyException,
5059 lang::WrappedTargetException,
5060 uno::RuntimeException )
5062 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getPropertyValue" );
5064 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5066 if ( !m_pImpl )
5068 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5069 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5072 if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
5073 && ( aPropertyName == "MediaType" || aPropertyName == MEDIATYPE_FALLBACK_USED_PROPERTY || aPropertyName == "Version" ) )
5077 m_pImpl->ReadContents();
5079 catch ( const uno::RuntimeException& rRuntimeException )
5081 m_pImpl->AddLog( rRuntimeException.Message );
5082 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5083 throw;
5085 catch ( const uno::Exception& rException )
5087 m_pImpl->AddLog( rException.Message );
5088 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5090 uno::Any aCaught( ::cppu::getCaughtException() );
5091 throw lang::WrappedTargetException(
5092 "Can't read contents!",
5093 uno::Reference< XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ),
5094 aCaught );
5097 if ( aPropertyName == "MediaType" )
5098 return uno::makeAny( m_pImpl->m_aMediaType );
5099 else if ( aPropertyName == "Version" )
5100 return uno::makeAny( m_pImpl->m_aVersion );
5101 else
5102 return uno::makeAny( m_pImpl->m_bMTFallbackUsed );
5104 else if ( aPropertyName == "IsRoot" )
5106 return uno::makeAny( m_pData->m_bIsRoot );
5108 else if ( aPropertyName == "OpenMode" )
5110 return uno::makeAny( m_pImpl->m_nStorageMode );
5112 else if ( m_pData->m_bIsRoot )
5114 if ( aPropertyName == "URL"
5115 || aPropertyName == "RepairPackage" )
5117 for ( sal_Int32 aInd = 0; aInd < m_pImpl->m_xProperties.getLength(); aInd++ )
5119 if ( m_pImpl->m_xProperties[aInd].Name.equals( aPropertyName ) )
5120 return m_pImpl->m_xProperties[aInd].Value;
5123 if ( aPropertyName == "URL" )
5124 return uno::makeAny( OUString() );
5126 return uno::makeAny( sal_False ); // RepairPackage
5128 else if ( m_pData->m_nStorageType == embed::StorageFormats::PACKAGE
5129 && ( aPropertyName == HAS_ENCRYPTED_ENTRIES_PROPERTY
5130 || aPropertyName == HAS_NONENCRYPTED_ENTRIES_PROPERTY
5131 || aPropertyName == IS_INCONSISTENT_PROPERTY ) )
5133 try {
5134 m_pImpl->ReadContents();
5135 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY );
5136 if ( !xPackPropSet.is() )
5137 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5139 return xPackPropSet->getPropertyValue( aPropertyName );
5141 catch ( const uno::RuntimeException& rRuntimeException )
5143 m_pImpl->AddLog( rRuntimeException.Message );
5144 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5145 throw;
5147 catch ( const uno::Exception& rException )
5149 m_pImpl->AddLog( rException.Message );
5150 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5152 uno::Any aCaught( ::cppu::getCaughtException() );
5153 throw lang::WrappedTargetException( OSL_LOG_PREFIX "Can not open package!\n",
5154 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
5155 uno::UNO_QUERY ),
5156 aCaught );
5161 throw beans::UnknownPropertyException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5165 //-----------------------------------------------
5166 void SAL_CALL OStorage::addPropertyChangeListener(
5167 const OUString& /*aPropertyName*/,
5168 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
5169 throw ( beans::UnknownPropertyException,
5170 lang::WrappedTargetException,
5171 uno::RuntimeException )
5173 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5175 if ( !m_pImpl )
5177 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5178 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5181 //TODO:
5185 //-----------------------------------------------
5186 void SAL_CALL OStorage::removePropertyChangeListener(
5187 const OUString& /*aPropertyName*/,
5188 const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
5189 throw ( beans::UnknownPropertyException,
5190 lang::WrappedTargetException,
5191 uno::RuntimeException )
5193 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5195 if ( !m_pImpl )
5197 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5198 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5201 //TODO:
5205 //-----------------------------------------------
5206 void SAL_CALL OStorage::addVetoableChangeListener(
5207 const OUString& /*PropertyName*/,
5208 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
5209 throw ( beans::UnknownPropertyException,
5210 lang::WrappedTargetException,
5211 uno::RuntimeException )
5213 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5215 if ( !m_pImpl )
5217 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5218 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5221 //TODO:
5225 //-----------------------------------------------
5226 void SAL_CALL OStorage::removeVetoableChangeListener(
5227 const OUString& /*PropertyName*/,
5228 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
5229 throw ( beans::UnknownPropertyException,
5230 lang::WrappedTargetException,
5231 uno::RuntimeException )
5233 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5235 if ( !m_pImpl )
5237 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5238 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5241 //TODO:
5244 //____________________________________________________________________________________________________
5245 // XRelationshipAccess
5246 //____________________________________________________________________________________________________
5248 // TODO/LATER: the storage and stream implementations of this interface are very similar, they could use a helper class
5250 //-----------------------------------------------
5251 sal_Bool SAL_CALL OStorage::hasByID( const OUString& sID )
5252 throw ( io::IOException,
5253 uno::RuntimeException )
5255 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5257 if ( !m_pImpl )
5259 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5260 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5263 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5264 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5268 getRelationshipByID( sID );
5269 return sal_True;
5271 catch( const container::NoSuchElementException& rNoSuchElementException )
5273 m_pImpl->AddLog( rNoSuchElementException.Message );
5274 m_pImpl->AddLog( OSL_LOG_PREFIX "Quiet exception" );
5277 return sal_False;
5280 //-----------------------------------------------
5281 OUString SAL_CALL OStorage::getTargetByID( const OUString& sID )
5282 throw ( container::NoSuchElementException,
5283 io::IOException,
5284 uno::RuntimeException )
5286 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5288 if ( !m_pImpl )
5290 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5291 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5294 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5295 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5297 uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
5298 for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
5299 if ( aSeq[nInd].First == "Target" )
5300 return aSeq[nInd].Second;
5302 return OUString();
5305 //-----------------------------------------------
5306 OUString SAL_CALL OStorage::getTypeByID( const OUString& sID )
5307 throw ( container::NoSuchElementException,
5308 io::IOException,
5309 uno::RuntimeException )
5311 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5313 if ( !m_pImpl )
5315 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5316 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5319 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5320 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5322 uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
5323 for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
5324 if ( aSeq[nInd].First == "Type" )
5325 return aSeq[nInd].Second;
5327 return OUString();
5330 //-----------------------------------------------
5331 uno::Sequence< beans::StringPair > SAL_CALL OStorage::getRelationshipByID( const OUString& sID )
5332 throw ( container::NoSuchElementException,
5333 io::IOException,
5334 uno::RuntimeException )
5336 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5338 if ( !m_pImpl )
5340 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5341 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5344 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5345 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5347 // TODO/LATER: in future the unification of the ID could be checked
5348 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5349 for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
5350 for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
5351 if ( aSeq[nInd1][nInd2].First == "Id" )
5353 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
5354 return aSeq[nInd1];
5355 break;
5358 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5361 //-----------------------------------------------
5362 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OStorage::getRelationshipsByType( const OUString& sType )
5363 throw ( io::IOException,
5364 uno::RuntimeException )
5366 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5368 if ( !m_pImpl )
5370 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5371 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5374 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5375 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5377 uno::Sequence< uno::Sequence< beans::StringPair > > aResult;
5378 sal_Int32 nEntriesNum = 0;
5380 // TODO/LATER: in future the unification of the ID could be checked
5381 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5382 for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
5383 for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
5384 if ( aSeq[nInd1][nInd2].First == "Type" )
5386 // the type is usually an URL, so the check should be case insensitive
5387 if ( aSeq[nInd1][nInd2].Second.equalsIgnoreAsciiCase( sType ) )
5389 aResult.realloc( ++nEntriesNum );
5390 aResult[nEntriesNum-1] = aSeq[nInd1];
5392 break;
5395 return aResult;
5398 //-----------------------------------------------
5399 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OStorage::getAllRelationships()
5400 throw (io::IOException, uno::RuntimeException)
5402 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5404 if ( !m_pImpl )
5406 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5407 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5410 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5411 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5413 return m_pImpl->GetAllRelationshipsIfAny();
5416 //-----------------------------------------------
5417 void SAL_CALL OStorage::insertRelationshipByID( const OUString& sID, const uno::Sequence< beans::StringPair >& aEntry, ::sal_Bool bReplace )
5418 throw ( container::ElementExistException,
5419 io::IOException,
5420 uno::RuntimeException )
5422 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5424 if ( !m_pImpl )
5426 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5427 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5430 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5431 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5433 OUString aIDTag( "Id" );
5435 sal_Int32 nIDInd = -1;
5437 // TODO/LATER: in future the unification of the ID could be checked
5438 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5439 for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
5440 for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
5441 if ( aSeq[nInd1][nInd2].First.equals( aIDTag ) )
5443 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
5444 nIDInd = nInd1;
5446 break;
5449 if ( nIDInd == -1 || bReplace )
5451 if ( nIDInd == -1 )
5453 nIDInd = aSeq.getLength();
5454 aSeq.realloc( nIDInd + 1 );
5457 aSeq[nIDInd].realloc( aEntry.getLength() + 1 );
5459 aSeq[nIDInd][0].First = aIDTag;
5460 aSeq[nIDInd][0].Second = sID;
5461 sal_Int32 nIndTarget = 1;
5462 for ( sal_Int32 nIndOrig = 0;
5463 nIndOrig < aEntry.getLength();
5464 nIndOrig++ )
5466 if ( !aEntry[nIndOrig].First.equals( aIDTag ) )
5467 aSeq[nIDInd][nIndTarget++] = aEntry[nIndOrig];
5470 aSeq[nIDInd].realloc( nIndTarget );
5472 else
5473 throw container::ElementExistException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5476 m_pImpl->m_aRelInfo = aSeq;
5477 m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
5478 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
5481 //-----------------------------------------------
5482 void SAL_CALL OStorage::removeRelationshipByID( const OUString& sID )
5483 throw ( container::NoSuchElementException,
5484 io::IOException,
5485 uno::RuntimeException )
5487 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5489 if ( !m_pImpl )
5491 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5492 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5495 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5496 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5498 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5499 for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
5500 for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
5501 if ( aSeq[nInd1][nInd2].First == "Id" )
5503 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
5505 sal_Int32 nLength = aSeq.getLength();
5506 aSeq[nInd1] = aSeq[nLength-1];
5507 aSeq.realloc( nLength - 1 );
5509 m_pImpl->m_aRelInfo = aSeq;
5510 m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
5511 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
5513 // TODO/LATER: in future the unification of the ID could be checked
5514 return;
5517 break;
5520 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5523 //-----------------------------------------------
5524 void SAL_CALL OStorage::insertRelationships( const uno::Sequence< uno::Sequence< beans::StringPair > >& aEntries, ::sal_Bool bReplace )
5525 throw ( container::ElementExistException,
5526 io::IOException,
5527 uno::RuntimeException )
5529 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5531 if ( !m_pImpl )
5533 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5534 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5537 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5538 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5540 OUString aIDTag( "Id" );
5541 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
5542 uno::Sequence< uno::Sequence< beans::StringPair > > aResultSeq( aSeq.getLength() + aEntries.getLength() );
5543 sal_Int32 nResultInd = 0;
5545 for ( sal_Int32 nIndTarget1 = 0; nIndTarget1 < aSeq.getLength(); nIndTarget1++ )
5546 for ( sal_Int32 nIndTarget2 = 0; nIndTarget2 < aSeq[nIndTarget1].getLength(); nIndTarget2++ )
5547 if ( aSeq[nIndTarget1][nIndTarget2].First.equals( aIDTag ) )
5549 sal_Int32 nIndSourceSame = -1;
5551 for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
5552 for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
5554 if ( aEntries[nIndSource1][nIndSource2].First.equals( aIDTag ) )
5556 if ( aEntries[nIndSource1][nIndSource2].Second.equals( aSeq[nIndTarget1][nIndTarget2].Second ) )
5558 if ( !bReplace )
5559 throw container::ElementExistException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5561 nIndSourceSame = nIndSource1;
5564 break;
5568 if ( nIndSourceSame == -1 )
5570 // no such element in the provided sequence
5571 aResultSeq[nResultInd++] = aSeq[nIndTarget1];
5574 break;
5577 for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
5579 aResultSeq[nResultInd].realloc( aEntries[nIndSource1].getLength() );
5580 sal_Bool bHasID = sal_False;
5581 sal_Int32 nResInd2 = 1;
5583 for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
5584 if ( aEntries[nIndSource1][nIndSource2].First.equals( aIDTag ) )
5586 aResultSeq[nResultInd][0] = aEntries[nIndSource1][nIndSource2];
5587 bHasID = sal_True;
5589 else if ( nResInd2 < aResultSeq[nResultInd].getLength() )
5590 aResultSeq[nResultInd][nResInd2++] = aEntries[nIndSource1][nIndSource2];
5591 else
5592 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: illegal relation ( no ID )
5594 if ( !bHasID )
5595 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: illegal relations
5597 nResultInd++;
5600 aResultSeq.realloc( nResultInd );
5601 m_pImpl->m_aRelInfo = aResultSeq;
5602 m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
5603 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
5606 //-----------------------------------------------
5607 void SAL_CALL OStorage::clearRelationships()
5608 throw ( io::IOException,
5609 uno::RuntimeException )
5611 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5613 if ( !m_pImpl )
5615 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5616 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5619 if ( m_pData->m_nStorageType != embed::StorageFormats::OFOPXML )
5620 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5622 m_pImpl->m_aRelInfo.realloc( 0 );
5623 m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
5624 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
5627 //____________________________________________________________________________________________________
5628 // XOptimizedStorage
5629 //____________________________________________________________________________________________________
5630 //-----------------------------------------------
5631 void SAL_CALL OStorage::insertRawNonEncrStreamElementDirect(
5632 const OUString& /*sStreamName*/,
5633 const uno::Reference< io::XInputStream >& /*xInStream*/ )
5634 throw ( embed::InvalidStorageException,
5635 lang::IllegalArgumentException,
5636 packages::NoRawFormatException,
5637 container::ElementExistException,
5638 io::IOException,
5639 embed::StorageWrappedTargetException,
5640 uno::RuntimeException )
5642 // not implemented currently because there is still no demand
5643 // might need to be implemented if direct copying of compressed streams is used
5644 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5647 //-----------------------------------------------
5648 void SAL_CALL OStorage::insertStreamElementDirect(
5649 const OUString& aStreamName,
5650 const uno::Reference< io::XInputStream >& xInStream,
5651 const uno::Sequence< beans::PropertyValue >& aProps )
5652 throw ( embed::InvalidStorageException,
5653 lang::IllegalArgumentException,
5654 container::ElementExistException,
5655 io::IOException,
5656 embed::StorageWrappedTargetException,
5657 uno::RuntimeException )
5659 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::insertStreamElementDirect" );
5661 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5663 if ( !m_pImpl )
5665 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5666 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5669 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
5670 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
5672 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aStreamName == "_rels" )
5673 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
5675 if ( m_pData->m_bReadOnlyWrap )
5676 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: access denied
5680 SotElement_Impl* pElement = m_pImpl->FindElement( aStreamName );
5682 if ( pElement )
5683 throw container::ElementExistException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5685 pElement = OpenStreamElement_Impl( aStreamName, embed::ElementModes::READWRITE, sal_False );
5686 OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
5688 pElement->m_pStream->InsertStreamDirectly( xInStream, aProps );
5690 catch( const embed::InvalidStorageException& rInvalidStorageException )
5692 m_pImpl->AddLog( rInvalidStorageException.Message );
5693 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5694 throw;
5696 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
5698 m_pImpl->AddLog( rIllegalArgumentException.Message );
5699 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5700 throw;
5702 catch( const container::ElementExistException& rElementExistException )
5704 m_pImpl->AddLog( rElementExistException.Message );
5705 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5706 throw;
5708 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
5710 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
5711 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5712 throw;
5714 catch( const io::IOException& rIOException )
5716 m_pImpl->AddLog( rIOException.Message );
5717 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5718 throw;
5720 catch( const uno::RuntimeException& rRuntimeException )
5722 m_pImpl->AddLog( rRuntimeException.Message );
5723 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5724 throw;
5726 catch( const uno::Exception& rException )
5728 m_pImpl->AddLog( rException.Message );
5729 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5731 uno::Any aCaught( ::cppu::getCaughtException() );
5732 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't insert stream directly!",
5733 uno::Reference< io::XInputStream >(),
5734 aCaught );
5738 //-----------------------------------------------
5739 void SAL_CALL OStorage::copyElementDirectlyTo(
5740 const OUString& aElementName,
5741 const uno::Reference< embed::XOptimizedStorage >& xDest,
5742 const OUString& aNewName )
5743 throw ( embed::InvalidStorageException,
5744 lang::IllegalArgumentException,
5745 container::NoSuchElementException,
5746 container::ElementExistException,
5747 io::IOException,
5748 embed::StorageWrappedTargetException,
5749 uno::RuntimeException )
5751 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyElementDirectlyTo" );
5753 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5755 if ( !m_pImpl )
5757 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5758 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5761 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
5762 || aNewName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
5763 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
5765 if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
5766 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 2 );
5768 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && ( aElementName == "_rels" || aNewName == "_rels" ) )
5769 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 0 ); // unacceptable name
5773 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
5774 if ( !pElement )
5775 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5777 uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
5778 if ( !xNameAccess.is() )
5779 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5781 if ( xNameAccess->hasByName( aNewName ) )
5782 throw container::ElementExistException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5784 // let the element be copied directly
5785 uno::Reference< embed::XStorage > xStorDest( xDest, uno::UNO_QUERY_THROW );
5786 m_pImpl->CopyStorageElement( pElement, xStorDest, aNewName, sal_True );
5788 catch( const embed::InvalidStorageException& rInvalidStorageException )
5790 m_pImpl->AddLog( rInvalidStorageException.Message );
5791 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5792 throw;
5794 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
5796 m_pImpl->AddLog( rIllegalArgumentException.Message );
5797 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5798 throw;
5800 catch( const container::NoSuchElementException& rNoSuchElementException )
5802 m_pImpl->AddLog( rNoSuchElementException.Message );
5803 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5804 throw;
5806 catch( const container::ElementExistException& rElementExistException )
5808 m_pImpl->AddLog( rElementExistException.Message );
5809 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5810 throw;
5812 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
5814 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
5815 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5816 throw;
5818 catch( const io::IOException& rIOException )
5820 m_pImpl->AddLog( rIOException.Message );
5821 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5822 throw;
5824 catch( const uno::RuntimeException& rRuntimeException )
5826 m_pImpl->AddLog( rRuntimeException.Message );
5827 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5828 throw;
5830 catch( const uno::Exception& rException )
5832 m_pImpl->AddLog( rException.Message );
5833 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5835 uno::Any aCaught( ::cppu::getCaughtException() );
5836 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't copy element direcly!",
5837 uno::Reference< io::XInputStream >(),
5838 aCaught );
5842 //-----------------------------------------------
5843 void SAL_CALL OStorage::writeAndAttachToStream( const uno::Reference< io::XStream >& xStream )
5844 throw ( embed::InvalidStorageException,
5845 lang::IllegalArgumentException,
5846 io::IOException,
5847 embed::StorageWrappedTargetException,
5848 uno::RuntimeException )
5850 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::writeAndAttachToStream" );
5852 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5854 if ( !m_pImpl )
5856 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5857 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5860 if ( !m_pData->m_bIsRoot )
5861 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 0 );
5863 if ( !m_pImpl->m_pSwitchStream )
5864 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5868 m_pImpl->m_pSwitchStream->CopyAndSwitchPersistenceTo( xStream );
5870 catch( const embed::InvalidStorageException& rInvalidStorageException )
5872 m_pImpl->AddLog( rInvalidStorageException.Message );
5873 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5874 throw;
5876 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
5878 m_pImpl->AddLog( rIllegalArgumentException.Message );
5879 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5880 throw;
5882 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
5884 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
5885 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5886 throw;
5888 catch( const io::IOException& rIOException )
5890 m_pImpl->AddLog( rIOException.Message );
5891 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5892 throw;
5894 catch( const uno::RuntimeException& rRuntimeException )
5896 m_pImpl->AddLog( rRuntimeException.Message );
5897 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5898 throw;
5900 catch( const uno::Exception& rException )
5902 m_pImpl->AddLog( rException.Message );
5903 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5905 uno::Any aCaught( ::cppu::getCaughtException() );
5906 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't write and attach to stream!",
5907 uno::Reference< io::XInputStream >(),
5908 aCaught );
5913 //-----------------------------------------------
5914 void SAL_CALL OStorage::attachToURL( const OUString& sURL,
5915 sal_Bool bReadOnly )
5916 throw ( embed::InvalidStorageException,
5917 lang::IllegalArgumentException,
5918 io::IOException,
5919 embed::StorageWrappedTargetException,
5920 uno::RuntimeException )
5922 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::attachToURL" );
5924 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5926 if ( !m_pImpl )
5928 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
5929 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5932 if ( !m_pData->m_bIsRoot )
5933 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 0 );
5935 if ( !m_pImpl->m_pSwitchStream )
5936 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
5938 uno::Reference < ucb::XSimpleFileAccess3 > xAccess(
5939 ucb::SimpleFileAccess::create( m_pImpl->m_xContext ) );
5943 if ( bReadOnly )
5945 uno::Reference< io::XInputStream > xInputStream = xAccess->openFileRead( sURL );
5946 m_pImpl->m_pSwitchStream->SwitchPersistenceTo( xInputStream );
5948 else
5950 uno::Reference< io::XStream > xStream = xAccess->openFileReadWrite( sURL );
5951 m_pImpl->m_pSwitchStream->SwitchPersistenceTo( xStream );
5954 catch( const embed::InvalidStorageException& rInvalidStorageException )
5956 m_pImpl->AddLog( rInvalidStorageException.Message );
5957 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5958 throw;
5960 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
5962 m_pImpl->AddLog( rIllegalArgumentException.Message );
5963 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5964 throw;
5966 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
5968 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
5969 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5970 throw;
5972 catch( const io::IOException& rIOException )
5974 m_pImpl->AddLog( rIOException.Message );
5975 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5976 throw;
5978 catch( const uno::RuntimeException& rRuntimeException )
5980 m_pImpl->AddLog( rRuntimeException.Message );
5981 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5982 throw;
5984 catch( const uno::Exception& rException )
5986 m_pImpl->AddLog( rException.Message );
5987 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
5989 uno::Any aCaught( ::cppu::getCaughtException() );
5990 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't attach to URL!",
5991 uno::Reference< io::XInputStream >(),
5992 aCaught );
5996 //-----------------------------------------------
5997 uno::Any SAL_CALL OStorage::getElementPropertyValue( const OUString& aElementName, const OUString& aPropertyName )
5998 throw ( embed::InvalidStorageException,
5999 lang::IllegalArgumentException,
6000 container::NoSuchElementException,
6001 io::IOException,
6002 beans::UnknownPropertyException,
6003 beans::PropertyVetoException,
6004 embed::StorageWrappedTargetException,
6005 uno::RuntimeException)
6007 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getElementPropertyValue" );
6009 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
6011 if ( !m_pImpl )
6013 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
6014 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
6017 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
6018 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
6020 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aElementName == "_rels" )
6021 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 ); // TODO: unacceptable name
6025 SotElement_Impl *pElement = m_pImpl->FindElement( aElementName );
6026 if ( !pElement )
6027 throw container::NoSuchElementException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
6029 // TODO/LATER: Currently it is only implemented for MediaType property of substorages, might be changed in future
6030 if ( !pElement->m_bIsStorage || m_pData->m_nStorageType != embed::StorageFormats::PACKAGE || aPropertyName != "MediaType" )
6031 throw beans::PropertyVetoException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
6033 if ( !pElement->m_pStorage )
6034 m_pImpl->OpenSubStorage( pElement, embed::ElementModes::READ );
6036 if ( !pElement->m_pStorage )
6037 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // TODO: general_error
6039 pElement->m_pStorage->ReadContents();
6040 return uno::makeAny( pElement->m_pStorage->m_aMediaType );
6042 catch( const embed::InvalidStorageException& rInvalidStorageException )
6044 m_pImpl->AddLog( rInvalidStorageException.Message );
6045 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6046 throw;
6048 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
6050 m_pImpl->AddLog( rIllegalArgumentException.Message );
6051 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6052 throw;
6054 catch( const container::NoSuchElementException& rNoSuchElementException )
6056 m_pImpl->AddLog( rNoSuchElementException.Message );
6057 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6058 throw;
6060 catch( const beans::UnknownPropertyException& rUnknownPropertyException )
6062 m_pImpl->AddLog( rUnknownPropertyException.Message );
6063 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6064 throw;
6066 catch( const beans::PropertyVetoException& rPropertyVetoException )
6068 m_pImpl->AddLog( rPropertyVetoException.Message );
6069 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6070 throw;
6072 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
6074 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
6075 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6076 throw;
6078 catch( const io::IOException& rIOException )
6080 m_pImpl->AddLog( rIOException.Message );
6081 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6082 throw;
6084 catch( const uno::RuntimeException& rRuntimeException )
6086 m_pImpl->AddLog( rRuntimeException.Message );
6087 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6088 throw;
6090 catch( const uno::Exception& rException )
6092 m_pImpl->AddLog( rException.Message );
6093 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6095 uno::Any aCaught( ::cppu::getCaughtException() );
6096 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't get element property!",
6097 uno::Reference< io::XInputStream >(),
6098 aCaught );
6102 //-----------------------------------------------
6103 void SAL_CALL OStorage::copyStreamElementData( const OUString& aStreamName, const uno::Reference< io::XStream >& xTargetStream )
6104 throw ( embed::InvalidStorageException,
6105 lang::IllegalArgumentException,
6106 packages::WrongPasswordException,
6107 io::IOException,
6108 embed::StorageWrappedTargetException,
6109 uno::RuntimeException )
6111 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
6113 if ( !m_pImpl )
6115 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
6116 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
6119 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
6120 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
6122 if ( m_pData->m_nStorageType == embed::StorageFormats::OFOPXML && aStreamName == "_rels" )
6123 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 1 ); // unacceptable name
6125 if ( !xTargetStream.is() )
6126 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 2 );
6130 uno::Reference< io::XStream > xNonconstRef = xTargetStream;
6131 m_pImpl->CloneStreamElement( aStreamName, sal_False, ::comphelper::SequenceAsHashMap(), xNonconstRef );
6133 OSL_ENSURE( xNonconstRef == xTargetStream, "The provided stream reference seems not be filled in correctly!\n" );
6134 if ( xNonconstRef != xTargetStream )
6135 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // if the stream reference is set it must not be changed!
6137 catch( const embed::InvalidStorageException& rInvalidStorageException )
6139 m_pImpl->AddLog( rInvalidStorageException.Message );
6140 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6141 throw;
6143 catch( const lang::IllegalArgumentException& rIllegalArgumentException )
6145 m_pImpl->AddLog( rIllegalArgumentException.Message );
6146 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6147 throw;
6149 catch( const packages::WrongPasswordException& rWrongPasswordException )
6151 m_pImpl->AddLog( rWrongPasswordException.Message );
6152 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6153 throw;
6155 catch( const io::IOException& rIOException )
6157 m_pImpl->AddLog( rIOException.Message );
6158 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6159 throw;
6161 catch( const embed::StorageWrappedTargetException& rStorageWrappedTargetException )
6163 m_pImpl->AddLog( rStorageWrappedTargetException.Message );
6164 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6165 throw;
6167 catch( const uno::RuntimeException& rRuntimeException )
6169 m_pImpl->AddLog( rRuntimeException.Message );
6170 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6171 throw;
6173 catch( const uno::Exception& rException )
6175 m_pImpl->AddLog( rException.Message );
6176 m_pImpl->AddLog( OSL_LOG_PREFIX "Rethrow" );
6178 uno::Any aCaught( ::cppu::getCaughtException() );
6179 throw embed::StorageWrappedTargetException( OSL_LOG_PREFIX "Can't copy stream data!",
6180 uno::Reference< io::XInputStream >(),
6181 aCaught );
6187 //____________________________________________________________________________________________________
6188 // XHierarchicalStorageAccess
6189 //____________________________________________________________________________________________________
6191 //-----------------------------------------------
6192 uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openStreamElementByHierarchicalName( const OUString& aStreamPath, ::sal_Int32 nOpenMode )
6193 throw ( embed::InvalidStorageException,
6194 lang::IllegalArgumentException,
6195 packages::WrongPasswordException,
6196 io::IOException,
6197 embed::StorageWrappedTargetException,
6198 uno::RuntimeException )
6200 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
6202 if ( !m_pImpl )
6204 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
6205 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
6208 if ( aStreamPath.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
6209 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
6211 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
6212 && ( nOpenMode & embed::ElementModes::WRITE ) )
6213 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // Access denied
6215 OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
6216 OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
6218 uno::Reference< embed::XExtendedStorageStream > xResult;
6219 if ( aListPath.size() == 1 )
6221 // that must be a direct request for a stream
6222 // the transacted version of the stream should be opened
6224 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamPath, nOpenMode, sal_False );
6225 OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
6227 xResult = uno::Reference< embed::XExtendedStorageStream >(
6228 pElement->m_pStream->GetStream( nOpenMode, sal_True ),
6229 uno::UNO_QUERY_THROW );
6231 else
6233 // there are still storages in between
6234 if ( !m_pData->m_rHierarchyHolder.is() )
6235 m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
6236 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
6238 xResult = m_pData->m_rHierarchyHolder->GetStreamHierarchically(
6239 ( m_pImpl->m_nStorageMode & embed::ElementModes::READWRITE ),
6240 aListPath,
6241 nOpenMode );
6244 if ( !xResult.is() )
6245 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
6247 return xResult;
6250 //-----------------------------------------------
6251 uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openEncryptedStreamElementByHierarchicalName( const OUString& aStreamPath, ::sal_Int32 nOpenMode, const OUString& sPassword )
6252 throw ( embed::InvalidStorageException,
6253 lang::IllegalArgumentException,
6254 packages::NoEncryptionException,
6255 packages::WrongPasswordException,
6256 io::IOException,
6257 embed::StorageWrappedTargetException,
6258 uno::RuntimeException )
6260 return openEncryptedStreamByHierarchicalName( aStreamPath, nOpenMode, ::comphelper::OStorageHelper::CreatePackageEncryptionData( sPassword ) );
6263 //-----------------------------------------------
6264 void SAL_CALL OStorage::removeStreamElementByHierarchicalName( const OUString& aStreamPath )
6265 throw ( embed::InvalidStorageException,
6266 lang::IllegalArgumentException,
6267 container::NoSuchElementException,
6268 io::IOException,
6269 embed::StorageWrappedTargetException,
6270 uno::RuntimeException )
6272 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
6274 if ( !m_pImpl )
6276 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
6277 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
6280 if ( aStreamPath.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
6281 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
6283 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
6284 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // Access denied
6286 OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
6287 OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
6289 if ( !m_pData->m_rHierarchyHolder.is() )
6290 m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
6291 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
6293 m_pData->m_rHierarchyHolder->RemoveStreamHierarchically( aListPath );
6296 //____________________________________________________________________________________________________
6297 // XHierarchicalStorageAccess2
6298 //____________________________________________________________________________________________________
6300 uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openEncryptedStreamByHierarchicalName( const OUString& aStreamPath, ::sal_Int32 nOpenMode, const uno::Sequence< beans::NamedValue >& aEncryptionData )
6301 throw ( embed::InvalidStorageException,
6302 lang::IllegalArgumentException,
6303 packages::NoEncryptionException,
6304 packages::WrongPasswordException,
6305 io::IOException,
6306 embed::StorageWrappedTargetException,
6307 uno::RuntimeException )
6309 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
6311 if ( !m_pImpl )
6313 ::package::StaticAddLog( OSL_LOG_PREFIX "Disposed!" );
6314 throw lang::DisposedException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
6317 if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
6318 throw packages::NoEncryptionException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
6320 if ( aStreamPath.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
6321 throw lang::IllegalArgumentException( OSL_LOG_PREFIX "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
6323 if ( !aEncryptionData.getLength() )
6324 throw lang::IllegalArgumentException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 3 );
6326 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
6327 && ( nOpenMode & embed::ElementModes::WRITE ) )
6328 throw io::IOException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() ); // Access denied
6330 OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
6331 OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
6333 uno::Reference< embed::XExtendedStorageStream > xResult;
6334 if ( aListPath.size() == 1 )
6336 // that must be a direct request for a stream
6337 // the transacted version of the stream should be opened
6339 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamPath, nOpenMode, sal_True );
6340 OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
6342 xResult = uno::Reference< embed::XExtendedStorageStream >(
6343 pElement->m_pStream->GetStream( nOpenMode, aEncryptionData, sal_True ),
6344 uno::UNO_QUERY_THROW );
6346 else
6348 // there are still storages in between
6349 if ( !m_pData->m_rHierarchyHolder.is() )
6350 m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
6351 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
6353 xResult = m_pData->m_rHierarchyHolder->GetStreamHierarchically(
6354 ( m_pImpl->m_nStorageMode & embed::ElementModes::READWRITE ),
6355 aListPath,
6356 nOpenMode,
6357 aEncryptionData );
6360 if ( !xResult.is() )
6361 throw uno::RuntimeException( OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
6363 return xResult;
6367 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */