fix toolbar import
[ooovba.git] / package / source / xstor / xstorage.cxx
bloba56c0a56e4194ae4247c9b462b473fe8f7866aa0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xstorage.cxx,v $
10 * $Revision: 1.33 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_package.hxx"
33 #include <com/sun/star/beans/PropertyValue.hpp>
34 #include <com/sun/star/embed/ElementModes.hpp>
35 #include <com/sun/star/embed/UseBackupException.hpp>
36 #include <com/sun/star/ucb/XProgressHandler.hpp>
37 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
38 #include <com/sun/star/container/XEnumerationAccess.hpp>
39 #include <com/sun/star/container/XNamed.hpp>
40 #include <com/sun/star/util/XChangesBatch.hpp>
41 #include <com/sun/star/util/XCloneable.hpp>
44 #include <com/sun/star/lang/XUnoTunnel.hpp>
45 #include <com/sun/star/lang/XComponent.hpp>
46 #include <com/sun/star/lang/DisposedException.hpp>
47 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
48 #include <com/sun/star/beans/NamedValue.hpp>
51 #include <comphelper/processfactory.hxx>
52 #include <cppuhelper/typeprovider.hxx>
53 #include <cppuhelper/exc_hlp.hxx>
54 #include <rtl/logfile.hxx>
56 #include <comphelper/storagehelper.hxx>
57 #include <comphelper/ofopxmlhelper.hxx>
59 #include "xstorage.hxx"
60 #include "owriteablestream.hxx"
61 #include "disposelistener.hxx"
62 #include "switchpersistencestream.hxx"
63 #include "ohierarchyholder.hxx"
65 using namespace ::com::sun::star;
67 //=========================================================
69 typedef ::std::list< uno::WeakReference< lang::XComponent > > WeakComponentList;
71 struct StorInternalData_Impl
73 SotMutexHolderRef m_rSharedMutexRef;
74 ::cppu::OMultiTypeInterfaceContainerHelper m_aListenersContainer; // list of listeners
75 ::cppu::OTypeCollection* m_pTypeCollection;
76 sal_Bool m_bIsRoot;
77 sal_Int16 m_nStorageType; // the mode in wich the storage is used
78 sal_Bool m_bReadOnlyWrap;
80 OChildDispListener_Impl* m_pSubElDispListener;
82 WeakComponentList m_aOpenSubComponentsList;
84 ::rtl::Reference< OHierarchyHolder_Impl > m_rHierarchyHolder;
86 // the mutex reference MUST NOT be empty
87 StorInternalData_Impl( const SotMutexHolderRef& rMutexRef, sal_Bool bRoot, sal_Int16 nStorType, sal_Bool bReadOnlyWrap )
88 : m_rSharedMutexRef( rMutexRef )
89 , m_aListenersContainer( rMutexRef->GetMutex() )
90 , m_pTypeCollection( NULL )
91 , m_bIsRoot( bRoot )
92 , m_nStorageType( nStorType )
93 , m_bReadOnlyWrap( bReadOnlyWrap )
94 , m_pSubElDispListener( NULL )
97 ~StorInternalData_Impl();
100 //=========================================================
102 extern uno::Sequence< sal_Int8 > MakeKeyFromPass( ::rtl::OUString aPass, sal_Bool bUseUTF );
104 ::rtl::OUString GetNewTempFileURL( const uno::Reference< lang::XMultiServiceFactory > xFactory );
106 // static
107 void OStorage_Impl::completeStorageStreamCopy_Impl(
108 const uno::Reference< io::XStream >& xSource,
109 const uno::Reference< io::XStream >& xDest,
110 sal_Int16 nStorageType,
111 const uno::Sequence< uno::Sequence< beans::StringPair > >& aRelInfo )
113 uno::Reference< beans::XPropertySet > xSourceProps( xSource, uno::UNO_QUERY );
114 uno::Reference< beans::XPropertySet > xDestProps( xDest, uno::UNO_QUERY );
115 if ( !xSourceProps.is() || !xDestProps.is() )
116 throw uno::RuntimeException(); //TODO
118 uno::Reference< io::XOutputStream > xDestOutStream = xDest->getOutputStream();
119 if ( !xDestOutStream.is() )
120 throw io::IOException(); // TODO
122 uno::Reference< io::XInputStream > xSourceInStream = xSource->getInputStream();
123 if ( !xSourceInStream.is() )
124 throw io::IOException(); // TODO
126 // TODO: headers of encripted streams should be copied also
127 ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInStream, xDestOutStream );
129 uno::Sequence< ::rtl::OUString > aPropNames( 1 );
130 aPropNames[0] = ::rtl::OUString::createFromAscii( "Compressed" );
132 if ( nStorageType == PACKAGE_STORAGE )
134 aPropNames.realloc( 3 );
135 aPropNames[1] = ::rtl::OUString::createFromAscii( "MediaType" );
136 aPropNames[2] = ::rtl::OUString::createFromAscii( "UseCommonStoragePasswordEncryption" );
138 else if ( nStorageType == OFOPXML_STORAGE )
140 // TODO/LATER: in future it might make sence to provide the stream if there is one
141 uno::Reference< embed::XRelationshipAccess > xRelAccess( xDest, uno::UNO_QUERY_THROW );
142 xRelAccess->clearRelationships();
143 xRelAccess->insertRelationships( aRelInfo, sal_False );
145 aPropNames.realloc( 2 );
146 aPropNames[1] = ::rtl::OUString::createFromAscii( "MediaType" );
149 for ( int ind = 0; ind < aPropNames.getLength(); ind++ )
150 xDestProps->setPropertyValue( aPropNames[ind], xSourceProps->getPropertyValue( aPropNames[ind] ) );
153 uno::Reference< io::XInputStream > GetSeekableTempCopy( uno::Reference< io::XInputStream > xInStream,
154 uno::Reference< lang::XMultiServiceFactory > xFactory )
156 uno::Reference < io::XOutputStream > xTempOut(
157 xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
158 uno::UNO_QUERY );
159 uno::Reference < io::XInputStream > xTempIn( xTempOut, uno::UNO_QUERY );
161 if ( !xTempOut.is() || !xTempIn.is() )
162 throw io::IOException();
164 ::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xTempOut );
165 xTempOut->closeOutput();
167 return xTempIn;
170 StorInternalData_Impl::~StorInternalData_Impl()
172 if ( m_pTypeCollection )
173 delete m_pTypeCollection;
177 SotElement_Impl::SotElement_Impl( const ::rtl::OUString& rName, sal_Bool bStor, sal_Bool bNew )
178 : m_aName( rName )
179 , m_aOriginalName( rName )
180 , m_bIsRemoved( sal_False )
181 , m_bIsInserted( bNew )
182 , m_bIsStorage( bStor )
183 , m_pStorage( NULL )
184 , m_pStream( NULL )
188 SotElement_Impl::~SotElement_Impl()
190 if ( m_pStorage )
191 delete m_pStorage;
193 if ( m_pStream )
194 delete m_pStream;
197 //-----------------------------------------------
198 // most of properties are holt by the storage but are not used
199 OStorage_Impl::OStorage_Impl( uno::Reference< io::XInputStream > xInputStream,
200 sal_Int32 nMode,
201 uno::Sequence< beans::PropertyValue > xProperties,
202 uno::Reference< lang::XMultiServiceFactory > xFactory,
203 sal_Int16 nStorageType )
204 : m_rMutexRef( new SotMutexHolder )
205 , m_pAntiImpl( NULL )
206 , m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
207 , m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
208 , m_bBroadcastModified( sal_False )
209 , m_bCommited( sal_False )
210 , m_bIsRoot( sal_True )
211 , m_bListCreated( sal_False )
212 , m_xFactory( xFactory )
213 , m_xProperties( xProperties )
214 , m_bHasCommonPassword( sal_False )
215 , m_pParent( NULL )
216 , m_bControlMediaType( sal_False )
217 , m_bMTFallbackUsed( sal_False )
218 , m_bControlVersion( sal_False )
219 , m_pSwitchStream( NULL )
220 , m_nStorageType( nStorageType )
221 , m_pRelStorElement( NULL )
222 , m_nRelInfoStatus( RELINFO_NO_INIT )
224 // all the checks done below by assertion statements must be done by factory
225 OSL_ENSURE( xInputStream.is(), "No input stream is provided!\n" );
227 m_pSwitchStream = (SwitchablePersistenceStream*) new SwitchablePersistenceStream( xFactory, xInputStream );
228 m_xInputStream = m_pSwitchStream->getInputStream();
230 if ( m_nStorageMode & embed::ElementModes::WRITE )
232 // check that the stream allows to write
233 OSL_ENSURE( sal_False, "No stream for writing is provided!\n" );
237 //-----------------------------------------------
238 // most of properties are holt by the storage but are not used
239 OStorage_Impl::OStorage_Impl( uno::Reference< io::XStream > xStream,
240 sal_Int32 nMode,
241 uno::Sequence< beans::PropertyValue > xProperties,
242 uno::Reference< lang::XMultiServiceFactory > xFactory,
243 sal_Int16 nStorageType )
244 : m_rMutexRef( new SotMutexHolder )
245 , m_pAntiImpl( NULL )
246 , m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
247 , m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
248 , m_bBroadcastModified( sal_False )
249 , m_bCommited( sal_False )
250 , m_bIsRoot( sal_True )
251 , m_bListCreated( sal_False )
252 , m_xFactory( xFactory )
253 , m_xProperties( xProperties )
254 , m_bHasCommonPassword( sal_False )
255 , m_pParent( NULL )
256 , m_bControlMediaType( sal_False )
257 , m_bMTFallbackUsed( sal_False )
258 , m_bControlVersion( sal_False )
259 , m_pSwitchStream( NULL )
260 , m_nStorageType( nStorageType )
261 , m_pRelStorElement( NULL )
262 , m_nRelInfoStatus( RELINFO_NO_INIT )
264 // all the checks done below by assertion statements must be done by factory
265 OSL_ENSURE( xStream.is(), "No stream is provided!\n" );
267 if ( m_nStorageMode & embed::ElementModes::WRITE )
269 m_pSwitchStream = (SwitchablePersistenceStream*) new SwitchablePersistenceStream( xFactory, xStream );
270 m_xStream = static_cast< io::XStream* >( m_pSwitchStream );
272 else
274 m_pSwitchStream = (SwitchablePersistenceStream*) new SwitchablePersistenceStream( xFactory,
275 xStream->getInputStream() );
276 m_xInputStream = m_pSwitchStream->getInputStream();
280 //-----------------------------------------------
281 OStorage_Impl::OStorage_Impl( OStorage_Impl* pParent,
282 sal_Int32 nMode,
283 uno::Reference< container::XNameContainer > xPackageFolder,
284 uno::Reference< lang::XSingleServiceFactory > xPackage,
285 uno::Reference< lang::XMultiServiceFactory > xFactory,
286 sal_Int16 nStorageType )
287 : m_rMutexRef( new SotMutexHolder )
288 , m_pAntiImpl( NULL )
289 , m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
290 , m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
291 , m_bBroadcastModified( sal_False )
292 , m_bCommited( sal_False )
293 , m_bIsRoot( sal_False )
294 , m_bListCreated( sal_False )
295 , m_xPackageFolder( xPackageFolder )
296 , m_xPackage( xPackage )
297 , m_xFactory( xFactory )
298 , m_bHasCommonPassword( sal_False )
299 , m_pParent( pParent ) // can be empty in case of temporary readonly substorages and relation storage
300 , m_bControlMediaType( sal_False )
301 , m_bMTFallbackUsed( sal_False )
302 , m_bControlVersion( sal_False )
303 , m_pSwitchStream( NULL )
304 , m_nStorageType( nStorageType )
305 , m_pRelStorElement( NULL )
306 , m_nRelInfoStatus( RELINFO_NO_INIT )
308 OSL_ENSURE( xPackageFolder.is(), "No package folder!\n" );
311 //-----------------------------------------------
312 OStorage_Impl::~OStorage_Impl()
315 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
316 if ( m_pAntiImpl ) // root storage wrapper must set this member to NULL before destruction of object
318 OSL_ENSURE( !m_bIsRoot, "The root storage wrapper must be disposed already" );
320 try {
321 m_pAntiImpl->InternalDispose( sal_False );
323 catch ( uno::Exception& )
325 m_pAntiImpl = NULL;
327 else if ( !m_aReadOnlyWrapList.empty() )
329 for ( OStorageList_Impl::iterator pStorageIter = m_aReadOnlyWrapList.begin();
330 pStorageIter != m_aReadOnlyWrapList.end(); pStorageIter++ )
332 uno::Reference< embed::XStorage > xTmp = pStorageIter->m_xWeakRef;
333 if ( xTmp.is() )
334 try {
335 pStorageIter->m_pPointer->InternalDispose( sal_False );
336 } catch( uno::Exception& ) {}
339 m_aReadOnlyWrapList.clear();
342 m_pParent = NULL;
345 for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
346 pElementIter != m_aChildrenList.end(); pElementIter++ )
347 delete *pElementIter;
349 m_aChildrenList.clear();
351 for ( SotElementList_Impl::iterator pDeletedIter = m_aDeletedList.begin();
352 pDeletedIter != m_aDeletedList.end(); pDeletedIter++ )
353 delete *pDeletedIter;
355 m_aDeletedList.clear();
357 if ( m_nStorageType == OFOPXML_STORAGE && m_pRelStorElement )
359 delete m_pRelStorElement;
360 m_pRelStorElement = NULL;
363 m_xPackageFolder = uno::Reference< container::XNameContainer >();
364 m_xPackage = uno::Reference< lang::XSingleServiceFactory >();
366 ::rtl::OUString aPropertyName = ::rtl::OUString::createFromAscii( "URL" );
367 for ( sal_Int32 aInd = 0; aInd < m_xProperties.getLength(); aInd++ )
369 if ( m_xProperties[aInd].Name.equals( aPropertyName ) )
371 // the storage is URL based so all the streams are opened by factory and should be closed
374 if ( m_xInputStream.is() )
376 m_xInputStream->closeInput();
377 m_xInputStream = uno::Reference< io::XInputStream >();
380 if ( m_xStream.is() )
382 uno::Reference< io::XInputStream > xInStr = m_xStream->getInputStream();
383 if ( xInStr.is() )
384 xInStr->closeInput();
386 uno::Reference< io::XOutputStream > xOutStr = m_xStream->getOutputStream();
387 if ( xOutStr.is() )
388 xOutStr->closeOutput();
390 m_xStream = uno::Reference< io::XStream >();
393 catch( uno::Exception& )
399 //-----------------------------------------------
400 void OStorage_Impl::SetReadOnlyWrap( OStorage& aStorage )
402 // Weak reference is used inside the holder so the refcount must not be zero at this point
403 OSL_ENSURE( aStorage.GetRefCount_Impl(), "There must be a reference alive to use this method!\n" );
404 m_aReadOnlyWrapList.push_back( StorageHolder_Impl( &aStorage ) );
407 //-----------------------------------------------
408 void OStorage_Impl::RemoveReadOnlyWrap( OStorage& aStorage )
410 for ( OStorageList_Impl::iterator pStorageIter = m_aReadOnlyWrapList.begin();
411 pStorageIter != m_aReadOnlyWrapList.end();)
413 uno::Reference< embed::XStorage > xTmp = pStorageIter->m_xWeakRef;
414 if ( !xTmp.is() || pStorageIter->m_pPointer == &aStorage )
416 try {
417 pStorageIter->m_pPointer->InternalDispose( sal_False );
418 } catch( uno::Exception& ) {}
420 OStorageList_Impl::iterator pIterToDelete( pStorageIter );
421 pStorageIter++;
422 m_aReadOnlyWrapList.erase( pIterToDelete );
424 else
425 pStorageIter++;
429 //-----------------------------------------------
430 void OStorage_Impl::OpenOwnPackage()
432 OSL_ENSURE( m_bIsRoot, "Opening of the package has no sence!\n" );
434 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
436 if ( !m_xPackageFolder.is() )
438 if ( !m_xPackage.is() )
440 uno::Sequence< uno::Any > aArguments( 2 );
441 if ( m_nStorageMode & embed::ElementModes::WRITE )
442 aArguments[ 0 ] <<= m_xStream;
443 else
445 OSL_ENSURE( m_xInputStream.is(), "Input stream must be set for readonly access!\n" );
446 aArguments[ 0 ] <<= m_xInputStream;
447 // TODO: if input stream is not seekable or XSeekable interface is supported
448 // on XStream object a wrapper must be used
451 // do not allow elements to remove themself from the old container in case of insertion to another container
452 aArguments[ 1 ] <<= beans::NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowRemoveOnInsert" ) ),
453 uno::makeAny( (sal_Bool)sal_False ) );
455 sal_Int32 nArgNum = 2;
456 for ( sal_Int32 aInd = 0; aInd < m_xProperties.getLength(); aInd++ )
458 if ( m_xProperties[aInd].Name.equalsAscii( "RepairPackage" )
459 || m_xProperties[aInd].Name.equalsAscii( "ProgressHandler" ) )
461 beans::NamedValue aNamedValue( m_xProperties[aInd].Name,
462 m_xProperties[aInd].Value );
463 aArguments.realloc( ++nArgNum );
464 aArguments[nArgNum-1] <<= aNamedValue;
466 else if ( m_xProperties[aInd].Name.equalsAscii( "Password" ) )
468 // TODO: implement password setting for documents
469 // the password entry must be removed after setting
473 if ( m_nStorageType == ZIP_STORAGE )
475 // let the package support only plain zip format
476 beans::NamedValue aNamedValue;
477 aNamedValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
478 aNamedValue.Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ZipFormat" ) );
479 aArguments.realloc( ++nArgNum );
480 aArguments[nArgNum-1] <<= aNamedValue;
482 else if ( m_nStorageType == OFOPXML_STORAGE )
484 // let the package support OFOPXML media type handling
485 beans::NamedValue aNamedValue;
486 aNamedValue.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
487 aNamedValue.Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OFOPXMLFormat" ) );
488 aArguments.realloc( ++nArgNum );
489 aArguments[nArgNum-1] <<= aNamedValue;
492 m_xPackage = uno::Reference< lang::XSingleServiceFactory > (
493 GetServiceFactory()->createInstanceWithArguments(
494 ::rtl::OUString::createFromAscii( "com.sun.star.packages.comp.ZipPackage" ),
495 aArguments ),
496 uno::UNO_QUERY );
499 uno::Reference< container::XHierarchicalNameAccess > xHNameAccess( m_xPackage, uno::UNO_QUERY );
500 OSL_ENSURE( xHNameAccess.is(), "The package could not be created!\n" );
502 if ( xHNameAccess.is() )
504 uno::Any aFolder = xHNameAccess->getByHierarchicalName( ::rtl::OUString::createFromAscii( "/" ) );
505 aFolder >>= m_xPackageFolder;
509 OSL_ENSURE( m_xPackageFolder.is(), "The package root folder can not be opened!\n" );
510 if ( !m_xPackageFolder.is() )
511 throw embed::InvalidStorageException(); // TODO
514 //-----------------------------------------------
515 uno::Reference< lang::XMultiServiceFactory > OStorage_Impl::GetServiceFactory()
517 if ( m_xFactory.is() )
518 return m_xFactory;
520 return ::comphelper::getProcessServiceFactory();
523 //-----------------------------------------------
524 SotElementList_Impl& OStorage_Impl::GetChildrenList()
526 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
528 ReadContents();
529 return m_aChildrenList;
532 //-----------------------------------------------
533 void OStorage_Impl::GetStorageProperties()
535 if ( m_nStorageType == PACKAGE_STORAGE )
537 uno::Reference< beans::XPropertySet > xProps( m_xPackageFolder, uno::UNO_QUERY_THROW );
539 if ( !m_bControlMediaType )
541 uno::Reference< beans::XPropertySet > xPackageProps( m_xPackage, uno::UNO_QUERY_THROW );
542 xPackageProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaTypeFallbackUsed" ) ) ) >>= m_bMTFallbackUsed;
544 xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ) ) >>= m_aMediaType;
545 m_bControlMediaType = sal_True;
548 if ( !m_bControlVersion )
550 xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= m_aVersion;
551 m_bControlVersion = sal_True;
555 // the properties of OFOPXML will be handled directly
558 //-----------------------------------------------
559 void OStorage_Impl::ReadRelInfoIfNecessary()
561 if ( m_nStorageType != OFOPXML_STORAGE )
562 return;
564 if ( m_nRelInfoStatus == RELINFO_NO_INIT )
566 // Init from original stream
567 uno::Reference< io::XInputStream > xRelInfoStream = GetRelInfoStreamForName( ::rtl::OUString() );
568 if ( xRelInfoStream.is() )
569 m_aRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
570 xRelInfoStream,
571 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/.rels" ) ),
572 m_xFactory );
574 m_nRelInfoStatus = RELINFO_READ;
576 else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
578 // Init from the new stream
581 if ( m_xNewRelInfoStream.is() )
582 m_aRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
583 m_xNewRelInfoStream,
584 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/.rels" ) ),
585 m_xFactory );
587 m_nRelInfoStatus = RELINFO_CHANGED_STREAM_READ;
589 catch( uno::Exception )
591 m_nRelInfoStatus = RELINFO_CHANGED_BROKEN;
596 //-----------------------------------------------
597 void OStorage_Impl::ReadContents()
599 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
601 if ( m_bListCreated )
602 return;
604 if ( m_bIsRoot )
605 OpenOwnPackage();
607 uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xPackageFolder, uno::UNO_QUERY );
608 if ( !xEnumAccess.is() )
609 throw uno::RuntimeException(); // TODO:
611 uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration();
612 if ( !xEnum.is() )
613 throw uno::RuntimeException(); // TODO:
615 m_bListCreated = sal_True;
617 while( xEnum->hasMoreElements() )
619 try {
620 uno::Reference< container::XNamed > xNamed;
621 xEnum->nextElement() >>= xNamed;
623 if ( !xNamed.is() )
625 OSL_ENSURE( sal_False, "XNamed is not supported!\n" );
626 throw uno::RuntimeException(); // TODO:
629 ::rtl::OUString aName = xNamed->getName();
630 OSL_ENSURE( aName.getLength(), "Empty name!\n" );
632 uno::Reference< container::XNameContainer > xNameContainer( xNamed, uno::UNO_QUERY );
634 SotElement_Impl* pNewElement = new SotElement_Impl( aName, xNameContainer.is(), sal_False );
635 if ( m_nStorageType == OFOPXML_STORAGE && aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
637 if ( !pNewElement->m_bIsStorage )
638 throw io::IOException(); // TODO: Unexpected format
640 m_pRelStorElement = pNewElement;
641 CreateRelStorage();
643 else
645 if ( ( m_nStorageMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE )
647 // if a storage is truncated all of it elements are marked as deleted
648 pNewElement->m_bIsRemoved = sal_True;
651 m_aChildrenList.push_back( pNewElement );
654 catch( container::NoSuchElementException& )
656 OSL_ENSURE( sal_False, "hasMoreElements() implementation has problems!\n" );
657 break;
660 if ( ( m_nStorageMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE )
662 // if a storage is truncated the relations information should be cleaned
663 m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
664 m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
665 m_nRelInfoStatus = RELINFO_CHANGED;
668 // cache changeable folder properties
669 GetStorageProperties();
672 //-----------------------------------------------
673 void OStorage_Impl::CopyToStorage( const uno::Reference< embed::XStorage >& xDest, sal_Bool bDirect )
675 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
677 uno::Reference< beans::XPropertySet > xPropSet( xDest, uno::UNO_QUERY );
678 if ( !xPropSet.is() )
679 throw lang::IllegalArgumentException(); // TODO:
681 sal_Int32 nDestMode = embed::ElementModes::READ;
682 xPropSet->getPropertyValue( ::rtl::OUString::createFromAscii( "OpenMode" ) ) >>= nDestMode;
684 if ( !( nDestMode & embed::ElementModes::WRITE ) )
685 throw io::IOException(); // TODO: access_denied
687 ReadContents();
689 if ( !m_xPackageFolder.is() )
690 throw embed::InvalidStorageException(); // TODO:
692 for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
693 pElementIter != m_aChildrenList.end(); pElementIter++ )
695 if ( !(*pElementIter)->m_bIsRemoved )
696 CopyStorageElement( *pElementIter, xDest, (*pElementIter)->m_aName, bDirect );
699 // move storage properties to the destination one ( means changeable properties )
700 if ( m_nStorageType == PACKAGE_STORAGE )
702 ::rtl::OUString aMediaTypeString = ::rtl::OUString::createFromAscii( "MediaType" );
703 ::rtl::OUString aVersionString = ::rtl::OUString::createFromAscii( "Version" );
704 xPropSet->setPropertyValue( aMediaTypeString, uno::makeAny( m_aMediaType ) );
705 xPropSet->setPropertyValue( aVersionString, uno::makeAny( m_aVersion ) );
708 if ( m_nStorageType == PACKAGE_STORAGE )
710 // if this is a root storage, the common key from current one should be moved there
711 sal_Bool bIsRoot = sal_False;
712 ::rtl::OUString aRootString = ::rtl::OUString::createFromAscii( "IsRoot" );
713 if ( ( xPropSet->getPropertyValue( aRootString ) >>= bIsRoot ) && bIsRoot )
717 ::rtl::OUString aCommonPass = GetCommonRootPass();
718 uno::Reference< embed::XEncryptionProtectedSource > xEncr( xDest, uno::UNO_QUERY );
719 if ( xEncr.is() )
720 xEncr->setEncryptionPassword( aCommonPass );
722 catch( packages::NoEncryptionException& )
726 else if ( m_nStorageType == OFOPXML_STORAGE )
729 // TODO/LATER: currently the optimization is not active
730 // uno::Reference< io::XInputStream > xRelInfoStream = GetRelInfoStreamForName( ::rtl::OUString() ); // own stream
731 // if ( xRelInfoStream.is() )
732 // {
733 // // Relations info stream is a writeonly property, introduced only to optimyze copying
734 // // Should be used carefuly since no check for stream consistency is done, and the stream must not stay locked
736 // ::rtl::OUString aRelInfoString = ::rtl::OUString::createFromAscii( "RelationsInfoStream" );
737 // xPropSet->setPropertyValue( aRelInfoString, uno::makeAny( GetSeekableTempCopy( xRelInfoStream, m_xFactory ) ) );
738 // }
740 uno::Reference< embed::XRelationshipAccess > xRels( xDest, uno::UNO_QUERY );
741 if ( !xRels.is() )
742 throw lang::IllegalArgumentException(); // TODO:
744 xRels->insertRelationships( GetAllRelationshipsIfAny(), sal_False );
747 // if possible the destination storage should be commited after successful copying
748 uno::Reference< embed::XTransactedObject > xObjToCommit( xDest, uno::UNO_QUERY );
749 if ( xObjToCommit.is() )
750 xObjToCommit->commit();
753 //-----------------------------------------------
754 void OStorage_Impl::CopyStorageElement( SotElement_Impl* pElement,
755 uno::Reference< embed::XStorage > xDest,
756 ::rtl::OUString aName,
757 sal_Bool bDirect )
759 OSL_ENSURE( xDest.is(), "No destination storage!\n" );
760 OSL_ENSURE( aName.getLength(), "Empty element name!\n" );
762 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
764 uno::Reference< container::XNameAccess > xDestAccess( xDest, uno::UNO_QUERY );
765 if ( !xDestAccess.is() )
766 throw uno::RuntimeException();
768 if ( xDestAccess->hasByName( aName )
769 && !( pElement->m_bIsStorage && xDest->isStorageElement( aName ) ) )
770 xDest->removeElement( aName );
772 if ( pElement->m_bIsStorage )
774 uno::Reference< embed::XStorage > xSubDest =
775 xDest->openStorageElement( aName,
776 embed::ElementModes::WRITE );
778 OSL_ENSURE( xSubDest.is(), "No destination substorage!\n" );
780 if ( !pElement->m_pStorage )
782 OpenSubStorage( pElement, embed::ElementModes::READ );
783 if ( !pElement->m_pStorage )
784 throw io::IOException(); // TODO
787 pElement->m_pStorage->CopyToStorage( xSubDest, bDirect );
789 else
791 if ( !pElement->m_pStream )
793 OpenSubStream( pElement );
794 if ( !pElement->m_pStream )
795 throw io::IOException(); // TODO
798 if ( !pElement->m_pStream->IsEncrypted() )
800 if ( bDirect )
802 // fill in the properties for the stream
803 uno::Sequence< beans::PropertyValue > aStrProps(0);
804 uno::Sequence< beans::PropertyValue > aSrcPkgProps = pElement->m_pStream->GetStreamProperties();
805 sal_Int32 nNum = 0;
806 for ( int ind = 0; ind < aSrcPkgProps.getLength(); ind++ )
808 if ( aSrcPkgProps[ind].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "MediaType" ) ) )
809 || aSrcPkgProps[ind].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "Compressed" ) ) ) )
811 aStrProps.realloc( ++nNum );
812 aStrProps[nNum-1].Name = aSrcPkgProps[ind].Name;
813 aStrProps[nNum-1].Value = aSrcPkgProps[ind].Value;
817 if ( m_nStorageType == PACKAGE_STORAGE )
819 aStrProps.realloc( ++nNum );
820 aStrProps[nNum-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
821 aStrProps[nNum-1].Value <<= (sal_Bool)( pElement->m_pStream->UsesCommonPass_Impl() );
823 else if ( m_nStorageType == OFOPXML_STORAGE )
825 // TODO/LATER: currently the optimization is not active
826 // uno::Reference< io::XInputStream > xInStream = GetRelInfoStreamForName( ::rtl::OUString() ); // own rels stream
827 // if ( xInStream.is() )
828 // {
829 // aStrProps.realloc( ++nNum );
830 // aStrProps[nNum-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RelationsInfoStream" ) );
831 // aStrProps[nNum-1].Value <<= GetSeekableTempCopy( xInStream, m_xFactory );
832 // }
834 uno::Reference< embed::XRelationshipAccess > xRels( xDest, uno::UNO_QUERY );
835 if ( !xRels.is() )
836 throw lang::IllegalArgumentException(); // TODO:
838 xRels->insertRelationships( GetAllRelationshipsIfAny(), sal_False );
841 uno::Reference< embed::XOptimizedStorage > xOptDest( xDest, uno::UNO_QUERY_THROW );
842 uno::Reference < io::XInputStream > xInputToInsert;
844 if ( pElement->m_pStream->HasTempFile_Impl() || !pElement->m_pStream->m_xPackageStream.is() )
846 OSL_ENSURE( pElement->m_pStream->m_xPackageStream.is(), "No package stream!" );
848 // if the stream is modified - the temporary file must be used for insertion
849 xInputToInsert = pElement->m_pStream->GetTempFileAsInputStream();
851 else
853 // for now get just nonseekable access to the stream
854 // TODO/LATER: the raw stream can be used
856 xInputToInsert = pElement->m_pStream->m_xPackageStream->getDataStream();
859 if ( !xInputToInsert.is() )
860 throw io::IOException(); // TODO
862 xOptDest->insertStreamElementDirect( aName, xInputToInsert, aStrProps );
864 else
866 uno::Reference< io::XStream > xSubStr =
867 xDest->openStreamElement( aName,
868 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
869 OSL_ENSURE( xSubStr.is(), "No destination substream!\n" );
871 pElement->m_pStream->CopyInternallyTo_Impl( xSubStr );
874 else if ( m_nStorageType != PACKAGE_STORAGE )
876 OSL_ENSURE( sal_False, "Encryption is only supported in package storage!\n" );
877 throw io::IOException(); // TODO
879 else if ( pElement->m_pStream->HasCachedPassword()
880 && ( pElement->m_pStream->IsModified() || pElement->m_pStream->HasWriteOwner_Impl() ) )
882 ::rtl::OUString aCommonPass;
883 sal_Bool bHasCommonPass = sal_False;
886 aCommonPass = GetCommonRootPass();
887 bHasCommonPass = sal_True;
889 catch( packages::NoEncryptionException& )
892 if ( bHasCommonPass && pElement->m_pStream->GetCachedPassword().equals( aCommonPass ) )
894 // If the stream can be opened with the common storage password
895 // it must be stored with the common storage password as well
896 uno::Reference< io::XStream > xDestStream =
897 xDest->openStreamElement( aName,
898 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
900 pElement->m_pStream->CopyInternallyTo_Impl( xDestStream );
902 uno::Reference< beans::XPropertySet > xProps( xDestStream, uno::UNO_QUERY_THROW );
903 xProps->setPropertyValue(
904 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ),
905 uno::Any( (sal_Bool) sal_True ) );
907 else
909 // the stream is already opened for writing or was changed
910 uno::Reference< io::XStream > xSubStr =
911 xDest->openEncryptedStreamElement( aName,
912 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE,
913 pElement->m_pStream->GetCachedPassword() );
914 OSL_ENSURE( xSubStr.is(), "No destination substream!\n" );
916 pElement->m_pStream->CopyInternallyTo_Impl( xSubStr, pElement->m_pStream->GetCachedPassword() );
919 else
921 // the stream is not opened at all, so it can be just opened for reading
924 // If the stream can be opened with the common storage password
925 // it must be stored with the common storage password as well
927 uno::Reference< io::XStream > xOwnStream = pElement->m_pStream->GetStream( embed::ElementModes::READ,
928 sal_False );
929 uno::Reference< io::XStream > xDestStream =
930 xDest->openStreamElement( aName,
931 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
932 OSL_ENSURE( xDestStream.is(), "No destination substream!\n" );
933 completeStorageStreamCopy_Impl( xOwnStream, xDestStream, m_nStorageType, GetAllRelationshipsIfAny() );
935 uno::Reference< beans::XPropertySet > xProps( xDestStream, uno::UNO_QUERY_THROW );
936 xProps->setPropertyValue(
937 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) ),
938 uno::Any( (sal_Bool) sal_True ) );
940 catch( packages::WrongPasswordException& )
942 // If the common storage password does not allow to open the stream
943 // it must be copyed in raw way
944 uno::Reference< embed::XStorageRawAccess > xRawDest( xDest, uno::UNO_QUERY_THROW );
945 uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetRawInStream();
946 xRawDest->insertRawEncrStreamElement( aName, xRawInStream );
952 //-----------------------------------------------
953 uno::Sequence< uno::Sequence< beans::StringPair > > OStorage_Impl::GetAllRelationshipsIfAny()
955 if ( m_nStorageType != OFOPXML_STORAGE )
956 return uno::Sequence< uno::Sequence< beans::StringPair > >();
958 ReadRelInfoIfNecessary();
960 if ( m_nRelInfoStatus == RELINFO_READ
961 || m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ || m_nRelInfoStatus == RELINFO_CHANGED )
962 return m_aRelInfo;
963 else // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
964 throw io::IOException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Wrong relinfo stream!" ) ),
965 uno::Reference< uno::XInterface >() );
968 //-----------------------------------------------
969 void OStorage_Impl::CopyLastCommitTo( const uno::Reference< embed::XStorage >& xNewStor )
971 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
973 OSL_ENSURE( m_xPackageFolder.is(), "A commited storage is incomplete!\n" );
974 if ( !m_xPackageFolder.is() )
975 throw uno::RuntimeException();
977 OStorage_Impl aTempRepresent( NULL,
978 embed::ElementModes::READ,
979 m_xPackageFolder,
980 m_xPackage,
981 m_xFactory,
982 m_nStorageType);
984 // TODO/LATER: could use direct copying
985 aTempRepresent.CopyToStorage( xNewStor, sal_False );
988 //-----------------------------------------------
989 void OStorage_Impl::InsertIntoPackageFolder( const ::rtl::OUString& aName,
990 const uno::Reference< container::XNameContainer >& xParentPackageFolder )
992 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
994 OSL_ENSURE( m_xPackageFolder.is(), "An inserted storage is incomplete!\n" );
995 uno::Reference< lang::XUnoTunnel > xTunnel( m_xPackageFolder, uno::UNO_QUERY );
996 if ( !xTunnel.is() )
997 throw uno::RuntimeException(); // TODO
999 xParentPackageFolder->insertByName( aName, uno::makeAny( xTunnel ) );
1001 m_bCommited = sal_False;
1004 //-----------------------------------------------
1005 void OStorage_Impl::Commit()
1007 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1009 if ( !m_bIsModified )
1010 return;
1012 // in case of a new empty storage it is possible that the contents are still not read
1013 // ( the storage of course has no contents, but the initialization is postponed till the first use,
1014 // thus if a new storage was created and commited immediatelly it must be initialized here )
1015 ReadContents();
1017 // if storage is commited it should have a valid Package representation
1018 OSL_ENSURE( m_xPackageFolder.is(), "The package representation should exist!\n" );
1019 if ( !m_xPackageFolder.is() )
1020 throw embed::InvalidStorageException(); // TODO:
1022 OSL_ENSURE( m_nStorageMode & embed::ElementModes::WRITE,
1023 "Commit of readonly storage, should be detected before!\n" );
1025 uno::Reference< container::XNameContainer > xNewPackageFolder;
1027 // here the storage will switch to the temporary package folder
1028 // if the storage was already commited and the parent was not commited after that
1029 // the switch should not be done since the package folder in use is a temporary one;
1030 // it can be detected by m_bCommited flag ( root storage doesn't need temporary representation )
1031 if ( !m_bCommited && !m_bIsRoot )
1033 uno::Sequence< uno::Any > aSeq( 1 );
1034 aSeq[0] <<= sal_True;
1036 xNewPackageFolder = uno::Reference< container::XNameContainer >(
1037 m_xPackage->createInstanceWithArguments( aSeq ),
1038 uno::UNO_QUERY );
1040 else
1041 xNewPackageFolder = m_xPackageFolder;
1043 // remove replaced removed elements
1044 for ( SotElementList_Impl::iterator pDeletedIter = m_aDeletedList.begin();
1045 pDeletedIter != m_aDeletedList.end();
1046 pDeletedIter++ )
1049 if ( m_nStorageType == OFOPXML_STORAGE && !(*pDeletedIter)->m_bIsStorage )
1050 RemoveStreamRelInfo( (*pDeletedIter)->m_aOriginalName );
1052 // the removed elements are not in new temporary storage
1053 if ( m_bCommited || m_bIsRoot )
1054 xNewPackageFolder->removeByName( (*pDeletedIter)->m_aOriginalName );
1055 delete *pDeletedIter;
1056 *pDeletedIter = NULL;
1058 m_aDeletedList.clear();
1060 // remove removed elements
1061 SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1062 while ( pElementIter != m_aChildrenList.end() )
1064 // renamed and inserted elements must be really inserted to package later
1065 // since thay can conflict with removed elements
1067 if ( (*pElementIter)->m_bIsRemoved )
1069 if ( m_nStorageType == OFOPXML_STORAGE && !(*pElementIter)->m_bIsStorage )
1070 RemoveStreamRelInfo( (*pElementIter)->m_aOriginalName );
1072 // the removed elements are not in new temporary storage
1073 if ( m_bCommited || m_bIsRoot )
1074 xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1076 SotElement_Impl* pToDelete = *pElementIter;
1078 pElementIter++; // to let the iterator be valid it should be increased before removing
1080 m_aChildrenList.remove( pToDelete );
1081 delete pToDelete;
1083 else
1084 pElementIter++;
1087 // there should be no more deleted elements
1088 for ( pElementIter = m_aChildrenList.begin(); pElementIter != m_aChildrenList.end(); pElementIter++ )
1090 // if it is a 'duplicate commit' inserted elements must be really inserted to package later
1091 // since thay can conflict with renamed elements
1093 if ( !(*pElementIter)->m_bIsInserted )
1095 // for now stream is opened in direct mode that means that in case
1096 // storage is commited all the streams from it are commited in current state.
1097 // following two steps are separated to allow easily implement transacted mode
1098 // for streams if we need it in future.
1099 // Only hierarchical access uses transacted streams currently
1100 if ( !(*pElementIter)->m_bIsStorage && (*pElementIter)->m_pStream
1101 && !(*pElementIter)->m_pStream->IsTransacted() )
1102 (*pElementIter)->m_pStream->Commit();
1104 // if the storage was not open, there is no need to commit it ???
1105 // the storage should be checked that it is commited
1106 if ( (*pElementIter)->m_bIsStorage && (*pElementIter)->m_pStorage && (*pElementIter)->m_pStorage->m_bCommited )
1108 // it's temporary PackageFolder should be inserted instead of current one
1109 // also the new copy of PackageFolder should be used by the children storages
1111 // the renamed elements are not in new temporary storage
1112 if ( m_bCommited || m_bIsRoot )
1113 xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1115 (*pElementIter)->m_pStorage->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
1117 else if ( !(*pElementIter)->m_bIsStorage && (*pElementIter)->m_pStream && (*pElementIter)->m_pStream->m_bFlushed )
1119 if ( m_nStorageType == OFOPXML_STORAGE )
1120 CommitStreamRelInfo( *pElementIter );
1122 // the renamed elements are not in new temporary storage
1123 if ( m_bCommited || m_bIsRoot )
1124 xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1126 (*pElementIter)->m_pStream->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
1128 else if ( !m_bCommited && !m_bIsRoot )
1130 // the element must be just copied to the new temporary package folder
1131 // the connection with the original package should not be lost just because
1132 // the element is still refered by the folder in the original hierarchy
1133 uno::Any aPackageElement = m_xPackageFolder->getByName( (*pElementIter)->m_aOriginalName );
1134 xNewPackageFolder->insertByName( (*pElementIter)->m_aName, aPackageElement );
1136 else if ( (*pElementIter)->m_aName.compareTo( (*pElementIter)->m_aOriginalName ) )
1138 // this is the case when xNewPackageFolder refers to m_xPackageFolder
1139 // in case the name was changed and it is not a changed storage - rename the element
1140 uno::Reference< container::XNamed > xNamed;
1141 uno::Any aPackageElement = xNewPackageFolder->getByName( (*pElementIter)->m_aOriginalName );
1142 xNewPackageFolder->removeByName( (*pElementIter)->m_aOriginalName );
1143 xNewPackageFolder->insertByName( (*pElementIter)->m_aName, aPackageElement );
1145 if ( m_nStorageType == OFOPXML_STORAGE && !(*pElementIter)->m_bIsStorage )
1147 if ( !(*pElementIter)->m_pStream )
1149 OpenSubStream( *pElementIter );
1150 if ( !(*pElementIter)->m_pStream )
1151 throw uno::RuntimeException();
1154 CommitStreamRelInfo( *pElementIter );
1158 (*pElementIter)->m_aOriginalName = (*pElementIter)->m_aName;
1162 for ( pElementIter = m_aChildrenList.begin(); pElementIter != m_aChildrenList.end(); pElementIter++ )
1164 // now inserted elements can be inserted to the package
1165 if ( (*pElementIter)->m_bIsInserted )
1167 (*pElementIter)->m_aOriginalName = (*pElementIter)->m_aName;
1168 uno::Reference< lang::XUnoTunnel > xNewElement;
1170 if ( (*pElementIter)->m_bIsStorage )
1172 if ( (*pElementIter)->m_pStorage->m_bCommited )
1174 OSL_ENSURE( (*pElementIter)->m_pStorage, "An inserted storage is incomplete!\n" );
1175 if ( !(*pElementIter)->m_pStorage )
1176 throw uno::RuntimeException(); // TODO
1178 (*pElementIter)->m_pStorage->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
1180 (*pElementIter)->m_bIsInserted = sal_False;
1183 else
1185 OSL_ENSURE( (*pElementIter)->m_pStream, "An inserted stream is incomplete!\n" );
1186 if ( !(*pElementIter)->m_pStream )
1187 throw uno::RuntimeException(); // TODO
1189 if ( !(*pElementIter)->m_pStream->IsTransacted() )
1190 (*pElementIter)->m_pStream->Commit();
1192 if ( (*pElementIter)->m_pStream->m_bFlushed )
1194 if ( m_nStorageType == OFOPXML_STORAGE )
1195 CommitStreamRelInfo( *pElementIter );
1197 (*pElementIter)->m_pStream->InsertIntoPackageFolder( (*pElementIter)->m_aName, xNewPackageFolder );
1199 (*pElementIter)->m_bIsInserted = sal_False;
1205 if ( m_nStorageType == PACKAGE_STORAGE )
1207 // move properties to the destination package folder
1208 uno::Reference< beans::XPropertySet > xProps( xNewPackageFolder, uno::UNO_QUERY );
1209 if ( !xProps.is() )
1210 throw uno::RuntimeException(); // TODO:
1212 xProps->setPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ), uno::makeAny( m_aMediaType ) );
1213 xProps->setPropertyValue( ::rtl::OUString::createFromAscii( "Version" ), uno::makeAny( m_aVersion ) );
1216 if ( m_nStorageType == OFOPXML_STORAGE )
1217 CommitRelInfo( xNewPackageFolder ); // store own relations and commit complete relations storage
1219 if ( m_bIsRoot )
1221 uno::Reference< util::XChangesBatch > xChangesBatch( m_xPackage, uno::UNO_QUERY );
1223 OSL_ENSURE( xChangesBatch.is(), "Impossible to commit package!\n" );
1224 if ( !xChangesBatch.is() )
1225 throw uno::RuntimeException(); // TODO
1229 xChangesBatch->commitChanges();
1231 catch( lang::WrappedTargetException& r )
1233 // the wrapped UseBackupException means that the target medium can be corrupted
1234 embed::UseBackupException aException;
1235 if ( r.TargetException >>= aException )
1237 m_xStream = uno::Reference< io::XStream >();
1238 m_xInputStream = uno::Reference< io::XInputStream >();
1239 throw aException;
1242 throw;
1245 else if ( !m_bCommited )
1247 m_xPackageFolder = xNewPackageFolder;
1248 m_bCommited = sal_True;
1251 // after commit the mediatype treated as the correct one
1252 m_bMTFallbackUsed = sal_False;
1255 //-----------------------------------------------
1256 void OStorage_Impl::Revert()
1258 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1260 if ( !( m_nStorageMode & embed::ElementModes::WRITE ) )
1261 return; // nothing to do
1263 // all the children must be removed
1264 // they will be created later on demand
1266 SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1267 while ( pElementIter != m_aChildrenList.end() )
1269 if ( (*pElementIter)->m_bIsInserted )
1271 SotElement_Impl* pToDelete = *pElementIter;
1273 pElementIter++; // to let the iterator be valid it should be increased before removing
1275 m_aChildrenList.remove( pToDelete );
1276 delete pToDelete;
1278 else
1280 ClearElement( *pElementIter );
1282 (*pElementIter)->m_aName = (*pElementIter)->m_aOriginalName;
1283 (*pElementIter)->m_bIsRemoved = sal_False;
1285 pElementIter++;
1289 // return replaced removed elements
1290 for ( SotElementList_Impl::iterator pDeletedIter = m_aDeletedList.begin();
1291 pDeletedIter != m_aDeletedList.end();
1292 pDeletedIter++ )
1294 m_aChildrenList.push_back( (*pDeletedIter) );
1296 ClearElement( *pDeletedIter );
1298 (*pDeletedIter)->m_aName = (*pDeletedIter)->m_aOriginalName;
1299 (*pDeletedIter)->m_bIsRemoved = sal_False;
1301 m_aDeletedList.clear();
1303 m_bControlMediaType = sal_False;
1304 m_bControlVersion = sal_False;
1306 GetStorageProperties();
1308 if ( m_nStorageType == OFOPXML_STORAGE )
1310 // currently the relations storage is changed only on commit
1311 m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
1312 m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
1313 m_nRelInfoStatus = RELINFO_NO_INIT;
1317 //-----------------------------------------------
1318 ::rtl::OUString OStorage_Impl::GetCommonRootPass()
1319 throw ( packages::NoEncryptionException )
1321 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() ) ;
1323 if ( m_nStorageType != PACKAGE_STORAGE )
1324 throw packages::NoEncryptionException(); // TODO:
1326 if ( m_bIsRoot )
1328 if ( !m_bHasCommonPassword )
1329 throw packages::NoEncryptionException();
1331 return m_aCommonPassword;
1333 else
1335 if ( !m_pParent )
1336 throw packages::NoEncryptionException();
1338 return m_pParent->GetCommonRootPass();
1342 //-----------------------------------------------
1343 SotElement_Impl* OStorage_Impl::FindElement( const ::rtl::OUString& rName )
1345 OSL_ENSURE( rName.getLength(), "Name is empty!" );
1347 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1349 ReadContents();
1351 for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1352 pElementIter != m_aChildrenList.end(); pElementIter++ )
1354 if ( (*pElementIter)->m_aName == rName && !(*pElementIter)->m_bIsRemoved )
1355 return *pElementIter;
1358 return NULL;
1361 //-----------------------------------------------
1362 SotElement_Impl* OStorage_Impl::InsertStream( ::rtl::OUString aName, sal_Bool bEncr )
1364 OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
1365 if ( !m_xPackage.is() )
1366 throw embed::InvalidStorageException(); // TODO
1368 uno::Sequence< uno::Any > aSeq( 1 );
1369 aSeq[0] <<= sal_False;
1370 uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1371 uno::UNO_QUERY );
1373 OSL_ENSURE( xNewElement.is(), "Not possible to create a new stream!\n" );
1374 if ( !xNewElement.is() )
1375 throw io::IOException(); // TODO:
1377 uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xNewElement, uno::UNO_QUERY );
1378 if ( !xPackageSubStream.is() )
1379 throw uno::RuntimeException(); // TODO
1381 OSL_ENSURE( m_nStorageType == PACKAGE_STORAGE || !bEncr, "Only package storage supports encryption!\n" );
1382 if ( m_nStorageType != PACKAGE_STORAGE && bEncr )
1383 throw packages::NoEncryptionException(); // TODO
1385 // the mode is not needed for storage stream internal implementation
1386 SotElement_Impl* pNewElement = InsertElement( aName, sal_False );
1387 pNewElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xFactory, bEncr, m_nStorageType );
1389 m_aChildrenList.push_back( pNewElement );
1390 m_bIsModified = sal_True;
1391 m_bBroadcastModified = sal_True;
1393 return pNewElement;
1396 //-----------------------------------------------
1397 SotElement_Impl* OStorage_Impl::InsertRawStream( ::rtl::OUString aName, const uno::Reference< io::XInputStream >& xInStream )
1399 // insert of raw stream means insert and commit
1400 OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
1401 if ( !m_xPackage.is() )
1402 throw embed::InvalidStorageException(); // TODO
1404 if ( m_nStorageType != PACKAGE_STORAGE )
1405 throw packages::NoEncryptionException(); // TODO
1407 uno::Reference< io::XSeekable > xSeek( xInStream, uno::UNO_QUERY );
1408 uno::Reference< io::XInputStream > xInStrToInsert = xSeek.is() ? xInStream :
1409 GetSeekableTempCopy( xInStream, GetServiceFactory() );
1411 uno::Sequence< uno::Any > aSeq( 1 );
1412 aSeq[0] <<= sal_False;
1413 uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1414 uno::UNO_QUERY );
1416 OSL_ENSURE( xNewElement.is(), "Not possible to create a new stream!\n" );
1417 if ( !xNewElement.is() )
1418 throw io::IOException(); // TODO:
1420 uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xNewElement, uno::UNO_QUERY );
1421 if ( !xPackageSubStream.is() )
1422 throw uno::RuntimeException(); // TODO
1424 xPackageSubStream->setRawStream( xInStrToInsert );
1426 // the mode is not needed for storage stream internal implementation
1427 SotElement_Impl* pNewElement = InsertElement( aName, sal_False );
1428 pNewElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xFactory, sal_True, m_nStorageType );
1429 // the stream is inserted and must be treated as a commited one
1430 pNewElement->m_pStream->SetToBeCommited();
1432 m_aChildrenList.push_back( pNewElement );
1433 m_bIsModified = sal_True;
1434 m_bBroadcastModified = sal_True;
1436 return pNewElement;
1439 //-----------------------------------------------
1440 OStorage_Impl* OStorage_Impl::CreateNewStorageImpl( sal_Int32 nStorageMode )
1442 OSL_ENSURE( m_xPackage.is(), "Not possible to refer to package as to factory!\n" );
1443 if ( !m_xPackage.is() )
1444 throw embed::InvalidStorageException(); // TODO
1446 uno::Sequence< uno::Any > aSeq( 1 );
1447 aSeq[0] <<= sal_True;
1448 uno::Reference< lang::XUnoTunnel > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ),
1449 uno::UNO_QUERY );
1451 OSL_ENSURE( xNewElement.is(), "Not possible to create a new storage!\n" );
1452 if ( !xNewElement.is() )
1453 throw io::IOException(); // TODO:
1455 uno::Reference< container::XNameContainer > xPackageSubFolder( xNewElement, uno::UNO_QUERY );
1456 if ( !xPackageSubFolder.is() )
1457 throw uno::RuntimeException(); // TODO:
1459 OStorage_Impl* pResult =
1460 new OStorage_Impl( this, nStorageMode, xPackageSubFolder, m_xPackage, m_xFactory, m_nStorageType );
1461 pResult->m_bIsModified = sal_True;
1463 return pResult;
1466 //-----------------------------------------------
1467 SotElement_Impl* OStorage_Impl::InsertStorage( ::rtl::OUString aName, sal_Int32 nStorageMode )
1469 SotElement_Impl* pNewElement = InsertElement( aName, sal_True );
1471 pNewElement->m_pStorage = CreateNewStorageImpl( nStorageMode );
1473 m_aChildrenList.push_back( pNewElement );
1475 return pNewElement;
1478 //-----------------------------------------------
1479 SotElement_Impl* OStorage_Impl::InsertElement( ::rtl::OUString aName, sal_Bool bIsStorage )
1481 OSL_ENSURE( FindElement( aName ) == NULL, "Should not try to insert existing element" );
1483 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1485 SotElement_Impl* pDeletedElm = NULL;
1487 for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1488 pElementIter != m_aChildrenList.end(); pElementIter++ )
1490 if ( (*pElementIter)->m_aName == aName )
1492 OSL_ENSURE( (*pElementIter)->m_bIsRemoved, "Try to insert an element instead of existing one!\n" );
1493 if ( (*pElementIter)->m_bIsRemoved )
1495 OSL_ENSURE( !(*pElementIter)->m_bIsInserted, "Inserted elements must be deleted immediatelly!\n" );
1496 pDeletedElm = *pElementIter;
1497 break;
1502 if ( pDeletedElm )
1504 if ( pDeletedElm->m_bIsStorage )
1505 OpenSubStorage( pDeletedElm, embed::ElementModes::READWRITE );
1506 else
1507 OpenSubStream( pDeletedElm );
1509 m_aChildrenList.remove( pDeletedElm ); // correct usage of list ???
1510 m_aDeletedList.push_back( pDeletedElm );
1513 // create new element
1514 return new SotElement_Impl( aName, bIsStorage, sal_True );
1517 //-----------------------------------------------
1518 void OStorage_Impl::OpenSubStorage( SotElement_Impl* pElement, sal_Int32 nStorageMode )
1520 OSL_ENSURE( pElement, "pElement is not set!\n" );
1521 OSL_ENSURE( pElement->m_bIsStorage, "Storage flag is not set!\n" );
1523 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1525 if ( !pElement->m_pStorage )
1527 OSL_ENSURE( !pElement->m_bIsInserted, "Inserted element must be created already!\n" );
1529 uno::Reference< lang::XUnoTunnel > xTunnel;
1530 m_xPackageFolder->getByName( pElement->m_aOriginalName ) >>= xTunnel;
1531 if ( !xTunnel.is() )
1532 throw container::NoSuchElementException(); // TODO:
1534 uno::Reference< container::XNameContainer > xPackageSubFolder( xTunnel, uno::UNO_QUERY );
1536 OSL_ENSURE( xPackageSubFolder.is(), "Can not get XNameContainer interface from folder!\n" );
1538 if ( !xPackageSubFolder.is() )
1539 throw uno::RuntimeException(); // TODO:
1541 pElement->m_pStorage = new OStorage_Impl( this, nStorageMode, xPackageSubFolder, m_xPackage, m_xFactory, m_nStorageType );
1545 //-----------------------------------------------
1546 void OStorage_Impl::OpenSubStream( SotElement_Impl* pElement )
1548 OSL_ENSURE( pElement, "pElement is not set!\n" );
1549 OSL_ENSURE( !pElement->m_bIsStorage, "Storage flag is set!\n" );
1551 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1553 if ( !pElement->m_pStream )
1555 OSL_ENSURE( !pElement->m_bIsInserted, "Inserted element must be created already!\n" );
1557 uno::Reference< lang::XUnoTunnel > xTunnel;
1558 m_xPackageFolder->getByName( pElement->m_aOriginalName ) >>= xTunnel;
1559 if ( !xTunnel.is() )
1560 throw container::NoSuchElementException(); // TODO:
1562 uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xTunnel, uno::UNO_QUERY );
1563 if ( !xPackageSubStream.is() )
1564 throw uno::RuntimeException(); // TODO
1566 // the stream can never be inserted here, because inserted stream element holds the stream till commit or destruction
1567 pElement->m_pStream = new OWriteStream_Impl( this, xPackageSubStream, m_xPackage, m_xFactory, sal_False, m_nStorageType, GetRelInfoStreamForName( pElement->m_aOriginalName ) );
1571 //-----------------------------------------------
1572 uno::Sequence< ::rtl::OUString > OStorage_Impl::GetElementNames()
1574 ::osl::MutexGuard aGuard( m_rMutexRef->GetMutex() );
1576 ReadContents();
1578 sal_uInt32 nSize = m_aChildrenList.size();
1579 uno::Sequence< ::rtl::OUString > aElementNames( nSize );
1581 sal_uInt32 nInd = 0;
1582 for ( SotElementList_Impl::iterator pElementIter = m_aChildrenList.begin();
1583 pElementIter != m_aChildrenList.end(); pElementIter++ )
1585 if ( !(*pElementIter)->m_bIsRemoved )
1586 aElementNames[nInd++] = (*pElementIter)->m_aName;
1589 aElementNames.realloc( nInd );
1590 return aElementNames;
1593 //-----------------------------------------------
1594 void OStorage_Impl::RemoveElement( SotElement_Impl* pElement )
1596 OSL_ENSURE( pElement, "Element must be provided!" );
1598 if ( !pElement )
1599 return;
1601 if ( pElement->m_pStorage && ( pElement->m_pStorage->m_pAntiImpl || !pElement->m_pStorage->m_aReadOnlyWrapList.empty() )
1602 || pElement->m_pStream && ( pElement->m_pStream->m_pAntiImpl || !pElement->m_pStream->m_aInputStreamsList.empty() ) )
1603 throw io::IOException(); // TODO: Access denied
1605 if ( pElement->m_bIsInserted )
1607 m_aChildrenList.remove( pElement );
1608 delete pElement; // ???
1610 else
1612 pElement->m_bIsRemoved = sal_True;
1613 ClearElement( pElement );
1616 // TODO/OFOPXML: the rel stream should be removed as well
1619 //-----------------------------------------------
1620 void OStorage_Impl::ClearElement( SotElement_Impl* pElement )
1622 if ( pElement->m_pStorage )
1624 delete pElement->m_pStorage;
1625 pElement->m_pStorage = NULL;
1628 if ( pElement->m_pStream )
1630 delete pElement->m_pStream;
1631 pElement->m_pStream = NULL;
1635 //-----------------------------------------------
1636 void OStorage_Impl::CloneStreamElement( const ::rtl::OUString& aStreamName,
1637 sal_Bool bPassProvided,
1638 const ::rtl::OUString& aPass,
1639 uno::Reference< io::XStream >& xTargetStream )
1640 throw ( embed::InvalidStorageException,
1641 lang::IllegalArgumentException,
1642 packages::WrongPasswordException,
1643 io::IOException,
1644 embed::StorageWrappedTargetException,
1645 uno::RuntimeException )
1647 SotElement_Impl *pElement = FindElement( aStreamName );
1648 if ( !pElement )
1650 // element does not exist, throw exception
1651 throw io::IOException(); // TODO: access_denied
1653 else if ( pElement->m_bIsStorage )
1654 throw io::IOException(); // TODO:
1656 if ( !pElement->m_pStream )
1657 OpenSubStream( pElement );
1659 if ( pElement->m_pStream && pElement->m_pStream->m_xPackageStream.is() )
1661 // the existence of m_pAntiImpl of the child is not interesting,
1662 // the copy will be created internally
1664 // usual copying is not applicable here, only last flushed version of the
1665 // child stream should be used for copiing. Probably the childs m_xPackageStream
1666 // can be used as a base of a new stream, that would be copied to result
1667 // storage. The only problem is that some package streams can be accessed from outside
1668 // at the same time ( now solwed by wrappers that remember own position ).
1670 if ( bPassProvided )
1671 pElement->m_pStream->GetCopyOfLastCommit( xTargetStream, aPass );
1672 else
1673 pElement->m_pStream->GetCopyOfLastCommit( xTargetStream );
1675 else
1676 throw io::IOException(); // TODO: general_error
1679 //-----------------------------------------------
1680 void OStorage_Impl::RemoveStreamRelInfo( const ::rtl::OUString& aOriginalName )
1682 // this method should be used only in OStorage_Impl::Commit() method
1683 // the aOriginalName can be empty, in this case the storage relation info should be removed
1685 if ( m_nStorageType == OFOPXML_STORAGE && m_xRelStorage.is() )
1687 ::rtl::OUString aRelStreamName = aOriginalName;
1688 aRelStreamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) );
1690 if ( m_xRelStorage->hasByName( aRelStreamName ) )
1691 m_xRelStorage->removeElement( aRelStreamName );
1695 //-----------------------------------------------
1696 void OStorage_Impl::CreateRelStorage()
1698 if ( m_nStorageType != OFOPXML_STORAGE )
1699 return;
1701 if ( !m_xRelStorage.is() )
1703 if ( !m_pRelStorElement )
1705 m_pRelStorElement = new SotElement_Impl( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ), sal_True, sal_True );
1706 m_pRelStorElement->m_pStorage = CreateNewStorageImpl( embed::ElementModes::WRITE );
1707 if ( m_pRelStorElement->m_pStorage )
1708 m_pRelStorElement->m_pStorage->m_pParent = NULL; // the relation storage is completely controlled by parent
1711 if ( !m_pRelStorElement->m_pStorage )
1712 OpenSubStorage( m_pRelStorElement, embed::ElementModes::WRITE );
1714 if ( !m_pRelStorElement->m_pStorage )
1715 throw uno::RuntimeException();
1717 OStorage* pResultStorage = new OStorage( m_pRelStorElement->m_pStorage, sal_False );
1718 m_xRelStorage = uno::Reference< embed::XStorage >( (embed::XStorage*) pResultStorage );
1722 //-----------------------------------------------
1723 void OStorage_Impl::CommitStreamRelInfo( SotElement_Impl* pStreamElement )
1725 // this method should be used only in OStorage_Impl::Commit() method
1727 // the stream element must be provided
1728 if ( !pStreamElement )
1729 throw uno::RuntimeException();
1731 if ( m_nStorageType == OFOPXML_STORAGE && pStreamElement->m_pStream )
1733 OSL_ENSURE( pStreamElement->m_aName.getLength(), "The name must not be empty!\n" );
1735 if ( !m_xRelStorage.is() )
1737 // Create new rels storage, this is commit scenario so it must be possible
1738 CreateRelStorage();
1741 pStreamElement->m_pStream->CommitStreamRelInfo( m_xRelStorage, pStreamElement->m_aOriginalName, pStreamElement->m_aName );
1745 //-----------------------------------------------
1746 uno::Reference< io::XInputStream > OStorage_Impl::GetRelInfoStreamForName( const ::rtl::OUString& aName )
1748 if ( m_nStorageType == OFOPXML_STORAGE )
1750 ReadContents();
1751 if ( m_xRelStorage.is() )
1753 ::rtl::OUString aRelStreamName = aName;
1754 aRelStreamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) );
1755 if ( m_xRelStorage->hasByName( aRelStreamName ) )
1757 uno::Reference< io::XStream > xStream = m_xRelStorage->openStreamElement( aRelStreamName, embed::ElementModes::READ );
1758 if ( xStream.is() )
1759 return xStream->getInputStream();
1764 return uno::Reference< io::XInputStream >();
1767 //-----------------------------------------------
1768 void OStorage_Impl::CommitRelInfo( const uno::Reference< container::XNameContainer >& xNewPackageFolder )
1770 // this method should be used only in OStorage_Impl::Commit() method
1771 ::rtl::OUString aRelsStorName( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) );
1773 if ( !xNewPackageFolder.is() )
1774 throw uno::RuntimeException(); // TODO:
1776 if ( m_nStorageType == OFOPXML_STORAGE )
1778 if ( m_nRelInfoStatus == RELINFO_BROKEN || m_nRelInfoStatus == RELINFO_CHANGED_BROKEN )
1779 throw io::IOException(); // TODO:
1781 if ( m_nRelInfoStatus == RELINFO_CHANGED
1782 || m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
1783 || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1785 if ( m_nRelInfoStatus == RELINFO_CHANGED )
1787 if ( m_aRelInfo.getLength() )
1789 CreateRelStorage();
1791 uno::Reference< io::XStream > xRelsStream =
1792 m_xRelStorage->openStreamElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) ),
1793 embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
1795 uno::Reference< io::XOutputStream > xOutStream = xRelsStream->getOutputStream();
1796 if ( !xOutStream.is() )
1797 throw uno::RuntimeException();
1799 ::comphelper::OFOPXMLHelper::WriteRelationsInfoSequence( xOutStream, m_aRelInfo, m_xFactory );
1801 // set the mediatype
1802 uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
1803 xPropSet->setPropertyValue(
1804 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
1805 uno::makeAny( ::rtl::OUString(
1806 RTL_CONSTASCII_USTRINGPARAM( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) );
1808 m_nRelInfoStatus = RELINFO_READ;
1810 else if ( m_xRelStorage.is() )
1811 RemoveStreamRelInfo( ::rtl::OUString() ); // remove own rel info
1813 else if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM_READ
1814 || m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1816 CreateRelStorage();
1818 uno::Reference< io::XStream > xRelsStream =
1819 m_xRelStorage->openStreamElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".rels" ) ),
1820 embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE );
1822 uno::Reference< io::XOutputStream > xOutputStream = xRelsStream->getOutputStream();
1823 if ( !xOutputStream.is() )
1824 throw uno::RuntimeException();
1826 uno::Reference< io::XSeekable > xSeek( m_xNewRelInfoStream, uno::UNO_QUERY_THROW );
1827 xSeek->seek( 0 );
1828 ::comphelper::OStorageHelper::CopyInputToOutput( m_xNewRelInfoStream, xOutputStream );
1830 // set the mediatype
1831 uno::Reference< beans::XPropertySet > xPropSet( xRelsStream, uno::UNO_QUERY_THROW );
1832 xPropSet->setPropertyValue(
1833 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
1834 uno::makeAny( ::rtl::OUString(
1835 RTL_CONSTASCII_USTRINGPARAM( "application/vnd.openxmlformats-package.relationships+xml" ) ) ) );
1837 m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
1838 if ( m_nRelInfoStatus == RELINFO_CHANGED_STREAM )
1840 m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
1841 m_nRelInfoStatus = RELINFO_NO_INIT;
1843 else
1844 m_nRelInfoStatus = RELINFO_READ;
1848 if ( m_xRelStorage.is() )
1850 if ( m_xRelStorage->hasElements() )
1852 uno::Reference< embed::XTransactedObject > xTrans( m_xRelStorage, uno::UNO_QUERY_THROW );
1853 if ( xTrans.is() )
1854 xTrans->commit();
1857 if ( xNewPackageFolder.is() && xNewPackageFolder->hasByName( aRelsStorName ) )
1858 xNewPackageFolder->removeByName( aRelsStorName );
1860 if ( !m_xRelStorage->hasElements() )
1862 // the empty relations storage should not be created
1863 delete m_pRelStorElement;
1864 m_pRelStorElement = NULL;
1865 m_xRelStorage = uno::Reference< embed::XStorage >();
1867 else if ( m_pRelStorElement && m_pRelStorElement->m_pStorage && xNewPackageFolder.is() )
1868 m_pRelStorElement->m_pStorage->InsertIntoPackageFolder( aRelsStorName, xNewPackageFolder );
1873 //=====================================================
1874 // OStorage implementation
1875 //=====================================================
1877 //-----------------------------------------------
1878 OStorage::OStorage( uno::Reference< io::XInputStream > xInputStream,
1879 sal_Int32 nMode,
1880 uno::Sequence< beans::PropertyValue > xProperties,
1881 uno::Reference< lang::XMultiServiceFactory > xFactory,
1882 sal_Int16 nStorageType )
1883 : m_pImpl( new OStorage_Impl( xInputStream, nMode, xProperties, xFactory, nStorageType ) )
1885 m_pImpl->m_pAntiImpl = this;
1886 m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, sal_False );
1889 //-----------------------------------------------
1890 OStorage::OStorage( uno::Reference< io::XStream > xStream,
1891 sal_Int32 nMode,
1892 uno::Sequence< beans::PropertyValue > xProperties,
1893 uno::Reference< lang::XMultiServiceFactory > xFactory,
1894 sal_Int16 nStorageType )
1895 : m_pImpl( new OStorage_Impl( xStream, nMode, xProperties, xFactory, nStorageType ) )
1897 m_pImpl->m_pAntiImpl = this;
1898 m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, sal_False );
1901 //-----------------------------------------------
1902 OStorage::OStorage( OStorage_Impl* pImpl, sal_Bool bReadOnlyWrap )
1903 : m_pImpl( pImpl )
1905 // this call can be done only from OStorage_Impl implementation to create child storage
1906 OSL_ENSURE( m_pImpl && m_pImpl->m_rMutexRef.Is(), "The provided pointer & mutex MUST NOT be empty!\n" );
1908 m_pData = new StorInternalData_Impl( m_pImpl->m_rMutexRef, m_pImpl->m_bIsRoot, m_pImpl->m_nStorageType, bReadOnlyWrap );
1910 OSL_ENSURE( ( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) == embed::ElementModes::WRITE ||
1911 m_pData->m_bReadOnlyWrap,
1912 "The wrapper can not allow writing in case implementation does not!\n" );
1914 if ( !bReadOnlyWrap )
1915 m_pImpl->m_pAntiImpl = this;
1918 //-----------------------------------------------
1919 OStorage::~OStorage()
1922 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
1923 if ( m_pImpl )
1925 m_refCount++; // to call dispose
1926 try {
1927 dispose();
1929 catch( uno::RuntimeException& )
1934 if ( m_pData )
1936 if ( m_pData->m_pSubElDispListener )
1938 m_pData->m_pSubElDispListener->release();
1939 m_pData->m_pSubElDispListener = NULL;
1942 if ( m_pData->m_pTypeCollection )
1944 delete m_pData->m_pTypeCollection;
1945 m_pData->m_pTypeCollection = NULL;
1948 delete m_pData;
1952 //-----------------------------------------------
1953 void SAL_CALL OStorage::InternalDispose( sal_Bool bNotifyImpl )
1955 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::InternalDispose" );
1957 if ( !m_pImpl )
1958 throw lang::DisposedException();
1960 // the source object is also a kind of locker for the current object
1961 // since the listeners could dispose the object while being notified
1962 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
1963 m_pData->m_aListenersContainer.disposeAndClear( aSource );
1965 if ( m_pData->m_bReadOnlyWrap )
1967 OSL_ENSURE( !m_pData->m_aOpenSubComponentsList.size() || m_pData->m_pSubElDispListener,
1968 "If any subelements are open the listener must exist!\n" );
1970 if ( m_pData->m_pSubElDispListener )
1972 m_pData->m_pSubElDispListener->OwnerIsDisposed();
1974 // iterate through m_pData->m_aOpenSubComponentsList
1975 // deregister m_pData->m_pSubElDispListener and dispose all of them
1976 if ( !m_pData->m_aOpenSubComponentsList.empty() )
1978 for ( WeakComponentList::iterator pCompIter = m_pData->m_aOpenSubComponentsList.begin();
1979 pCompIter != m_pData->m_aOpenSubComponentsList.end(); pCompIter++ )
1981 uno::Reference< lang::XComponent > xTmp = (*pCompIter);
1982 if ( xTmp.is() )
1984 xTmp->removeEventListener( uno::Reference< lang::XEventListener >(
1985 static_cast< lang::XEventListener* >( m_pData->m_pSubElDispListener ) ) );
1987 try {
1988 xTmp->dispose();
1989 } catch( uno::Exception& ) {}
1993 m_pData->m_aOpenSubComponentsList.clear();
1997 if ( bNotifyImpl )
1998 m_pImpl->RemoveReadOnlyWrap( *this );
2000 else
2002 m_pImpl->m_pAntiImpl = NULL;
2004 if ( bNotifyImpl )
2006 if ( m_pData->m_bIsRoot )
2007 delete m_pImpl;
2008 else
2010 // the noncommited changes for the storage must be removed
2011 m_pImpl->Revert();
2016 m_pImpl = NULL;
2019 //-----------------------------------------------
2020 void OStorage::ChildIsDisposed( const uno::Reference< uno::XInterface >& xChild )
2022 // this method can only be called by child disposing listener
2024 // this method must not contain any locking
2025 // the locking is done in the listener
2027 if ( !m_pData->m_aOpenSubComponentsList.empty() )
2029 for ( WeakComponentList::iterator pCompIter = m_pData->m_aOpenSubComponentsList.begin();
2030 pCompIter != m_pData->m_aOpenSubComponentsList.end(); )
2032 uno::Reference< lang::XComponent > xTmp = (*pCompIter);
2033 if ( !xTmp.is() || xTmp == xChild )
2035 WeakComponentList::iterator pIterToRemove = pCompIter;
2036 pCompIter++;
2037 m_pData->m_aOpenSubComponentsList.erase( pIterToRemove );
2039 else
2040 pCompIter++;
2045 //-----------------------------------------------
2046 void OStorage::BroadcastModifiedIfNecessary()
2048 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
2049 if ( !m_pImpl )
2050 throw lang::DisposedException();
2052 if ( !m_pImpl->m_bBroadcastModified )
2053 return;
2055 m_pImpl->m_bBroadcastModified = sal_False;
2057 OSL_ENSURE( !m_pData->m_bReadOnlyWrap, "The storage can not be modified at all!\n" );
2059 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
2061 ::cppu::OInterfaceContainerHelper* pContainer =
2062 m_pData->m_aListenersContainer.getContainer(
2063 ::getCppuType( ( const uno::Reference< util::XModifyListener >*) NULL ) );
2064 if ( pContainer )
2066 ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
2067 while ( pIterator.hasMoreElements( ) )
2069 ( ( util::XModifyListener* )pIterator.next( ) )->modified( aSource );
2074 //-----------------------------------------------
2075 void OStorage::BroadcastTransaction( sal_Int8 nMessage )
2077 1 - preCommit
2078 2 - commited
2079 3 - preRevert
2080 4 - reverted
2083 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
2084 if ( !m_pImpl )
2085 throw lang::DisposedException();
2087 OSL_ENSURE( !m_pData->m_bReadOnlyWrap, "The storage can not be modified at all!\n" );
2089 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
2091 ::cppu::OInterfaceContainerHelper* pContainer =
2092 m_pData->m_aListenersContainer.getContainer(
2093 ::getCppuType( ( const uno::Reference< embed::XTransactionListener >*) NULL ) );
2094 if ( pContainer )
2096 ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
2097 while ( pIterator.hasMoreElements( ) )
2099 OSL_ENSURE( nMessage >= 1 && nMessage <= 4, "Wrong internal notification code is used!\n" );
2101 switch( nMessage )
2103 case STOR_MESS_PRECOMMIT:
2104 ( ( embed::XTransactionListener* )pIterator.next( ) )->preCommit( aSource );
2105 break;
2106 case STOR_MESS_COMMITED:
2107 ( ( embed::XTransactionListener* )pIterator.next( ) )->commited( aSource );
2108 break;
2109 case STOR_MESS_PREREVERT:
2110 ( ( embed::XTransactionListener* )pIterator.next( ) )->preRevert( aSource );
2111 break;
2112 case STOR_MESS_REVERTED:
2113 ( ( embed::XTransactionListener* )pIterator.next( ) )->reverted( aSource );
2114 break;
2120 //-----------------------------------------------
2121 SotElement_Impl* OStorage::OpenStreamElement_Impl( const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode, sal_Bool bEncr )
2123 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2125 OSL_ENSURE( !m_pData->m_bReadOnlyWrap || ( nOpenMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE,
2126 "An element can not be opened for writing in readonly storage!\n" );
2128 SotElement_Impl *pElement = m_pImpl->FindElement( aStreamName );
2129 if ( !pElement )
2131 // element does not exist, check if creation is allowed
2132 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
2133 || (( nOpenMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
2134 || ( nOpenMode & embed::ElementModes::NOCREATE ) == embed::ElementModes::NOCREATE )
2135 throw io::IOException(); // TODO: access_denied
2137 // create a new StreamElement and insert it into the list
2138 pElement = m_pImpl->InsertStream( aStreamName, bEncr );
2140 else if ( pElement->m_bIsStorage )
2142 throw io::IOException(); // TODO:
2145 OSL_ENSURE( pElement, "In case element can not be created an exception must be thrown!" );
2147 if ( !pElement->m_pStream )
2148 m_pImpl->OpenSubStream( pElement );
2150 if ( !pElement->m_pStream )
2151 throw io::IOException(); // TODO:
2153 return pElement;
2156 //-----------------------------------------------
2157 void OStorage::MakeLinkToSubComponent_Impl( const uno::Reference< lang::XComponent >& xComponent )
2159 if ( !xComponent.is() )
2160 throw uno::RuntimeException();
2162 if ( !m_pData->m_pSubElDispListener )
2164 m_pData->m_pSubElDispListener = new OChildDispListener_Impl( *this );
2165 m_pData->m_pSubElDispListener->acquire();
2168 xComponent->addEventListener( uno::Reference< lang::XEventListener >(
2169 static_cast< ::cppu::OWeakObject* >( m_pData->m_pSubElDispListener ), uno::UNO_QUERY ) );
2171 m_pData->m_aOpenSubComponentsList.push_back( xComponent );
2174 //____________________________________________________________________________________________________
2175 // XInterface
2176 //____________________________________________________________________________________________________
2178 //-----------------------------------------------
2179 uno::Any SAL_CALL OStorage::queryInterface( const uno::Type& rType )
2180 throw( uno::RuntimeException )
2182 uno::Any aReturn;
2184 // common interfaces
2185 aReturn <<= ::cppu::queryInterface
2186 ( rType
2187 , static_cast<lang::XTypeProvider*> ( this )
2188 , static_cast<embed::XStorage*> ( this )
2189 , static_cast<embed::XTransactedObject*> ( this )
2190 , static_cast<embed::XTransactionBroadcaster*> ( this )
2191 , static_cast<util::XModifiable*> ( this )
2192 , static_cast<container::XNameAccess*> ( this )
2193 , static_cast<container::XElementAccess*> ( this )
2194 , static_cast<lang::XComponent*> ( this )
2195 , static_cast<beans::XPropertySet*> ( this )
2196 , static_cast<embed::XOptimizedStorage*> ( this )
2197 , static_cast<embed::XHierarchicalStorageAccess*> ( this ) );
2199 if ( aReturn.hasValue() == sal_True )
2200 return aReturn ;
2202 if ( m_pData->m_nStorageType == PACKAGE_STORAGE )
2204 if ( m_pData->m_bIsRoot )
2206 aReturn <<= ::cppu::queryInterface
2207 ( rType
2208 , static_cast<embed::XStorageRawAccess*> ( this )
2209 , static_cast<embed::XEncryptionProtectedSource*> ( this ) );
2211 else
2213 aReturn <<= ::cppu::queryInterface
2214 ( rType
2215 , static_cast<embed::XStorageRawAccess*> ( this ) );
2218 else if ( m_pData->m_nStorageType == OFOPXML_STORAGE )
2220 aReturn <<= ::cppu::queryInterface
2221 ( rType
2222 , static_cast<embed::XRelationshipAccess*> ( this ) );
2225 if ( aReturn.hasValue() == sal_True )
2226 return aReturn ;
2228 return OWeakObject::queryInterface( rType );
2231 //-----------------------------------------------
2232 void SAL_CALL OStorage::acquire() throw()
2234 OWeakObject::acquire();
2237 //-----------------------------------------------
2238 void SAL_CALL OStorage::release() throw()
2240 OWeakObject::release();
2243 //____________________________________________________________________________________________________
2244 // XTypeProvider
2245 //____________________________________________________________________________________________________
2247 //-----------------------------------------------
2248 uno::Sequence< uno::Type > SAL_CALL OStorage::getTypes()
2249 throw( uno::RuntimeException )
2251 if ( m_pData->m_pTypeCollection == NULL )
2253 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2255 if ( m_pData->m_pTypeCollection == NULL )
2257 if ( m_pData->m_nStorageType == PACKAGE_STORAGE )
2259 if ( m_pData->m_bIsRoot )
2261 m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2262 ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2263 , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2264 , ::getCppuType( ( const uno::Reference< embed::XStorageRawAccess >* )NULL )
2265 , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2266 , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2267 , ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2268 , ::getCppuType( ( const uno::Reference< embed::XEncryptionProtectedSource >* )NULL )
2269 , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2271 else
2273 m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2274 ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2275 , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2276 , ::getCppuType( ( const uno::Reference< embed::XStorageRawAccess >* )NULL )
2277 , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2278 , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2279 , ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2280 , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2283 else if ( m_pData->m_nStorageType == OFOPXML_STORAGE )
2285 m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2286 ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2287 , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2288 , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2289 , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2290 , ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2291 , ::getCppuType( ( const uno::Reference< embed::XRelationshipAccess >* )NULL )
2292 , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2294 else
2296 m_pData->m_pTypeCollection = new ::cppu::OTypeCollection
2297 ( ::getCppuType( ( const uno::Reference< lang::XTypeProvider >* )NULL )
2298 , ::getCppuType( ( const uno::Reference< embed::XStorage >* )NULL )
2299 , ::getCppuType( ( const uno::Reference< embed::XTransactedObject >* )NULL )
2300 , ::getCppuType( ( const uno::Reference< embed::XTransactionBroadcaster >* )NULL )
2301 , ::getCppuType( ( const uno::Reference< util::XModifiable >* )NULL )
2302 , ::getCppuType( ( const uno::Reference< beans::XPropertySet >* )NULL ) );
2307 return m_pData->m_pTypeCollection->getTypes() ;
2310 //-----------------------------------------------
2311 uno::Sequence< sal_Int8 > SAL_CALL OStorage::getImplementationId()
2312 throw( uno::RuntimeException )
2314 static ::cppu::OImplementationId* pID = NULL ;
2316 if ( pID == NULL )
2318 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ;
2320 if ( pID == NULL )
2322 static ::cppu::OImplementationId aID( sal_False ) ;
2323 pID = &aID ;
2327 return pID->getImplementationId() ;
2331 //____________________________________________________________________________________________________
2332 // XStorage
2333 //____________________________________________________________________________________________________
2336 //-----------------------------------------------
2337 void SAL_CALL OStorage::copyToStorage( const uno::Reference< embed::XStorage >& xDest )
2338 throw ( embed::InvalidStorageException,
2339 io::IOException,
2340 lang::IllegalArgumentException,
2341 embed::StorageWrappedTargetException,
2342 uno::RuntimeException )
2344 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyToStorage" );
2346 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2348 if ( !m_pImpl )
2349 throw lang::DisposedException();
2351 if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject*> ( this ), uno::UNO_QUERY ) )
2352 throw lang::IllegalArgumentException(); // TODO:
2354 try {
2355 m_pImpl->CopyToStorage( xDest, sal_False );
2357 catch( embed::InvalidStorageException& )
2359 throw;
2361 catch( lang::IllegalArgumentException& )
2363 throw;
2365 catch( embed::StorageWrappedTargetException& )
2367 throw;
2369 catch( io::IOException& )
2371 throw;
2373 catch( uno::RuntimeException& )
2375 throw;
2377 catch( uno::Exception& )
2379 uno::Any aCaught( ::cppu::getCaughtException() );
2380 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy storage!" ),
2381 uno::Reference< io::XInputStream >(),
2382 aCaught );
2386 //-----------------------------------------------
2387 uno::Reference< io::XStream > SAL_CALL OStorage::openStreamElement(
2388 const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode )
2389 throw ( embed::InvalidStorageException,
2390 lang::IllegalArgumentException,
2391 packages::WrongPasswordException,
2392 io::IOException,
2393 embed::StorageWrappedTargetException,
2394 uno::RuntimeException )
2396 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openStreamElement" );
2398 ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2400 if ( !m_pImpl )
2401 throw lang::DisposedException();
2403 if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
2404 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
2406 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
2407 && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
2408 throw lang::IllegalArgumentException(); // TODO: unacceptable element name
2410 if ( ( nOpenMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
2411 throw io::IOException(); // TODO: access denied
2413 uno::Reference< io::XStream > xResult;
2416 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamName, nOpenMode, sal_False );
2417 OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
2419 xResult = pElement->m_pStream->GetStream( nOpenMode, sal_False );
2420 OSL_ENSURE( xResult.is(), "The method must throw exception instead of removing empty result!\n" );
2422 if ( m_pData->m_bReadOnlyWrap )
2424 // before the storage disposes the stream it must deregister itself as listener
2425 uno::Reference< lang::XComponent > xStreamComponent( xResult, uno::UNO_QUERY );
2426 if ( !xStreamComponent.is() )
2427 throw uno::RuntimeException(); // TODO
2429 MakeLinkToSubComponent_Impl( xStreamComponent );
2432 catch( embed::InvalidStorageException& )
2434 throw;
2436 catch( lang::IllegalArgumentException& )
2438 throw;
2440 catch( packages::WrongPasswordException& )
2442 throw;
2444 catch( embed::StorageWrappedTargetException& )
2446 throw;
2448 catch( io::IOException& )
2450 throw;
2452 catch( uno::RuntimeException& )
2454 throw;
2456 catch( uno::Exception& )
2458 uno::Any aCaught( ::cppu::getCaughtException() );
2459 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't open stream element!" ),
2460 uno::Reference< io::XInputStream >(),
2461 aCaught );
2464 aGuard.clear();
2466 BroadcastModifiedIfNecessary();
2468 return xResult;
2471 //-----------------------------------------------
2472 uno::Reference< io::XStream > SAL_CALL OStorage::openEncryptedStreamElement(
2473 const ::rtl::OUString& aStreamName, sal_Int32 nOpenMode, const ::rtl::OUString& aPass )
2474 throw ( embed::InvalidStorageException,
2475 lang::IllegalArgumentException,
2476 packages::NoEncryptionException,
2477 packages::WrongPasswordException,
2478 io::IOException,
2479 embed::StorageWrappedTargetException,
2480 uno::RuntimeException )
2482 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openEncryptedStreamElement" );
2484 ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2486 if ( !m_pImpl )
2487 throw lang::DisposedException();
2489 if ( m_pData->m_nStorageType != PACKAGE_STORAGE )
2490 packages::NoEncryptionException(); // TODO:
2492 if ( ( nOpenMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
2493 throw io::IOException(); // TODO: access denied
2495 if ( !aPass.getLength() )
2496 throw lang::IllegalArgumentException();
2498 uno::Reference< io::XStream > xResult;
2501 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamName, nOpenMode, sal_True );
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, aPass, 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(); // TODO
2514 MakeLinkToSubComponent_Impl( xStreamComponent );
2517 catch( embed::InvalidStorageException& )
2519 throw;
2521 catch( lang::IllegalArgumentException& )
2523 throw;
2525 catch( packages::NoEncryptionException& )
2527 throw;
2529 catch( packages::WrongPasswordException& )
2531 throw;
2533 catch( embed::StorageWrappedTargetException& )
2535 throw;
2537 catch( io::IOException& )
2539 throw;
2541 catch( uno::RuntimeException& )
2543 throw;
2545 catch( uno::Exception& )
2547 uno::Any aCaught( ::cppu::getCaughtException() );
2548 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't open encrypted stream stream!" ),
2549 uno::Reference< io::XInputStream >(),
2550 aCaught );
2553 aGuard.clear();
2555 BroadcastModifiedIfNecessary();
2557 return xResult;
2560 //-----------------------------------------------
2561 uno::Reference< embed::XStorage > SAL_CALL OStorage::openStorageElement(
2562 const ::rtl::OUString& aStorName, sal_Int32 nStorageMode )
2563 throw ( embed::InvalidStorageException,
2564 lang::IllegalArgumentException,
2565 io::IOException,
2566 embed::StorageWrappedTargetException,
2567 uno::RuntimeException )
2569 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::openStorageElement" );
2571 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2573 if ( !m_pImpl )
2574 throw lang::DisposedException();
2576 if ( !aStorName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName, sal_False ) )
2577 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
2579 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
2580 && aStorName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
2581 throw lang::IllegalArgumentException(); // TODO: unacceptable storage name
2583 if ( ( nStorageMode & embed::ElementModes::WRITE ) && m_pData->m_bReadOnlyWrap )
2584 throw io::IOException(); // TODO: access denied
2586 if ( ( nStorageMode & embed::ElementModes::TRUNCATE )
2587 && !( nStorageMode & embed::ElementModes::WRITE ) )
2588 throw io::IOException(); // TODO: access denied
2590 // it's allways possible to read written storage in this implementation
2591 nStorageMode |= embed::ElementModes::READ;
2593 uno::Reference< embed::XStorage > xResult;
2596 SotElement_Impl *pElement = m_pImpl->FindElement( aStorName );
2597 if ( !pElement )
2599 // element does not exist, check if creation is allowed
2600 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
2601 || (( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
2602 || ( nStorageMode & embed::ElementModes::NOCREATE ) == embed::ElementModes::NOCREATE )
2603 throw io::IOException(); // TODO: access_denied
2605 // create a new StorageElement and insert it into the list
2606 pElement = m_pImpl->InsertStorage( aStorName, nStorageMode );
2608 else if ( !pElement->m_bIsStorage )
2610 throw io::IOException(); // TODO:
2612 else if ( pElement->m_pStorage )
2614 // storage has already been opened; it may be opened another time, if it the mode allows to do so
2615 if ( pElement->m_pStorage->m_pAntiImpl )
2617 throw io::IOException(); // TODO: access_denied
2619 else if ( !pElement->m_pStorage->m_aReadOnlyWrapList.empty()
2620 && ( nStorageMode & embed::ElementModes::WRITE ) )
2622 throw io::IOException(); // TODO: access_denied
2624 else
2626 // in case parent storage allows writing the readonly mode of the child storage is
2627 // virtual, that means that it is just enough to change the flag to let it be writable
2628 // and since there is no AntiImpl nobody should be notified about it
2629 pElement->m_pStorage->m_nStorageMode = nStorageMode | embed::ElementModes::READ;
2631 if ( ( nStorageMode & embed::ElementModes::TRUNCATE ) )
2633 for ( SotElementList_Impl::iterator pElementIter = pElement->m_pStorage->m_aChildrenList.begin();
2634 pElementIter != pElement->m_pStorage->m_aChildrenList.end(); )
2636 SotElement_Impl* pElementToDel = (*pElementIter);
2637 pElementIter++;
2639 m_pImpl->RemoveElement( pElementToDel );
2645 if ( !pElement->m_pStorage )
2646 m_pImpl->OpenSubStorage( pElement, nStorageMode );
2648 if ( !pElement->m_pStorage )
2649 throw io::IOException(); // TODO: general_error
2651 sal_Bool bReadOnlyWrap = ( ( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE );
2652 OStorage* pResultStorage = new OStorage( pElement->m_pStorage, bReadOnlyWrap );
2653 xResult = uno::Reference< embed::XStorage >( (embed::XStorage*) pResultStorage );
2655 if ( bReadOnlyWrap )
2657 // Before this call is done the object must be refcounted already
2658 pElement->m_pStorage->SetReadOnlyWrap( *pResultStorage );
2660 // before the storage disposes the stream it must deregister itself as listener
2661 uno::Reference< lang::XComponent > xStorageComponent( xResult, uno::UNO_QUERY );
2662 if ( !xStorageComponent.is() )
2663 throw uno::RuntimeException(); // TODO
2665 MakeLinkToSubComponent_Impl( xStorageComponent );
2668 catch( embed::InvalidStorageException& )
2670 throw;
2672 catch( lang::IllegalArgumentException& )
2674 throw;
2676 catch( embed::StorageWrappedTargetException& )
2678 throw;
2680 catch( io::IOException& )
2682 throw;
2684 catch( uno::RuntimeException& )
2686 throw;
2688 catch( uno::Exception& )
2690 uno::Any aCaught( ::cppu::getCaughtException() );
2691 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't open storage!" ),
2692 uno::Reference< io::XInputStream >(),
2693 aCaught );
2696 return xResult;
2699 //-----------------------------------------------
2700 uno::Reference< io::XStream > SAL_CALL OStorage::cloneStreamElement( const ::rtl::OUString& aStreamName )
2701 throw ( embed::InvalidStorageException,
2702 lang::IllegalArgumentException,
2703 packages::WrongPasswordException,
2704 io::IOException,
2705 embed::StorageWrappedTargetException,
2706 uno::RuntimeException )
2708 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::cloneStreamElement" );
2710 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2712 if ( !m_pImpl )
2713 throw lang::DisposedException();
2715 if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
2716 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
2718 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
2719 && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
2720 throw lang::IllegalArgumentException(); // TODO: unacceptable storage name
2724 uno::Reference< io::XStream > xResult;
2725 m_pImpl->CloneStreamElement( aStreamName, sal_False, ::rtl::OUString(), xResult );
2726 if ( !xResult.is() )
2727 throw uno::RuntimeException();
2728 return xResult;
2730 catch( embed::InvalidStorageException& )
2732 throw;
2734 catch( lang::IllegalArgumentException& )
2736 throw;
2738 catch( packages::WrongPasswordException& )
2740 throw;
2742 catch( io::IOException& )
2744 throw;
2746 catch( embed::StorageWrappedTargetException& )
2748 throw;
2750 catch( uno::RuntimeException& )
2752 throw;
2754 catch( uno::Exception& )
2756 uno::Any aCaught( ::cppu::getCaughtException() );
2757 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't clone stream!" ),
2758 uno::Reference< io::XInputStream >(),
2759 aCaught );
2763 //-----------------------------------------------
2764 uno::Reference< io::XStream > SAL_CALL OStorage::cloneEncryptedStreamElement(
2765 const ::rtl::OUString& aStreamName,
2766 const ::rtl::OUString& aPass )
2767 throw ( embed::InvalidStorageException,
2768 lang::IllegalArgumentException,
2769 packages::NoEncryptionException,
2770 packages::WrongPasswordException,
2771 io::IOException,
2772 embed::StorageWrappedTargetException,
2773 uno::RuntimeException )
2775 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::cloneEncryptedStreamElement" );
2777 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2779 if ( !m_pImpl )
2780 throw lang::DisposedException();
2782 if ( m_pData->m_nStorageType != PACKAGE_STORAGE )
2783 packages::NoEncryptionException(); // TODO:
2785 if ( !aPass.getLength() )
2786 throw lang::IllegalArgumentException();
2790 uno::Reference< io::XStream > xResult;
2791 m_pImpl->CloneStreamElement( aStreamName, sal_True, aPass, xResult );
2792 if ( !xResult.is() )
2793 throw uno::RuntimeException();
2794 return xResult;
2796 catch( embed::InvalidStorageException& )
2798 throw;
2800 catch( lang::IllegalArgumentException& )
2802 throw;
2804 catch( packages::NoEncryptionException& )
2806 throw;
2808 catch( packages::WrongPasswordException& )
2810 throw;
2812 catch( io::IOException& )
2814 throw;
2816 catch( embed::StorageWrappedTargetException& )
2818 throw;
2820 catch( uno::RuntimeException& )
2822 throw;
2824 catch( uno::Exception& )
2826 uno::Any aCaught( ::cppu::getCaughtException() );
2827 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't clone encrypted stream!" ),
2828 uno::Reference< io::XInputStream >(),
2829 aCaught );
2833 //-----------------------------------------------
2834 void SAL_CALL OStorage::copyLastCommitTo(
2835 const uno::Reference< embed::XStorage >& xTargetStorage )
2836 throw ( embed::InvalidStorageException,
2837 lang::IllegalArgumentException,
2838 io::IOException,
2839 embed::StorageWrappedTargetException,
2840 uno::RuntimeException )
2842 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyLastCommitTo" );
2844 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2846 if ( !m_pImpl )
2847 throw lang::DisposedException();
2851 m_pImpl->CopyLastCommitTo( xTargetStorage );
2853 catch( embed::InvalidStorageException& )
2855 throw;
2857 catch( lang::IllegalArgumentException& )
2859 throw;
2861 catch( embed::StorageWrappedTargetException& )
2863 throw;
2865 catch( io::IOException& )
2867 throw;
2869 catch( uno::RuntimeException& )
2871 throw;
2873 catch( uno::Exception& )
2875 uno::Any aCaught( ::cppu::getCaughtException() );
2876 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy last commit version!" ),
2877 uno::Reference< io::XInputStream >(),
2878 aCaught );
2883 //-----------------------------------------------
2884 void SAL_CALL OStorage::copyStorageElementLastCommitTo(
2885 const ::rtl::OUString& aStorName,
2886 const uno::Reference< embed::XStorage >& xTargetStorage )
2887 throw ( embed::InvalidStorageException,
2888 lang::IllegalArgumentException,
2889 io::IOException,
2890 embed::StorageWrappedTargetException,
2891 uno::RuntimeException )
2893 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyStorageElementLastCommitTo" );
2895 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2897 if ( !m_pImpl )
2898 throw lang::DisposedException();
2900 if ( !aStorName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName, sal_False ) )
2901 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
2903 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
2904 && aStorName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
2905 throw lang::IllegalArgumentException(); // TODO: unacceptable storage name
2907 // it's allways possible to read written storage in this implementation
2908 sal_Int32 nStorageMode = embed::ElementModes::READ;
2912 SotElement_Impl *pElement = m_pImpl->FindElement( aStorName );
2913 if ( !pElement )
2915 // element does not exist, throw exception
2916 throw io::IOException(); // TODO: access_denied
2918 else if ( !pElement->m_bIsStorage )
2920 throw io::IOException(); // TODO:
2923 if ( !pElement->m_pStorage )
2924 m_pImpl->OpenSubStorage( pElement, nStorageMode );
2926 uno::Reference< embed::XStorage > xResult;
2927 if ( pElement->m_pStorage )
2929 // the existence of m_pAntiImpl of the child is not interesting,
2930 // the copy will be created internally
2932 pElement->m_pStorage->CopyLastCommitTo( xTargetStorage );
2934 else
2935 throw io::IOException(); // TODO: general_error
2937 catch( embed::InvalidStorageException& )
2939 throw;
2941 catch( lang::IllegalArgumentException& )
2943 throw;
2945 catch( io::IOException& )
2947 throw;
2949 catch( embed::StorageWrappedTargetException& )
2951 throw;
2953 catch( uno::RuntimeException& )
2955 throw;
2957 catch( uno::Exception& )
2959 uno::Any aCaught( ::cppu::getCaughtException() );
2960 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy last commit element version!" ),
2961 uno::Reference< io::XInputStream >(),
2962 aCaught );
2966 //-----------------------------------------------
2967 sal_Bool SAL_CALL OStorage::isStreamElement( const ::rtl::OUString& aElementName )
2968 throw ( embed::InvalidStorageException,
2969 lang::IllegalArgumentException,
2970 container::NoSuchElementException,
2971 uno::RuntimeException )
2973 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
2975 if ( !m_pImpl )
2976 throw lang::DisposedException();
2978 if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
2979 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
2981 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
2982 && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
2983 throw lang::IllegalArgumentException(); // TODO: unacceptable storage name
2985 SotElement_Impl* pElement = NULL;
2989 pElement = m_pImpl->FindElement( aElementName );
2991 catch( embed::InvalidStorageException& )
2993 throw;
2995 catch( lang::IllegalArgumentException& )
2997 throw;
2999 catch( container::NoSuchElementException& )
3001 throw;
3003 catch( uno::RuntimeException& )
3005 throw;
3007 catch( uno::Exception& )
3009 uno::Any aCaught( ::cppu::getCaughtException() );
3010 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't detect whether it is a stream!" ),
3011 uno::Reference< io::XInputStream >(),
3012 aCaught );
3015 if ( !pElement )
3016 throw container::NoSuchElementException(); //???
3018 return !pElement->m_bIsStorage;
3021 //-----------------------------------------------
3022 sal_Bool SAL_CALL OStorage::isStorageElement( const ::rtl::OUString& aElementName )
3023 throw ( embed::InvalidStorageException,
3024 lang::IllegalArgumentException,
3025 container::NoSuchElementException,
3026 uno::RuntimeException )
3028 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3030 if ( !m_pImpl )
3031 throw lang::DisposedException();
3033 if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
3034 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3036 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
3037 && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
3038 throw lang::IllegalArgumentException();
3040 SotElement_Impl* pElement = NULL;
3044 pElement = m_pImpl->FindElement( aElementName );
3046 catch( embed::InvalidStorageException& )
3048 throw;
3050 catch( lang::IllegalArgumentException& )
3052 throw;
3054 catch( container::NoSuchElementException& )
3056 throw;
3058 catch( uno::RuntimeException& )
3060 throw;
3062 catch( uno::Exception& )
3064 uno::Any aCaught( ::cppu::getCaughtException() );
3065 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't detect whether it is a storage" ),
3066 uno::Reference< io::XInputStream >(),
3067 aCaught );
3070 if ( !pElement )
3071 throw container::NoSuchElementException(); //???
3073 return pElement->m_bIsStorage;
3076 //-----------------------------------------------
3077 void SAL_CALL OStorage::removeElement( const ::rtl::OUString& aElementName )
3078 throw ( embed::InvalidStorageException,
3079 lang::IllegalArgumentException,
3080 container::NoSuchElementException,
3081 io::IOException,
3082 embed::StorageWrappedTargetException,
3083 uno::RuntimeException )
3085 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::removeElement" );
3087 ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3089 if ( !m_pImpl )
3090 throw lang::DisposedException();
3092 if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
3093 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3095 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
3096 && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
3097 throw lang::IllegalArgumentException(); // TODO: unacceptable storage name
3099 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3100 throw io::IOException(); // TODO: access denied
3104 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3106 if ( !pElement )
3107 throw container::NoSuchElementException(); //???
3109 m_pImpl->RemoveElement( pElement );
3111 m_pImpl->m_bIsModified = sal_True;
3112 m_pImpl->m_bBroadcastModified = sal_True;
3114 catch( embed::InvalidStorageException& )
3116 throw;
3118 catch( lang::IllegalArgumentException& )
3120 throw;
3122 catch( container::NoSuchElementException& )
3124 throw;
3126 catch( io::IOException& )
3128 throw;
3130 catch( embed::StorageWrappedTargetException& )
3132 throw;
3134 catch( uno::RuntimeException& )
3136 throw;
3138 catch( uno::Exception& )
3140 uno::Any aCaught( ::cppu::getCaughtException() );
3141 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't remove element!" ),
3142 uno::Reference< io::XInputStream >(),
3143 aCaught );
3146 aGuard.clear();
3148 BroadcastModifiedIfNecessary();
3151 //-----------------------------------------------
3152 void SAL_CALL OStorage::renameElement( const ::rtl::OUString& aElementName, const ::rtl::OUString& aNewName )
3153 throw ( embed::InvalidStorageException,
3154 lang::IllegalArgumentException,
3155 container::NoSuchElementException,
3156 container::ElementExistException,
3157 io::IOException,
3158 embed::StorageWrappedTargetException,
3159 uno::RuntimeException )
3161 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::renameElement" );
3163 ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3165 if ( !m_pImpl )
3166 throw lang::DisposedException();
3168 if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
3169 || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
3170 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3172 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
3173 && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
3174 || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
3175 throw lang::IllegalArgumentException(); // TODO: unacceptable element name
3177 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3178 throw io::IOException(); // TODO: access denied
3182 SotElement_Impl* pRefElement = m_pImpl->FindElement( aNewName );
3183 if ( pRefElement )
3184 throw container::ElementExistException(); //???
3186 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3187 if ( !pElement )
3188 throw container::NoSuchElementException(); //???
3190 pElement->m_aName = aNewName;
3192 m_pImpl->m_bIsModified = sal_True;
3193 m_pImpl->m_bBroadcastModified = sal_True;
3195 catch( embed::InvalidStorageException& )
3197 throw;
3199 catch( lang::IllegalArgumentException& )
3201 throw;
3203 catch( container::NoSuchElementException& )
3205 throw;
3207 catch( container::ElementExistException& )
3209 throw;
3211 catch( io::IOException& )
3213 throw;
3215 catch( embed::StorageWrappedTargetException& )
3217 throw;
3219 catch( uno::RuntimeException& )
3221 throw;
3223 catch( uno::Exception& )
3225 uno::Any aCaught( ::cppu::getCaughtException() );
3226 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't rename element!" ),
3227 uno::Reference< io::XInputStream >(),
3228 aCaught );
3231 aGuard.clear();
3233 BroadcastModifiedIfNecessary();
3236 //-----------------------------------------------
3237 void SAL_CALL OStorage::copyElementTo( const ::rtl::OUString& aElementName,
3238 const uno::Reference< embed::XStorage >& xDest,
3239 const ::rtl::OUString& aNewName )
3240 throw ( embed::InvalidStorageException,
3241 lang::IllegalArgumentException,
3242 container::NoSuchElementException,
3243 container::ElementExistException,
3244 io::IOException,
3245 embed::StorageWrappedTargetException,
3246 uno::RuntimeException )
3248 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyElementTo" );
3250 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3252 if ( !m_pImpl )
3253 throw lang::DisposedException();
3255 if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
3256 || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
3257 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3259 if ( !xDest.is() )
3260 // || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
3261 throw lang::IllegalArgumentException();
3263 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
3264 && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
3265 || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
3266 throw lang::IllegalArgumentException(); // TODO: unacceptable element name
3270 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3271 if ( !pElement )
3272 throw container::NoSuchElementException(); //TODO
3274 uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
3275 if ( !xNameAccess.is() )
3276 throw uno::RuntimeException(); // TODO
3278 if ( xNameAccess->hasByName( aNewName ) )
3279 throw container::ElementExistException();
3281 m_pImpl->CopyStorageElement( pElement, xDest, aNewName, sal_False );
3283 catch( embed::InvalidStorageException& )
3285 throw;
3287 catch( lang::IllegalArgumentException& )
3289 throw;
3291 catch( container::NoSuchElementException& )
3293 throw;
3295 catch( container::ElementExistException& )
3297 throw;
3299 catch( embed::StorageWrappedTargetException& )
3301 throw;
3303 catch( io::IOException& )
3305 throw;
3307 catch( uno::RuntimeException& )
3309 throw;
3311 catch( uno::Exception& )
3313 uno::Any aCaught( ::cppu::getCaughtException() );
3314 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy element!" ),
3315 uno::Reference< io::XInputStream >(),
3316 aCaught );
3321 //-----------------------------------------------
3322 void SAL_CALL OStorage::moveElementTo( const ::rtl::OUString& aElementName,
3323 const uno::Reference< embed::XStorage >& xDest,
3324 const ::rtl::OUString& aNewName )
3325 throw ( embed::InvalidStorageException,
3326 lang::IllegalArgumentException,
3327 container::NoSuchElementException,
3328 container::ElementExistException,
3329 io::IOException,
3330 embed::StorageWrappedTargetException,
3331 uno::RuntimeException )
3333 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::moveElementTo" );
3335 ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3337 if ( !m_pImpl )
3338 throw lang::DisposedException();
3340 if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
3341 || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
3342 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3344 if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
3345 throw lang::IllegalArgumentException();
3347 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
3348 && ( aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) )
3349 || aNewName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) ) )
3350 throw lang::IllegalArgumentException(); // TODO: unacceptable element name
3352 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3353 throw io::IOException(); // TODO: access denied
3357 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
3358 if ( !pElement )
3359 throw container::NoSuchElementException(); //???
3361 uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
3362 if ( !xNameAccess.is() )
3363 throw uno::RuntimeException(); // TODO
3365 if ( xNameAccess->hasByName( aNewName ) )
3366 throw container::ElementExistException();
3368 m_pImpl->CopyStorageElement( pElement, xDest, aNewName, sal_False );
3370 m_pImpl->RemoveElement( pElement );
3372 m_pImpl->m_bIsModified = sal_True;
3373 m_pImpl->m_bBroadcastModified = sal_True;
3375 catch( embed::InvalidStorageException& )
3377 throw;
3379 catch( lang::IllegalArgumentException& )
3381 throw;
3383 catch( container::NoSuchElementException& )
3385 throw;
3387 catch( container::ElementExistException& )
3389 throw;
3391 catch( embed::StorageWrappedTargetException& )
3393 throw;
3395 catch( io::IOException& )
3397 throw;
3399 catch( uno::RuntimeException& )
3401 throw;
3403 catch( uno::Exception& )
3405 uno::Any aCaught( ::cppu::getCaughtException() );
3406 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't move element!" ),
3407 uno::Reference< io::XInputStream >(),
3408 aCaught );
3411 aGuard.clear();
3413 BroadcastModifiedIfNecessary();
3416 //____________________________________________________________________________________________________
3417 // XStorageRawAccess
3418 //____________________________________________________________________________________________________
3420 //-----------------------------------------------
3421 uno::Reference< io::XInputStream > SAL_CALL OStorage::getPlainRawStreamElement(
3422 const ::rtl::OUString& sStreamName )
3423 throw ( embed::InvalidStorageException,
3424 lang::IllegalArgumentException,
3425 container::NoSuchElementException,
3426 io::IOException,
3427 embed::StorageWrappedTargetException,
3428 uno::RuntimeException )
3430 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getPlainRawStreamElement" );
3432 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3434 if ( !m_pImpl )
3435 throw lang::DisposedException();
3437 if ( m_pData->m_nStorageType == OFOPXML_STORAGE )
3438 throw uno::RuntimeException(); // the interface is not supported and must not be accessible
3440 if ( !sStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName, sal_False ) )
3441 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3443 uno::Reference < io::XInputStream > xTempIn;
3446 SotElement_Impl* pElement = m_pImpl->FindElement( sStreamName );
3447 if ( !pElement )
3448 throw container::NoSuchElementException(); //TODO
3450 if ( !pElement->m_pStream )
3452 m_pImpl->OpenSubStream( pElement );
3453 if ( !pElement->m_pStream )
3454 throw io::IOException(); // TODO
3457 uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetPlainRawInStream();
3458 if ( !xRawInStream.is() )
3459 throw io::IOException();
3461 uno::Reference < io::XOutputStream > xTempOut(
3462 m_pImpl->GetServiceFactory()->createInstance (
3463 ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
3464 uno::UNO_QUERY );
3465 xTempIn = uno::Reference < io::XInputStream >( xTempOut, uno::UNO_QUERY );
3466 uno::Reference < io::XSeekable > xSeek( xTempOut, uno::UNO_QUERY );
3468 if ( !xTempOut.is() || !xTempIn.is() || !xSeek.is() )
3469 throw io::IOException();
3471 // Copy temporary file to a new one
3472 ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
3473 xTempOut->closeOutput();
3474 xSeek->seek( 0 );
3476 catch( embed::InvalidStorageException& )
3478 throw;
3480 catch( lang::IllegalArgumentException& )
3482 throw;
3484 catch( container::NoSuchElementException& )
3486 throw;
3488 catch( embed::StorageWrappedTargetException& )
3490 throw;
3492 catch( io::IOException& )
3494 throw;
3496 catch( uno::RuntimeException& )
3498 throw;
3500 catch( uno::Exception& )
3502 uno::Any aCaught( ::cppu::getCaughtException() );
3503 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't get plain raw stream!" ),
3504 uno::Reference< io::XInputStream >(),
3505 aCaught );
3508 return xTempIn;
3511 //-----------------------------------------------
3512 uno::Reference< io::XInputStream > SAL_CALL OStorage::getRawEncrStreamElement(
3513 const ::rtl::OUString& sStreamName )
3514 throw ( embed::InvalidStorageException,
3515 lang::IllegalArgumentException,
3516 packages::NoEncryptionException,
3517 container::NoSuchElementException,
3518 io::IOException,
3519 embed::StorageWrappedTargetException,
3520 uno::RuntimeException )
3522 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getRawEncrStreamElement" );
3524 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3526 if ( !m_pImpl )
3527 throw lang::DisposedException();
3529 if ( m_pData->m_nStorageType != PACKAGE_STORAGE )
3530 throw packages::NoEncryptionException();
3532 if ( !sStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName, sal_False ) )
3533 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3535 uno::Reference < io::XInputStream > xTempIn;
3538 SotElement_Impl* pElement = m_pImpl->FindElement( sStreamName );
3539 if ( !pElement )
3540 throw container::NoSuchElementException(); //TODO
3542 if ( !pElement->m_pStream )
3544 m_pImpl->OpenSubStream( pElement );
3545 if ( !pElement->m_pStream )
3546 throw io::IOException(); // TODO
3549 if ( !pElement->m_pStream->IsEncrypted() )
3550 throw packages::NoEncryptionException(); // TODO
3552 uno::Reference< io::XInputStream > xRawInStream = pElement->m_pStream->GetRawInStream();
3553 if ( !xRawInStream.is() )
3554 throw io::IOException();
3556 uno::Reference < io::XOutputStream > xTempOut(
3557 m_pImpl->GetServiceFactory()->createInstance (
3558 ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
3559 uno::UNO_QUERY );
3560 xTempIn = uno::Reference < io::XInputStream >( xTempOut, uno::UNO_QUERY );
3561 uno::Reference < io::XSeekable > xSeek( xTempOut, uno::UNO_QUERY );
3563 if ( !xTempOut.is() || !xTempIn.is() || !xSeek.is() )
3564 throw io::IOException();
3566 // Copy temporary file to a new one
3567 ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
3568 xTempOut->closeOutput();
3569 xSeek->seek( 0 );
3572 catch( embed::InvalidStorageException& )
3574 throw;
3576 catch( lang::IllegalArgumentException& )
3578 throw;
3580 catch( packages::NoEncryptionException& )
3582 throw;
3584 catch( container::NoSuchElementException& )
3586 throw;
3588 catch( embed::StorageWrappedTargetException& )
3590 throw;
3592 catch( io::IOException& )
3594 throw;
3596 catch( uno::RuntimeException& )
3598 throw;
3600 catch( uno::Exception& )
3602 uno::Any aCaught( ::cppu::getCaughtException() );
3603 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't get raw stream!" ),
3604 uno::Reference< io::XInputStream >(),
3605 aCaught );
3608 return xTempIn;
3611 //-----------------------------------------------
3612 void SAL_CALL OStorage::insertRawEncrStreamElement( const ::rtl::OUString& aStreamName,
3613 const uno::Reference< io::XInputStream >& xInStream )
3614 throw ( embed::InvalidStorageException,
3615 lang::IllegalArgumentException,
3616 packages::NoRawFormatException,
3617 container::ElementExistException,
3618 io::IOException,
3619 embed::StorageWrappedTargetException,
3620 uno::RuntimeException)
3622 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::insertRawEncrStreamElement" );
3624 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3626 if ( !m_pImpl )
3627 throw lang::DisposedException();
3629 if ( m_pData->m_nStorageType != PACKAGE_STORAGE )
3630 throw packages::NoEncryptionException();
3632 if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
3633 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3635 if ( !xInStream.is() )
3636 throw lang::IllegalArgumentException(); // TODO
3638 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3639 throw io::IOException(); // TODO: access denied
3643 SotElement_Impl* pElement = m_pImpl->FindElement( aStreamName );
3644 if ( pElement )
3645 throw container::ElementExistException(); //TODO
3647 m_pImpl->InsertRawStream( aStreamName, xInStream );
3649 catch( embed::InvalidStorageException& )
3651 throw;
3653 catch( lang::IllegalArgumentException& )
3655 throw;
3657 catch( packages::NoRawFormatException& )
3659 throw;
3661 catch( container::ElementExistException& )
3663 throw;
3665 catch( embed::StorageWrappedTargetException& )
3667 throw;
3669 catch( io::IOException& )
3671 throw;
3673 catch( uno::RuntimeException& )
3675 throw;
3677 catch( uno::Exception& )
3679 uno::Any aCaught( ::cppu::getCaughtException() );
3680 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't insert raw stream!" ),
3681 uno::Reference< io::XInputStream >(),
3682 aCaught );
3686 //____________________________________________________________________________________________________
3687 // XTransactedObject
3688 //____________________________________________________________________________________________________
3690 //-----------------------------------------------
3691 void SAL_CALL OStorage::commit()
3692 throw ( io::IOException,
3693 embed::StorageWrappedTargetException,
3694 uno::RuntimeException )
3696 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::commit" );
3698 uno::Reference< util::XModifiable > xParentModif;
3700 try {
3701 BroadcastTransaction( STOR_MESS_PRECOMMIT );
3703 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3705 if ( !m_pImpl )
3706 throw lang::DisposedException();
3708 if ( m_pData->m_bReadOnlyWrap )
3709 throw io::IOException(); // TODO: access_denied
3711 m_pImpl->Commit(); // the root storage initiates the storing to source
3713 // when the storage is commited the parent is modified
3714 if ( m_pImpl->m_pParent && m_pImpl->m_pParent->m_pAntiImpl )
3715 xParentModif = (util::XModifiable*)m_pImpl->m_pParent->m_pAntiImpl;
3717 catch( io::IOException& )
3719 throw;
3721 catch( embed::StorageWrappedTargetException& )
3723 throw;
3725 catch( uno::RuntimeException& )
3727 throw;
3729 catch( uno::Exception& )
3731 uno::Any aCaught( ::cppu::getCaughtException() );
3732 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Problems on commit!" ),
3733 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ),
3734 aCaught );
3737 setModified( sal_False );
3738 if ( xParentModif.is() )
3739 xParentModif->setModified( sal_True );
3741 BroadcastTransaction( STOR_MESS_COMMITED );
3744 //-----------------------------------------------
3745 void SAL_CALL OStorage::revert()
3746 throw ( io::IOException,
3747 embed::StorageWrappedTargetException,
3748 uno::RuntimeException )
3750 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::revert" );
3752 // the method removes all the changes done after last commit
3754 BroadcastTransaction( STOR_MESS_PREREVERT );
3756 ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3758 if ( !m_pImpl )
3759 throw lang::DisposedException();
3761 for ( SotElementList_Impl::iterator pElementIter = m_pImpl->m_aChildrenList.begin();
3762 pElementIter != m_pImpl->m_aChildrenList.end(); pElementIter++ )
3763 if ( (*pElementIter)->m_pStorage
3764 && ( (*pElementIter)->m_pStorage->m_pAntiImpl || !(*pElementIter)->m_pStorage->m_aReadOnlyWrapList.empty() )
3765 || (*pElementIter)->m_pStream
3766 && ( (*pElementIter)->m_pStream->m_pAntiImpl || !(*pElementIter)->m_pStream->m_aInputStreamsList.empty() ) )
3767 throw io::IOException(); // TODO: access denied
3769 if ( m_pData->m_bReadOnlyWrap || !m_pImpl->m_bListCreated )
3770 return; // nothing to do
3772 try {
3773 m_pImpl->Revert();
3774 m_pImpl->m_bIsModified = sal_False;
3775 m_pImpl->m_bBroadcastModified = sal_True;
3777 catch( io::IOException& )
3779 throw;
3781 catch( embed::StorageWrappedTargetException& )
3783 throw;
3785 catch( uno::RuntimeException& )
3787 throw;
3789 catch( uno::Exception& )
3791 uno::Any aCaught( ::cppu::getCaughtException() );
3792 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Problems on revert!" ),
3793 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ),
3794 aCaught );
3797 aGuard.clear();
3799 setModified( sal_False );
3800 BroadcastTransaction( STOR_MESS_REVERTED );
3803 //____________________________________________________________________________________________________
3804 // XTransactionBroadcaster
3805 //____________________________________________________________________________________________________
3807 //-----------------------------------------------
3808 void SAL_CALL OStorage::addTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
3809 throw ( uno::RuntimeException )
3811 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3813 if ( !m_pImpl )
3814 throw lang::DisposedException();
3816 m_pData->m_aListenersContainer.addInterface( ::getCppuType((const uno::Reference< embed::XTransactionListener >*)0),
3817 aListener );
3820 //-----------------------------------------------
3821 void SAL_CALL OStorage::removeTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
3822 throw ( uno::RuntimeException )
3824 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3826 if ( !m_pImpl )
3827 throw lang::DisposedException();
3829 m_pData->m_aListenersContainer.removeInterface( ::getCppuType((const uno::Reference< embed::XTransactionListener >*)0),
3830 aListener );
3833 //____________________________________________________________________________________________________
3834 // XModifiable
3835 // TODO: if there will be no demand on this interface it will be removed from implementation,
3836 // I do not want to remove it now since it is still possible that it will be inserted
3837 // to the service back.
3838 //____________________________________________________________________________________________________
3840 //-----------------------------------------------
3841 sal_Bool SAL_CALL OStorage::isModified()
3842 throw ( uno::RuntimeException )
3844 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3846 if ( !m_pImpl )
3847 throw lang::DisposedException();
3849 return m_pImpl->m_bIsModified;
3853 //-----------------------------------------------
3854 void SAL_CALL OStorage::setModified( sal_Bool bModified )
3855 throw ( beans::PropertyVetoException,
3856 uno::RuntimeException )
3858 ::osl::ResettableMutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3860 if ( !m_pImpl )
3861 throw lang::DisposedException();
3863 if ( m_pData->m_bReadOnlyWrap )
3864 throw beans::PropertyVetoException(); // TODO: access denied
3866 if ( m_pImpl->m_bIsModified != bModified )
3867 m_pImpl->m_bIsModified = bModified;
3869 aGuard.clear();
3870 if ( bModified )
3872 m_pImpl->m_bBroadcastModified = sal_True;
3873 BroadcastModifiedIfNecessary();
3877 //-----------------------------------------------
3878 void SAL_CALL OStorage::addModifyListener(
3879 const uno::Reference< util::XModifyListener >& aListener )
3880 throw ( uno::RuntimeException )
3882 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3884 if ( !m_pImpl )
3885 throw lang::DisposedException();
3887 m_pData->m_aListenersContainer.addInterface(
3888 ::getCppuType( ( const uno::Reference< util::XModifyListener >* )0 ), aListener );
3892 //-----------------------------------------------
3893 void SAL_CALL OStorage::removeModifyListener(
3894 const uno::Reference< util::XModifyListener >& aListener )
3895 throw ( uno::RuntimeException )
3897 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3899 if ( !m_pImpl )
3900 throw lang::DisposedException();
3902 m_pData->m_aListenersContainer.removeInterface(
3903 ::getCppuType( ( const uno::Reference< util::XModifyListener >* )0 ), aListener );
3906 //____________________________________________________________________________________________________
3907 // XNameAccess
3908 //____________________________________________________________________________________________________
3910 //-----------------------------------------------
3911 uno::Any SAL_CALL OStorage::getByName( const ::rtl::OUString& aName )
3912 throw ( container::NoSuchElementException,
3913 lang::WrappedTargetException,
3914 uno::RuntimeException )
3916 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getByName" );
3918 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3920 if ( !m_pImpl )
3921 throw lang::DisposedException();
3923 if ( !aName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aName, sal_False ) )
3924 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
3926 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
3927 && aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
3928 throw lang::IllegalArgumentException(); // TODO: unacceptable element name
3930 uno::Any aResult;
3933 SotElement_Impl* pElement = m_pImpl->FindElement( aName );
3934 if ( !pElement )
3935 throw container::NoSuchElementException(); //TODO:
3937 if ( pElement->m_bIsStorage )
3938 aResult <<= openStorageElement( aName, embed::ElementModes::READ );
3939 else
3940 aResult <<= openStreamElement( aName, embed::ElementModes::READ );
3942 catch( container::NoSuchElementException& )
3944 throw;
3946 catch( lang::WrappedTargetException& )
3948 throw;
3950 catch( uno::RuntimeException& )
3952 throw;
3954 catch ( uno::Exception& )
3956 uno::Any aCaught( ::cppu::getCaughtException() );
3957 throw lang::WrappedTargetException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
3958 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
3959 uno::UNO_QUERY ),
3960 aCaught );
3963 return aResult;
3967 //-----------------------------------------------
3968 uno::Sequence< ::rtl::OUString > SAL_CALL OStorage::getElementNames()
3969 throw ( uno::RuntimeException )
3971 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getElementNames" );
3973 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
3975 if ( !m_pImpl )
3976 throw lang::DisposedException();
3980 return m_pImpl->GetElementNames();
3982 catch( uno::RuntimeException& )
3984 throw;
3986 catch ( uno::Exception& )
3988 uno::Any aCaught( ::cppu::getCaughtException() );
3989 throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
3990 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
3991 uno::UNO_QUERY ),
3992 aCaught );
3997 //-----------------------------------------------
3998 sal_Bool SAL_CALL OStorage::hasByName( const ::rtl::OUString& aName )
3999 throw ( uno::RuntimeException )
4001 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::hasByName" );
4003 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4005 if ( !m_pImpl )
4006 throw lang::DisposedException();
4008 if ( !aName.getLength() )
4009 return sal_False;
4011 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
4012 && aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
4013 return sal_False;
4015 SotElement_Impl* pElement = NULL;
4018 pElement = m_pImpl->FindElement( aName );
4020 catch( uno::RuntimeException& )
4022 throw;
4024 catch ( uno::Exception& )
4026 uno::Any aCaught( ::cppu::getCaughtException() );
4027 throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
4028 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
4029 uno::UNO_QUERY ),
4030 aCaught );
4033 return ( pElement != NULL );
4037 //-----------------------------------------------
4038 uno::Type SAL_CALL OStorage::getElementType()
4039 throw ( uno::RuntimeException )
4041 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4043 if ( !m_pImpl )
4044 throw lang::DisposedException();
4046 // it is a multitype container
4047 return uno::Type();
4051 //-----------------------------------------------
4052 sal_Bool SAL_CALL OStorage::hasElements()
4053 throw ( uno::RuntimeException )
4055 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::hasElements" );
4057 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4059 if ( !m_pImpl )
4060 throw lang::DisposedException();
4064 return ( m_pImpl->GetChildrenList().size() != 0 );
4066 catch( uno::RuntimeException& )
4068 throw;
4070 catch ( uno::Exception& )
4072 uno::Any aCaught( ::cppu::getCaughtException() );
4073 throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
4074 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
4075 uno::UNO_QUERY ),
4076 aCaught );
4081 //____________________________________________________________________________________________________
4082 // XComponent
4083 //____________________________________________________________________________________________________
4085 //-----------------------------------------------
4086 void SAL_CALL OStorage::dispose()
4087 throw ( uno::RuntimeException )
4089 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4091 if ( !m_pImpl )
4092 throw lang::DisposedException();
4096 InternalDispose( sal_True );
4098 catch( uno::RuntimeException& )
4100 throw;
4102 catch ( uno::Exception& )
4104 uno::Any aCaught( ::cppu::getCaughtException() );
4105 throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open storage!\n" ),
4106 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
4107 uno::UNO_QUERY ),
4108 aCaught );
4112 //-----------------------------------------------
4113 void SAL_CALL OStorage::addEventListener(
4114 const uno::Reference< lang::XEventListener >& xListener )
4115 throw ( uno::RuntimeException )
4117 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4119 if ( !m_pImpl )
4120 throw lang::DisposedException();
4122 m_pData->m_aListenersContainer.addInterface(
4123 ::getCppuType( ( const uno::Reference< lang::XEventListener >* )0 ), xListener );
4126 //-----------------------------------------------
4127 void SAL_CALL OStorage::removeEventListener(
4128 const uno::Reference< lang::XEventListener >& xListener )
4129 throw ( uno::RuntimeException )
4131 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4133 if ( !m_pImpl )
4134 throw lang::DisposedException();
4136 m_pData->m_aListenersContainer.removeInterface(
4137 ::getCppuType( ( const uno::Reference< lang::XEventListener >* )0 ), xListener );
4140 //____________________________________________________________________________________________________
4141 // XEncryptionProtectedSource
4142 //____________________________________________________________________________________________________
4144 void SAL_CALL OStorage::setEncryptionPassword( const ::rtl::OUString& aPass )
4145 throw ( uno::RuntimeException,
4146 io::IOException )
4148 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setEncryptionPassword" );
4150 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4152 if ( !m_pImpl )
4153 throw lang::DisposedException();
4155 if ( m_pData->m_nStorageType != PACKAGE_STORAGE )
4156 throw uno::RuntimeException(); // the interface must be visible only for package storage
4158 OSL_ENSURE( m_pData->m_bIsRoot, "setEncryptionPassword() method is not available for nonroot storages!\n" );
4160 if ( m_pData->m_bIsRoot )
4162 try {
4163 m_pImpl->ReadContents();
4165 catch ( uno::RuntimeException& )
4167 throw;
4169 catch ( uno::Exception& )
4171 uno::Any aCaught( ::cppu::getCaughtException() );
4172 throw lang::WrappedTargetException( ::rtl::OUString::createFromAscii( "Can not open package!\n" ),
4173 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
4174 uno::UNO_QUERY ),
4175 aCaught );
4178 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY );
4179 if ( !xPackPropSet.is() )
4180 throw uno::RuntimeException(); // TODO
4184 xPackPropSet->setPropertyValue( ::rtl::OUString::createFromAscii("EncryptionKey"),
4185 uno::makeAny( MakeKeyFromPass( aPass, sal_True ) ) );
4187 m_pImpl->m_bHasCommonPassword = sal_True;
4188 m_pImpl->m_aCommonPassword = aPass;
4190 catch( uno::Exception& )
4192 OSL_ENSURE( sal_False, "The call must not fail, it is pretty simple!" );
4193 throw io::IOException(); // TODO:
4198 //-----------------------------------------------
4199 void SAL_CALL OStorage::removeEncryption()
4200 throw ( uno::RuntimeException,
4201 io::IOException )
4203 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::removeEncryption" );
4205 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4207 if ( !m_pImpl )
4208 throw lang::DisposedException();
4210 if ( m_pData->m_nStorageType != PACKAGE_STORAGE )
4211 throw uno::RuntimeException(); // the interface must be visible only for package storage
4213 OSL_ENSURE( m_pData->m_bIsRoot, "removeEncryption() method is not available for nonroot storages!\n" );
4215 if ( m_pData->m_bIsRoot )
4217 try {
4218 m_pImpl->ReadContents();
4220 catch ( uno::RuntimeException& )
4222 throw;
4224 catch ( uno::Exception& )
4226 uno::Any aCaught( ::cppu::getCaughtException() );
4227 throw lang::WrappedTargetRuntimeException( ::rtl::OUString::createFromAscii( "Can not open package!\n" ),
4228 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
4229 uno::UNO_QUERY ),
4230 aCaught );
4233 // TODO: check if the password is valid
4234 // update all streams that was encrypted with old password
4236 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY );
4237 if ( !xPackPropSet.is() )
4238 throw uno::RuntimeException(); // TODO
4242 xPackPropSet->setPropertyValue( ::rtl::OUString::createFromAscii("EncryptionKey"),
4243 uno::makeAny( uno::Sequence< sal_Int8 >() ) );
4245 m_pImpl->m_bHasCommonPassword = sal_False;
4246 m_pImpl->m_aCommonPassword = ::rtl::OUString();
4248 catch( uno::Exception& )
4250 OSL_ENSURE( sal_False, "The call must not fail, it is pretty simple!" );
4251 throw io::IOException(); // TODO:
4256 //____________________________________________________________________________________________________
4257 // XPropertySet
4258 //____________________________________________________________________________________________________
4260 //-----------------------------------------------
4261 uno::Reference< beans::XPropertySetInfo > SAL_CALL OStorage::getPropertySetInfo()
4262 throw ( uno::RuntimeException )
4264 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4266 if ( !m_pImpl )
4267 throw lang::DisposedException();
4269 //TODO:
4270 return uno::Reference< beans::XPropertySetInfo >();
4274 //-----------------------------------------------
4275 void SAL_CALL OStorage::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& aValue )
4276 throw ( beans::UnknownPropertyException,
4277 beans::PropertyVetoException,
4278 lang::IllegalArgumentException,
4279 lang::WrappedTargetException,
4280 uno::RuntimeException )
4282 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::setPropertyValue" );
4284 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4286 if ( !m_pImpl )
4287 throw lang::DisposedException();
4289 //TODO: think about interaction handler
4291 if ( m_pData->m_bReadOnlyWrap )
4292 throw io::IOException(); // TODO: Access denied
4294 if ( m_pData->m_nStorageType == ZIP_STORAGE )
4295 throw beans::UnknownPropertyException(); // TODO
4296 else if ( m_pData->m_nStorageType == PACKAGE_STORAGE )
4298 if ( aPropertyName.equalsAscii( "MediaType" ) )
4300 aValue >>= m_pImpl->m_aMediaType;
4301 m_pImpl->m_bControlMediaType = sal_True;
4303 m_pImpl->m_bBroadcastModified = sal_True;
4304 m_pImpl->m_bIsModified = sal_True;
4306 else if ( aPropertyName.equalsAscii( "Version" ) )
4308 aValue >>= m_pImpl->m_aVersion;
4309 m_pImpl->m_bControlVersion = sal_True;
4311 m_pImpl->m_bBroadcastModified = sal_True;
4312 m_pImpl->m_bIsModified = sal_True;
4314 else if ( m_pData->m_bIsRoot && ( aPropertyName.equalsAscii( "HasEncryptedEntries" )
4315 || aPropertyName.equalsAscii( "URL" )
4316 || aPropertyName.equalsAscii( "RepairPackage" ) )
4317 || aPropertyName.equalsAscii( "IsRoot" )
4318 || aPropertyName.equalsAscii( "MediaTypeFallbackUsed" ) )
4319 throw beans::PropertyVetoException(); // TODO
4320 else
4321 throw beans::UnknownPropertyException(); // TODO
4323 else if ( m_pData->m_nStorageType == OFOPXML_STORAGE )
4325 if ( aPropertyName.equalsAscii( "RelationsInfoStream" ) )
4327 uno::Reference< io::XInputStream > xInRelStream;
4328 if ( ( aValue >>= xInRelStream ) && xInRelStream.is() )
4330 uno::Reference< io::XSeekable > xSeek( xInRelStream, uno::UNO_QUERY );
4331 if ( !xSeek.is() )
4333 // currently this is an internal property that is used for optimization
4334 // and the stream must support XSeekable interface
4335 // TODO/LATER: in future it can be changed if property is used from outside
4336 throw lang::IllegalArgumentException(); // TODO
4339 m_pImpl->m_xNewRelInfoStream = xInRelStream;
4340 m_pImpl->m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
4341 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED_STREAM;
4342 m_pImpl->m_bBroadcastModified = sal_True;
4343 m_pImpl->m_bIsModified = sal_True;
4345 else
4346 throw lang::IllegalArgumentException(); // TODO
4348 else if ( aPropertyName.equalsAscii( "RelationsInfo" ) )
4350 if ( aValue >>= m_pImpl->m_aRelInfo )
4352 m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
4353 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
4354 m_pImpl->m_bBroadcastModified = sal_True;
4355 m_pImpl->m_bIsModified = sal_True;
4357 else
4358 throw lang::IllegalArgumentException(); // TODO
4360 else if ( m_pData->m_bIsRoot && ( aPropertyName.equalsAscii( "URL" )
4361 || aPropertyName.equalsAscii( "RepairPackage" ) )
4362 || aPropertyName.equalsAscii( "IsRoot" ) )
4363 throw beans::PropertyVetoException(); // TODO
4364 else
4365 throw beans::UnknownPropertyException(); // TODO
4367 else
4368 throw beans::UnknownPropertyException(); // TODO
4370 BroadcastModifiedIfNecessary();
4374 //-----------------------------------------------
4375 uno::Any SAL_CALL OStorage::getPropertyValue( const ::rtl::OUString& aPropertyName )
4376 throw ( beans::UnknownPropertyException,
4377 lang::WrappedTargetException,
4378 uno::RuntimeException )
4380 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getPropertyValue" );
4382 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4384 if ( !m_pImpl )
4385 throw lang::DisposedException();
4387 if ( m_pData->m_nStorageType == PACKAGE_STORAGE
4388 && ( aPropertyName.equalsAscii( "MediaType" )
4389 || aPropertyName.equalsAscii( "MediaTypeFallbackUsed" )
4390 || aPropertyName.equalsAscii( "Version" ) ) )
4394 m_pImpl->ReadContents();
4396 catch ( uno::RuntimeException& )
4398 throw;
4400 catch ( uno::Exception& )
4402 uno::Any aCaught( ::cppu::getCaughtException() );
4403 throw lang::WrappedTargetException(
4404 ::rtl::OUString::createFromAscii( "Can't read contents!" ),
4405 uno::Reference< XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ),
4406 aCaught );
4409 if ( aPropertyName.equalsAscii( "MediaType" ) )
4410 return uno::makeAny( m_pImpl->m_aMediaType );
4411 else if ( aPropertyName.equalsAscii( "Version" ) )
4412 return uno::makeAny( m_pImpl->m_aVersion );
4413 else
4414 return uno::makeAny( m_pImpl->m_bMTFallbackUsed );
4416 else if ( aPropertyName.equalsAscii( "IsRoot" ) )
4418 return uno::makeAny( m_pData->m_bIsRoot );
4420 else if ( aPropertyName.equalsAscii( "OpenMode" ) )
4422 return uno::makeAny( m_pImpl->m_nStorageMode );
4424 else if ( m_pData->m_bIsRoot )
4426 if ( aPropertyName.equalsAscii( "URL" )
4427 || aPropertyName.equalsAscii( "RepairPackage" ) )
4429 for ( sal_Int32 aInd = 0; aInd < m_pImpl->m_xProperties.getLength(); aInd++ )
4431 if ( m_pImpl->m_xProperties[aInd].Name.equals( aPropertyName ) )
4432 return m_pImpl->m_xProperties[aInd].Value;
4435 if ( aPropertyName.equalsAscii( "URL" ) )
4436 return uno::makeAny( ::rtl::OUString() );
4438 return uno::makeAny( sal_False ); // RepairPackage
4440 else if ( m_pData->m_nStorageType == PACKAGE_STORAGE && aPropertyName.equalsAscii( "HasEncryptedEntries" ) )
4442 try {
4443 m_pImpl->ReadContents();
4444 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY );
4445 if ( !xPackPropSet.is() )
4446 throw uno::RuntimeException(); // TODO
4448 return xPackPropSet->getPropertyValue( aPropertyName );
4450 catch ( uno::RuntimeException& )
4452 throw;
4454 catch ( uno::Exception& )
4456 uno::Any aCaught( ::cppu::getCaughtException() );
4457 throw lang::WrappedTargetException( ::rtl::OUString::createFromAscii( "Can not open package!\n" ),
4458 uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ),
4459 uno::UNO_QUERY ),
4460 aCaught );
4465 throw beans::UnknownPropertyException(); // TODO
4469 //-----------------------------------------------
4470 void SAL_CALL OStorage::addPropertyChangeListener(
4471 const ::rtl::OUString& /*aPropertyName*/,
4472 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
4473 throw ( beans::UnknownPropertyException,
4474 lang::WrappedTargetException,
4475 uno::RuntimeException )
4477 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4479 if ( !m_pImpl )
4480 throw lang::DisposedException();
4482 //TODO:
4486 //-----------------------------------------------
4487 void SAL_CALL OStorage::removePropertyChangeListener(
4488 const ::rtl::OUString& /*aPropertyName*/,
4489 const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
4490 throw ( beans::UnknownPropertyException,
4491 lang::WrappedTargetException,
4492 uno::RuntimeException )
4494 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4496 if ( !m_pImpl )
4497 throw lang::DisposedException();
4499 //TODO:
4503 //-----------------------------------------------
4504 void SAL_CALL OStorage::addVetoableChangeListener(
4505 const ::rtl::OUString& /*PropertyName*/,
4506 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
4507 throw ( beans::UnknownPropertyException,
4508 lang::WrappedTargetException,
4509 uno::RuntimeException )
4511 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4513 if ( !m_pImpl )
4514 throw lang::DisposedException();
4516 //TODO:
4520 //-----------------------------------------------
4521 void SAL_CALL OStorage::removeVetoableChangeListener(
4522 const ::rtl::OUString& /*PropertyName*/,
4523 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
4524 throw ( beans::UnknownPropertyException,
4525 lang::WrappedTargetException,
4526 uno::RuntimeException )
4528 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4530 if ( !m_pImpl )
4531 throw lang::DisposedException();
4533 //TODO:
4536 //____________________________________________________________________________________________________
4537 // XRelationshipAccess
4538 //____________________________________________________________________________________________________
4540 // TODO/LATER: the storage and stream implementations of this interface are very similar, they could use a helper class
4542 //-----------------------------------------------
4543 sal_Bool SAL_CALL OStorage::hasByID( const ::rtl::OUString& sID )
4544 throw ( io::IOException,
4545 uno::RuntimeException )
4547 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4549 if ( !m_pImpl )
4550 throw lang::DisposedException();
4552 if ( m_pData->m_nStorageType != OFOPXML_STORAGE )
4553 throw uno::RuntimeException();
4557 getRelationshipByID( sID );
4558 return sal_True;
4560 catch( container::NoSuchElementException& )
4563 return sal_False;
4566 //-----------------------------------------------
4567 ::rtl::OUString SAL_CALL OStorage::getTargetByID( const ::rtl::OUString& sID )
4568 throw ( container::NoSuchElementException,
4569 io::IOException,
4570 uno::RuntimeException )
4572 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4574 if ( !m_pImpl )
4575 throw lang::DisposedException();
4577 if ( m_pData->m_nStorageType != OFOPXML_STORAGE )
4578 throw uno::RuntimeException();
4580 uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
4581 for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
4582 if ( aSeq[nInd].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Target" ) ) )
4583 return aSeq[nInd].Second;
4585 return ::rtl::OUString();
4588 //-----------------------------------------------
4589 ::rtl::OUString SAL_CALL OStorage::getTypeByID( const ::rtl::OUString& sID )
4590 throw ( container::NoSuchElementException,
4591 io::IOException,
4592 uno::RuntimeException )
4594 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4596 if ( !m_pImpl )
4597 throw lang::DisposedException();
4599 if ( m_pData->m_nStorageType != OFOPXML_STORAGE )
4600 throw uno::RuntimeException();
4602 uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
4603 for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
4604 if ( aSeq[nInd].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
4605 return aSeq[nInd].Second;
4607 return ::rtl::OUString();
4610 //-----------------------------------------------
4611 uno::Sequence< beans::StringPair > SAL_CALL OStorage::getRelationshipByID( const ::rtl::OUString& sID )
4612 throw ( container::NoSuchElementException,
4613 io::IOException,
4614 uno::RuntimeException )
4616 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4618 if ( !m_pImpl )
4619 throw lang::DisposedException();
4621 if ( m_pData->m_nStorageType != OFOPXML_STORAGE )
4622 throw uno::RuntimeException();
4624 // TODO/LATER: in future the unification of the ID could be checked
4625 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4626 for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
4627 for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
4628 if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
4630 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
4631 return aSeq[nInd1];
4632 break;
4635 throw container::NoSuchElementException();
4638 //-----------------------------------------------
4639 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OStorage::getRelationshipsByType( const ::rtl::OUString& sType )
4640 throw ( io::IOException,
4641 uno::RuntimeException )
4643 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4645 if ( !m_pImpl )
4646 throw lang::DisposedException();
4648 if ( m_pData->m_nStorageType != OFOPXML_STORAGE )
4649 throw uno::RuntimeException();
4651 uno::Sequence< uno::Sequence< beans::StringPair > > aResult;
4652 sal_Int32 nEntriesNum = 0;
4654 // TODO/LATER: in future the unification of the ID could be checked
4655 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4656 for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
4657 for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
4658 if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Type" ) ) )
4660 // the type is usually an URL, so the check should be case insensitive
4661 if ( aSeq[nInd1][nInd2].Second.equalsIgnoreAsciiCase( sType ) )
4663 aResult.realloc( ++nEntriesNum );
4664 aResult[nEntriesNum-1] = aSeq[nInd1];
4666 break;
4669 return aResult;
4672 //-----------------------------------------------
4673 uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OStorage::getAllRelationships()
4674 throw (io::IOException, uno::RuntimeException)
4676 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4678 if ( !m_pImpl )
4679 throw lang::DisposedException();
4681 if ( m_pData->m_nStorageType != OFOPXML_STORAGE )
4682 throw uno::RuntimeException();
4684 return m_pImpl->GetAllRelationshipsIfAny();
4687 //-----------------------------------------------
4688 void SAL_CALL OStorage::insertRelationshipByID( const ::rtl::OUString& sID, const uno::Sequence< beans::StringPair >& aEntry, ::sal_Bool bReplace )
4689 throw ( container::ElementExistException,
4690 io::IOException,
4691 uno::RuntimeException )
4693 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4695 if ( !m_pImpl )
4696 throw lang::DisposedException();
4698 if ( m_pData->m_nStorageType != OFOPXML_STORAGE )
4699 throw uno::RuntimeException();
4701 ::rtl::OUString aIDTag( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
4703 sal_Int32 nIDInd = -1;
4705 // TODO/LATER: in future the unification of the ID could be checked
4706 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4707 for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
4708 for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
4709 if ( aSeq[nInd1][nInd2].First.equals( aIDTag ) )
4711 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
4712 nIDInd = nInd1;
4714 break;
4717 if ( nIDInd == -1 || bReplace )
4719 if ( nIDInd == -1 )
4721 nIDInd = aSeq.getLength();
4722 aSeq.realloc( nIDInd + 1 );
4725 aSeq[nIDInd].realloc( aEntry.getLength() + 1 );
4727 aSeq[nIDInd][0].First = aIDTag;
4728 aSeq[nIDInd][0].Second = sID;
4729 sal_Int32 nIndTarget = 1;
4730 for ( sal_Int32 nIndOrig = 0;
4731 nIndOrig < aEntry.getLength();
4732 nIndOrig++ )
4734 if ( !aEntry[nIndOrig].First.equals( aIDTag ) )
4735 aSeq[nIDInd][nIndTarget++] = aEntry[nIndOrig];
4738 aSeq[nIDInd].realloc( nIndTarget );
4740 else
4741 throw container::ElementExistException(); // TODO
4744 m_pImpl->m_aRelInfo = aSeq;
4745 m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
4746 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
4749 //-----------------------------------------------
4750 void SAL_CALL OStorage::removeRelationshipByID( const ::rtl::OUString& sID )
4751 throw ( container::NoSuchElementException,
4752 io::IOException,
4753 uno::RuntimeException )
4755 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4757 if ( !m_pImpl )
4758 throw lang::DisposedException();
4760 if ( m_pData->m_nStorageType != OFOPXML_STORAGE )
4761 throw uno::RuntimeException();
4763 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4764 for ( sal_Int32 nInd1 = 0; nInd1 < aSeq.getLength(); nInd1++ )
4765 for ( sal_Int32 nInd2 = 0; nInd2 < aSeq[nInd1].getLength(); nInd2++ )
4766 if ( aSeq[nInd1][nInd2].First.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Id" ) ) )
4768 if ( aSeq[nInd1][nInd2].Second.equals( sID ) )
4770 sal_Int32 nLength = aSeq.getLength();
4771 aSeq[nInd1] = aSeq[nLength-1];
4772 aSeq.realloc( nLength - 1 );
4774 m_pImpl->m_aRelInfo = aSeq;
4775 m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
4776 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
4778 // TODO/LATER: in future the unification of the ID could be checked
4779 return;
4782 break;
4785 throw container::NoSuchElementException();
4788 //-----------------------------------------------
4789 void SAL_CALL OStorage::insertRelationships( const uno::Sequence< uno::Sequence< beans::StringPair > >& aEntries, ::sal_Bool bReplace )
4790 throw ( container::ElementExistException,
4791 io::IOException,
4792 uno::RuntimeException )
4794 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4796 if ( !m_pImpl )
4797 throw lang::DisposedException();
4799 if ( m_pData->m_nStorageType != OFOPXML_STORAGE )
4800 throw uno::RuntimeException();
4802 ::rtl::OUString aIDTag( RTL_CONSTASCII_USTRINGPARAM( "Id" ) );
4803 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4804 uno::Sequence< uno::Sequence< beans::StringPair > > aResultSeq( aSeq.getLength() + aEntries.getLength() );
4805 sal_Int32 nResultInd = 0;
4807 for ( sal_Int32 nIndTarget1 = 0; nIndTarget1 < aSeq.getLength(); nIndTarget1++ )
4808 for ( sal_Int32 nIndTarget2 = 0; nIndTarget2 < aSeq[nIndTarget1].getLength(); nIndTarget2++ )
4809 if ( aSeq[nIndTarget1][nIndTarget2].First.equals( aIDTag ) )
4811 sal_Int32 nIndSourceSame = -1;
4813 for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
4814 for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
4816 if ( aEntries[nIndSource1][nIndSource2].First.equals( aIDTag ) )
4818 if ( aEntries[nIndSource1][nIndSource2].Second.equals( aSeq[nIndTarget1][nIndTarget2].Second ) )
4820 if ( !bReplace )
4821 throw container::ElementExistException();
4823 nIndSourceSame = nIndSource1;
4826 break;
4830 if ( nIndSourceSame == -1 )
4832 // no such element in the provided sequence
4833 aResultSeq[nResultInd++] = aSeq[nIndTarget1];
4836 break;
4839 for ( sal_Int32 nIndSource1 = 0; nIndSource1 < aEntries.getLength(); nIndSource1++ )
4841 aResultSeq[nResultInd].realloc( aEntries[nIndSource1].getLength() );
4842 sal_Bool bHasID = sal_False;
4843 sal_Int32 nResInd2 = 1;
4845 for ( sal_Int32 nIndSource2 = 0; nIndSource2 < aEntries[nIndSource1].getLength(); nIndSource2++ )
4846 if ( aEntries[nIndSource1][nIndSource2].First.equals( aIDTag ) )
4848 aResultSeq[nResultInd][0] = aEntries[nIndSource1][nIndSource2];
4849 bHasID = sal_True;
4851 else if ( nResInd2 < aResultSeq[nResultInd].getLength() )
4852 aResultSeq[nResultInd][nResInd2++] = aEntries[nIndSource1][nIndSource2];
4853 else
4854 throw io::IOException(); // TODO: illegal relation ( no ID )
4856 if ( !bHasID )
4857 throw io::IOException(); // TODO: illegal relations
4859 nResultInd++;
4862 aResultSeq.realloc( nResultInd );
4863 m_pImpl->m_aRelInfo = aResultSeq;
4864 m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
4865 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
4868 //-----------------------------------------------
4869 void SAL_CALL OStorage::clearRelationships()
4870 throw ( io::IOException,
4871 uno::RuntimeException )
4873 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4875 if ( !m_pImpl )
4876 throw lang::DisposedException();
4878 if ( m_pData->m_nStorageType != OFOPXML_STORAGE )
4879 throw uno::RuntimeException();
4881 m_pImpl->m_aRelInfo.realloc( 0 );
4882 m_pImpl->m_xNewRelInfoStream = uno::Reference< io::XInputStream >();
4883 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
4886 //____________________________________________________________________________________________________
4887 // XOptimizedStorage
4888 //____________________________________________________________________________________________________
4889 //-----------------------------------------------
4890 void SAL_CALL OStorage::insertRawNonEncrStreamElementDirect(
4891 const ::rtl::OUString& /*sStreamName*/,
4892 const uno::Reference< io::XInputStream >& /*xInStream*/ )
4893 throw ( embed::InvalidStorageException,
4894 lang::IllegalArgumentException,
4895 packages::NoRawFormatException,
4896 container::ElementExistException,
4897 io::IOException,
4898 embed::StorageWrappedTargetException,
4899 uno::RuntimeException )
4901 // not implemented currently because there is still no demand
4902 // might need to be implemented if direct copying of compressed streams is used
4903 throw io::IOException();
4906 //-----------------------------------------------
4907 void SAL_CALL OStorage::insertStreamElementDirect(
4908 const ::rtl::OUString& aStreamName,
4909 const uno::Reference< io::XInputStream >& xInStream,
4910 const uno::Sequence< beans::PropertyValue >& aProps )
4911 throw ( embed::InvalidStorageException,
4912 lang::IllegalArgumentException,
4913 container::ElementExistException,
4914 io::IOException,
4915 embed::StorageWrappedTargetException,
4916 uno::RuntimeException )
4918 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::insertStreamElementDirect" );
4920 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4922 if ( !m_pImpl )
4923 throw lang::DisposedException();
4925 if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
4926 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
4928 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
4929 && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
4930 throw lang::IllegalArgumentException(); // TODO: unacceptable storage name
4932 if ( m_pData->m_bReadOnlyWrap )
4933 throw io::IOException(); // TODO: access denied
4937 SotElement_Impl* pElement = m_pImpl->FindElement( aStreamName );
4939 if ( pElement )
4940 throw container::ElementExistException();
4942 pElement = OpenStreamElement_Impl( aStreamName, embed::ElementModes::READWRITE, sal_False );
4943 OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
4945 pElement->m_pStream->InsertStreamDirectly( xInStream, aProps );
4947 catch( embed::InvalidStorageException& )
4949 throw;
4951 catch( lang::IllegalArgumentException& )
4953 throw;
4955 catch( container::ElementExistException )
4957 throw;
4959 catch( embed::StorageWrappedTargetException& )
4961 throw;
4963 catch( io::IOException& )
4965 throw;
4967 catch( uno::RuntimeException& )
4969 throw;
4971 catch( uno::Exception& )
4973 uno::Any aCaught( ::cppu::getCaughtException() );
4974 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't insert stream directly!" ),
4975 uno::Reference< io::XInputStream >(),
4976 aCaught );
4980 //-----------------------------------------------
4981 void SAL_CALL OStorage::copyElementDirectlyTo(
4982 const ::rtl::OUString& aElementName,
4983 const uno::Reference< embed::XOptimizedStorage >& xDest,
4984 const ::rtl::OUString& aNewName )
4985 throw ( embed::InvalidStorageException,
4986 lang::IllegalArgumentException,
4987 container::NoSuchElementException,
4988 container::ElementExistException,
4989 io::IOException,
4990 embed::StorageWrappedTargetException,
4991 uno::RuntimeException )
4993 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::copyElementDirectlyTo" );
4995 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
4997 if ( !m_pImpl )
4998 throw lang::DisposedException();
5000 if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False )
5001 || !aNewName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, sal_False ) )
5002 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
5004 if ( !xDest.is() || xDest == uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( this ), uno::UNO_QUERY ) )
5005 throw lang::IllegalArgumentException();
5007 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
5008 && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
5009 throw lang::IllegalArgumentException(); // TODO: unacceptable storage name
5013 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
5014 if ( !pElement )
5015 throw container::NoSuchElementException(); //TODO
5017 uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY );
5018 if ( !xNameAccess.is() )
5019 throw uno::RuntimeException(); // TODO
5021 if ( xNameAccess->hasByName( aNewName ) )
5022 throw container::ElementExistException();
5024 // let the element be copied directly
5025 uno::Reference< embed::XStorage > xStorDest( xDest, uno::UNO_QUERY_THROW );
5026 m_pImpl->CopyStorageElement( pElement, xStorDest, aNewName, sal_True );
5028 catch( embed::InvalidStorageException& )
5030 throw;
5032 catch( lang::IllegalArgumentException& )
5034 throw;
5036 catch( container::NoSuchElementException& )
5038 throw;
5040 catch( container::ElementExistException& )
5042 throw;
5044 catch( embed::StorageWrappedTargetException& )
5046 throw;
5048 catch( io::IOException& )
5050 throw;
5052 catch( uno::RuntimeException& )
5054 throw;
5056 catch( uno::Exception& )
5058 uno::Any aCaught( ::cppu::getCaughtException() );
5059 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy element direcly!" ),
5060 uno::Reference< io::XInputStream >(),
5061 aCaught );
5065 //-----------------------------------------------
5066 void SAL_CALL OStorage::writeAndAttachToStream( const uno::Reference< io::XStream >& xStream )
5067 throw ( embed::InvalidStorageException,
5068 lang::IllegalArgumentException,
5069 io::IOException,
5070 embed::StorageWrappedTargetException,
5071 uno::RuntimeException )
5073 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::writeAndAttachToStream" );
5075 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5077 if ( !m_pImpl )
5078 throw lang::DisposedException();
5080 if ( !m_pData->m_bIsRoot )
5081 throw lang::IllegalArgumentException();
5083 if ( !m_pImpl->m_pSwitchStream )
5084 throw uno::RuntimeException();
5088 m_pImpl->m_pSwitchStream->CopyAndSwitchPersistenceTo( xStream );
5090 catch( embed::InvalidStorageException& )
5092 throw;
5094 catch( lang::IllegalArgumentException& )
5096 throw;
5098 catch( embed::StorageWrappedTargetException& )
5100 throw;
5102 catch( io::IOException& )
5104 throw;
5106 catch( uno::RuntimeException& )
5108 throw;
5110 catch( uno::Exception& )
5112 uno::Any aCaught( ::cppu::getCaughtException() );
5113 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't write and attach to stream!" ),
5114 uno::Reference< io::XInputStream >(),
5115 aCaught );
5120 //-----------------------------------------------
5121 void SAL_CALL OStorage::attachToURL( const ::rtl::OUString& sURL,
5122 sal_Bool bReadOnly )
5123 throw ( embed::InvalidStorageException,
5124 lang::IllegalArgumentException,
5125 io::IOException,
5126 embed::StorageWrappedTargetException,
5127 uno::RuntimeException )
5129 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::attachToURL" );
5131 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5133 if ( !m_pImpl )
5134 throw lang::DisposedException();
5136 if ( !m_pData->m_bIsRoot )
5137 throw lang::IllegalArgumentException();
5139 if ( !m_pImpl->m_pSwitchStream )
5140 throw uno::RuntimeException();
5142 uno::Reference < ucb::XSimpleFileAccess > xAccess(
5143 m_pImpl->m_xFactory->createInstance (
5144 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
5145 uno::UNO_QUERY_THROW );
5149 if ( bReadOnly )
5151 uno::Reference< io::XInputStream > xInputStream = xAccess->openFileRead( sURL );
5152 m_pImpl->m_pSwitchStream->SwitchPersistenceTo( xInputStream );
5154 else
5156 uno::Reference< io::XStream > xStream = xAccess->openFileReadWrite( sURL );
5157 m_pImpl->m_pSwitchStream->SwitchPersistenceTo( xStream );
5160 catch( embed::InvalidStorageException& )
5162 throw;
5164 catch( lang::IllegalArgumentException& )
5166 throw;
5168 catch( embed::StorageWrappedTargetException& )
5170 throw;
5172 catch( io::IOException& )
5174 throw;
5176 catch( uno::RuntimeException& )
5178 throw;
5180 catch( uno::Exception& )
5182 uno::Any aCaught( ::cppu::getCaughtException() );
5183 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't attach to URL!" ),
5184 uno::Reference< io::XInputStream >(),
5185 aCaught );
5189 //-----------------------------------------------
5190 uno::Any SAL_CALL OStorage::getElementPropertyValue( const ::rtl::OUString& aElementName, const ::rtl::OUString& aPropertyName )
5191 throw ( embed::InvalidStorageException,
5192 lang::IllegalArgumentException,
5193 container::NoSuchElementException,
5194 io::IOException,
5195 beans::UnknownPropertyException,
5196 beans::PropertyVetoException,
5197 embed::StorageWrappedTargetException,
5198 uno::RuntimeException)
5200 RTL_LOGFILE_CONTEXT( aLog, "package (mv76033) OStorage::getElementPropertyValue" );
5202 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5204 if ( !m_pImpl )
5205 throw lang::DisposedException();
5207 if ( !aElementName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, sal_False ) )
5208 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
5210 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
5211 && aElementName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
5212 throw lang::IllegalArgumentException(); // TODO: unacceptable storage name
5216 SotElement_Impl *pElement = m_pImpl->FindElement( aElementName );
5217 if ( !pElement )
5218 throw container::NoSuchElementException();
5220 // TODO/LATER: Currently it is only implemented for MediaType property of substorages, might be changed in future
5221 if ( !pElement->m_bIsStorage || m_pData->m_nStorageType != PACKAGE_STORAGE || !aPropertyName.equalsAscii( "MediaType" ) )
5222 throw beans::PropertyVetoException();
5224 if ( !pElement->m_pStorage )
5225 m_pImpl->OpenSubStorage( pElement, embed::ElementModes::READ );
5227 if ( !pElement->m_pStorage )
5228 throw io::IOException(); // TODO: general_error
5230 pElement->m_pStorage->ReadContents();
5231 return uno::makeAny( pElement->m_pStorage->m_aMediaType );
5233 catch( embed::InvalidStorageException& )
5235 throw;
5237 catch( lang::IllegalArgumentException& )
5239 throw;
5241 catch( container::NoSuchElementException& )
5243 throw;
5245 catch( beans::UnknownPropertyException& )
5247 throw;
5249 catch( beans::PropertyVetoException& )
5251 throw;
5253 catch( embed::StorageWrappedTargetException& )
5255 throw;
5257 catch( io::IOException& )
5259 throw;
5261 catch( uno::RuntimeException& )
5263 throw;
5265 catch( uno::Exception& )
5267 uno::Any aCaught( ::cppu::getCaughtException() );
5268 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't get element property!" ),
5269 uno::Reference< io::XInputStream >(),
5270 aCaught );
5274 //-----------------------------------------------
5275 void SAL_CALL OStorage::copyStreamElementData( const ::rtl::OUString& aStreamName, const uno::Reference< io::XStream >& xTargetStream )
5276 throw ( embed::InvalidStorageException,
5277 lang::IllegalArgumentException,
5278 packages::WrongPasswordException,
5279 io::IOException,
5280 embed::StorageWrappedTargetException,
5281 uno::RuntimeException )
5283 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5285 if ( !m_pImpl )
5286 throw lang::DisposedException();
5288 if ( !aStreamName.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, sal_False ) )
5289 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
5291 if ( m_pData->m_nStorageType == OFOPXML_STORAGE
5292 && aStreamName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels" ) ) ) )
5293 throw lang::IllegalArgumentException(); // TODO: unacceptable storage name
5295 if ( !xTargetStream.is() )
5296 throw lang::IllegalArgumentException();
5300 uno::Reference< io::XStream > xNonconstRef = xTargetStream;
5301 m_pImpl->CloneStreamElement( aStreamName, sal_False, ::rtl::OUString(), xNonconstRef );
5303 OSL_ENSURE( xNonconstRef == xTargetStream, "The provided stream reference seems not be filled in correctly!\n" );
5304 if ( xNonconstRef != xTargetStream )
5305 throw uno::RuntimeException(); // if the stream reference is set it must not be changed!
5307 catch( embed::InvalidStorageException& )
5309 throw;
5311 catch( lang::IllegalArgumentException& )
5313 throw;
5315 catch( packages::WrongPasswordException& )
5317 throw;
5319 catch( io::IOException& )
5321 throw;
5323 catch( embed::StorageWrappedTargetException& )
5325 throw;
5327 catch( uno::RuntimeException& )
5329 throw;
5331 catch( uno::Exception& )
5333 uno::Any aCaught( ::cppu::getCaughtException() );
5334 throw embed::StorageWrappedTargetException( ::rtl::OUString::createFromAscii( "Can't copy stream data!" ),
5335 uno::Reference< io::XInputStream >(),
5336 aCaught );
5342 //____________________________________________________________________________________________________
5343 // XHierarchicalStorageAccess
5344 //____________________________________________________________________________________________________
5346 //-----------------------------------------------
5347 uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openStreamElementByHierarchicalName( const ::rtl::OUString& aStreamPath, ::sal_Int32 nOpenMode )
5348 throw ( embed::InvalidStorageException,
5349 lang::IllegalArgumentException,
5350 packages::WrongPasswordException,
5351 io::IOException,
5352 embed::StorageWrappedTargetException,
5353 uno::RuntimeException )
5355 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5357 if ( !m_pImpl )
5358 throw lang::DisposedException();
5360 if ( !aStreamPath.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
5361 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
5363 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
5364 && ( nOpenMode & embed::ElementModes::WRITE ) )
5365 throw io::IOException(); // Access denied
5367 OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
5368 OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
5370 uno::Reference< embed::XExtendedStorageStream > xResult;
5371 if ( aListPath.size() == 1 )
5373 // that must be a direct request for a stream
5374 // the transacted version of the stream should be opened
5376 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamPath, nOpenMode, sal_False );
5377 OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
5379 xResult = uno::Reference< embed::XExtendedStorageStream >(
5380 pElement->m_pStream->GetStream( nOpenMode, sal_True ),
5381 uno::UNO_QUERY_THROW );
5383 else
5385 // there are still storages in between
5386 if ( !m_pData->m_rHierarchyHolder.is() )
5387 m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
5388 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
5390 xResult = m_pData->m_rHierarchyHolder->GetStreamHierarchically(
5391 ( m_pImpl->m_nStorageMode & embed::ElementModes::READWRITE ),
5392 aListPath,
5393 nOpenMode );
5396 if ( !xResult.is() )
5397 throw uno::RuntimeException();
5399 return xResult;
5402 //-----------------------------------------------
5403 uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openEncryptedStreamElementByHierarchicalName( const ::rtl::OUString& aStreamPath, ::sal_Int32 nOpenMode, const ::rtl::OUString& sPassword )
5404 throw ( embed::InvalidStorageException,
5405 lang::IllegalArgumentException,
5406 packages::NoEncryptionException,
5407 packages::WrongPasswordException,
5408 io::IOException,
5409 embed::StorageWrappedTargetException,
5410 uno::RuntimeException )
5412 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5414 if ( !m_pImpl )
5415 throw lang::DisposedException();
5417 if ( m_pData->m_nStorageType != PACKAGE_STORAGE )
5418 packages::NoEncryptionException(); // TODO:
5420 if ( !aStreamPath.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
5421 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
5423 if ( !sPassword.getLength() )
5424 throw lang::IllegalArgumentException();
5426 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
5427 && ( nOpenMode & embed::ElementModes::WRITE ) )
5428 throw io::IOException(); // Access denied
5430 OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
5431 OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
5433 uno::Reference< embed::XExtendedStorageStream > xResult;
5434 if ( aListPath.size() == 1 )
5436 // that must be a direct request for a stream
5437 // the transacted version of the stream should be opened
5439 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamPath, nOpenMode, sal_True );
5440 OSL_ENSURE( pElement && pElement->m_pStream, "In case element can not be created an exception must be thrown!" );
5442 xResult = uno::Reference< embed::XExtendedStorageStream >(
5443 pElement->m_pStream->GetStream( nOpenMode, sPassword, sal_True ),
5444 uno::UNO_QUERY_THROW );
5446 else
5448 // there are still storages in between
5449 if ( !m_pData->m_rHierarchyHolder.is() )
5450 m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
5451 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
5453 xResult = m_pData->m_rHierarchyHolder->GetStreamHierarchically(
5454 ( m_pImpl->m_nStorageMode & embed::ElementModes::READWRITE ),
5455 aListPath,
5456 nOpenMode,
5457 sPassword );
5460 if ( !xResult.is() )
5461 throw uno::RuntimeException();
5463 return xResult;
5466 //-----------------------------------------------
5467 void SAL_CALL OStorage::removeStreamElementByHierarchicalName( const ::rtl::OUString& aStreamPath )
5468 throw ( embed::InvalidStorageException,
5469 lang::IllegalArgumentException,
5470 container::NoSuchElementException,
5471 io::IOException,
5472 embed::StorageWrappedTargetException,
5473 uno::RuntimeException )
5475 ::osl::MutexGuard aGuard( m_pData->m_rSharedMutexRef->GetMutex() );
5477 if ( !m_pImpl )
5478 throw lang::DisposedException();
5480 if ( !aStreamPath.getLength() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, sal_True ) )
5481 throw lang::IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected entry name syntax." ) ), uno::Reference< uno::XInterface >(), 1 );
5483 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
5484 throw io::IOException(); // Access denied
5486 OStringList_Impl aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
5487 OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
5489 if ( !m_pData->m_rHierarchyHolder.is() )
5490 m_pData->m_rHierarchyHolder = new OHierarchyHolder_Impl(
5491 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
5493 m_pData->m_rHierarchyHolder->RemoveStreamHierarchically( aListPath );