LibreOffice Module package (master) 1
xstorage.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <memory>
21#include <sal/config.h>
22#include <sal/log.hxx>
23
24#include <cassert>
25#include <string_view>
26
27#include <com/sun/star/beans/PropertyValue.hpp>
28#include <com/sun/star/embed/ElementModes.hpp>
29#include <com/sun/star/embed/InvalidStorageException.hpp>
30#include <com/sun/star/embed/UseBackupException.hpp>
31#include <com/sun/star/embed/StorageFormats.hpp>
32#include <com/sun/star/embed/StorageWrappedTargetException.hpp>
33#include <com/sun/star/packages/NoEncryptionException.hpp>
34#include <com/sun/star/packages/NoRawFormatException.hpp>
35#include <com/sun/star/packages/WrongPasswordException.hpp>
36#include <com/sun/star/io/TempFile.hpp>
37#include <com/sun/star/ucb/SimpleFileAccess.hpp>
38#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
39#include <com/sun/star/container/XEnumerationAccess.hpp>
40#include <com/sun/star/container/XNamed.hpp>
41#include <com/sun/star/util/XChangesBatch.hpp>
42
43#include <com/sun/star/lang/XComponent.hpp>
44#include <com/sun/star/lang/DisposedException.hpp>
45#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
46#include <com/sun/star/beans/NamedValue.hpp>
47
48#include <PackageConstants.hxx>
49
53
57#include <utility>
59
60#include "xstorage.hxx"
61#include "owriteablestream.hxx"
63
64using namespace ::com::sun::star;
65
66#if OSL_DEBUG_LEVEL > 0
67#define THROW_WHERE SAL_WHERE
68#else
69#define THROW_WHERE ""
70#endif
71
72// static
74 const uno::Reference< io::XStream >& xSource,
75 const uno::Reference< io::XStream >& xDest,
76 sal_Int32 nStorageType,
77 const uno::Sequence< uno::Sequence< beans::StringPair > >& aRelInfo )
78{
79 uno::Reference< beans::XPropertySet > xSourceProps( xSource, uno::UNO_QUERY_THROW );
80 uno::Reference< beans::XPropertySet > xDestProps( xDest, uno::UNO_QUERY_THROW );
81
82 uno::Reference< io::XOutputStream > xDestOutStream = xDest->getOutputStream();
83 if ( !xDestOutStream.is() )
84 throw io::IOException( THROW_WHERE );
85
86 uno::Reference< io::XInputStream > xSourceInStream = xSource->getInputStream();
87 if ( !xSourceInStream.is() )
88 throw io::IOException( THROW_WHERE );
89
90 // TODO: headers of encrypted streams should be copied also
91 ::comphelper::OStorageHelper::CopyInputToOutput( xSourceInStream, xDestOutStream );
92
93 uno::Sequence<OUString> aPropNames { "Compressed", "MediaType",
94 "UseCommonStoragePasswordEncryption" };
95
96 if ( nStorageType == embed::StorageFormats::OFOPXML )
97 {
98 // TODO/LATER: in future it might make sense to provide the stream if there is one
99 uno::Reference< embed::XRelationshipAccess > xRelAccess( xDest, uno::UNO_QUERY_THROW );
100 xRelAccess->clearRelationships();
101 xRelAccess->insertRelationships( aRelInfo, false );
102
103 aPropNames.realloc( 2 );
104 }
105 else if ( nStorageType != embed::StorageFormats::PACKAGE )
106 {
107 aPropNames.realloc( 1 );
108 }
109
110 for ( const auto& rPropName : std::as_const(aPropNames) )
111 xDestProps->setPropertyValue( rPropName, xSourceProps->getPropertyValue( rPropName ) );
112}
113
114static uno::Reference< io::XInputStream > GetSeekableTempCopy( const uno::Reference< io::XInputStream >& xInStream )
115{
117 uno::Reference < io::XOutputStream > xTempOut = xTempFile->getOutputStream();
118 uno::Reference < io::XInputStream > xTempIn = xTempFile->getInputStream();
119
120 if ( !xTempOut.is() || !xTempIn.is() )
121 throw io::IOException( THROW_WHERE );
122
124 xTempOut->closeOutput();
125
126 return xTempIn;
127}
128
129SotElement_Impl::SotElement_Impl(OUString aName, bool bStor, bool bNew)
130 : m_aOriginalName(std::move(aName))
131 , m_bIsRemoved(false)
132 , m_bIsInserted(bNew)
133 , m_bIsStorage(bStor)
134{
135}
136
137// most of properties are holt by the storage but are not used
138OStorage_Impl::OStorage_Impl( uno::Reference< io::XInputStream > const & xInputStream,
139 sal_Int32 nMode,
140 const uno::Sequence< beans::PropertyValue >& xProperties,
141 uno::Reference< uno::XComponentContext > const & xContext,
142 sal_Int32 nStorageType )
143: m_xMutex( new comphelper::RefCountedMutex )
144, m_pAntiImpl( nullptr )
145, m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
146, m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
147, m_bBroadcastModified( false )
148, m_bCommited( false )
149, m_bIsRoot( true )
150, m_bListCreated( false )
151, m_nModifiedListenerCount( 0 )
152, m_xContext( xContext )
153, m_xProperties( xProperties )
154, m_bHasCommonEncryptionData( false )
155, m_pParent( nullptr )
156, m_bControlMediaType( false )
157, m_bMTFallbackUsed( false )
158, m_bControlVersion( false )
159, m_nStorageType( nStorageType )
160, m_pRelStorElement( nullptr )
161, m_nRelInfoStatus( RELINFO_NO_INIT )
162{
163 // all the checks done below by assertion statements must be done by factory
164 SAL_WARN_IF( !xInputStream.is(), "package.xstor", "No input stream is provided!" );
165 assert(xContext.is());
166
167 m_pSwitchStream = new SwitchablePersistenceStream(xInputStream);
168 m_xInputStream = m_pSwitchStream->getInputStream();
169
170 if ( m_nStorageMode & embed::ElementModes::WRITE )
171 {
172 // check that the stream allows to write
173 SAL_WARN( "package.xstor", "No stream for writing is provided!" );
174 }
175}
176
177// most of properties are holt by the storage but are not used
178OStorage_Impl::OStorage_Impl( uno::Reference< io::XStream > const & xStream,
179 sal_Int32 nMode,
180 const uno::Sequence< beans::PropertyValue >& xProperties,
181 uno::Reference< uno::XComponentContext > const & xContext,
182 sal_Int32 nStorageType )
183: m_xMutex( new comphelper::RefCountedMutex )
184, m_pAntiImpl( nullptr )
185, m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
186, m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
187, m_bBroadcastModified( false )
188, m_bCommited( false )
189, m_bIsRoot( true )
190, m_bListCreated( false )
191, m_nModifiedListenerCount( 0 )
192, m_xContext( xContext )
193, m_xProperties( xProperties )
194, m_bHasCommonEncryptionData( false )
195, m_pParent( nullptr )
196, m_bControlMediaType( false )
197, m_bMTFallbackUsed( false )
198, m_bControlVersion( false )
199, m_nStorageType( nStorageType )
200, m_pRelStorElement( nullptr )
201, m_nRelInfoStatus( RELINFO_NO_INIT )
202{
203 // all the checks done below by assertion statements must be done by factory
204 SAL_WARN_IF( !xStream.is(), "package.xstor", "No stream is provided!" );
205 assert(xContext.is());
206
207 if ( m_nStorageMode & embed::ElementModes::WRITE )
208 {
209 m_pSwitchStream = new SwitchablePersistenceStream(xStream);
210 m_xStream = static_cast< io::XStream* >( m_pSwitchStream.get() );
211 }
212 else
213 {
214 m_pSwitchStream = new SwitchablePersistenceStream(xStream->getInputStream());
215 m_xInputStream = m_pSwitchStream->getInputStream();
216 }
217}
218
220 sal_Int32 nMode,
221 uno::Reference< container::XNameContainer > const & xPackageFolder,
222 uno::Reference< lang::XSingleServiceFactory > xPackage,
223 uno::Reference< uno::XComponentContext > const & xContext,
224 sal_Int32 nStorageType )
225: m_xMutex( new comphelper::RefCountedMutex )
226, m_pAntiImpl( nullptr )
227, m_nStorageMode( nMode & ~embed::ElementModes::SEEKABLE )
228, m_bIsModified( ( nMode & ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) ) == ( embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE ) )
229, m_bBroadcastModified( false )
230, m_bCommited( false )
231, m_bIsRoot( false )
232, m_bListCreated( false )
233, m_nModifiedListenerCount( 0 )
234, m_xPackageFolder( xPackageFolder )
235, m_xPackage(std::move( xPackage ))
236, m_xContext( xContext )
237, m_bHasCommonEncryptionData( false )
238, m_pParent( pParent ) // can be empty in case of temporary readonly substorages and relation storage
239, m_bControlMediaType( false )
240, m_bMTFallbackUsed( false )
241, m_bControlVersion( false )
242, m_nStorageType( nStorageType )
243, m_pRelStorElement( nullptr )
244, m_nRelInfoStatus( RELINFO_NO_INIT )
245{
246 SAL_WARN_IF( !xPackageFolder.is(), "package.xstor", "No package folder!" );
247 assert(xContext.is());
248}
249
251{
252 {
253 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
254 if ( m_pAntiImpl ) // root storage wrapper must set this member to NULL before destruction of object
255 {
256 SAL_WARN_IF( m_bIsRoot, "package.xstor", "The root storage wrapper must be disposed already" );
257
258 try {
260 }
261 catch ( const uno::Exception& )
262 {
263 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
264 }
265 m_pAntiImpl = nullptr;
266 }
267 else if ( !m_aReadOnlyWrapVector.empty() )
268 {
269 for ( auto& rStorage : m_aReadOnlyWrapVector )
270 {
271 uno::Reference< embed::XStorage > xTmp = rStorage.m_xWeakRef;
272 if ( xTmp.is() )
273 try {
274 rStorage.m_pPointer->InternalDispose( false );
275 } catch( const uno::Exception& )
276 {
277 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
278 }
279 }
280
281 m_aReadOnlyWrapVector.clear();
282 }
283
284 m_pParent = nullptr;
285 }
286
287 for (const auto & pair : m_aChildrenMap)
288 for (auto pElement : pair.second)
289 delete pElement;
290 m_aChildrenMap.clear();
291
292 std::for_each(m_aDeletedVector.begin(), m_aDeletedVector.end(), std::default_delete<SotElement_Impl>());
293 m_aDeletedVector.clear();
294
295 if ( m_nStorageType == embed::StorageFormats::OFOPXML && m_pRelStorElement )
296 {
297 delete m_pRelStorElement;
298 m_pRelStorElement = nullptr;
299 }
300
301 m_xPackageFolder.clear();
302 m_xPackage.clear();
303
304 OUString aPropertyName = "URL";
305 for ( const auto& rProp : std::as_const(m_xProperties) )
306 {
307 if ( rProp.Name == aPropertyName )
308 {
309 // the storage is URL based so all the streams are opened by factory and should be closed
310 try
311 {
312 if ( m_xInputStream.is() )
313 {
314 m_xInputStream->closeInput();
315 m_xInputStream.clear();
316 }
317
318 if ( m_xStream.is() )
319 {
320 uno::Reference< io::XInputStream > xInStr = m_xStream->getInputStream();
321 if ( xInStr.is() )
322 xInStr->closeInput();
323
324 uno::Reference< io::XOutputStream > xOutStr = m_xStream->getOutputStream();
325 if ( xOutStr.is() )
326 xOutStr->closeOutput();
327
328 m_xStream.clear();
329 }
330 }
331 catch (const uno::Exception&)
332 {
333 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
334 }
335 }
336 }
337}
338
340{
341 // Weak reference is used inside the holder so the refcount must not be zero at this point
342 OSL_ENSURE( aStorage.GetRefCount_Impl(), "There must be a reference alive to use this method!" );
343 m_aReadOnlyWrapVector.emplace_back( &aStorage );
344}
345
347{
348 for ( StorageHoldersType::iterator pStorageIter = m_aReadOnlyWrapVector.begin();
349 pStorageIter != m_aReadOnlyWrapVector.end();)
350 {
351 uno::Reference< embed::XStorage > xTmp = pStorageIter->m_xWeakRef;
352 if ( !xTmp.is() || pStorageIter->m_pPointer == &aStorage )
353 {
354 try {
355 pStorageIter->m_pPointer->InternalDispose( false );
356 } catch( const uno::Exception& )
357 {
358 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
359 }
360
361 pStorageIter = m_aReadOnlyWrapVector.erase(pStorageIter);
362 }
363 else
364 ++pStorageIter;
365 }
366}
367
369{
370 SAL_WARN_IF( !m_bIsRoot, "package.xstor", "Opening of the package has no sense!" );
371
372 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
373
374 if ( !m_xPackageFolder.is() )
375 {
376 if ( !m_xPackage.is() )
377 {
378 uno::Sequence< uno::Any > aArguments( 2 );
379 auto pArguments = aArguments.getArray();
380 if ( m_nStorageMode & embed::ElementModes::WRITE )
381 pArguments[ 0 ] <<= m_xStream;
382 else
383 {
384 SAL_WARN_IF( !m_xInputStream.is(), "package.xstor", "Input stream must be set for readonly access!" );
385 pArguments[ 0 ] <<= m_xInputStream;
386 // TODO: if input stream is not seekable or XSeekable interface is supported
387 // on XStream object a wrapper must be used
388 }
389
390 // do not allow elements to remove themself from the old container in case of insertion to another container
391 pArguments[ 1 ] <<= beans::NamedValue( "AllowRemoveOnInsert",
392 uno::Any( false ) );
393
394 sal_Int32 nArgNum = 2;
395 for ( const auto& rProp : std::as_const(m_xProperties) )
396 {
397 if ( rProp.Name == "RepairPackage"
398 || rProp.Name == "ProgressHandler"
399 || rProp.Name == "NoFileSync" )
400 {
401 // Forward these to the package.
402 beans::NamedValue aNamedValue( rProp.Name, rProp.Value );
403 aArguments.realloc( ++nArgNum );
404 pArguments = aArguments.getArray();
405 pArguments[nArgNum-1] <<= aNamedValue;
406 }
407 else if ( rProp.Name == "Password" )
408 {
409 // TODO: implement password setting for documents
410 // the password entry must be removed after setting
411 }
412 }
413
414 if ( m_nStorageType == embed::StorageFormats::ZIP )
415 {
416 // let the package support only plain zip format
417 beans::NamedValue aNamedValue;
418 aNamedValue.Name = "StorageFormat";
419 aNamedValue.Value <<= OUString( "ZipFormat" );
420 aArguments.realloc( ++nArgNum );
421 pArguments = aArguments.getArray();
422 pArguments[nArgNum-1] <<= aNamedValue;
423 }
424 else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
425 {
426 // let the package support OFOPXML media type handling
427 beans::NamedValue aNamedValue;
428 aNamedValue.Name = "StorageFormat";
429 aNamedValue.Value <<= OUString( "OFOPXMLFormat" );
430 aArguments.realloc( ++nArgNum );
431 pArguments = aArguments.getArray();
432 pArguments[nArgNum-1] <<= aNamedValue;
433 }
434
435 m_xPackage.set( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
436 "com.sun.star.packages.comp.ZipPackage", aArguments, m_xContext),
437 uno::UNO_QUERY );
438 }
439
440 uno::Reference< container::XHierarchicalNameAccess > xHNameAccess( m_xPackage, uno::UNO_QUERY );
441 SAL_WARN_IF( !xHNameAccess.is(), "package.xstor", "The package could not be created!" );
442
443 if ( xHNameAccess.is() )
444 {
445 uno::Any aFolder = xHNameAccess->getByHierarchicalName("/");
446 aFolder >>= m_xPackageFolder;
447 }
448 }
449
450 SAL_WARN_IF( !m_xPackageFolder.is(), "package.xstor", "The package root folder can not be opened!" );
451 if ( !m_xPackageFolder.is() )
452 throw embed::InvalidStorageException( THROW_WHERE );
453}
454
456{
457 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
458
459 ReadContents();
460 return !m_aChildrenMap.empty();
461}
462
464{
465 if ( m_nStorageType != embed::StorageFormats::PACKAGE )
466 return;
467
468 uno::Reference< beans::XPropertySet > xProps( m_xPackageFolder, uno::UNO_QUERY_THROW );
469
470 if ( !m_bControlMediaType )
471 {
472 uno::Reference< beans::XPropertySet > xPackageProps( m_xPackage, uno::UNO_QUERY_THROW );
473 xPackageProps->getPropertyValue( MEDIATYPE_FALLBACK_USED_PROPERTY ) >>= m_bMTFallbackUsed;
474
475 static constexpr OUStringLiteral sMediaType(u"MediaType");
476 xProps->getPropertyValue( sMediaType ) >>= m_aMediaType;
477 m_bControlMediaType = true;
478 }
479
480 if ( !m_bControlVersion )
481 {
482 xProps->getPropertyValue( "Version" ) >>= m_aVersion;
483 m_bControlVersion = true;
484 }
485
486 // the properties of OFOPXML will be handled directly
487}
488
490{
491 if ( m_nStorageType != embed::StorageFormats::OFOPXML )
492 return;
493
495 {
496 // Init from original stream
497 uno::Reference< io::XInputStream > xRelInfoStream
498 = GetRelInfoStreamForName( std::u16string_view() );
499 try
500 {
501 if ( xRelInfoStream.is() )
502 m_aRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
503 xRelInfoStream,
504 u"_rels/.rels",
505 m_xContext );
507 }
508 catch (css::uno::Exception &)
509 {
510 TOOLS_INFO_EXCEPTION("package.xstor", "");
511 }
512 }
514 {
515 // Init from the new stream
516 try
517 {
518 if ( m_xNewRelInfoStream.is() )
519 m_aRelInfo = ::comphelper::OFOPXMLHelper::ReadRelationsInfoSequence(
521 u"_rels/.rels",
522 m_xContext );
523
525 }
526 catch( const uno::Exception& )
527 {
529 }
530 }
531}
532
534{
535 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
536
537 if ( m_bListCreated )
538 return;
539
540 if ( m_bIsRoot )
542
543 uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xPackageFolder, uno::UNO_QUERY_THROW );
544 uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration();
545 if ( !xEnum.is() )
546 throw uno::RuntimeException( THROW_WHERE );
547
548 m_bListCreated = true;
549
550 while( xEnum->hasMoreElements() )
551 {
552 try {
553 uno::Reference< container::XNamed > xNamed;
554 xEnum->nextElement() >>= xNamed;
555
556 if ( !xNamed.is() )
557 {
558 SAL_WARN( "package.xstor", "XNamed is not supported!" );
559 throw uno::RuntimeException( THROW_WHERE );
560 }
561
562 OUString aName = xNamed->getName();
563 SAL_WARN_IF( aName.isEmpty(), "package.xstor", "Empty name!" );
564
565 uno::Reference< container::XNameContainer > xNameContainer( xNamed, uno::UNO_QUERY );
566
567 std::unique_ptr<SotElement_Impl> xNewElement(new SotElement_Impl(aName, xNameContainer.is(), false));
568 if ( m_nStorageType == embed::StorageFormats::OFOPXML && aName == "_rels" )
569 {
570 if (!xNewElement->m_bIsStorage)
571 throw io::IOException( THROW_WHERE ); // TODO: Unexpected format
572
573 m_pRelStorElement = xNewElement.release();
575 }
576 else
577 {
578 if ( ( m_nStorageMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE )
579 {
580 // if a storage is truncated all of it elements are marked as deleted
581 xNewElement->m_bIsRemoved = true;
582 }
583
584 m_aChildrenMap[aName].push_back(xNewElement.release());
585 }
586 }
587 catch( const container::NoSuchElementException& )
588 {
589 TOOLS_WARN_EXCEPTION( "package.xstor", "hasMoreElements() implementation has problems!");
590 break;
591 }
592 }
593 if ( ( m_nStorageMode & embed::ElementModes::TRUNCATE ) == embed::ElementModes::TRUNCATE )
594 {
595 // if a storage is truncated the relations information should be cleaned
596 m_xNewRelInfoStream.clear();
597 m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
599 }
600
601 // cache changeable folder properties
603}
604
605void OStorage_Impl::CopyToStorage( const uno::Reference< embed::XStorage >& xDest, bool bDirect )
606{
607 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
608
609 uno::Reference< beans::XPropertySet > xPropSet( xDest, uno::UNO_QUERY );
610 if ( !xPropSet.is() )
611 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 );
612
613 sal_Int32 nDestMode = embed::ElementModes::READ;
614 xPropSet->getPropertyValue( "OpenMode" ) >>= nDestMode;
615
616 if ( !( nDestMode & embed::ElementModes::WRITE ) )
617 throw io::IOException( THROW_WHERE ); // TODO: access_denied
618
619 ReadContents();
620
621 if ( !m_xPackageFolder.is() )
622 throw embed::InvalidStorageException( THROW_WHERE );
623
624 for ( const auto& pair : m_aChildrenMap )
625 for (auto pElement : pair.second)
626 {
627 if ( !pElement->m_bIsRemoved )
628 CopyStorageElement( pElement, xDest, /*aName*/pair.first, bDirect );
629 }
630
631 // move storage properties to the destination one ( means changeable properties )
632 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
633 {
634 xPropSet->setPropertyValue( "MediaType", uno::Any( m_aMediaType ) );
635 xPropSet->setPropertyValue( "Version", uno::Any( m_aVersion ) );
636 }
637
638 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
639 {
640 // if this is a root storage, the common key from current one should be moved there
641 bool bIsRoot = false;
642 if ( ( xPropSet->getPropertyValue( "IsRoot" ) >>= bIsRoot ) && bIsRoot )
643 {
644 try
645 {
646 uno::Reference< embed::XEncryptionProtectedStorage > xEncr( xDest, uno::UNO_QUERY );
647 if ( xEncr.is() )
648 {
649 xEncr->setEncryptionData( GetCommonRootEncryptionData().getAsConstNamedValueList() );
650
651 uno::Sequence< beans::NamedValue > aAlgorithms;
652 uno::Reference< beans::XPropertySet > xPackPropSet( m_xPackage, uno::UNO_QUERY_THROW );
653 xPackPropSet->getPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY )
654 >>= aAlgorithms;
655 xEncr->setEncryptionAlgorithms( aAlgorithms );
656 }
657 }
658 catch( const packages::NoEncryptionException& )
659 {
660 TOOLS_INFO_EXCEPTION("package.xstor", "No Encryption");
661 }
662 }
663 }
664 else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
665 {
666
667 // TODO/LATER: currently the optimization is not active
668 // uno::Reference< io::XInputStream > xRelInfoStream = GetRelInfoStreamForName( OUString() ); // own stream
669 // if ( xRelInfoStream.is() )
670 // {
671 // // Relations info stream is a writeonly property, introduced only to optimize copying
672 // // Should be used carefully since no check for stream consistency is done, and the stream must not stay locked
673
674 // OUString aRelInfoString = "RelationsInfoStream";
675 // xPropSet->setPropertyValue( aRelInfoString, uno::makeAny( GetSeekableTempCopy( xRelInfoStream, m_xFactory ) ) );
676 // }
677
678 uno::Reference< embed::XRelationshipAccess > xRels( xDest, uno::UNO_QUERY );
679 if ( !xRels.is() )
680 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 );
681
682 xRels->insertRelationships( GetAllRelationshipsIfAny(), false );
683 }
684
685 // if possible the destination storage should be committed after successful copying
686 uno::Reference< embed::XTransactedObject > xObjToCommit( xDest, uno::UNO_QUERY );
687 if ( xObjToCommit.is() )
688 xObjToCommit->commit();
689}
690
692 const uno::Reference< embed::XStorage >& xDest,
693 const OUString& aName,
694 bool bDirect )
695{
696 SAL_WARN_IF( !xDest.is(), "package.xstor", "No destination storage!" );
697 SAL_WARN_IF( aName.isEmpty(), "package.xstor", "Empty element name!" );
698
699 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
700
701 uno::Reference< container::XNameAccess > xDestAccess( xDest, uno::UNO_QUERY_THROW );
702 if ( xDestAccess->hasByName( aName )
703 && !( pElement->m_bIsStorage && xDest->isStorageElement( aName ) ) )
704 xDest->removeElement( aName );
705
706 if ( pElement->m_bIsStorage )
707 {
708 uno::Reference< embed::XStorage > xSubDest =
709 xDest->openStorageElement( aName,
710 embed::ElementModes::WRITE );
711
712 SAL_WARN_IF( !xSubDest.is(), "package.xstor", "No destination substorage!" );
713
714 if (!pElement->m_xStorage)
715 {
716 OpenSubStorage( pElement, embed::ElementModes::READ );
717 if (!pElement->m_xStorage)
718 throw io::IOException( THROW_WHERE );
719 }
720
721 pElement->m_xStorage->CopyToStorage(xSubDest, bDirect);
722 }
723 else
724 {
725 if (!pElement->m_xStream)
726 {
727 OpenSubStream( pElement );
728 if (!pElement->m_xStream)
729 throw io::IOException( THROW_WHERE );
730 }
731
732 if (!pElement->m_xStream->IsEncrypted())
733 {
734 if ( bDirect )
735 {
736 // fill in the properties for the stream
737 uno::Sequence< beans::PropertyValue > aStrProps(0);
738 const uno::Sequence< beans::PropertyValue > aSrcPkgProps = pElement->m_xStream->GetStreamProperties();
739 sal_Int32 nNum = 0;
740 for ( const auto& rSrcPkgProp : aSrcPkgProps )
741 {
742 if ( rSrcPkgProp.Name == "MediaType" || rSrcPkgProp.Name == "Compressed" )
743 {
744 aStrProps.realloc( ++nNum );
745 auto pStrProps = aStrProps.getArray();
746 pStrProps[nNum-1].Name = rSrcPkgProp.Name;
747 pStrProps[nNum-1].Value = rSrcPkgProp.Value;
748 }
749 }
750
751 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
752 {
753 aStrProps.realloc( ++nNum );
754 auto pStrProps = aStrProps.getArray();
755 pStrProps[nNum-1].Name = "UseCommonStoragePasswordEncryption";
756 pStrProps[nNum-1].Value <<= pElement->m_xStream->UsesCommonEncryption_Impl();
757 }
758 else if ( m_nStorageType == embed::StorageFormats::OFOPXML )
759 {
760 // TODO/LATER: currently the optimization is not active
761 // uno::Reference< io::XInputStream > xInStream = GetRelInfoStreamForName( OUString() ); // own rels stream
762 // if ( xInStream.is() )
763 // {
764 // aStrProps.realloc( ++nNum );
765 // aStrProps[nNum-1].Name = "RelationsInfoStream";
766 // aStrProps[nNum-1].Value <<= GetSeekableTempCopy( xInStream, m_xFactory );
767 // }
768
769 uno::Reference< embed::XRelationshipAccess > xRels( xDest, uno::UNO_QUERY );
770 if ( !xRels.is() )
771 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
772
773 xRels->insertRelationships( GetAllRelationshipsIfAny(), false );
774 }
775
776 uno::Reference< embed::XOptimizedStorage > xOptDest( xDest, uno::UNO_QUERY_THROW );
777 uno::Reference < io::XInputStream > xInputToInsert;
778
779 if (pElement->m_xStream->HasTempFile_Impl() || !pElement->m_xStream->m_xPackageStream.is())
780 {
781 SAL_WARN_IF(!pElement->m_xStream->m_xPackageStream.is(), "package.xstor", "No package stream!");
782
783 // if the stream is modified - the temporary file must be used for insertion
784 xInputToInsert = pElement->m_xStream->GetTempFileAsInputStream();
785 }
786 else
787 {
788 // for now get just nonseekable access to the stream
789 // TODO/LATER: the raw stream can be used
790
791 xInputToInsert = pElement->m_xStream->m_xPackageStream->getDataStream();
792 }
793
794 if ( !xInputToInsert.is() )
795 throw io::IOException( THROW_WHERE );
796
797 xOptDest->insertStreamElementDirect( aName, xInputToInsert, aStrProps );
798 }
799 else
800 {
801 uno::Reference< io::XStream > xSubStr =
802 xDest->openStreamElement( aName,
803 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
804 SAL_WARN_IF( !xSubStr.is(), "package.xstor", "No destination substream!" );
805
806 pElement->m_xStream->CopyInternallyTo_Impl(xSubStr);
807 }
808 }
809 else if ( m_nStorageType != embed::StorageFormats::PACKAGE )
810 {
811 SAL_WARN( "package.xstor", "Encryption is only supported in package storage!" );
812 throw io::IOException( THROW_WHERE );
813 }
814 else if ( pElement->m_xStream->HasCachedEncryptionData()
815 && ( pElement->m_xStream->IsModified() || pElement->m_xStream->HasWriteOwner_Impl() ) )
816 {
817 ::comphelper::SequenceAsHashMap aCommonEncryptionData;
818 bool bHasCommonEncryptionData = false;
819 try
820 {
821 aCommonEncryptionData = GetCommonRootEncryptionData();
822 bHasCommonEncryptionData = true;
823 }
824 catch( const packages::NoEncryptionException& )
825 {
826 TOOLS_INFO_EXCEPTION("package.xstor", "No Encryption");
827 }
828
829 if (bHasCommonEncryptionData && ::package::PackageEncryptionDataLessOrEqual(pElement->m_xStream->GetCachedEncryptionData(), aCommonEncryptionData))
830 {
831 // If the stream can be opened with the common storage password
832 // it must be stored with the common storage password as well
833 uno::Reference< io::XStream > xDestStream =
834 xDest->openStreamElement( aName,
835 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
836
837 pElement->m_xStream->CopyInternallyTo_Impl( xDestStream );
838
839 uno::Reference< beans::XPropertySet > xProps( xDestStream, uno::UNO_QUERY_THROW );
840 xProps->setPropertyValue(
841 "UseCommonStoragePasswordEncryption",
842 uno::Any( true ) );
843 }
844 else
845 {
846 // the stream is already opened for writing or was changed
847 uno::Reference< embed::XStorage2 > xDest2( xDest, uno::UNO_QUERY_THROW );
848 uno::Reference< io::XStream > xSubStr =
849 xDest2->openEncryptedStream( aName,
850 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE,
851 pElement->m_xStream->GetCachedEncryptionData().getAsConstNamedValueList() );
852 SAL_WARN_IF( !xSubStr.is(), "package.xstor", "No destination substream!" );
853
854 pElement->m_xStream->CopyInternallyTo_Impl(xSubStr, pElement->m_xStream->GetCachedEncryptionData());
855 }
856 }
857 else
858 {
859 // the stream is not opened at all, so it can be just opened for reading
860 try
861 {
862 // If the stream can be opened with the common storage password
863 // it must be stored with the common storage password as well
864
865 uno::Reference< io::XStream > xOwnStream = pElement->m_xStream->GetStream(embed::ElementModes::READ,
866 false);
867 uno::Reference< io::XStream > xDestStream =
868 xDest->openStreamElement( aName,
869 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
870 SAL_WARN_IF( !xDestStream.is(), "package.xstor", "No destination substream!" );
872
873 uno::Reference< beans::XPropertySet > xProps( xDestStream, uno::UNO_QUERY_THROW );
874 xProps->setPropertyValue(
875 "UseCommonStoragePasswordEncryption",
876 uno::Any( true ) );
877 }
878 catch( const packages::WrongPasswordException& )
879 {
880 TOOLS_INFO_EXCEPTION("package.xstor", "Handled exception");
881
882 // If the common storage password does not allow to open the stream
883 // it could be copied in raw way, the problem is that the StartKey should be the same
884 // in the ODF1.2 package, so an invalid package could be produced if the stream
885 // is copied from ODF1.1 package, where it is allowed to have different StartKeys
886 uno::Reference< embed::XStorageRawAccess > xRawDest( xDest, uno::UNO_QUERY_THROW );
887 uno::Reference< io::XInputStream > xRawInStream = pElement->m_xStream->GetRawInStream();
888 xRawDest->insertRawEncrStreamElement( aName, xRawInStream );
889 }
890 }
891 }
892}
893
894uno::Sequence< uno::Sequence< beans::StringPair > > OStorage_Impl::GetAllRelationshipsIfAny()
895{
896 if ( m_nStorageType != embed::StorageFormats::OFOPXML )
897 return uno::Sequence< uno::Sequence< beans::StringPair > >();
898
900
904 throw io::IOException( THROW_WHERE "Wrong relinfo stream!" );
905 // m_nRelInfoStatus == RELINFO_CHANGED_BROKEN || m_nRelInfoStatus == RELINFO_BROKEN
906 return m_aRelInfo;
907}
908
909void OStorage_Impl::CopyLastCommitTo( const uno::Reference< embed::XStorage >& xNewStor )
910{
911 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
912
913 SAL_WARN_IF( !m_xPackageFolder.is(), "package.xstor", "A committed storage is incomplete!" );
914 if ( !m_xPackageFolder.is() )
915 throw uno::RuntimeException( THROW_WHERE );
916
917 OStorage_Impl aTempRepresent( nullptr,
918 embed::ElementModes::READ,
923
924 // TODO/LATER: could use direct copying
925 aTempRepresent.CopyToStorage( xNewStor, false );
926}
927
928void OStorage_Impl::InsertIntoPackageFolder( const OUString& aName,
929 const uno::Reference< container::XNameContainer >& xParentPackageFolder )
930{
931 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
932
933 SAL_WARN_IF( !m_xPackageFolder.is(), "package.xstor", "An inserted storage is incomplete!" );
934 uno::Reference< uno::XInterface > xTmp( m_xPackageFolder, uno::UNO_QUERY_THROW );
935 xParentPackageFolder->insertByName( aName, uno::Any( xTmp ) );
936
937 m_bCommited = false;
938}
939
941{
942 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
943
944 if ( !m_bIsModified )
945 return;
946
947 // in case of a new empty storage it is possible that the contents are still not read
948 // ( the storage of course has no contents, but the initialization is postponed till the first use,
949 // thus if a new storage was created and committed immediately it must be initialized here )
950 ReadContents();
951
952 // if storage is committed it should have a valid Package representation
953 SAL_WARN_IF( !m_xPackageFolder.is(), "package.xstor", "The package representation should exist!" );
954 if ( !m_xPackageFolder.is() )
955 throw embed::InvalidStorageException( THROW_WHERE );
956
957 OSL_ENSURE( m_nStorageMode & embed::ElementModes::WRITE,
958 "Commit of readonly storage, should be detected before!" );
959
960 uno::Reference< container::XNameContainer > xNewPackageFolder;
961
962 // here the storage will switch to the temporary package folder
963 // if the storage was already committed and the parent was not committed after that
964 // the switch should not be done since the package folder in use is a temporary one;
965 // it can be detected by m_bCommited flag ( root storage doesn't need temporary representation )
966 if ( !m_bCommited && !m_bIsRoot )
967 {
968 uno::Sequence< uno::Any > aSeq{ uno::Any(true) };
969 xNewPackageFolder.set( m_xPackage->createInstanceWithArguments( aSeq ),
970 uno::UNO_QUERY );
971 }
972 else
973 xNewPackageFolder = m_xPackageFolder;
974
975 // remove replaced removed elements
976 for ( auto& pDeleted : m_aDeletedVector )
977 {
978
979 if ( m_nStorageType == embed::StorageFormats::OFOPXML && !pDeleted->m_bIsStorage )
980 RemoveStreamRelInfo( pDeleted->m_aOriginalName );
981
982 // the removed elements are not in new temporary storage
983 if ( m_bCommited || m_bIsRoot )
984 xNewPackageFolder->removeByName( pDeleted->m_aOriginalName );
985 delete pDeleted;
986 pDeleted = nullptr;
987 }
988 m_aDeletedVector.clear();
989
990 // remove removed elements
991 for (auto mapIt = m_aChildrenMap.begin(); mapIt != m_aChildrenMap.end(); )
992 {
993 for (auto it = mapIt->second.begin(); it != mapIt->second.end(); )
994 {
995 // renamed and inserted elements must be really inserted to package later
996 // since they can conflict with removed elements
997 auto & pElement = *it;
998 if ( pElement->m_bIsRemoved )
999 {
1000 if ( m_nStorageType == embed::StorageFormats::OFOPXML && !pElement->m_bIsStorage )
1001 RemoveStreamRelInfo( pElement->m_aOriginalName );
1002
1003 // the removed elements are not in new temporary storage
1004 if ( m_bCommited || m_bIsRoot )
1005 xNewPackageFolder->removeByName( pElement->m_aOriginalName );
1006
1007 delete pElement;
1008 it = mapIt->second.erase(it);
1009 }
1010 else
1011 ++it;
1012 }
1013 if (mapIt->second.empty())
1014 mapIt = m_aChildrenMap.erase(mapIt);
1015 else
1016 ++mapIt;
1017 }
1018
1019
1020 // there should be no more deleted elements
1021 for ( const auto& pair : m_aChildrenMap )
1022 for (auto pElement : pair.second)
1023 {
1024 // if it is a 'duplicate commit' inserted elements must be really inserted to package later
1025 // since they can conflict with renamed elements
1026 if ( !pElement->m_bIsInserted )
1027 {
1028 // for now stream is opened in direct mode that means that in case
1029 // storage is committed all the streams from it are committed in current state.
1030 // following two steps are separated to allow easily implement transacted mode
1031 // for streams if we need it in future.
1032 // Only hierarchical access uses transacted streams currently
1033 if ( !pElement->m_bIsStorage && pElement->m_xStream
1034 && !pElement->m_xStream->IsTransacted() )
1035 pElement->m_xStream->Commit();
1036
1037 // if the storage was not open, there is no need to commit it ???
1038 // the storage should be checked that it is committed
1039 if (pElement->m_bIsStorage && pElement->m_xStorage && pElement->m_xStorage->m_bCommited)
1040 {
1041 // it's temporary PackageFolder should be inserted instead of current one
1042 // also the new copy of PackageFolder should be used by the children storages
1043
1044 // the renamed elements are not in new temporary storage
1045 if ( m_bCommited || m_bIsRoot )
1046 xNewPackageFolder->removeByName( pElement->m_aOriginalName );
1047
1048 pElement->m_xStorage->InsertIntoPackageFolder(/*aName*/pair.first, xNewPackageFolder);
1049 }
1050 else if (!pElement->m_bIsStorage && pElement->m_xStream && pElement->m_xStream->m_bFlushed)
1051 {
1052 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1053 CommitStreamRelInfo( /*aName*/pair.first, pElement );
1054
1055 // the renamed elements are not in new temporary storage
1056 if ( m_bCommited || m_bIsRoot )
1057 xNewPackageFolder->removeByName( pElement->m_aOriginalName );
1058
1059 pElement->m_xStream->InsertIntoPackageFolder(/*aName*/pair.first, xNewPackageFolder);
1060 }
1061 else if ( !m_bCommited && !m_bIsRoot )
1062 {
1063 // the element must be just copied to the new temporary package folder
1064 // the connection with the original package should not be lost just because
1065 // the element is still referred by the folder in the original hierarchy
1066 uno::Any aPackageElement = m_xPackageFolder->getByName( pElement->m_aOriginalName );
1067 xNewPackageFolder->insertByName( /*aName*/pair.first, aPackageElement );
1068 }
1069 else if ( pair.first != pElement->m_aOriginalName )
1070 {
1071 // this is the case when xNewPackageFolder refers to m_xPackageFolder
1072 // in case the name was changed and it is not a changed storage - rename the element
1073 uno::Any aPackageElement = xNewPackageFolder->getByName( pElement->m_aOriginalName );
1074 xNewPackageFolder->removeByName( pElement->m_aOriginalName );
1075 xNewPackageFolder->insertByName( /*aName*/pair.first, aPackageElement );
1076
1077 if ( m_nStorageType == embed::StorageFormats::OFOPXML && !pElement->m_bIsStorage )
1078 {
1079 if (!pElement->m_xStream)
1080 {
1081 OpenSubStream( pElement );
1082 if (!pElement->m_xStream)
1083 throw uno::RuntimeException( THROW_WHERE );
1084 }
1085
1086 CommitStreamRelInfo( /*aName*/pair.first, pElement );
1087 }
1088 }
1089
1090 pElement->m_aOriginalName = pair.first;
1091 }
1092 }
1093
1094 for ( const auto& pair : m_aChildrenMap )
1095 for (auto pElement : pair.second)
1096 {
1097 // now inserted elements can be inserted to the package
1098 if ( pElement->m_bIsInserted )
1099 {
1100 pElement->m_aOriginalName = pair.first;
1101
1102 if ( pElement->m_bIsStorage )
1103 {
1104 OSL_ENSURE(pElement->m_xStorage, "An inserted storage is incomplete!");
1105 if (!pElement->m_xStorage)
1106 throw uno::RuntimeException( THROW_WHERE );
1107
1108 if (pElement->m_xStorage->m_bCommited)
1109 {
1110 pElement->m_xStorage->InsertIntoPackageFolder(/*aName*/pair.first, xNewPackageFolder);
1111
1112 pElement->m_bIsInserted = false;
1113 }
1114 }
1115 else
1116 {
1117 OSL_ENSURE(pElement->m_xStream, "An inserted stream is incomplete!");
1118 if (!pElement->m_xStream)
1119 throw uno::RuntimeException( THROW_WHERE );
1120
1121 if (!pElement->m_xStream->IsTransacted())
1122 pElement->m_xStream->Commit();
1123
1124 if (pElement->m_xStream->m_bFlushed)
1125 {
1126 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1127 CommitStreamRelInfo( /*aName*/pair.first, pElement );
1128
1129 pElement->m_xStream->InsertIntoPackageFolder( /*aName*/pair.first, xNewPackageFolder );
1130
1131 pElement->m_bIsInserted = false;
1132 }
1133 }
1134 }
1135 }
1136
1137 if ( m_nStorageType == embed::StorageFormats::PACKAGE )
1138 {
1139 // move properties to the destination package folder
1140 uno::Reference< beans::XPropertySet > xProps( xNewPackageFolder, uno::UNO_QUERY_THROW );
1141 xProps->setPropertyValue( "MediaType", uno::Any( m_aMediaType ) );
1142 xProps->setPropertyValue( "Version", uno::Any( m_aVersion ) );
1143 }
1144
1145 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1146 CommitRelInfo( xNewPackageFolder ); // store own relations and commit complete relations storage
1147
1148 if ( m_bIsRoot )
1149 {
1150 uno::Reference< util::XChangesBatch > xChangesBatch( m_xPackage, uno::UNO_QUERY_THROW );
1151 try
1152 {
1153 xChangesBatch->commitChanges();
1154 }
1155 catch( const lang::WrappedTargetException& r )
1156 {
1157 css::uno::Any ex( cppu::getCaughtException() );
1158 // the wrapped UseBackupException means that the target medium can be corrupted
1159 embed::UseBackupException aException;
1160 if ( r.TargetException >>= aException )
1161 {
1162 m_xStream.clear();
1163 m_xInputStream.clear();
1164 throw aException;
1165 }
1166
1167 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(ex));
1168 throw;
1169 }
1170 }
1171 else if ( !m_bCommited )
1172 {
1173 m_xPackageFolder = xNewPackageFolder;
1174 m_bCommited = true;
1175 }
1176
1177 // after commit the mediatype treated as the correct one
1178 m_bMTFallbackUsed = false;
1179}
1180
1182{
1183 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
1184
1185 if ( !( m_nStorageMode & embed::ElementModes::WRITE ) )
1186 return; // nothing to do
1187
1188 // all the children must be removed
1189 // they will be created later on demand
1190
1191 // rebuild the map - cannot do it in-place, because we're changing some of the key values
1192 std::unordered_map<OUString, std::vector<SotElement_Impl*>> oldMap;
1193 std::swap(oldMap, m_aChildrenMap);
1194
1195 for (const auto & rPair : oldMap)
1196 for (auto pElement : rPair.second)
1197 {
1198 if ( pElement->m_bIsInserted )
1199 delete pElement;
1200 else
1201 {
1202 ClearElement( pElement );
1203
1204 pElement->m_bIsRemoved = false;
1205
1206 m_aChildrenMap[pElement->m_aOriginalName].push_back(pElement);
1207 }
1208 }
1209
1210 // return replaced removed elements
1211 for ( auto& pDeleted : m_aDeletedVector )
1212 {
1213 m_aChildrenMap[pDeleted->m_aOriginalName].push_back(pDeleted);
1214
1215 ClearElement( pDeleted );
1216
1217 pDeleted->m_bIsRemoved = false;
1218 }
1219 m_aDeletedVector.clear();
1220
1221 m_bControlMediaType = false;
1222 m_bControlVersion = false;
1223
1225
1226 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1227 {
1228 // currently the relations storage is changed only on commit
1229 m_xNewRelInfoStream.clear();
1230 m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
1232 }
1233}
1234
1236{
1237 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() ) ;
1238
1239 if ( m_nStorageType != embed::StorageFormats::PACKAGE )
1240 throw packages::NoEncryptionException( THROW_WHERE );
1241
1242 if ( m_bIsRoot )
1243 {
1245 throw packages::NoEncryptionException( THROW_WHERE );
1246
1248 }
1249 else
1250 {
1251 if ( !m_pParent )
1252 throw packages::NoEncryptionException( THROW_WHERE );
1253
1255 }
1256}
1257
1259{
1260 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
1261
1262 SAL_WARN_IF( rName.isEmpty(), "package.xstor", "Name is empty!" );
1263
1264 ReadContents();
1265
1266 auto mapIt = m_aChildrenMap.find(rName);
1267 if (mapIt == m_aChildrenMap.end())
1268 return nullptr;
1269 for (auto pElement : mapIt->second)
1270 if (!pElement->m_bIsRemoved)
1271 return pElement;
1272
1273 return nullptr;
1274}
1275
1276SotElement_Impl* OStorage_Impl::InsertStream( const OUString& aName, bool bEncr )
1277{
1278 SAL_WARN_IF( !m_xPackage.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1279 if ( !m_xPackage.is() )
1280 throw embed::InvalidStorageException( THROW_WHERE);
1281
1282 uno::Sequence< uno::Any > aSeq{ uno::Any(false) };
1283 uno::Reference< uno::XInterface > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ) );
1284
1285 SAL_WARN_IF( !xNewElement.is(), "package.xstor", "Not possible to create a new stream!" );
1286 if ( !xNewElement.is() )
1287 throw io::IOException( THROW_WHERE );
1288
1289 uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xNewElement, uno::UNO_QUERY_THROW );
1290
1291 OSL_ENSURE( m_nStorageType == embed::StorageFormats::PACKAGE || !bEncr, "Only package storage supports encryption!" );
1292 if ( m_nStorageType != embed::StorageFormats::PACKAGE && bEncr )
1293 throw packages::NoEncryptionException( THROW_WHERE );
1294
1295 // the mode is not needed for storage stream internal implementation
1296 SotElement_Impl* pNewElement = InsertElement( aName, false );
1297 pNewElement->m_xStream.reset(new OWriteStream_Impl(this, xPackageSubStream, m_xPackage, m_xContext, bEncr, m_nStorageType, true));
1298
1299 m_aChildrenMap[aName].push_back( pNewElement );
1300 m_bIsModified = true;
1301 m_bBroadcastModified = true;
1302
1303 return pNewElement;
1304}
1305
1306void OStorage_Impl::InsertRawStream( const OUString& aName, const uno::Reference< io::XInputStream >& xInStream )
1307{
1308 // insert of raw stream means insert and commit
1309 SAL_WARN_IF( !m_xPackage.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1310 if ( !m_xPackage.is() )
1311 throw embed::InvalidStorageException( THROW_WHERE );
1312
1313 if ( m_nStorageType != embed::StorageFormats::PACKAGE )
1314 throw packages::NoEncryptionException( THROW_WHERE );
1315
1316 uno::Reference< io::XSeekable > xSeek( xInStream, uno::UNO_QUERY );
1317 uno::Reference< io::XInputStream > xInStrToInsert = xSeek.is() ? xInStream :
1318 GetSeekableTempCopy( xInStream );
1319
1320 uno::Sequence< uno::Any > aSeq{ uno::Any(false) };
1321 uno::Reference< uno::XInterface > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ) );
1322
1323 SAL_WARN_IF( !xNewElement.is(), "package.xstor", "Not possible to create a new stream!" );
1324 if ( !xNewElement.is() )
1325 throw io::IOException( THROW_WHERE );
1326
1327 uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xNewElement, uno::UNO_QUERY_THROW );
1328 xPackageSubStream->setRawStream( xInStrToInsert );
1329
1330 // the mode is not needed for storage stream internal implementation
1331 SotElement_Impl* pNewElement = InsertElement( aName, false );
1332 pNewElement->m_xStream.reset(new OWriteStream_Impl(this, xPackageSubStream, m_xPackage, m_xContext, true, m_nStorageType, false));
1333 // the stream is inserted and must be treated as a committed one
1334 pNewElement->m_xStream->SetToBeCommited();
1335
1336 m_aChildrenMap[aName].push_back( pNewElement );
1337 m_bIsModified = true;
1338 m_bBroadcastModified = true;
1339}
1340
1341std::unique_ptr<OStorage_Impl> OStorage_Impl::CreateNewStorageImpl( sal_Int32 nStorageMode )
1342{
1343 SAL_WARN_IF( !m_xPackage.is(), "package.xstor", "Not possible to refer to package as to factory!" );
1344 if ( !m_xPackage.is() )
1345 throw embed::InvalidStorageException( THROW_WHERE );
1346
1347 uno::Sequence< uno::Any > aSeq{ uno::Any(true) };
1348 uno::Reference< uno::XInterface > xNewElement( m_xPackage->createInstanceWithArguments( aSeq ) );
1349
1350 SAL_WARN_IF( !xNewElement.is(), "package.xstor", "Not possible to create a new storage!" );
1351 if ( !xNewElement.is() )
1352 throw io::IOException( THROW_WHERE );
1353
1354 uno::Reference< container::XNameContainer > xPackageSubFolder( xNewElement, uno::UNO_QUERY_THROW );
1355 std::unique_ptr<OStorage_Impl> pResult(
1356 new OStorage_Impl( this, nStorageMode, xPackageSubFolder, m_xPackage, m_xContext, m_nStorageType ));
1357 pResult->m_bIsModified = true;
1358
1359 return pResult;
1360}
1361
1362SotElement_Impl* OStorage_Impl::InsertStorage( const OUString& aName, sal_Int32 nStorageMode )
1363{
1364 SotElement_Impl* pNewElement = InsertElement( aName, true );
1365
1366 pNewElement->m_xStorage = CreateNewStorageImpl(nStorageMode);
1367
1368 m_aChildrenMap[aName].push_back( pNewElement );
1369
1370 return pNewElement;
1371}
1372
1373SotElement_Impl* OStorage_Impl::InsertElement( const OUString& aName, bool bIsStorage )
1374{
1375 assert( FindElement(aName) == nullptr && "Should not try to insert existing element");
1376
1377 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
1378
1379 SotElement_Impl* pDeletedElm = nullptr;
1380
1381 auto it = m_aChildrenMap.find(aName);
1382 if (it != m_aChildrenMap.end())
1383 for (auto pElement : it->second)
1384 {
1385 SAL_WARN_IF( !pElement->m_bIsRemoved, "package.xstor", "Try to insert an element instead of existing one!" );
1386 if ( pElement->m_bIsRemoved )
1387 {
1388 SAL_WARN_IF( pElement->m_bIsInserted, "package.xstor", "Inserted elements must be deleted immediately!" );
1389 pDeletedElm = pElement;
1390 }
1391 }
1392
1393 if ( pDeletedElm )
1394 {
1395 if ( pDeletedElm->m_bIsStorage )
1396 OpenSubStorage( pDeletedElm, embed::ElementModes::READWRITE );
1397 else
1398 OpenSubStream( pDeletedElm );
1399
1400 auto & rVec = m_aChildrenMap[aName];
1401 rVec.erase(std::remove(rVec.begin(), rVec.end(), pDeletedElm), rVec.end());
1402 if (rVec.empty())
1403 m_aChildrenMap.erase(aName);
1404 m_aDeletedVector.push_back( pDeletedElm );
1405 }
1406
1407 // create new element
1408 return new SotElement_Impl( aName, bIsStorage, true );
1409}
1410
1411void OStorage_Impl::OpenSubStorage( SotElement_Impl* pElement, sal_Int32 nStorageMode )
1412{
1413 SAL_WARN_IF( !pElement, "package.xstor", "pElement is not set!" );
1414 SAL_WARN_IF( !pElement->m_bIsStorage, "package.xstor", "Storage flag is not set!" );
1415
1416 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
1417
1418 if (!pElement->m_xStorage)
1419 {
1420 SAL_WARN_IF( pElement->m_bIsInserted, "package.xstor", "Inserted element must be created already!" );
1421
1422 uno::Reference< uno::XInterface > xTmp;
1423 m_xPackageFolder->getByName( pElement->m_aOriginalName ) >>= xTmp;
1424 if ( !xTmp.is() )
1425 throw container::NoSuchElementException( THROW_WHERE );
1426
1427 uno::Reference< container::XNameContainer > xPackageSubFolder( xTmp, uno::UNO_QUERY_THROW );
1428 pElement->m_xStorage.reset(new OStorage_Impl(this, nStorageMode, xPackageSubFolder, m_xPackage, m_xContext, m_nStorageType));
1429 }
1430}
1431
1433{
1434 SAL_WARN_IF( !pElement, "package.xstor", "pElement is not set!" );
1435 SAL_WARN_IF( pElement->m_bIsStorage, "package.xstor", "Storage flag is set!" );
1436
1437 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
1438
1439 if (pElement->m_xStream)
1440 return;
1441
1442 SAL_WARN_IF( pElement->m_bIsInserted, "package.xstor", "Inserted element must be created already!" );
1443
1444 uno::Reference< uno::XInterface > xTmp;
1445 m_xPackageFolder->getByName( pElement->m_aOriginalName ) >>= xTmp;
1446 if ( !xTmp.is() )
1447 throw container::NoSuchElementException( THROW_WHERE );
1448
1449 uno::Reference< packages::XDataSinkEncrSupport > xPackageSubStream( xTmp, uno::UNO_QUERY_THROW );
1450
1451 // the stream can never be inserted here, because inserted stream element holds the stream till commit or destruction
1452 pElement->m_xStream.reset(new OWriteStream_Impl(this, xPackageSubStream, m_xPackage, m_xContext, false, m_nStorageType, false, GetRelInfoStreamForName(pElement->m_aOriginalName)));
1453}
1454
1455uno::Sequence< OUString > OStorage_Impl::GetElementNames()
1456{
1457 ::osl::MutexGuard aGuard( m_xMutex->GetMutex() );
1458
1459 ReadContents();
1460
1461 sal_Int32 nCnt = 0;
1462 for ( const auto& pair : m_aChildrenMap )
1463 for (auto pElement : pair.second)
1464 {
1465 if ( !pElement->m_bIsRemoved )
1466 nCnt++;
1467 }
1468
1469 uno::Sequence<OUString> aElementNames(nCnt);
1470 OUString* pArray = aElementNames.getArray();
1471 for ( const auto& pair : m_aChildrenMap )
1472 for (auto pElement : pair.second)
1473 {
1474 if ( !pElement->m_bIsRemoved )
1475 *pArray++ = pair.first;
1476 }
1477
1478 return aElementNames;
1479}
1480
1481void OStorage_Impl::RemoveElement( OUString const & rName, SotElement_Impl* pElement )
1482{
1483 assert(pElement);
1484
1485 if ( (pElement->m_xStorage && ( pElement->m_xStorage->m_pAntiImpl || !pElement->m_xStorage->m_aReadOnlyWrapVector.empty() ))
1486 || (pElement->m_xStream && ( pElement->m_xStream->m_pAntiImpl || !pElement->m_xStream->m_aInputStreamsVector.empty() )) )
1487 throw io::IOException( THROW_WHERE ); // TODO: Access denied
1488
1489 auto mapIt = m_aChildrenMap.find(rName);
1490 for (auto it = mapIt->second.begin(); it != mapIt->second.end(); ++it)
1491 if (pElement == *it)
1492 {
1493 if ( pElement->m_bIsInserted )
1494 {
1495 delete pElement;
1496 mapIt->second.erase(std::remove(mapIt->second.begin(), mapIt->second.end(), pElement), mapIt->second.end());
1497 if (mapIt->second.empty())
1498 m_aChildrenMap.erase(mapIt);
1499 }
1500 else
1501 {
1502 pElement->m_bIsRemoved = true;
1503 ClearElement( pElement );
1504 }
1505 return;
1506 }
1507 assert(false && "not found");
1508
1509 // TODO/OFOPXML: the rel stream should be removed as well
1510}
1511
1513{
1514 pElement->m_xStorage.reset();
1515 pElement->m_xStream.reset();
1516}
1517
1518void OStorage_Impl::CloneStreamElement( const OUString& aStreamName,
1519 bool bEncryptionDataProvided,
1520 const ::comphelper::SequenceAsHashMap& aEncryptionData,
1521 uno::Reference< io::XStream >& xTargetStream )
1522{
1523 SotElement_Impl *pElement = FindElement( aStreamName );
1524 if ( !pElement )
1525 {
1526 // element does not exist, throw exception
1527 throw io::IOException( THROW_WHERE ); // TODO: access_denied
1528 }
1529 else if ( pElement->m_bIsStorage )
1530 throw io::IOException( THROW_WHERE );
1531
1532 if (!pElement->m_xStream)
1533 OpenSubStream( pElement );
1534
1535 if (!pElement->m_xStream || !pElement->m_xStream->m_xPackageStream.is())
1536 throw io::IOException( THROW_WHERE ); // TODO: general_error
1537
1538 // the existence of m_pAntiImpl of the child is not interesting,
1539 // the copy will be created internally
1540
1541 // usual copying is not applicable here, only last flushed version of the
1542 // child stream should be used for copying. Probably the children m_xPackageStream
1543 // can be used as a base of a new stream, that would be copied to result
1544 // storage. The only problem is that some package streams can be accessed from outside
1545 // at the same time (now solved by wrappers that remember own position).
1546
1547 if (bEncryptionDataProvided)
1548 pElement->m_xStream->GetCopyOfLastCommit(xTargetStream, aEncryptionData);
1549 else
1550 pElement->m_xStream->GetCopyOfLastCommit(xTargetStream);
1551}
1552
1553void OStorage_Impl::RemoveStreamRelInfo( std::u16string_view aOriginalName )
1554{
1555 // this method should be used only in OStorage_Impl::Commit() method
1556 // the aOriginalName can be empty, in this case the storage relation info should be removed
1557
1558 if ( m_nStorageType == embed::StorageFormats::OFOPXML && m_xRelStorage.is() )
1559 {
1560 OUString aRelStreamName = OUString::Concat(aOriginalName) + ".rels";
1561
1562 if ( m_xRelStorage->hasByName( aRelStreamName ) )
1563 m_xRelStorage->removeElement( aRelStreamName );
1564 }
1565}
1566
1568{
1569 if ( m_nStorageType != embed::StorageFormats::OFOPXML )
1570 return;
1571
1572 if ( m_xRelStorage.is() )
1573 return;
1574
1575 if ( !m_pRelStorElement )
1576 {
1577 m_pRelStorElement = new SotElement_Impl( "_rels", true, true );
1578 m_pRelStorElement->m_xStorage = CreateNewStorageImpl(embed::ElementModes::WRITE);
1580 m_pRelStorElement->m_xStorage->m_pParent = nullptr; // the relation storage is completely controlled by parent
1581 }
1582
1584 OpenSubStorage( m_pRelStorElement, embed::ElementModes::WRITE );
1585
1587 throw uno::RuntimeException( THROW_WHERE );
1588
1590}
1591
1592void OStorage_Impl::CommitStreamRelInfo( std::u16string_view rName, SotElement_Impl const * pStreamElement )
1593{
1594 // this method should be used only in OStorage_Impl::Commit() method
1595
1596 // the stream element must be provided
1597 if ( !pStreamElement )
1598 throw uno::RuntimeException( THROW_WHERE );
1599
1600 if (m_nStorageType == embed::StorageFormats::OFOPXML && pStreamElement->m_xStream)
1601 {
1602 SAL_WARN_IF( rName.empty(), "package.xstor", "The name must not be empty!" );
1603
1604 if ( !m_xRelStorage.is() )
1605 {
1606 // Create new rels storage, this is commit scenario so it must be possible
1608 }
1609
1610 pStreamElement->m_xStream->CommitStreamRelInfo(m_xRelStorage, pStreamElement->m_aOriginalName, rName);
1611 }
1612}
1613
1614uno::Reference< io::XInputStream > OStorage_Impl::GetRelInfoStreamForName(
1615 std::u16string_view aName )
1616{
1617 if ( m_nStorageType == embed::StorageFormats::OFOPXML )
1618 {
1619 ReadContents();
1620 if ( m_xRelStorage.is() )
1621 {
1622 OUString aRelStreamName = OUString::Concat(aName) + ".rels";
1623 if ( m_xRelStorage->hasByName( aRelStreamName ) )
1624 {
1625 uno::Reference< io::XStream > xStream = m_xRelStorage->openStreamElement( aRelStreamName, embed::ElementModes::READ );
1626 if ( xStream.is() )
1627 return xStream->getInputStream();
1628 }
1629 }
1630 }
1631
1632 return uno::Reference< io::XInputStream >();
1633}
1634
1635void OStorage_Impl::CommitRelInfo( const uno::Reference< container::XNameContainer >& xNewPackageFolder )
1636{
1637 // this method should be used only in OStorage_Impl::Commit() method
1638 OUString aRelsStorName("_rels");
1639
1640 if ( !xNewPackageFolder.is() )
1641 throw uno::RuntimeException( THROW_WHERE );
1642
1643 if ( m_nStorageType != embed::StorageFormats::OFOPXML )
1644 return;
1645
1647 throw io::IOException( THROW_WHERE );
1648
1650 {
1651 if (m_aRelInfo.hasElements())
1652 {
1654
1655 uno::Reference<io::XStream> xRelsStream = m_xRelStorage->openStreamElement(
1656 ".rels", embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE);
1657
1658 uno::Reference<io::XOutputStream> xOutStream = xRelsStream->getOutputStream();
1659 if (!xOutStream.is())
1660 throw uno::RuntimeException(THROW_WHERE);
1661
1662 ::comphelper::OFOPXMLHelper::WriteRelationsInfoSequence(xOutStream, m_aRelInfo,
1663 m_xContext);
1664
1665 // set the mediatype
1666 uno::Reference<beans::XPropertySet> xPropSet(xRelsStream, uno::UNO_QUERY_THROW);
1667 xPropSet->setPropertyValue(
1668 "MediaType", uno::Any(OUString(
1669 "application/vnd.openxmlformats-package.relationships+xml")));
1670
1672 }
1673 else if (m_xRelStorage.is())
1674 RemoveStreamRelInfo(std::u16string_view()); // remove own rel info
1675 }
1678 {
1680
1681 uno::Reference<io::XStream> xRelsStream = m_xRelStorage->openStreamElement(
1682 ".rels", embed::ElementModes::TRUNCATE | embed::ElementModes::READWRITE);
1683
1684 uno::Reference<io::XOutputStream> xOutputStream = xRelsStream->getOutputStream();
1685 if (!xOutputStream.is())
1686 throw uno::RuntimeException(THROW_WHERE);
1687
1688 uno::Reference<io::XSeekable> xSeek(m_xNewRelInfoStream, uno::UNO_QUERY_THROW);
1689 xSeek->seek(0);
1691
1692 // set the mediatype
1693 uno::Reference<beans::XPropertySet> xPropSet(xRelsStream, uno::UNO_QUERY_THROW);
1694 xPropSet->setPropertyValue(
1695 "MediaType",
1696 uno::Any(OUString("application/vnd.openxmlformats-package.relationships+xml")));
1697
1698 m_xNewRelInfoStream.clear();
1700 {
1701 m_aRelInfo = uno::Sequence<uno::Sequence<beans::StringPair>>();
1703 }
1704 else
1706 }
1707
1708 if ( !m_xRelStorage.is() )
1709 return;
1710
1711 if ( m_xRelStorage->hasElements() )
1712 {
1713 uno::Reference< embed::XTransactedObject > xTrans( m_xRelStorage, uno::UNO_QUERY_THROW );
1714 xTrans->commit();
1715 }
1716
1717 if ( xNewPackageFolder.is() && xNewPackageFolder->hasByName( aRelsStorName ) )
1718 xNewPackageFolder->removeByName( aRelsStorName );
1719
1720 if ( !m_xRelStorage->hasElements() )
1721 {
1722 // the empty relations storage should not be created
1723 delete m_pRelStorElement;
1724 m_pRelStorElement = nullptr;
1725 m_xRelStorage.clear();
1726 }
1727 else if ( m_pRelStorElement && m_pRelStorElement->m_xStorage && xNewPackageFolder.is() )
1728 m_pRelStorElement->m_xStorage->InsertIntoPackageFolder( aRelsStorName, xNewPackageFolder );
1729}
1730
1731// OStorage implementation
1732
1733OStorage::OStorage( uno::Reference< io::XInputStream > const & xInputStream,
1734 sal_Int32 nMode,
1735 const uno::Sequence< beans::PropertyValue >& xProperties,
1736 uno::Reference< uno::XComponentContext > const & xContext,
1737 sal_Int32 nStorageType )
1738: m_pImpl( new OStorage_Impl( xInputStream, nMode, xProperties, xContext, nStorageType ) )
1739, m_xSharedMutex( m_pImpl->m_xMutex )
1740, m_aListenersContainer( m_pImpl->m_xMutex->GetMutex() )
1741, m_bReadOnlyWrap( false )
1742{
1743 m_pImpl->m_pAntiImpl = this;
1744}
1745
1746OStorage::OStorage( uno::Reference< io::XStream > const & xStream,
1747 sal_Int32 nMode,
1748 const uno::Sequence< beans::PropertyValue >& xProperties,
1749 uno::Reference< uno::XComponentContext > const & xContext,
1750 sal_Int32 nStorageType )
1751: m_pImpl( new OStorage_Impl( xStream, nMode, xProperties, xContext, nStorageType ) )
1752, m_xSharedMutex( m_pImpl->m_xMutex )
1753, m_aListenersContainer( m_pImpl->m_xMutex->GetMutex() )
1754, m_bReadOnlyWrap( false )
1755{
1756 m_pImpl->m_pAntiImpl = this;
1757}
1758
1759OStorage::OStorage( OStorage_Impl* pImpl, bool bReadOnlyWrap )
1760: m_pImpl( pImpl )
1761, m_xSharedMutex( m_pImpl->m_xMutex )
1762, m_aListenersContainer( m_pImpl->m_xMutex->GetMutex() )
1763, m_bReadOnlyWrap( bReadOnlyWrap )
1764{
1765 // this call can be done only from OStorage_Impl implementation to create child storage
1766 assert( m_pImpl && m_pImpl->m_xMutex.is() && "The provided pointer & mutex MUST NOT be empty!" );
1767
1768 OSL_ENSURE( ( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) == embed::ElementModes::WRITE ||
1770 "The wrapper can not allow writing in case implementation does not!" );
1771
1772 if ( !bReadOnlyWrap )
1773 m_pImpl->m_pAntiImpl = this;
1774}
1775
1777{
1778 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
1779 if ( m_pImpl )
1780 {
1781 osl_atomic_increment(&m_refCount); // to call dispose
1782 try {
1783 dispose();
1784 }
1785 catch( const uno::RuntimeException& )
1786 {
1787 TOOLS_INFO_EXCEPTION("package.xstor", "Handled exception");
1788 }
1789 }
1790}
1791
1792void OStorage::InternalDispose( bool bNotifyImpl )
1793{
1794 if ( !m_pImpl )
1795 return;
1796
1797 // the source object is also a kind of locker for the current object
1798 // since the listeners could dispose the object while being notified
1799 lang::EventObject aSource( getXWeak() );
1801
1802 if ( !m_pImpl )
1803 return;
1804
1806
1807 if ( m_bReadOnlyWrap )
1808 {
1809 OSL_ENSURE( m_aOpenSubComponentsVector.empty() || m_pSubElDispListener,
1810 "If any subelements are open the listener must exist!" );
1811
1813 {
1814 m_pSubElDispListener->OwnerIsDisposed();
1815
1816 // iterate through m_pData->m_aOpenSubComponentsVector
1817 // deregister m_pData->m_pSubElDispListener and dispose all of them
1818 if ( !m_aOpenSubComponentsVector.empty() )
1819 {
1820 for ( const auto& pComp : m_aOpenSubComponentsVector )
1821 {
1822 uno::Reference< lang::XComponent > xTmp = pComp;
1823 if ( xTmp.is() )
1824 {
1825 xTmp->removeEventListener( uno::Reference< lang::XEventListener >(
1826 static_cast< lang::XEventListener* >( m_pSubElDispListener.get())));
1827
1828 try {
1829 xTmp->dispose();
1830 } catch( const uno::Exception& )
1831 {
1832 TOOLS_INFO_EXCEPTION("package.xstor", "Quiet exception");
1833 }
1834 }
1835 }
1836
1838 }
1839 }
1840
1841 if ( bNotifyImpl )
1842 m_pImpl->RemoveReadOnlyWrap( *this );
1843 }
1844 else
1845 {
1846 m_pImpl->m_pAntiImpl = nullptr;
1847
1848 if ( bNotifyImpl )
1849 {
1850 if ( m_pImpl->m_bIsRoot )
1851 delete m_pImpl;
1852 else
1853 {
1854 // the non-committed changes for the storage must be removed
1855 m_pImpl->Revert();
1856 }
1857 }
1858 }
1859
1860 m_pImpl = nullptr;
1861}
1862
1863void OStorage::ChildIsDisposed( const uno::Reference< uno::XInterface >& xChild )
1864{
1865 // this method can only be called by child disposing listener
1866
1867 // this method must not contain any locking
1868 // the locking is done in the listener
1869
1870 auto& rVec = m_aOpenSubComponentsVector;
1871 rVec.erase(std::remove_if(rVec.begin(), rVec.end(),
1872 [&xChild](const uno::Reference<lang::XComponent>& xTmp) {
1873 return !xTmp.is() || xTmp == xChild;
1874 }),
1875 rVec.end());
1876}
1877
1879{
1880 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
1881 if ( !m_pImpl )
1882 {
1883 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
1884 throw lang::DisposedException( THROW_WHERE );
1885 }
1886
1888 return;
1889
1891
1892 SAL_WARN_IF( m_bReadOnlyWrap, "package.xstor", "The storage can not be modified at all!" );
1893
1894 lang::EventObject aSource( getXWeak() );
1895
1899 if ( pContainer )
1900 {
1901 comphelper::OInterfaceIteratorHelper2 pIterator( *pContainer );
1902 while ( pIterator.hasMoreElements( ) )
1903 {
1904 static_cast<util::XModifyListener*>( pIterator.next( ) )->modified( aSource );
1905 }
1906 }
1907}
1908
1910/*
1911 1 - preCommit
1912 2 - committed
1913 3 - preRevert
1914 4 - reverted
1915*/
1916{
1917 // no need to lock mutex here for the checking of m_pImpl, and m_pData is alive until the object is destructed
1918 if ( !m_pImpl )
1919 {
1920 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
1921 throw lang::DisposedException( THROW_WHERE );
1922 }
1923
1924 SAL_WARN_IF( m_bReadOnlyWrap, "package.xstor", "The storage can not be modified at all!" );
1925
1926 lang::EventObject aSource( getXWeak() );
1927
1931 if ( !pContainer )
1932 return;
1933
1934 comphelper::OInterfaceIteratorHelper2 pIterator( *pContainer );
1935 while ( pIterator.hasMoreElements( ) )
1936 {
1937 OSL_ENSURE( nMessage >= 1 && nMessage <= 4, "Wrong internal notification code is used!" );
1938
1939 switch( nMessage )
1940 {
1942 static_cast<embed::XTransactionListener*>( pIterator.next( ) )->preCommit( aSource );
1943 break;
1945 static_cast<embed::XTransactionListener*>( pIterator.next( ) )->commited( aSource );
1946 break;
1948 static_cast<embed::XTransactionListener*>( pIterator.next( ) )->preRevert( aSource );
1949 break;
1950 case STOR_MESS_REVERTED:
1951 static_cast<embed::XTransactionListener*>( pIterator.next( ) )->reverted( aSource );
1952 break;
1953 }
1954 }
1955}
1956
1957SotElement_Impl* OStorage::OpenStreamElement_Impl( const OUString& aStreamName, sal_Int32 nOpenMode, bool bEncr )
1958{
1959 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
1960
1961 OSL_ENSURE( !m_bReadOnlyWrap || ( nOpenMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE,
1962 "An element can not be opened for writing in readonly storage!" );
1963
1964 SotElement_Impl *pElement = m_pImpl->FindElement( aStreamName );
1965 if ( !pElement )
1966 {
1967 // element does not exist, check if creation is allowed
1968 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
1969 || (( nOpenMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
1970 || ( nOpenMode & embed::ElementModes::NOCREATE ) == embed::ElementModes::NOCREATE )
1971 {
1972 throw io::IOException("Element does not exist and cannot be "
1973 "created: \"" + aStreamName + "\""); // TODO: access_denied
1974 }
1975
1976 // create a new StreamElement and insert it into the list
1977 pElement = m_pImpl->InsertStream( aStreamName, bEncr );
1978 }
1979 else if ( pElement->m_bIsStorage )
1980 {
1981 throw io::IOException( THROW_WHERE );
1982 }
1983
1984 SAL_WARN_IF( !pElement, "package.xstor", "In case element can not be created an exception must be thrown!" );
1985
1986 if (!pElement->m_xStream)
1987 m_pImpl->OpenSubStream( pElement );
1988
1989 if (!pElement->m_xStream)
1990 throw io::IOException( THROW_WHERE );
1991
1992 return pElement;
1993}
1994
1995void OStorage::MakeLinkToSubComponent_Impl( const uno::Reference< lang::XComponent >& xComponent )
1996{
1997 if ( !xComponent.is() )
1998 throw uno::RuntimeException( THROW_WHERE );
1999
2001 {
2003 }
2004
2005 xComponent->addEventListener( m_pSubElDispListener );
2006
2007 m_aOpenSubComponentsVector.emplace_back(xComponent );
2008}
2009
2010// XInterface
2011
2013{
2014 // common interfaces
2015 uno::Any aReturn = ::cppu::queryInterface
2016 ( rType
2017 , static_cast<lang::XTypeProvider*> ( this )
2018 , static_cast<embed::XStorage*> ( this )
2019 , static_cast<embed::XStorage2*> ( this )
2020 , static_cast<embed::XTransactedObject*> ( this )
2021 , static_cast<embed::XTransactionBroadcaster*> ( this )
2022 , static_cast<util::XModifiable*> ( this )
2023 , static_cast<container::XNameAccess*> ( this )
2024 , static_cast<container::XElementAccess*> ( this )
2025 , static_cast<lang::XComponent*> ( this )
2026 , static_cast<beans::XPropertySet*> ( this )
2027 , static_cast<embed::XOptimizedStorage*> ( this ) );
2028
2029 if ( aReturn.hasValue() )
2030 return aReturn ;
2031
2032 aReturn = ::cppu::queryInterface
2033 ( rType
2034 , static_cast<embed::XHierarchicalStorageAccess*> ( this )
2035 , static_cast<embed::XHierarchicalStorageAccess2*> ( this ) );
2036
2037 if ( aReturn.hasValue() )
2038 return aReturn ;
2039
2040 if ( m_pImpl->m_nStorageType == embed::StorageFormats::PACKAGE )
2041 {
2042 if ( m_pImpl->m_bIsRoot )
2043 {
2044 aReturn = ::cppu::queryInterface
2045 ( rType
2046 , static_cast<embed::XStorageRawAccess*> ( this )
2047 , static_cast<embed::XEncryptionProtectedSource*> ( this )
2048 , static_cast<embed::XEncryptionProtectedSource2*> ( this )
2049 , static_cast<embed::XEncryptionProtectedStorage*> ( this ) );
2050 }
2051 else
2052 {
2053 aReturn = ::cppu::queryInterface
2054 ( rType
2055 , static_cast<embed::XStorageRawAccess*> ( this ) );
2056 }
2057 }
2058 else if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML )
2059 {
2060 aReturn = ::cppu::queryInterface
2061 ( rType
2062 , static_cast<embed::XRelationshipAccess*> ( this ) );
2063 }
2064
2065 if ( aReturn.hasValue() )
2066 return aReturn ;
2067
2068 return OWeakObject::queryInterface( rType );
2069}
2070
2071void SAL_CALL OStorage::acquire() noexcept
2072{
2073 OWeakObject::acquire();
2074}
2075
2076void SAL_CALL OStorage::release() noexcept
2077{
2078 OWeakObject::release();
2079}
2080
2081// XTypeProvider
2082uno::Sequence< uno::Type > SAL_CALL OStorage::getTypes()
2083{
2084 if (! m_oTypeCollection)
2085 {
2086 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
2087
2088 if (! m_oTypeCollection)
2089 {
2090 if ( m_pImpl->m_nStorageType == embed::StorageFormats::PACKAGE )
2091 {
2092 if ( m_pImpl->m_bIsRoot )
2093 {
2094 m_oTypeCollection.emplace(
2106 }
2107 else
2108 {
2109 m_oTypeCollection.emplace(
2118 }
2119 }
2120 else if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML )
2121 {
2122 m_oTypeCollection.emplace(
2130 }
2131 else
2132 {
2133 m_oTypeCollection.emplace(
2140 }
2141 }
2142 }
2143
2144 return m_oTypeCollection->getTypes() ;
2145}
2146
2147uno::Sequence< sal_Int8 > SAL_CALL OStorage::getImplementationId()
2148{
2149 static const comphelper::UnoIdInit lcl_ImplId;
2150 return lcl_ImplId.getSeq();
2151}
2152
2153// XStorage
2154void SAL_CALL OStorage::copyToStorage( const uno::Reference< embed::XStorage >& xDest )
2155{
2156 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
2157
2158 if ( !m_pImpl )
2159 {
2160 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2161 throw lang::DisposedException( THROW_WHERE );
2162 }
2163
2164 if ( !xDest.is() || xDest == getXWeak() )
2165 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 );
2166
2167 try {
2168 m_pImpl->CopyToStorage( xDest, false );
2169 }
2170 catch( const embed::InvalidStorageException& )
2171 {
2172 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2173 throw;
2174 }
2175 catch( const lang::IllegalArgumentException& )
2176 {
2177 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2178 throw;
2179 }
2180 catch( const embed::StorageWrappedTargetException& )
2181 {
2182 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2183 throw;
2184 }
2185 catch( const io::IOException& )
2186 {
2187 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2188 throw;
2189 }
2190 catch( const uno::RuntimeException& )
2191 {
2192 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2193 throw;
2194 }
2195 catch( const uno::Exception& )
2196 {
2197 uno::Any aCaught( ::cppu::getCaughtException() );
2198 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
2199
2200 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't copy storage!",
2201 uno::Reference< io::XInputStream >(),
2202 aCaught );
2203 }
2204}
2205
2206uno::Reference< io::XStream > SAL_CALL OStorage::openStreamElement(
2207 const OUString& aStreamName, sal_Int32 nOpenMode )
2208{
2209 osl::ClearableMutexGuard aGuard(m_xSharedMutex->GetMutex());
2210
2211 if ( !m_pImpl )
2212 {
2213 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2214 throw lang::DisposedException( THROW_WHERE );
2215 }
2216
2217 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, false ) )
2218 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2219
2220 if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML && aStreamName == "_rels" )
2221 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable element name
2222
2223 if ( ( nOpenMode & embed::ElementModes::WRITE ) && m_bReadOnlyWrap )
2224 throw io::IOException( THROW_WHERE ); // TODO: access denied
2225
2226 uno::Reference< io::XStream > xResult;
2227 try
2228 {
2229 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamName, nOpenMode, false );
2230 OSL_ENSURE(pElement && pElement->m_xStream, "In case element can not be created an exception must be thrown!");
2231
2232 xResult = pElement->m_xStream->GetStream(nOpenMode, false);
2233 SAL_WARN_IF( !xResult.is(), "package.xstor", "The method must throw exception instead of removing empty result!" );
2234
2235 if ( m_bReadOnlyWrap )
2236 {
2237 // before the storage disposes the stream it must deregister itself as listener
2238 uno::Reference< lang::XComponent > xStreamComponent( xResult, uno::UNO_QUERY_THROW );
2239 MakeLinkToSubComponent_Impl( xStreamComponent );
2240 }
2241 }
2242 catch( const embed::InvalidStorageException& )
2243 {
2244 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2245 throw;
2246 }
2247 catch( const lang::IllegalArgumentException& )
2248 {
2249 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2250 throw;
2251 }
2252 catch( const packages::WrongPasswordException& )
2253 {
2254 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2255 throw;
2256 }
2257 catch( const embed::StorageWrappedTargetException& )
2258 {
2259 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2260 throw;
2261 }
2262 catch( const io::IOException& )
2263 {
2264 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2265 throw;
2266 }
2267 catch( const uno::RuntimeException& )
2268 {
2269 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2270 throw;
2271 }
2272 catch( const uno::Exception& )
2273 {
2274 uno::Any aCaught( ::cppu::getCaughtException() );
2275 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
2276
2277 throw embed::StorageWrappedTargetException(THROW_WHERE "Can't open stream element!",
2278 uno::Reference< io::XInputStream >(),
2279 aCaught );
2280 }
2281
2282 aGuard.clear();
2283
2285
2286 return xResult;
2287}
2288
2289uno::Reference< io::XStream > SAL_CALL OStorage::openEncryptedStreamElement(
2290 const OUString& aStreamName, sal_Int32 nOpenMode, const OUString& aPass )
2291{
2292 return openEncryptedStream( aStreamName, nOpenMode, ::comphelper::OStorageHelper::CreatePackageEncryptionData( aPass ) );
2293}
2294
2295uno::Reference< embed::XStorage > SAL_CALL OStorage::openStorageElement(
2296 const OUString& aStorName, sal_Int32 nStorageMode )
2297{
2298 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
2299
2300 if ( !m_pImpl )
2301 {
2302 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2303 throw lang::DisposedException( THROW_WHERE );
2304 }
2305
2306 if ( aStorName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName, false ) )
2307 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2308
2309 if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML && aStorName == "_rels" )
2310 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2311
2312 if ( ( nStorageMode & embed::ElementModes::WRITE ) && m_bReadOnlyWrap )
2313 throw io::IOException( THROW_WHERE ); // TODO: access denied
2314
2315 if ( ( nStorageMode & embed::ElementModes::TRUNCATE )
2316 && !( nStorageMode & embed::ElementModes::WRITE ) )
2317 throw io::IOException( THROW_WHERE ); // TODO: access denied
2318
2319 // it's always possible to read written storage in this implementation
2320 nStorageMode |= embed::ElementModes::READ;
2321
2322 uno::Reference< embed::XStorage > xResult;
2323 try
2324 {
2325 SotElement_Impl *pElement = m_pImpl->FindElement( aStorName );
2326 if ( !pElement )
2327 {
2328 // element does not exist, check if creation is allowed
2329 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
2330 || (( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE )
2331 || ( nStorageMode & embed::ElementModes::NOCREATE ) == embed::ElementModes::NOCREATE )
2332 throw io::IOException( THROW_WHERE ); // TODO: access_denied
2333
2334 // create a new StorageElement and insert it into the list
2335 pElement = m_pImpl->InsertStorage( aStorName, nStorageMode );
2336 }
2337 else if ( !pElement->m_bIsStorage )
2338 {
2339 throw io::IOException( THROW_WHERE );
2340 }
2341 else if (pElement->m_xStorage)
2342 {
2343 // storage has already been opened; it may be opened another time, if it the mode allows to do so
2344 if (pElement->m_xStorage->m_pAntiImpl)
2345 {
2346 throw io::IOException( THROW_WHERE ); // TODO: access_denied
2347 }
2348 else if ( !pElement->m_xStorage->m_aReadOnlyWrapVector.empty()
2349 && ( nStorageMode & embed::ElementModes::WRITE ) )
2350 {
2351 throw io::IOException( THROW_WHERE ); // TODO: access_denied
2352 }
2353 else
2354 {
2355 // in case parent storage allows writing the readonly mode of the child storage is
2356 // virtual, that means that it is just enough to change the flag to let it be writable
2357 // and since there is no AntiImpl nobody should be notified about it
2358 pElement->m_xStorage->m_nStorageMode = nStorageMode | embed::ElementModes::READ;
2359
2360 if ( nStorageMode & embed::ElementModes::TRUNCATE )
2361 {
2362 for (const auto & rPair : pElement->m_xStorage->m_aChildrenMap)
2363 for (auto pElementToDel : rPair.second)
2364 m_pImpl->RemoveElement( /*aName*/rPair.first, pElementToDel );
2365 }
2366 }
2367 }
2368
2369 if (!pElement->m_xStorage)
2370 m_pImpl->OpenSubStorage(pElement, nStorageMode);
2371
2372 if (!pElement->m_xStorage)
2373 throw io::IOException( THROW_WHERE ); // TODO: general_error
2374
2375 bool bReadOnlyWrap = ( ( nStorageMode & embed::ElementModes::WRITE ) != embed::ElementModes::WRITE );
2376 rtl::Reference<OStorage> pResultStorage = new OStorage(pElement->m_xStorage.get(), bReadOnlyWrap);
2377 xResult = pResultStorage;
2378
2379 if ( bReadOnlyWrap )
2380 {
2381 // Before this call is done the object must be refcounted already
2382 pElement->m_xStorage->SetReadOnlyWrap(*pResultStorage);
2383
2384 // before the storage disposes the stream it must deregister itself as listener
2385 uno::Reference< lang::XComponent > xStorageComponent( xResult, uno::UNO_QUERY_THROW );
2386 MakeLinkToSubComponent_Impl( xStorageComponent );
2387 }
2388 }
2389 catch( const embed::InvalidStorageException& )
2390 {
2391 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2392 throw;
2393 }
2394 catch( const lang::IllegalArgumentException& )
2395 {
2396 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2397 throw;
2398 }
2399 catch( const embed::StorageWrappedTargetException& )
2400 {
2401 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2402 throw;
2403 }
2404 catch( const io::IOException& )
2405 {
2406 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2407 throw;
2408 }
2409 catch( const uno::RuntimeException& )
2410 {
2411 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2412 throw;
2413 }
2414 catch( const uno::Exception& )
2415 {
2416 uno::Any aCaught( ::cppu::getCaughtException() );
2417 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
2418
2419 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't open storage!",
2420 uno::Reference< io::XInputStream >(),
2421 aCaught );
2422 }
2423
2424 return xResult;
2425}
2426
2427uno::Reference< io::XStream > SAL_CALL OStorage::cloneStreamElement( const OUString& aStreamName )
2428{
2429 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
2430
2431 if ( !m_pImpl )
2432 {
2433 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2434 throw lang::DisposedException( THROW_WHERE );
2435 }
2436
2437 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, false ) )
2438 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2439
2440 if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML && aStreamName == "_rels" )
2441 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2442
2443 try
2444 {
2445 uno::Reference< io::XStream > xResult;
2446 m_pImpl->CloneStreamElement( aStreamName, false, ::comphelper::SequenceAsHashMap(), xResult );
2447 if ( !xResult.is() )
2448 throw uno::RuntimeException( THROW_WHERE );
2449 return xResult;
2450 }
2451 catch( const embed::InvalidStorageException& )
2452 {
2453 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2454 throw;
2455 }
2456 catch( const lang::IllegalArgumentException& )
2457 {
2458 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2459 throw;
2460 }
2461 catch( const packages::WrongPasswordException& )
2462 {
2463 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2464 throw;
2465 }
2466 catch( const io::IOException& )
2467 {
2468 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2469 throw;
2470 }
2471 catch( const embed::StorageWrappedTargetException& )
2472 {
2473 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2474 throw;
2475 }
2476 catch( const uno::RuntimeException& )
2477 {
2478 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2479 throw;
2480 }
2481 catch( const uno::Exception& )
2482 {
2483 uno::Any aCaught( ::cppu::getCaughtException() );
2484 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
2485
2486 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't clone stream!",
2487 uno::Reference< io::XInputStream >(),
2488 aCaught );
2489 }
2490}
2491
2492uno::Reference< io::XStream > SAL_CALL OStorage::cloneEncryptedStreamElement(
2493 const OUString& aStreamName,
2494 const OUString& aPass )
2495{
2497}
2498
2500 const uno::Reference< embed::XStorage >& xTargetStorage )
2501{
2502 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
2503
2504 if ( !m_pImpl )
2505 {
2506 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2507 throw lang::DisposedException( THROW_WHERE );
2508 }
2509
2510 try
2511 {
2512 m_pImpl->CopyLastCommitTo( xTargetStorage );
2513 }
2514 catch( const embed::InvalidStorageException& )
2515 {
2516 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2517 throw;
2518 }
2519 catch( const lang::IllegalArgumentException& )
2520 {
2521 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2522 throw;
2523 }
2524 catch( const embed::StorageWrappedTargetException& )
2525 {
2526 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2527 throw;
2528 }
2529 catch( const io::IOException& )
2530 {
2531 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2532 throw;
2533 }
2534 catch( const uno::RuntimeException& )
2535 {
2536 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2537 throw;
2538 }
2539 catch( const uno::Exception& )
2540 {
2541 uno::Any aCaught( ::cppu::getCaughtException() );
2542 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
2543
2544 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't copy last commit version!",
2545 uno::Reference< io::XInputStream >(),
2546 aCaught );
2547 }
2548
2549}
2550
2552 const OUString& aStorName,
2553 const uno::Reference< embed::XStorage >& xTargetStorage )
2554{
2555 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
2556
2557 if ( !m_pImpl )
2558 {
2559 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2560 throw lang::DisposedException( THROW_WHERE );
2561 }
2562
2563 if ( aStorName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStorName, false ) )
2564 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2565
2566 if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML && aStorName == "_rels" )
2567 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
2568
2569 try
2570 {
2571 SotElement_Impl *pElement = m_pImpl->FindElement( aStorName );
2572 if ( !pElement )
2573 {
2574 // element does not exist, throw exception
2575 throw io::IOException( THROW_WHERE ); // TODO: access_denied
2576 }
2577 else if ( !pElement->m_bIsStorage )
2578 {
2579 throw io::IOException( THROW_WHERE );
2580 }
2581
2582 if (!pElement->m_xStorage)
2583 m_pImpl->OpenSubStorage( pElement, embed::ElementModes::READ );
2584
2585 if (!pElement->m_xStorage)
2586 throw io::IOException( THROW_WHERE ); // TODO: general_error
2587
2588 // the existence of m_pAntiImpl of the child is not interesting,
2589 // the copy will be created internally
2590
2591 pElement->m_xStorage->CopyLastCommitTo(xTargetStorage);
2592 }
2593 catch( const embed::InvalidStorageException& )
2594 {
2595 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2596 throw;
2597 }
2598 catch( const lang::IllegalArgumentException& )
2599 {
2600 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2601 throw;
2602 }
2603 catch( const io::IOException& )
2604 {
2605 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2606 throw;
2607 }
2608 catch( const embed::StorageWrappedTargetException& )
2609 {
2610 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2611 throw;
2612 }
2613 catch( const uno::RuntimeException& )
2614 {
2615 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2616 throw;
2617 }
2618 catch( const uno::Exception& )
2619 {
2620 uno::Any aCaught( ::cppu::getCaughtException() );
2621 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
2622
2623 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't copy last commit element version!",
2624 uno::Reference< io::XInputStream >(),
2625 aCaught );
2626 }
2627}
2628
2629sal_Bool SAL_CALL OStorage::isStreamElement( const OUString& aElementName )
2630{
2631 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
2632
2633 if ( !m_pImpl )
2634 {
2635 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2636 throw lang::DisposedException( THROW_WHERE );
2637 }
2638
2639 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, false ) )
2640 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2641
2642 if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML && aElementName == "_rels" )
2643 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable name
2644
2645 SotElement_Impl* pElement = nullptr;
2646
2647 try
2648 {
2649 pElement = m_pImpl->FindElement( aElementName );
2650 }
2651 catch( const embed::InvalidStorageException& )
2652 {
2653 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2654 throw;
2655 }
2656 catch( const lang::IllegalArgumentException& )
2657 {
2658 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2659 throw;
2660 }
2661 catch( const container::NoSuchElementException& )
2662 {
2663 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2664 throw;
2665 }
2666 catch( const uno::RuntimeException& )
2667 {
2668 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2669 throw;
2670 }
2671 catch( const uno::Exception& )
2672 {
2673 uno::Any aCaught( ::cppu::getCaughtException() );
2674 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
2675
2676 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can't detect whether it is a stream!",
2677 uno::Reference< io::XInputStream >(),
2678 aCaught );
2679 }
2680
2681 if ( !pElement )
2682 throw container::NoSuchElementException( THROW_WHERE ); //???
2683
2684 return !pElement->m_bIsStorage;
2685}
2686
2687sal_Bool SAL_CALL OStorage::isStorageElement( const OUString& aElementName )
2688{
2689 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
2690
2691 if ( !m_pImpl )
2692 {
2693 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2694 throw lang::DisposedException( THROW_WHERE );
2695 }
2696
2697 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, false ) )
2698 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2699
2700 if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML && aElementName == "_rels" )
2701 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 );
2702
2703 SotElement_Impl* pElement = nullptr;
2704
2705 try
2706 {
2707 pElement = m_pImpl->FindElement( aElementName );
2708 }
2709 catch( const embed::InvalidStorageException& )
2710 {
2711 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2712 throw;
2713 }
2714 catch( const lang::IllegalArgumentException& )
2715 {
2716 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2717 throw;
2718 }
2719 catch( const container::NoSuchElementException& )
2720 {
2721 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2722 throw;
2723 }
2724 catch( const uno::RuntimeException& )
2725 {
2726 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2727 throw;
2728 }
2729 catch( const uno::Exception& )
2730 {
2731 uno::Any aCaught( ::cppu::getCaughtException() );
2732 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
2733
2734 throw lang::WrappedTargetRuntimeException( THROW_WHERE "can't detect whether it is a storage",
2735 uno::Reference< io::XInputStream >(),
2736 aCaught );
2737 }
2738
2739 if ( !pElement )
2740 throw container::NoSuchElementException( THROW_WHERE ); //???
2741
2742 return pElement->m_bIsStorage;
2743}
2744
2745void SAL_CALL OStorage::removeElement( const OUString& aElementName )
2746{
2747 {
2748 osl::MutexGuard aGuard(m_xSharedMutex->GetMutex());
2749
2750 if (!m_pImpl)
2751 {
2752 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2753 throw lang::DisposedException(THROW_WHERE);
2754 }
2755
2756 if (aElementName.isEmpty()
2758 throw lang::IllegalArgumentException(THROW_WHERE "Unexpected entry name syntax.",
2759 uno::Reference<uno::XInterface>(), 1);
2760
2761 if (m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML && aElementName == "_rels")
2762 throw lang::IllegalArgumentException(THROW_WHERE, uno::Reference<uno::XInterface>(),
2763 1); // TODO: unacceptable name
2764
2765 if (!(m_pImpl->m_nStorageMode & embed::ElementModes::WRITE))
2766 throw io::IOException(THROW_WHERE); // TODO: access denied
2767
2768 try
2769 {
2770 auto pElement = m_pImpl->FindElement(aElementName);
2771 if ( !pElement )
2772 throw container::NoSuchElementException(THROW_WHERE); //???
2773
2774 m_pImpl->RemoveElement(aElementName, pElement);
2775
2776 m_pImpl->m_bIsModified = true;
2778 }
2779 catch (const embed::InvalidStorageException&)
2780 {
2781 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2782 throw;
2783 }
2784 catch (const lang::IllegalArgumentException&)
2785 {
2786 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2787 throw;
2788 }
2789 catch (const container::NoSuchElementException&)
2790 {
2791 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2792 throw;
2793 }
2794 catch (const io::IOException&)
2795 {
2796 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2797 throw;
2798 }
2799 catch (const embed::StorageWrappedTargetException&)
2800 {
2801 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2802 throw;
2803 }
2804 catch (const uno::RuntimeException&)
2805 {
2806 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2807 throw;
2808 }
2809 catch (const uno::Exception&)
2810 {
2811 uno::Any aCaught(::cppu::getCaughtException());
2812 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
2813
2814 throw embed::StorageWrappedTargetException(THROW_WHERE "Can't remove element!",
2815 uno::Reference<io::XInputStream>(), aCaught);
2816 }
2817 }
2818
2820}
2821
2822void SAL_CALL OStorage::renameElement( const OUString& aElementName, const OUString& aNewName )
2823{
2824 {
2825 osl::MutexGuard aGuard(m_xSharedMutex->GetMutex());
2826
2827 if (!m_pImpl)
2828 {
2829 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2830 throw lang::DisposedException(THROW_WHERE);
2831 }
2832
2833 if (aElementName.isEmpty()
2835 || aNewName.isEmpty()
2837 throw lang::IllegalArgumentException(THROW_WHERE "Unexpected entry name syntax.",
2838 uno::Reference<uno::XInterface>(), 1);
2839
2840 if (m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML
2841 && (aElementName == "_rels" || aNewName == "_rels"))
2842 throw lang::IllegalArgumentException(THROW_WHERE, uno::Reference<uno::XInterface>(),
2843 0); // TODO: unacceptable element name
2844
2845 if (!(m_pImpl->m_nStorageMode & embed::ElementModes::WRITE))
2846 throw io::IOException(THROW_WHERE); // TODO: access denied
2847
2848 try
2849 {
2850 SotElement_Impl* pRefElement = m_pImpl->FindElement(aNewName);
2851 if (pRefElement)
2852 throw container::ElementExistException(THROW_WHERE); //???
2853
2854 auto pElement = m_pImpl->FindElement( aElementName );
2855 if ( !pElement )
2856 throw container::NoSuchElementException(THROW_WHERE); //???
2857
2858 auto mapIt = m_pImpl->m_aChildrenMap.find(aElementName);
2859 auto rVec = mapIt->second;
2860 for (auto it = rVec.begin(); it != rVec.end(); ++it)
2861 if (pElement == *it)
2862 {
2863 rVec.erase(std::remove(rVec.begin(), rVec.end(), pElement), rVec.end());
2864 if (rVec.empty())
2865 m_pImpl->m_aChildrenMap.erase(mapIt);
2866 break;
2867 }
2868 m_pImpl->m_aChildrenMap[aNewName].push_back(pElement);
2869 m_pImpl->m_bIsModified = true;
2871 }
2872 catch (const embed::InvalidStorageException&)
2873 {
2874 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2875 throw;
2876 }
2877 catch (const lang::IllegalArgumentException&)
2878 {
2879 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2880 throw;
2881 }
2882 catch (const container::NoSuchElementException&)
2883 {
2884 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2885 throw;
2886 }
2887 catch (const container::ElementExistException&)
2888 {
2889 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2890 throw;
2891 }
2892 catch (const io::IOException&)
2893 {
2894 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2895 throw;
2896 }
2897 catch (const embed::StorageWrappedTargetException&)
2898 {
2899 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2900 throw;
2901 }
2902 catch (const uno::RuntimeException&)
2903 {
2904 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2905 throw;
2906 }
2907 catch (const uno::Exception&)
2908 {
2909 uno::Any aCaught(::cppu::getCaughtException());
2910 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
2911
2912 throw embed::StorageWrappedTargetException(THROW_WHERE "Can't rename element!",
2913 uno::Reference<io::XInputStream>(), aCaught);
2914 }
2915 }
2916
2918}
2919
2920void SAL_CALL OStorage::copyElementTo( const OUString& aElementName,
2921 const uno::Reference< embed::XStorage >& xDest,
2922 const OUString& aNewName )
2923{
2924 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
2925
2926 if ( !m_pImpl )
2927 {
2928 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
2929 throw lang::DisposedException( THROW_WHERE );
2930 }
2931
2932 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, false )
2933 || aNewName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, false ) )
2934 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
2935
2936 if ( !xDest.is() )
2937 // || xDest == getXWeak() )
2938 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 2 );
2939
2940 if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML && ( aElementName == "_rels" || aNewName == "_rels" ) )
2941 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 ); // unacceptable element name
2942
2943 try
2944 {
2945 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
2946 if ( !pElement )
2947 throw container::NoSuchElementException( THROW_WHERE );
2948
2949 uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY_THROW );
2950 if ( xNameAccess->hasByName( aNewName ) )
2951 throw container::ElementExistException( THROW_WHERE );
2952
2953 m_pImpl->CopyStorageElement( pElement, xDest, aNewName, false );
2954 }
2955 catch( const embed::InvalidStorageException& )
2956 {
2957 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2958 throw;
2959 }
2960 catch( const lang::IllegalArgumentException& )
2961 {
2962 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2963 throw;
2964 }
2965 catch( const container::NoSuchElementException& )
2966 {
2967 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2968 throw;
2969 }
2970 catch( const container::ElementExistException& )
2971 {
2972 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2973 throw;
2974 }
2975 catch( const embed::StorageWrappedTargetException& )
2976 {
2977 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2978 throw;
2979 }
2980 catch( const io::IOException& )
2981 {
2982 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2983 throw;
2984 }
2985 catch( const uno::RuntimeException& )
2986 {
2987 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
2988 throw;
2989 }
2990 catch( const uno::Exception& )
2991 {
2992 uno::Any aCaught( ::cppu::getCaughtException() );
2993 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
2994
2995 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't copy element!",
2996 uno::Reference< io::XInputStream >(),
2997 aCaught );
2998 }
2999}
3000
3001void SAL_CALL OStorage::moveElementTo( const OUString& aElementName,
3002 const uno::Reference< embed::XStorage >& xDest,
3003 const OUString& aNewName )
3004{
3005 {
3006 osl::MutexGuard aGuard(m_xSharedMutex->GetMutex());
3007
3008 if (!m_pImpl)
3009 {
3010 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3011 throw lang::DisposedException(THROW_WHERE);
3012 }
3013
3014 if (aElementName.isEmpty()
3016 || aNewName.isEmpty()
3018 throw lang::IllegalArgumentException(THROW_WHERE "Unexpected entry name syntax.",
3019 uno::Reference<uno::XInterface>(), 1);
3020
3021 if (!xDest.is() || xDest == getXWeak())
3022 throw lang::IllegalArgumentException(THROW_WHERE, uno::Reference<uno::XInterface>(), 2);
3023
3024 if (m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML
3025 && (aElementName == "_rels" || aNewName == "_rels"))
3026 throw lang::IllegalArgumentException(THROW_WHERE, uno::Reference<uno::XInterface>(),
3027 0); // unacceptable element name
3028
3029 if (!(m_pImpl->m_nStorageMode & embed::ElementModes::WRITE))
3030 throw io::IOException(THROW_WHERE); // TODO: access denied
3031
3032 try
3033 {
3034 auto pElement = m_pImpl->FindElement( aElementName );
3035 if ( !pElement )
3036 throw container::NoSuchElementException(THROW_WHERE); //???
3037
3038 uno::Reference<XNameAccess> xNameAccess(xDest, uno::UNO_QUERY_THROW);
3039 if (xNameAccess->hasByName(aNewName))
3040 throw container::ElementExistException(THROW_WHERE);
3041
3042 m_pImpl->CopyStorageElement(pElement, xDest, aNewName, false);
3043
3044 m_pImpl->RemoveElement(aElementName, pElement);
3045
3046 m_pImpl->m_bIsModified = true;
3048 }
3049 catch (const embed::InvalidStorageException&)
3050 {
3051 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3052 throw;
3053 }
3054 catch (const lang::IllegalArgumentException&)
3055 {
3056 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3057 throw;
3058 }
3059 catch (const container::NoSuchElementException&)
3060 {
3061 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3062 throw;
3063 }
3064 catch (const container::ElementExistException&)
3065 {
3066 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3067 throw;
3068 }
3069 catch (const embed::StorageWrappedTargetException&)
3070 {
3071 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3072 throw;
3073 }
3074 catch (const io::IOException&)
3075 {
3076 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3077 throw;
3078 }
3079 catch (const uno::RuntimeException&)
3080 {
3081 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3082 throw;
3083 }
3084 catch (const uno::Exception&)
3085 {
3086 uno::Any aCaught(::cppu::getCaughtException());
3087 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
3088
3089 throw embed::StorageWrappedTargetException(THROW_WHERE "Can't move element!",
3090 uno::Reference<io::XInputStream>(), aCaught);
3091 }
3092 }
3093
3095}
3096
3097// XStorage2
3098uno::Reference< io::XStream > SAL_CALL OStorage::openEncryptedStream(
3099 const OUString& aStreamName, sal_Int32 nOpenMode, const uno::Sequence< beans::NamedValue >& aEncryptionData )
3100{
3101 osl::ClearableMutexGuard aGuard( m_xSharedMutex->GetMutex() );
3102
3103 if ( !m_pImpl )
3104 {
3105 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3106 throw lang::DisposedException( THROW_WHERE );
3107 }
3108
3109 if ( ( nOpenMode & embed::ElementModes::WRITE ) && m_bReadOnlyWrap )
3110 throw io::IOException( THROW_WHERE ); // TODO: access denied
3111
3112 if ( !aEncryptionData.hasElements() )
3113 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 3 );
3114
3115 uno::Reference< io::XStream > xResult;
3116 try
3117 {
3118 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamName, nOpenMode, true );
3119 OSL_ENSURE(pElement && pElement->m_xStream, "In case element can not be created an exception must be thrown!");
3120
3121 xResult = pElement->m_xStream->GetStream(nOpenMode, aEncryptionData, false);
3122 SAL_WARN_IF( !xResult.is(), "package.xstor", "The method must throw exception instead of removing empty result!" );
3123
3124 if ( m_bReadOnlyWrap )
3125 {
3126 // before the storage disposes the stream it must deregister itself as listener
3127 uno::Reference< lang::XComponent > xStreamComponent( xResult, uno::UNO_QUERY_THROW );
3128 MakeLinkToSubComponent_Impl( xStreamComponent );
3129 }
3130 }
3131 catch( const embed::InvalidStorageException& )
3132 {
3133 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3134 throw;
3135 }
3136 catch( const lang::IllegalArgumentException& )
3137 {
3138 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3139 throw;
3140 }
3141 catch( const packages::NoEncryptionException& )
3142 {
3143 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3144 throw;
3145 }
3146 catch( const packages::WrongPasswordException& )
3147 {
3148 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3149 throw;
3150 }
3151 catch( const embed::StorageWrappedTargetException& )
3152 {
3153 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3154 throw;
3155 }
3156 catch( const io::IOException& )
3157 {
3158 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3159 throw;
3160 }
3161 catch( const uno::RuntimeException& )
3162 {
3163 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3164 throw;
3165 }
3166 catch( const uno::Exception& )
3167 {
3168 uno::Any aCaught( ::cppu::getCaughtException() );
3169 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
3170
3171 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't open encrypted stream!",
3172 uno::Reference< io::XInputStream >(),
3173 aCaught );
3174 }
3175
3176 aGuard.clear();
3177
3179
3180 return xResult;
3181}
3182
3183uno::Reference< io::XStream > SAL_CALL OStorage::cloneEncryptedStream(
3184 const OUString& aStreamName,
3185 const uno::Sequence< beans::NamedValue >& aEncryptionData )
3186{
3187 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3188
3189 if ( !m_pImpl )
3190 {
3191 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3192 throw lang::DisposedException( THROW_WHERE );
3193 }
3194
3195 if ( !aEncryptionData.hasElements() )
3196 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 2 );
3197
3198 try
3199 {
3200 uno::Reference< io::XStream > xResult;
3201 m_pImpl->CloneStreamElement( aStreamName, true, aEncryptionData, xResult );
3202 if ( !xResult.is() )
3203 throw uno::RuntimeException( THROW_WHERE );
3204 return xResult;
3205 }
3206 catch( const embed::InvalidStorageException& )
3207 {
3208 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3209 throw;
3210 }
3211 catch( const lang::IllegalArgumentException& )
3212 {
3213 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3214 throw;
3215 }
3216 catch( const packages::NoEncryptionException& )
3217 {
3218 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3219 throw;
3220 }
3221 catch( const packages::WrongPasswordException& )
3222 {
3223 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3224 throw;
3225 }
3226 catch( const io::IOException& )
3227 {
3228 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3229 throw;
3230 }
3231 catch( const embed::StorageWrappedTargetException& )
3232 {
3233 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3234 throw;
3235 }
3236 catch( const uno::RuntimeException& )
3237 {
3238 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3239 throw;
3240 }
3241 catch( const uno::Exception& )
3242 {
3243 uno::Any aCaught( ::cppu::getCaughtException() );
3244 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
3245
3246 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't clone encrypted stream!",
3247 uno::Reference< io::XInputStream >(),
3248 aCaught );
3249 }
3250}
3251
3252// XStorageRawAccess
3253uno::Reference< io::XInputStream > SAL_CALL OStorage::getPlainRawStreamElement(
3254 const OUString& sStreamName )
3255{
3256 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3257
3258 if ( !m_pImpl )
3259 {
3260 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3261 throw lang::DisposedException( THROW_WHERE );
3262 }
3263
3264 if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML )
3265 throw uno::RuntimeException( THROW_WHERE ); // the interface is not supported and must not be accessible
3266
3267 if ( sStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName, false ) )
3268 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3269
3270 uno::Reference < io::XInputStream > xTempIn;
3271 try
3272 {
3273 SotElement_Impl* pElement = m_pImpl->FindElement( sStreamName );
3274 if ( !pElement )
3275 throw container::NoSuchElementException( THROW_WHERE );
3276
3277 if (!pElement->m_xStream)
3278 {
3279 m_pImpl->OpenSubStream( pElement );
3280 if (!pElement->m_xStream)
3281 throw io::IOException( THROW_WHERE );
3282 }
3283
3284 uno::Reference<io::XInputStream> xRawInStream = pElement->m_xStream->GetPlainRawInStream();
3285 if ( !xRawInStream.is() )
3286 throw io::IOException( THROW_WHERE );
3287
3289 uno::Reference < io::XOutputStream > xTempOut = xTempFile->getOutputStream();
3290 xTempIn = xTempFile->getInputStream();
3291
3292 if ( !xTempOut.is() || !xTempIn.is() )
3293 throw io::IOException( THROW_WHERE );
3294
3295 // Copy temporary file to a new one
3296 ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
3297 xTempOut->closeOutput();
3298 xTempFile->seek( 0 );
3299 }
3300 catch( const embed::InvalidStorageException& )
3301 {
3302 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3303 throw;
3304 }
3305 catch( const lang::IllegalArgumentException& )
3306 {
3307 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3308 throw;
3309 }
3310 catch( const container::NoSuchElementException& )
3311 {
3312 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3313 throw;
3314 }
3315 catch( const embed::StorageWrappedTargetException& )
3316 {
3317 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3318 throw;
3319 }
3320 catch( const io::IOException& )
3321 {
3322 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3323 throw;
3324 }
3325 catch( const uno::RuntimeException& )
3326 {
3327 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3328 throw;
3329 }
3330 catch( const uno::Exception& )
3331 {
3332 uno::Any aCaught( ::cppu::getCaughtException() );
3333 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
3334
3335 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't get plain raw stream!",
3336 uno::Reference< io::XInputStream >(),
3337 aCaught );
3338 }
3339
3340 return xTempIn;
3341}
3342
3343uno::Reference< io::XInputStream > SAL_CALL OStorage::getRawEncrStreamElement(
3344 const OUString& sStreamName )
3345{
3346 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3347
3348 if ( !m_pImpl )
3349 {
3350 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3351 throw lang::DisposedException( THROW_WHERE );
3352 }
3353
3354 if ( m_pImpl->m_nStorageType != embed::StorageFormats::PACKAGE )
3355 throw packages::NoEncryptionException( THROW_WHERE );
3356
3357 if ( sStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( sStreamName, false ) )
3358 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3359
3360 uno::Reference < io::XInputStream > xTempIn;
3361 try
3362 {
3363 SotElement_Impl* pElement = m_pImpl->FindElement( sStreamName );
3364 if ( !pElement )
3365 throw container::NoSuchElementException( THROW_WHERE );
3366
3367 if (!pElement->m_xStream)
3368 {
3369 m_pImpl->OpenSubStream( pElement );
3370 if (!pElement->m_xStream)
3371 throw io::IOException( THROW_WHERE );
3372 }
3373
3374 if (!pElement->m_xStream->IsEncrypted())
3375 throw packages::NoEncryptionException( THROW_WHERE );
3376
3377 uno::Reference< io::XInputStream > xRawInStream = pElement->m_xStream->GetRawInStream();
3378 if ( !xRawInStream.is() )
3379 throw io::IOException( THROW_WHERE );
3380
3382 uno::Reference < io::XOutputStream > xTempOut = xTempFile;
3383 xTempIn = xTempFile;
3384
3385 if ( !xTempFile )
3386 throw io::IOException( THROW_WHERE );
3387
3388 // Copy temporary file to a new one
3389 ::comphelper::OStorageHelper::CopyInputToOutput( xRawInStream, xTempOut );
3390 xTempFile->closeOutput();
3391 xTempFile->seek( 0 );
3392
3393 }
3394 catch( const embed::InvalidStorageException& )
3395 {
3396 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3397 throw;
3398 }
3399 catch( const lang::IllegalArgumentException& )
3400 {
3401 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3402 throw;
3403 }
3404 catch( const packages::NoEncryptionException& )
3405 {
3406 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3407 throw;
3408 }
3409 catch( const container::NoSuchElementException& )
3410 {
3411 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3412 throw;
3413 }
3414 catch( const embed::StorageWrappedTargetException& )
3415 {
3416 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3417 throw;
3418 }
3419 catch( const io::IOException& )
3420 {
3421 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3422 throw;
3423 }
3424 catch( const uno::RuntimeException& )
3425 {
3426 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow");
3427 throw;
3428 }
3429 catch( const uno::Exception& )
3430 {
3431 uno::Any aCaught( ::cppu::getCaughtException() );
3432 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
3433
3434 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't get raw stream!",
3435 uno::Reference< io::XInputStream >(),
3436 aCaught );
3437 }
3438
3439 return xTempIn;
3440}
3441
3442void SAL_CALL OStorage::insertRawEncrStreamElement( const OUString& aStreamName,
3443 const uno::Reference< io::XInputStream >& xInStream )
3444{
3445 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3446
3447 if ( !m_pImpl )
3448 {
3449 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3450 throw lang::DisposedException( THROW_WHERE );
3451 }
3452
3453 if ( m_pImpl->m_nStorageType != embed::StorageFormats::PACKAGE )
3454 throw embed::InvalidStorageException( THROW_WHERE );
3455
3456 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, false ) )
3457 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3458
3459 if ( !xInStream.is() )
3460 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 2 );
3461
3462 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
3463 throw io::IOException( THROW_WHERE ); // TODO: access denied
3464
3465 try
3466 {
3467 SotElement_Impl* pElement = m_pImpl->FindElement( aStreamName );
3468 if ( pElement )
3469 throw container::ElementExistException( THROW_WHERE );
3470
3471 m_pImpl->InsertRawStream( aStreamName, xInStream );
3472 }
3473 catch( const embed::InvalidStorageException& )
3474 {
3475 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3476 throw;
3477 }
3478 catch( const lang::IllegalArgumentException& )
3479 {
3480 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3481 throw;
3482 }
3483 catch( const packages::NoRawFormatException& )
3484 {
3485 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3486 throw;
3487 }
3488 catch( const container::ElementExistException& )
3489 {
3490 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3491 throw;
3492 }
3493 catch( const embed::StorageWrappedTargetException& )
3494 {
3495 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3496 throw;
3497 }
3498 catch( const io::IOException& )
3499 {
3500 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3501 throw;
3502 }
3503 catch( const uno::RuntimeException& )
3504 {
3505 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3506 throw;
3507 }
3508 catch( const uno::Exception& )
3509 {
3510 uno::Any aCaught( ::cppu::getCaughtException() );
3511 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
3512
3513 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't insert raw stream!",
3514 uno::Reference< io::XInputStream >(),
3515 aCaught );
3516 }
3517}
3518
3519// XTransactedObject
3520void SAL_CALL OStorage::commit()
3521{
3522 uno::Reference< util::XModifiable > xParentModif;
3523
3524 try {
3526
3527 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3528
3529 if ( !m_pImpl )
3530 {
3531 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3532 throw lang::DisposedException( THROW_WHERE );
3533 }
3534
3535 if ( m_bReadOnlyWrap )
3536 throw io::IOException( THROW_WHERE ); // TODO: access_denied
3537
3538 m_pImpl->Commit(); // the root storage initiates the storing to source
3539
3540 // when the storage is committed the parent is modified
3542 xParentModif = static_cast<util::XModifiable*>(m_pImpl->m_pParent->m_pAntiImpl);
3543 }
3544 catch( const io::IOException& )
3545 {
3546 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3547 throw;
3548 }
3549 catch( const embed::StorageWrappedTargetException& )
3550 {
3551 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3552 throw;
3553 }
3554 catch( const uno::RuntimeException& )
3555 {
3556 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3557 throw;
3558 }
3559 catch( const uno::Exception& )
3560 {
3561 uno::Any aCaught( ::cppu::getCaughtException() );
3562 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
3563
3564 throw embed::StorageWrappedTargetException( THROW_WHERE "Problems on commit!",
3565 getXWeak(),
3566 aCaught );
3567 }
3568
3569 setModified( false );
3570 if ( xParentModif.is() )
3571 xParentModif->setModified( true );
3572
3574}
3575
3576void SAL_CALL OStorage::revert()
3577{
3578 // the method removes all the changes done after last commit
3579
3581
3582 {
3583 osl::MutexGuard aGuard(m_xSharedMutex->GetMutex());
3584
3585 if (!m_pImpl)
3586 {
3587 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3588 throw lang::DisposedException(THROW_WHERE);
3589 }
3590
3591 for (const auto & rPair : m_pImpl->m_aChildrenMap)
3592 for (auto pElement : rPair.second)
3593 {
3594 bool bThrow = (pElement->m_xStorage
3595 && (pElement->m_xStorage->m_pAntiImpl
3596 || !pElement->m_xStorage->m_aReadOnlyWrapVector.empty()))
3597 || (pElement->m_xStream
3598 && (pElement->m_xStream->m_pAntiImpl
3599 || !pElement->m_xStream->m_aInputStreamsVector.empty()));
3600 if (bThrow)
3601 throw io::IOException(THROW_WHERE); // TODO: access denied
3602 }
3603
3605 return; // nothing to do
3606
3607 try
3608 {
3609 m_pImpl->Revert();
3610 m_pImpl->m_bIsModified = false;
3612 }
3613 catch (const io::IOException&)
3614 {
3615 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3616 throw;
3617 }
3618 catch (const embed::StorageWrappedTargetException&)
3619 {
3620 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3621 throw;
3622 }
3623 catch (const uno::RuntimeException&)
3624 {
3625 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3626 throw;
3627 }
3628 catch (const uno::Exception&)
3629 {
3630 uno::Any aCaught(::cppu::getCaughtException());
3631 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
3632
3633 throw embed::StorageWrappedTargetException(THROW_WHERE "Problems on revert!",
3634 getXWeak(),
3635 aCaught);
3636 }
3637 }
3638
3639 setModified( false );
3641}
3642
3643// XTransactionBroadcaster
3644void SAL_CALL OStorage::addTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
3645{
3646 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3647
3648 if ( !m_pImpl )
3649 {
3650 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3651 throw lang::DisposedException( THROW_WHERE );
3652 }
3653
3655 aListener );
3656}
3657
3658void SAL_CALL OStorage::removeTransactionListener( const uno::Reference< embed::XTransactionListener >& aListener )
3659{
3660 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3661
3662 if ( !m_pImpl )
3663 {
3664 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3665 throw lang::DisposedException( THROW_WHERE );
3666 }
3667
3669 aListener );
3670}
3671
3672// XModifiable
3673// TODO: if there will be no demand on this interface it will be removed from implementation,
3674// I do not want to remove it now since it is still possible that it will be inserted
3675// to the service back.
3676
3678{
3679 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3680
3681 if ( !m_pImpl )
3682 {
3683 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3684 throw lang::DisposedException( THROW_WHERE );
3685 }
3686
3687 return m_pImpl->m_bIsModified;
3688}
3689
3690void SAL_CALL OStorage::setModified( sal_Bool bModified )
3691{
3692 {
3693 osl::MutexGuard aGuard(m_xSharedMutex->GetMutex());
3694
3695 if (!m_pImpl)
3696 {
3697 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3698 throw lang::DisposedException(THROW_WHERE);
3699 }
3700
3701 if (m_bReadOnlyWrap)
3702 throw beans::PropertyVetoException(THROW_WHERE); // TODO: access denied
3703
3704 if (m_pImpl->m_bIsModified != bool(bModified))
3705 m_pImpl->m_bIsModified = bModified;
3706 }
3707
3708 if ( bModified )
3709 {
3712 }
3713}
3714
3716 const uno::Reference< util::XModifyListener >& aListener )
3717{
3718 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3719
3720 if ( !m_pImpl )
3721 {
3722 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3723 throw lang::DisposedException( THROW_WHERE );
3724 }
3725
3726 osl_atomic_increment( &m_pImpl->m_nModifiedListenerCount );
3729}
3730
3732 const uno::Reference< util::XModifyListener >& aListener )
3733{
3734 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3735
3736 if ( !m_pImpl )
3737 {
3738 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3739 throw lang::DisposedException( THROW_WHERE );
3740 }
3741
3742 osl_atomic_decrement( &m_pImpl->m_nModifiedListenerCount );
3745}
3746
3747// XNameAccess
3748
3749uno::Any SAL_CALL OStorage::getByName( const OUString& aName )
3750{
3751 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3752
3753 if ( !m_pImpl )
3754 {
3755 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3756 throw lang::DisposedException( THROW_WHERE );
3757 }
3758
3760 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
3761
3762 if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML && aName == "_rels" )
3763 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable element name
3764
3765 uno::Any aResult;
3766 try
3767 {
3768 SotElement_Impl* pElement = m_pImpl->FindElement( aName );
3769 if ( !pElement )
3770 throw container::NoSuchElementException( THROW_WHERE );
3771
3772 if ( pElement->m_bIsStorage )
3773 aResult <<= openStorageElement( aName, embed::ElementModes::READ );
3774 else
3775 aResult <<= openStreamElement( aName, embed::ElementModes::READ );
3776 }
3777 catch( const container::NoSuchElementException& )
3778 {
3779 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3780 throw;
3781 }
3782 catch( const lang::WrappedTargetException& )
3783 {
3784 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3785 throw;
3786 }
3787 catch( const uno::RuntimeException& )
3788 {
3789 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3790 throw;
3791 }
3792 catch( const uno::Exception& )
3793 {
3794 uno::Any aCaught( ::cppu::getCaughtException() );
3795 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
3796
3797 throw lang::WrappedTargetException( THROW_WHERE "Can not open storage!",
3798 getXWeak(),
3799 aCaught );
3800 }
3801
3802 return aResult;
3803}
3804
3805uno::Sequence< OUString > SAL_CALL OStorage::getElementNames()
3806{
3807 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3808
3809 if ( !m_pImpl )
3810 {
3811 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3812 throw lang::DisposedException( THROW_WHERE );
3813 }
3814
3815 try
3816 {
3817 return m_pImpl->GetElementNames();
3818 }
3819 catch( const uno::RuntimeException& )
3820 {
3821 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3822 throw;
3823 }
3824 catch ( const uno::Exception& )
3825 {
3826 uno::Any aCaught( ::cppu::getCaughtException() );
3827 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
3828
3829 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open storage!",
3830 getXWeak(),
3831 aCaught );
3832 }
3833}
3834
3835sal_Bool SAL_CALL OStorage::hasByName( const OUString& aName )
3836{
3837 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3838
3839 if ( !m_pImpl )
3840 {
3841 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3842 throw lang::DisposedException( THROW_WHERE );
3843 }
3844
3845 if ( aName.isEmpty() )
3846 return false;
3847
3848 if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML && aName == "_rels" )
3849 return false;
3850
3851 SotElement_Impl* pElement = nullptr;
3852 try
3853 {
3854 pElement = m_pImpl->FindElement( aName );
3855 }
3856 catch( const uno::RuntimeException& )
3857 {
3858 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3859 throw;
3860 }
3861 catch ( const uno::Exception& )
3862 {
3863 uno::Any aCaught( ::cppu::getCaughtException() );
3864 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
3865
3866 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open storage!",
3867 getXWeak(),
3868 aCaught );
3869 }
3870
3871 return ( pElement != nullptr );
3872}
3873
3875{
3876 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3877
3878 if ( !m_pImpl )
3879 {
3880 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3881 throw lang::DisposedException( THROW_WHERE );
3882 }
3883
3884 // it is a multitype container
3885 return uno::Type();
3886}
3887
3889{
3890 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3891
3892 if ( !m_pImpl )
3893 {
3894 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3895 throw lang::DisposedException( THROW_WHERE );
3896 }
3897
3898 try
3899 {
3900 return m_pImpl->HasChildren();
3901 }
3902 catch( const uno::RuntimeException& )
3903 {
3904 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3905 throw;
3906 }
3907 catch( const uno::Exception& )
3908 {
3909 uno::Any aCaught( ::cppu::getCaughtException() );
3910 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
3911
3912 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open storage!",
3913 getXWeak(),
3914 aCaught );
3915 }
3916}
3917
3918// XComponent
3919void SAL_CALL OStorage::dispose()
3920{
3921 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3922
3923 if ( !m_pImpl )
3924 {
3925 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3926 throw lang::DisposedException( THROW_WHERE );
3927 }
3928
3929 try
3930 {
3931 InternalDispose( true );
3932 }
3933 catch( const uno::RuntimeException& )
3934 {
3935 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
3936 throw;
3937 }
3938 catch( const uno::Exception& )
3939 {
3940 uno::Any aCaught( ::cppu::getCaughtException() );
3941 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
3942
3943 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open storage!",
3944 getXWeak(),
3945 aCaught );
3946 }
3947}
3948
3950 const uno::Reference< lang::XEventListener >& xListener )
3951{
3952 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3953
3954 if ( !m_pImpl )
3955 {
3956 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3957 throw lang::DisposedException( THROW_WHERE );
3958 }
3959
3962}
3963
3965 const uno::Reference< lang::XEventListener >& xListener )
3966{
3967 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3968
3969 if ( !m_pImpl )
3970 {
3971 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3972 throw lang::DisposedException( THROW_WHERE );
3973 }
3974
3977}
3978
3979// XEncryptionProtectedSource
3980
3981void SAL_CALL OStorage::setEncryptionPassword( const OUString& aPass )
3982{
3984}
3985
3987{
3988 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
3989
3990 if ( !m_pImpl )
3991 {
3992 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
3993 throw lang::DisposedException( THROW_WHERE );
3994 }
3995
3996 if ( m_pImpl->m_nStorageType != embed::StorageFormats::PACKAGE )
3997 throw uno::RuntimeException( THROW_WHERE ); // the interface must be visible only for package storage
3998
3999 SAL_WARN_IF( !m_pImpl->m_bIsRoot, "package.xstor", "removeEncryption() method is not available for nonroot storages!" );
4000 if ( !m_pImpl->m_bIsRoot )
4001 return;
4002
4003 try {
4005 }
4006 catch ( const uno::RuntimeException& )
4007 {
4008 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4009 throw;
4010 }
4011 catch ( const uno::Exception& )
4012 {
4013 uno::Any aCaught( ::cppu::getCaughtException() );
4014 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
4015
4016 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4017 getXWeak(),
4018 aCaught );
4019 }
4020
4021 // TODO: check if the password is valid
4022 // update all streams that was encrypted with old password
4023
4024 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4025 try
4026 {
4027 xPackPropSet->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY,
4028 uno::Any( uno::Sequence< beans::NamedValue >() ) );
4029
4032 }
4033 catch( const uno::RuntimeException& )
4034 {
4035 TOOLS_WARN_EXCEPTION( "package.xstor", "The call must not fail, it is pretty simple!" );
4036 throw;
4037 }
4038 catch( const uno::Exception& )
4039 {
4040 TOOLS_WARN_EXCEPTION( "package.xstor", "The call must not fail, it is pretty simple!" );
4041 throw io::IOException( THROW_WHERE );
4042 }
4043}
4044
4045// XEncryptionProtectedSource2
4046
4047void SAL_CALL OStorage::setEncryptionData( const uno::Sequence< beans::NamedValue >& aEncryptionData )
4048{
4049 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4050
4051 if ( !m_pImpl )
4052 {
4053 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4054 throw lang::DisposedException( THROW_WHERE );
4055 }
4056
4057 if ( m_pImpl->m_nStorageType != embed::StorageFormats::PACKAGE )
4058 throw uno::RuntimeException( THROW_WHERE ); // the interface must be visible only for package storage
4059
4060 if ( !aEncryptionData.hasElements() )
4061 throw uno::RuntimeException( THROW_WHERE "Unexpected empty encryption data!" );
4062
4063 SAL_WARN_IF( !m_pImpl->m_bIsRoot, "package.xstor", "setEncryptionData() method is not available for nonroot storages!" );
4064 if ( !m_pImpl->m_bIsRoot )
4065 return;
4066
4067 try {
4069 }
4070 catch ( const uno::RuntimeException& )
4071 {
4072 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4073 throw;
4074 }
4075 catch ( const uno::Exception& )
4076 {
4077 uno::Any aCaught( ::cppu::getCaughtException() );
4078 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
4079
4080 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4081 getXWeak(),
4082 aCaught );
4083 }
4084
4085 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4086 try
4087 {
4088 ::comphelper::SequenceAsHashMap aEncryptionMap( aEncryptionData );
4089 xPackPropSet->setPropertyValue( STORAGE_ENCRYPTION_KEYS_PROPERTY,
4090 uno::Any( aEncryptionMap.getAsConstNamedValueList() ) );
4091
4093 m_pImpl->m_aCommonEncryptionData = aEncryptionMap;
4094 }
4095 catch( const uno::Exception& )
4096 {
4097 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:" );
4098
4099 throw io::IOException( THROW_WHERE );
4100 }
4101}
4102
4104{
4105 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4106
4108}
4109
4110// XEncryptionProtectedStorage
4111
4112void SAL_CALL OStorage::setEncryptionAlgorithms( const uno::Sequence< beans::NamedValue >& aAlgorithms )
4113{
4114 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4115
4116 if ( !m_pImpl )
4117 {
4118 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4119 throw lang::DisposedException( THROW_WHERE );
4120 }
4121
4122 if ( m_pImpl->m_nStorageType != embed::StorageFormats::PACKAGE )
4123 throw uno::RuntimeException( THROW_WHERE ); // the interface must be visible only for package storage
4124
4125 if ( !aAlgorithms.hasElements() )
4126 throw uno::RuntimeException( THROW_WHERE "Unexpected empty encryption algorithms list!" );
4127
4128 SAL_WARN_IF( !m_pImpl->m_bIsRoot, "package.xstor", "setEncryptionAlgorithms() method is not available for nonroot storages!" );
4129 if ( !m_pImpl->m_bIsRoot )
4130 return;
4131
4132 try {
4134 }
4135 catch ( const uno::RuntimeException& )
4136 {
4137 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4138 throw;
4139 }
4140 catch ( const uno::Exception& )
4141 {
4142 uno::Any aCaught( ::cppu::getCaughtException() );
4143 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
4144
4145 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4146 getXWeak(),
4147 aCaught );
4148 }
4149
4150 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4151 try
4152 {
4153 xPackPropSet->setPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY,
4154 uno::Any( aAlgorithms ) );
4155 }
4156 catch ( const uno::RuntimeException& )
4157 {
4158 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4159 throw;
4160 }
4161 catch( const uno::Exception& )
4162 {
4163 uno::Any aCaught( ::cppu::getCaughtException() );
4164 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
4165
4166 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4167 getXWeak(),
4168 aCaught );
4169 }
4170}
4171
4172void SAL_CALL OStorage::setGpgProperties( const uno::Sequence< uno::Sequence< beans::NamedValue > >& aProps )
4173{
4174 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4175
4176 if ( !m_pImpl )
4177 {
4178 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4179 throw lang::DisposedException( THROW_WHERE );
4180 }
4181
4182 if ( m_pImpl->m_nStorageType != embed::StorageFormats::PACKAGE )
4183 throw uno::RuntimeException( THROW_WHERE ); // the interface must be visible only for package storage
4184
4185 if ( !aProps.hasElements() )
4186 throw uno::RuntimeException( THROW_WHERE "Unexpected empty encryption algorithms list!" );
4187
4188 SAL_WARN_IF( !m_pImpl->m_bIsRoot, "package.xstor", "setGpgProperties() method is not available for nonroot storages!" );
4189 if ( !m_pImpl->m_bIsRoot )
4190 return;
4191
4192 try {
4194 }
4195 catch ( const uno::RuntimeException& aRuntimeException )
4196 {
4197 SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException.Message);
4198 throw;
4199 }
4200 catch ( const uno::Exception& )
4201 {
4202 uno::Any aCaught( ::cppu::getCaughtException() );
4203 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
4204
4205 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4206 getXWeak(),
4207 aCaught );
4208 }
4209
4210 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4211 try
4212 {
4213 xPackPropSet->setPropertyValue( ENCRYPTION_GPG_PROPERTIES,
4214 uno::Any( aProps ) );
4215 }
4216 catch ( const uno::RuntimeException& aRuntimeException )
4217 {
4218 SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException.Message);
4219 throw;
4220 }
4221 catch( const uno::Exception& )
4222 {
4223 uno::Any aCaught( ::cppu::getCaughtException() );
4224 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
4225
4226 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4227 getXWeak(),
4228 aCaught );
4229 }
4230}
4231
4232uno::Sequence< beans::NamedValue > SAL_CALL OStorage::getEncryptionAlgorithms()
4233{
4234 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4235
4236 if ( !m_pImpl )
4237 {
4238 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4239 throw lang::DisposedException( THROW_WHERE );
4240 }
4241
4242 if ( m_pImpl->m_nStorageType != embed::StorageFormats::PACKAGE )
4243 throw uno::RuntimeException( THROW_WHERE ); // the interface must be visible only for package storage
4244
4245 uno::Sequence< beans::NamedValue > aResult;
4246 SAL_WARN_IF( !m_pImpl->m_bIsRoot, "package.xstor", "getEncryptionAlgorithms() method is not available for nonroot storages!" );
4247 if ( m_pImpl->m_bIsRoot )
4248 {
4249 try {
4251 }
4252 catch ( const uno::RuntimeException& )
4253 {
4254 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4255 throw;
4256 }
4257 catch ( const uno::Exception& )
4258 {
4259 uno::Any aCaught( ::cppu::getCaughtException() );
4260 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
4261
4262 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4263 getXWeak(),
4264 aCaught );
4265 }
4266
4267 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4268 try
4269 {
4270 xPackPropSet->getPropertyValue( ENCRYPTION_ALGORITHMS_PROPERTY ) >>= aResult;
4271 }
4272 catch ( const uno::RuntimeException& )
4273 {
4274 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4275 throw;
4276 }
4277 catch( const uno::Exception& )
4278 {
4279 uno::Any aCaught( ::cppu::getCaughtException() );
4280 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
4281
4282 throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
4283 getXWeak(),
4284 aCaught );
4285 }
4286 }
4287
4288 return aResult;
4289}
4290
4291// XPropertySet
4292
4293uno::Reference< beans::XPropertySetInfo > SAL_CALL OStorage::getPropertySetInfo()
4294{
4295 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4296
4297 if ( !m_pImpl )
4298 {
4299 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4300 throw lang::DisposedException( THROW_WHERE );
4301 }
4302
4303 //TODO:
4304 return uno::Reference< beans::XPropertySetInfo >();
4305}
4306
4307void SAL_CALL OStorage::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
4308{
4309 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4310
4311 if ( !m_pImpl )
4312 {
4313 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4314 throw lang::DisposedException( THROW_WHERE );
4315 }
4316
4317 //TODO: think about interaction handler
4318
4319 // WORKAROUND:
4320 // The old document might have no version in the manifest.xml, so we have to allow to set the version
4321 // even for readonly storages, so that the version from content.xml can be used.
4322 if ( m_bReadOnlyWrap && aPropertyName != "Version" )
4323 throw uno::RuntimeException( THROW_WHERE ); // TODO: Access denied
4324
4325 if ( m_pImpl->m_nStorageType == embed::StorageFormats::ZIP )
4326 throw beans::UnknownPropertyException( aPropertyName );
4327 else if ( m_pImpl->m_nStorageType == embed::StorageFormats::PACKAGE )
4328 {
4329 if ( aPropertyName == "MediaType" )
4330 {
4331 aValue >>= m_pImpl->m_aMediaType;
4333
4335 m_pImpl->m_bIsModified = true;
4336 }
4337 else if ( aPropertyName == "Version" )
4338 {
4339 aValue >>= m_pImpl->m_aVersion;
4340 m_pImpl->m_bControlVersion = true;
4341
4342 // this property can be set even for readonly storage
4343 if ( !m_bReadOnlyWrap )
4344 {
4346 m_pImpl->m_bIsModified = true;
4347 }
4348 }
4349 else if ( ( m_pImpl->m_bIsRoot && ( aPropertyName == HAS_ENCRYPTED_ENTRIES_PROPERTY
4350 || aPropertyName == HAS_NONENCRYPTED_ENTRIES_PROPERTY
4351 || aPropertyName == IS_INCONSISTENT_PROPERTY
4352 || aPropertyName == "URL"
4353 || aPropertyName == "RepairPackage"
4354 || aPropertyName == ENCRYPTION_GPG_PROPERTIES) )
4355 || aPropertyName == "IsRoot"
4356 || aPropertyName == MEDIATYPE_FALLBACK_USED_PROPERTY )
4357 throw beans::PropertyVetoException( THROW_WHERE );
4358 else
4359 throw beans::UnknownPropertyException( aPropertyName );
4360 }
4361 else if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML )
4362 {
4363 if ( aPropertyName == "RelationsInfoStream" )
4364 {
4365 uno::Reference< io::XInputStream > xInRelStream;
4366 if ( !( aValue >>= xInRelStream ) || !xInRelStream.is() )
4367 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
4368
4369 uno::Reference< io::XSeekable > xSeek( xInRelStream, uno::UNO_QUERY );
4370 if ( !xSeek.is() )
4371 {
4372 // currently this is an internal property that is used for optimization
4373 // and the stream must support XSeekable interface
4374 // TODO/LATER: in future it can be changed if property is used from outside
4375 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
4376 }
4377
4378 m_pImpl->m_xNewRelInfoStream = xInRelStream;
4379 m_pImpl->m_aRelInfo = uno::Sequence< uno::Sequence< beans::StringPair > >();
4382 m_pImpl->m_bIsModified = true;
4383 }
4384 else if ( aPropertyName == "RelationsInfo" )
4385 {
4386 if ( !(aValue >>= m_pImpl->m_aRelInfo) )
4387 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
4388
4392 m_pImpl->m_bIsModified = true;
4393 }
4394 else if ( ( m_pImpl->m_bIsRoot && ( aPropertyName == "URL" || aPropertyName == "RepairPackage") )
4395 || aPropertyName == "IsRoot" )
4396 throw beans::PropertyVetoException( THROW_WHERE );
4397 else
4398 throw beans::UnknownPropertyException( aPropertyName );
4399 }
4400 else
4401 throw beans::UnknownPropertyException( aPropertyName );
4402
4404}
4405
4406uno::Any SAL_CALL OStorage::getPropertyValue( const OUString& aPropertyName )
4407{
4408 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4409
4410 if ( !m_pImpl )
4411 {
4412 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4413 throw lang::DisposedException( THROW_WHERE );
4414 }
4415
4416 if ( m_pImpl->m_nStorageType == embed::StorageFormats::PACKAGE
4417 && ( aPropertyName == "MediaType" || aPropertyName == MEDIATYPE_FALLBACK_USED_PROPERTY || aPropertyName == "Version" ) )
4418 {
4419 try
4420 {
4422 }
4423 catch ( const uno::RuntimeException& )
4424 {
4425 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4426 throw;
4427 }
4428 catch ( const uno::Exception& )
4429 {
4430 uno::Any aCaught( ::cppu::getCaughtException() );
4431 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
4432
4433 throw lang::WrappedTargetException(
4434 "Can't read contents!",
4435 getXWeak(),
4436 aCaught );
4437 }
4438
4439 if ( aPropertyName == "MediaType" )
4440 return uno::Any( m_pImpl->m_aMediaType );
4441 else if ( aPropertyName == "Version" )
4442 return uno::Any( m_pImpl->m_aVersion );
4443 else
4445 }
4446 else if ( aPropertyName == "IsRoot" )
4447 {
4448 return uno::Any( m_pImpl->m_bIsRoot );
4449 }
4450 else if ( aPropertyName == "OpenMode" )
4451 {
4452 return uno::Any( m_pImpl->m_nStorageMode );
4453 }
4454 else if ( m_pImpl->m_bIsRoot )
4455 {
4456 if ( aPropertyName == "URL"
4457 || aPropertyName == "RepairPackage" )
4458 {
4459 auto pProp = std::find_if(std::cbegin(m_pImpl->m_xProperties), std::cend(m_pImpl->m_xProperties),
4460 [&aPropertyName](const css::beans::PropertyValue& rProp) { return rProp.Name == aPropertyName; });
4461 if (pProp != std::cend(m_pImpl->m_xProperties))
4462 return pProp->Value;
4463
4464 if ( aPropertyName == "URL" )
4465 return uno::Any( OUString() );
4466
4467 return uno::Any( false ); // RepairPackage
4468 }
4469 else if ( m_pImpl->m_nStorageType == embed::StorageFormats::PACKAGE
4470 && ( aPropertyName == HAS_ENCRYPTED_ENTRIES_PROPERTY
4471 || aPropertyName == HAS_NONENCRYPTED_ENTRIES_PROPERTY
4472 || aPropertyName == ENCRYPTION_GPG_PROPERTIES
4473 || aPropertyName == IS_INCONSISTENT_PROPERTY ) )
4474 {
4475 try {
4477 uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
4478 return xPackPropSet->getPropertyValue( aPropertyName );
4479 }
4480 catch ( const uno::RuntimeException& )
4481 {
4482 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4483 throw;
4484 }
4485 catch ( const uno::Exception& )
4486 {
4487 uno::Any aCaught( ::cppu::getCaughtException() );
4488 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
4489
4490 throw lang::WrappedTargetException( THROW_WHERE "Can not open package!",
4491 getXWeak(),
4492 aCaught );
4493 }
4494 }
4495 }
4496
4497 throw beans::UnknownPropertyException(aPropertyName);
4498}
4499
4501 const OUString& /*aPropertyName*/,
4502 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
4503{
4504 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4505
4506 if ( !m_pImpl )
4507 {
4508 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4509 throw lang::DisposedException( THROW_WHERE );
4510 }
4511
4512 //TODO:
4513}
4514
4516 const OUString& /*aPropertyName*/,
4517 const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
4518{
4519 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4520
4521 if ( !m_pImpl )
4522 {
4523 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4524 throw lang::DisposedException( THROW_WHERE );
4525 }
4526
4527 //TODO:
4528}
4529
4531 const OUString& /*PropertyName*/,
4532 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
4533{
4534 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4535
4536 if ( !m_pImpl )
4537 {
4538 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4539 throw lang::DisposedException( THROW_WHERE );
4540 }
4541
4542 //TODO:
4543}
4544
4546 const OUString& /*PropertyName*/,
4547 const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
4548{
4549 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4550
4551 if ( !m_pImpl )
4552 {
4553 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4554 throw lang::DisposedException( THROW_WHERE );
4555 }
4556
4557 //TODO:
4558}
4559
4560// XRelationshipAccess
4561
4562// TODO/LATER: the storage and stream implementations of this interface are very similar, they could use a helper class
4563
4564sal_Bool SAL_CALL OStorage::hasByID( const OUString& sID )
4565{
4566 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4567
4568 if ( !m_pImpl )
4569 {
4570 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4571 throw lang::DisposedException( THROW_WHERE );
4572 }
4573
4574 if ( m_pImpl->m_nStorageType != embed::StorageFormats::OFOPXML )
4575 throw uno::RuntimeException( THROW_WHERE );
4576
4577 try
4578 {
4579 getRelationshipByID( sID );
4580 return true;
4581 }
4582 catch( const container::NoSuchElementException& )
4583 {
4584 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4585 }
4586
4587 return false;
4588}
4589
4590namespace
4591{
4592
4593const beans::StringPair* lcl_findPairByName(const uno::Sequence<beans::StringPair>& rSeq, const OUString& rName)
4594{
4595 return std::find_if(rSeq.begin(), rSeq.end(), [&rName](const beans::StringPair& rPair) { return rPair.First == rName; });
4596}
4597
4598}
4599
4600OUString SAL_CALL OStorage::getTargetByID( const OUString& sID )
4601{
4602 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4603
4604 if ( !m_pImpl )
4605 {
4606 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4607 throw lang::DisposedException( THROW_WHERE );
4608 }
4609
4610 if ( m_pImpl->m_nStorageType != embed::StorageFormats::OFOPXML )
4611 throw uno::RuntimeException( THROW_WHERE );
4612
4613 const uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
4614 auto pRel = lcl_findPairByName(aSeq, "Target");
4615 if (pRel != aSeq.end())
4616 return pRel->Second;
4617
4618 return OUString();
4619}
4620
4621OUString SAL_CALL OStorage::getTypeByID( const OUString& sID )
4622{
4623 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4624
4625 if ( !m_pImpl )
4626 {
4627 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4628 throw lang::DisposedException( THROW_WHERE );
4629 }
4630
4631 if ( m_pImpl->m_nStorageType != embed::StorageFormats::OFOPXML )
4632 throw uno::RuntimeException( THROW_WHERE );
4633
4634 const uno::Sequence< beans::StringPair > aSeq = getRelationshipByID( sID );
4635 auto pRel = lcl_findPairByName(aSeq, "Type");
4636 if (pRel != aSeq.end())
4637 return pRel->Second;
4638
4639 return OUString();
4640}
4641
4642uno::Sequence< beans::StringPair > SAL_CALL OStorage::getRelationshipByID( const OUString& sID )
4643{
4644 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4645
4646 if ( !m_pImpl )
4647 {
4648 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4649 throw lang::DisposedException( THROW_WHERE );
4650 }
4651
4652 if ( m_pImpl->m_nStorageType != embed::StorageFormats::OFOPXML )
4653 throw uno::RuntimeException( THROW_WHERE );
4654
4655 // TODO/LATER: in future the unification of the ID could be checked
4656 const uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4657 const beans::StringPair aIDRel("Id", sID);
4658
4659 auto pRel = std::find_if(aSeq.begin(), aSeq.end(),
4660 [&aIDRel](const uno::Sequence<beans::StringPair>& rRel) {
4661 return std::find(rRel.begin(), rRel.end(), aIDRel) != rRel.end(); });
4662 if (pRel != aSeq.end())
4663 return *pRel;
4664
4665 throw container::NoSuchElementException( THROW_WHERE );
4666}
4667
4668uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OStorage::getRelationshipsByType( const OUString& sType )
4669{
4670 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4671
4672 if ( !m_pImpl )
4673 {
4674 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4675 throw lang::DisposedException( THROW_WHERE );
4676 }
4677
4678 if ( m_pImpl->m_nStorageType != embed::StorageFormats::OFOPXML )
4679 throw uno::RuntimeException( THROW_WHERE );
4680
4681 // TODO/LATER: in future the unification of the ID could be checked
4682 const uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4683 std::vector< uno::Sequence< beans::StringPair > > aResult;
4684 aResult.reserve(aSeq.getLength());
4685
4686 std::copy_if(aSeq.begin(), aSeq.end(), std::back_inserter(aResult),
4687 [&sType](const uno::Sequence<beans::StringPair>& rRel) {
4688 auto pRel = lcl_findPairByName(rRel, "Type");
4689 return pRel != rRel.end()
4690 // the type is usually a URL, so the check should be case insensitive
4691 && pRel->Second.equalsIgnoreAsciiCase( sType );
4692 });
4693
4694 return comphelper::containerToSequence(aResult);
4695}
4696
4697uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OStorage::getAllRelationships()
4698{
4699 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4700
4701 if ( !m_pImpl )
4702 {
4703 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4704 throw lang::DisposedException( THROW_WHERE );
4705 }
4706
4707 if ( m_pImpl->m_nStorageType != embed::StorageFormats::OFOPXML )
4708 throw uno::RuntimeException( THROW_WHERE );
4709
4710 uno::Sequence< uno::Sequence< beans::StringPair > > aRet;
4711 try
4712 {
4714 }
4715 catch (const io::IOException&)
4716 {
4717 throw;
4718 }
4719 catch (const uno::RuntimeException&)
4720 {
4721 throw;
4722 }
4723 catch (const uno::Exception &)
4724 {
4725 uno::Any aCaught( ::cppu::getCaughtException() );
4726 throw lang::WrappedTargetRuntimeException(THROW_WHERE "Can't getAllRelationships!",
4727 uno::Reference< uno::XInterface >(),
4728 aCaught);
4729 }
4730
4731 return aRet;
4732}
4733
4734void SAL_CALL OStorage::insertRelationshipByID( const OUString& sID, const uno::Sequence< beans::StringPair >& aEntry, sal_Bool bReplace )
4735{
4736 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4737
4738 if ( !m_pImpl )
4739 {
4740 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4741 throw lang::DisposedException( THROW_WHERE );
4742 }
4743
4744 if ( m_pImpl->m_nStorageType != embed::StorageFormats::OFOPXML )
4745 throw uno::RuntimeException( THROW_WHERE );
4746
4747 const beans::StringPair aIDRel("Id", sID);
4748
4749 uno::Sequence<beans::StringPair>* pResult = nullptr;
4750
4751 // TODO/LATER: in future the unification of the ID could be checked
4752 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4753 for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
4754 {
4755 const auto& rRel = aSeq[nInd];
4756 if (std::find(rRel.begin(), rRel.end(), aIDRel) != rRel.end())
4757 pResult = &aSeq.getArray()[nInd];
4758 }
4759
4760 if ( pResult && !bReplace )
4761 throw container::ElementExistException( THROW_WHERE );
4762
4763 if ( !pResult )
4764 {
4765 const sal_Int32 nIDInd = aSeq.getLength();
4766 aSeq.realloc( nIDInd + 1 );
4767 pResult = &aSeq.getArray()[nIDInd];
4768 }
4769
4770 std::vector<beans::StringPair> aResult;
4771 aResult.reserve(aEntry.getLength() + 1);
4772
4773 aResult.push_back(aIDRel);
4774 std::copy_if(aEntry.begin(), aEntry.end(), std::back_inserter(aResult),
4775 [](const beans::StringPair& rPair) { return rPair.First != "Id"; });
4776
4777 *pResult = comphelper::containerToSequence(aResult);
4778
4782}
4783
4784void SAL_CALL OStorage::removeRelationshipByID( const OUString& sID )
4785{
4786 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4787
4788 if ( !m_pImpl )
4789 {
4790 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4791 throw lang::DisposedException( THROW_WHERE );
4792 }
4793
4794 if ( m_pImpl->m_nStorageType != embed::StorageFormats::OFOPXML )
4795 throw uno::RuntimeException( THROW_WHERE );
4796
4797 uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4798 const beans::StringPair aIDRel("Id", sID);
4799 auto pRel = std::find_if(std::cbegin(aSeq), std::cend(aSeq),
4800 [&aIDRel](const uno::Sequence< beans::StringPair >& rRel) {
4801 return std::find(rRel.begin(), rRel.end(), aIDRel) != rRel.end(); });
4802 if (pRel != std::cend(aSeq))
4803 {
4804 auto nInd = static_cast<sal_Int32>(std::distance(std::cbegin(aSeq), pRel));
4806
4810
4811 // TODO/LATER: in future the unification of the ID could be checked
4812 return;
4813 }
4814
4815 throw container::NoSuchElementException( THROW_WHERE );
4816}
4817
4818void SAL_CALL OStorage::insertRelationships( const uno::Sequence< uno::Sequence< beans::StringPair > >& aEntries, sal_Bool bReplace )
4819{
4820 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4821
4822 if ( !m_pImpl )
4823 {
4824 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4825 throw lang::DisposedException( THROW_WHERE );
4826 }
4827
4828 if ( m_pImpl->m_nStorageType != embed::StorageFormats::OFOPXML )
4829 throw uno::RuntimeException( THROW_WHERE );
4830
4831 OUString aIDTag( "Id" );
4832 const uno::Sequence< uno::Sequence< beans::StringPair > > aSeq = getAllRelationships();
4833 std::vector< uno::Sequence<beans::StringPair> > aResultVec;
4834 aResultVec.reserve(aSeq.getLength() + aEntries.getLength());
4835
4836 std::copy_if(aSeq.begin(), aSeq.end(), std::back_inserter(aResultVec),
4837 [&aIDTag, &aEntries, bReplace](const uno::Sequence<beans::StringPair>& rTargetRel) {
4838 auto pTargetPair = lcl_findPairByName(rTargetRel, aIDTag);
4839 if (pTargetPair == rTargetRel.end())
4840 return false;
4841
4842 bool bIsSourceSame = std::any_of(aEntries.begin(), aEntries.end(),
4843 [&pTargetPair](const uno::Sequence<beans::StringPair>& rSourceEntry) {
4844 return std::find(rSourceEntry.begin(), rSourceEntry.end(), *pTargetPair) != rSourceEntry.end(); });
4845
4846 if ( bIsSourceSame && !bReplace )
4847 throw container::ElementExistException( THROW_WHERE );
4848
4849 // if no such element in the provided sequence
4850 return !bIsSourceSame;
4851 });
4852
4853 std::transform(aEntries.begin(), aEntries.end(), std::back_inserter(aResultVec),
4854 [&aIDTag](const uno::Sequence<beans::StringPair>& rEntry) -> uno::Sequence<beans::StringPair> {
4855 auto pPair = lcl_findPairByName(rEntry, aIDTag);
4856 if (pPair == rEntry.end())
4857 throw io::IOException( THROW_WHERE ); // TODO: illegal relation ( no ID )
4858
4859 auto aResult = comphelper::sequenceToContainer<std::vector<beans::StringPair>>(rEntry);
4860 auto nIDInd = std::distance(rEntry.begin(), pPair);
4861 std::rotate(aResult.begin(), std::next(aResult.begin(), nIDInd), std::next(aResult.begin(), nIDInd + 1));
4862
4863 return comphelper::containerToSequence(aResult);
4864 });
4865
4866 m_pImpl->m_aRelInfo = comphelper::containerToSequence(aResultVec);
4867 m_pImpl->m_xNewRelInfoStream.clear();
4868 m_pImpl->m_nRelInfoStatus = RELINFO_CHANGED;
4869}
4870
4872{
4873 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4874
4875 if ( !m_pImpl )
4876 {
4877 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4878 throw lang::DisposedException( THROW_WHERE );
4879 }
4880
4881 if ( m_pImpl->m_nStorageType != embed::StorageFormats::OFOPXML )
4882 throw uno::RuntimeException( THROW_WHERE );
4883
4884 m_pImpl->m_aRelInfo.realloc( 0 );
4887}
4888
4889// XOptimizedStorage
4891 const OUString& /*sStreamName*/,
4892 const uno::Reference< io::XInputStream >& /*xInStream*/ )
4893{
4894 // not implemented currently because there is still no demand
4895 // might need to be implemented if direct copying of compressed streams is used
4896 throw io::IOException( THROW_WHERE );
4897}
4898
4900 const OUString& aStreamName,
4901 const uno::Reference< io::XInputStream >& xInStream,
4902 const uno::Sequence< beans::PropertyValue >& aProps )
4903{
4904 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4905
4906 if ( !m_pImpl )
4907 {
4908 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4909 throw lang::DisposedException( THROW_WHERE );
4910 }
4911
4912 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, false ) )
4913 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
4914
4915 if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML && aStreamName == "_rels" )
4916 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable storage name
4917
4918 if ( m_bReadOnlyWrap )
4919 throw io::IOException( THROW_WHERE ); // TODO: access denied
4920
4921 try
4922 {
4923 SotElement_Impl* pElement = m_pImpl->FindElement( aStreamName );
4924
4925 if ( pElement )
4926 throw container::ElementExistException( THROW_WHERE );
4927
4928 pElement = OpenStreamElement_Impl( aStreamName, embed::ElementModes::READWRITE, false );
4929 OSL_ENSURE(pElement && pElement->m_xStream, "In case element can not be created an exception must be thrown!");
4930
4931 pElement->m_xStream->InsertStreamDirectly(xInStream, aProps);
4932 }
4933 catch( const embed::InvalidStorageException& )
4934 {
4935 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4936 throw;
4937 }
4938 catch( const lang::IllegalArgumentException& )
4939 {
4940 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4941 throw;
4942 }
4943 catch( const container::ElementExistException& )
4944 {
4945 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4946 throw;
4947 }
4948 catch( const embed::StorageWrappedTargetException& )
4949 {
4950 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4951 throw;
4952 }
4953 catch( const io::IOException& )
4954 {
4955 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4956 throw;
4957 }
4958 catch( const uno::RuntimeException& )
4959 {
4960 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
4961 throw;
4962 }
4963 catch( const uno::Exception& )
4964 {
4965 uno::Any aCaught( ::cppu::getCaughtException() );
4966 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
4967
4968 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't insert stream directly!",
4969 uno::Reference< io::XInputStream >(),
4970 aCaught );
4971 }
4972}
4973
4975 const OUString& aElementName,
4976 const uno::Reference< embed::XOptimizedStorage >& xDest,
4977 const OUString& aNewName )
4978{
4979 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
4980
4981 if ( !m_pImpl )
4982 {
4983 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
4984 throw lang::DisposedException( THROW_WHERE );
4985 }
4986
4987 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, false )
4988 || aNewName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aNewName, false ) )
4989 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
4990
4991 if ( !xDest.is() || xDest == getXWeak() )
4992 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 2 );
4993
4994 if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML && ( aElementName == "_rels" || aNewName == "_rels" ) )
4995 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 ); // unacceptable name
4996
4997 try
4998 {
4999 SotElement_Impl* pElement = m_pImpl->FindElement( aElementName );
5000 if ( !pElement )
5001 throw container::NoSuchElementException( THROW_WHERE );
5002
5003 uno::Reference< XNameAccess > xNameAccess( xDest, uno::UNO_QUERY_THROW );
5004 if ( xNameAccess->hasByName( aNewName ) )
5005 throw container::ElementExistException( THROW_WHERE );
5006
5007 // let the element be copied directly
5008 uno::Reference< embed::XStorage > xStorDest( xDest, uno::UNO_QUERY_THROW );
5009 m_pImpl->CopyStorageElement( pElement, xStorDest, aNewName, true );
5010 }
5011 catch( const embed::InvalidStorageException& )
5012 {
5013 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5014 throw;
5015 }
5016 catch( const lang::IllegalArgumentException& )
5017 {
5018 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5019 throw;
5020 }
5021 catch( const container::NoSuchElementException& )
5022 {
5023 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5024 throw;
5025 }
5026 catch( const container::ElementExistException& )
5027 {
5028 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5029 throw;
5030 }
5031 catch( const embed::StorageWrappedTargetException& )
5032 {
5033 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5034 throw;
5035 }
5036 catch( const io::IOException& )
5037 {
5038 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5039 throw;
5040 }
5041 catch( const uno::RuntimeException& )
5042 {
5043 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5044 throw;
5045 }
5046 catch( const uno::Exception& )
5047 {
5048 uno::Any aCaught( ::cppu::getCaughtException() );
5049 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
5050
5051 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't copy element directly!",
5052 uno::Reference< io::XInputStream >(),
5053 aCaught );
5054 }
5055}
5056
5057void SAL_CALL OStorage::writeAndAttachToStream( const uno::Reference< io::XStream >& xStream )
5058{
5059 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
5060
5061 if ( !m_pImpl )
5062 {
5063 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5064 throw lang::DisposedException( THROW_WHERE );
5065 }
5066
5067 if ( !m_pImpl->m_bIsRoot )
5068 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
5069
5070 if ( !m_pImpl->m_pSwitchStream )
5071 throw uno::RuntimeException( THROW_WHERE );
5072
5073 try
5074 {
5075 m_pImpl->m_pSwitchStream->CopyAndSwitchPersistenceTo( xStream );
5076 }
5077 catch( const embed::InvalidStorageException& )
5078 {
5079 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5080 throw;
5081 }
5082 catch( const lang::IllegalArgumentException& )
5083 {
5084 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5085 throw;
5086 }
5087 catch( const embed::StorageWrappedTargetException& )
5088 {
5089 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5090 throw;
5091 }
5092 catch( const io::IOException& )
5093 {
5094 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:" );
5095 throw;
5096 }
5097 catch( const uno::RuntimeException& )
5098 {
5099 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5100 throw;
5101 }
5102 catch( const uno::Exception& )
5103 {
5104 uno::Any aCaught( ::cppu::getCaughtException() );
5105 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
5106
5107 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't write and attach to stream!",
5108 uno::Reference< io::XInputStream >(),
5109 aCaught );
5110 }
5111
5112}
5113
5114void SAL_CALL OStorage::attachToURL( const OUString& sURL,
5115 sal_Bool bReadOnly )
5116{
5117 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
5118
5119 if ( !m_pImpl )
5120 {
5121 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5122 throw lang::DisposedException( THROW_WHERE );
5123 }
5124
5125 if ( !m_pImpl->m_bIsRoot )
5126 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 0 );
5127
5128 if ( !m_pImpl->m_pSwitchStream )
5129 throw uno::RuntimeException( THROW_WHERE );
5130
5131 uno::Reference < ucb::XSimpleFileAccess3 > xAccess(
5132 ucb::SimpleFileAccess::create( m_pImpl->m_xContext ) );
5133
5134 try
5135 {
5136 if ( bReadOnly )
5137 {
5138 uno::Reference< io::XInputStream > xInputStream = xAccess->openFileRead( sURL );
5139 m_pImpl->m_pSwitchStream->SwitchPersistenceTo( xInputStream );
5140 }
5141 else
5142 {
5143 uno::Reference< io::XStream > xStream = xAccess->openFileReadWrite( sURL );
5144 m_pImpl->m_pSwitchStream->SwitchPersistenceTo( xStream );
5145 }
5146 }
5147 catch( const embed::InvalidStorageException& )
5148 {
5149 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5150 throw;
5151 }
5152 catch( const lang::IllegalArgumentException& )
5153 {
5154 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5155 throw;
5156 }
5157 catch( const embed::StorageWrappedTargetException& )
5158 {
5159 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5160 throw;
5161 }
5162 catch( const io::IOException& )
5163 {
5164 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5165 throw;
5166 }
5167 catch( const uno::RuntimeException& )
5168 {
5169 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5170 throw;
5171 }
5172 catch( const uno::Exception& )
5173 {
5174 uno::Any aCaught( ::cppu::getCaughtException() );
5175 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
5176
5177 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't attach to URL!",
5178 uno::Reference< io::XInputStream >(),
5179 aCaught );
5180 }
5181}
5182
5183uno::Any SAL_CALL OStorage::getElementPropertyValue( const OUString& aElementName, const OUString& aPropertyName )
5184{
5185 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
5186
5187 if ( !m_pImpl )
5188 {
5189 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5190 throw lang::DisposedException( THROW_WHERE );
5191 }
5192
5193 if ( aElementName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aElementName, false ) )
5194 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
5195
5196 if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML && aElementName == "_rels" )
5197 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // TODO: unacceptable name
5198
5199 try
5200 {
5201 SotElement_Impl *pElement = m_pImpl->FindElement( aElementName );
5202 if ( !pElement )
5203 throw container::NoSuchElementException( THROW_WHERE );
5204
5205 // TODO/LATER: Currently it is only implemented for MediaType property of substorages, might be changed in future
5206 if ( !pElement->m_bIsStorage || m_pImpl->m_nStorageType != embed::StorageFormats::PACKAGE || aPropertyName != "MediaType" )
5207 throw beans::PropertyVetoException( THROW_WHERE );
5208
5209 if (!pElement->m_xStorage)
5210 m_pImpl->OpenSubStorage( pElement, embed::ElementModes::READ );
5211
5212 if (!pElement->m_xStorage)
5213 throw io::IOException( THROW_WHERE ); // TODO: general_error
5214
5215 pElement->m_xStorage->ReadContents();
5216 return uno::Any(pElement->m_xStorage->m_aMediaType);
5217 }
5218 catch( const embed::InvalidStorageException& )
5219 {
5220 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5221 throw;
5222 }
5223 catch( const lang::IllegalArgumentException& )
5224 {
5225 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5226 throw;
5227 }
5228 catch( const container::NoSuchElementException& )
5229 {
5230 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5231 throw;
5232 }
5233 catch( const beans::UnknownPropertyException& )
5234 {
5235 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5236 throw;
5237 }
5238 catch( const beans::PropertyVetoException& )
5239 {
5240 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5241 throw;
5242 }
5243 catch( const embed::StorageWrappedTargetException& )
5244 {
5245 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5246 throw;
5247 }
5248 catch( const io::IOException& )
5249 {
5250 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5251 throw;
5252 }
5253 catch( const uno::RuntimeException& )
5254 {
5255 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5256 throw;
5257 }
5258 catch( const uno::Exception& )
5259 {
5260 uno::Any aCaught( ::cppu::getCaughtException() );
5261 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
5262
5263 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't get element property!",
5264 uno::Reference< io::XInputStream >(),
5265 aCaught );
5266 }
5267}
5268
5269void SAL_CALL OStorage::copyStreamElementData( const OUString& aStreamName, const uno::Reference< io::XStream >& xTargetStream )
5270{
5271 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
5272
5273 if ( !m_pImpl )
5274 {
5275 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5276 throw lang::DisposedException( THROW_WHERE );
5277 }
5278
5279 if ( aStreamName.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamName, false ) )
5280 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
5281
5282 if ( m_pImpl->m_nStorageType == embed::StorageFormats::OFOPXML && aStreamName == "_rels" )
5283 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 1 ); // unacceptable name
5284
5285 if ( !xTargetStream.is() )
5286 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 2 );
5287
5288 try
5289 {
5290 uno::Reference< io::XStream > xNonconstRef = xTargetStream;
5291 m_pImpl->CloneStreamElement( aStreamName, false, ::comphelper::SequenceAsHashMap(), xNonconstRef );
5292
5293 SAL_WARN_IF( xNonconstRef != xTargetStream, "package.xstor", "The provided stream reference seems not be filled in correctly!" );
5294 if ( xNonconstRef != xTargetStream )
5295 throw uno::RuntimeException( THROW_WHERE ); // if the stream reference is set it must not be changed!
5296 }
5297 catch( const embed::InvalidStorageException& )
5298 {
5299 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5300 throw;
5301 }
5302 catch( const lang::IllegalArgumentException& )
5303 {
5304 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5305 throw;
5306 }
5307 catch( const packages::WrongPasswordException& )
5308 {
5309 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5310 throw;
5311 }
5312 catch( const io::IOException& )
5313 {
5314 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5315 throw;
5316 }
5317 catch( const embed::StorageWrappedTargetException& )
5318 {
5319 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5320 throw;
5321 }
5322 catch( const uno::RuntimeException& )
5323 {
5324 TOOLS_INFO_EXCEPTION("package.xstor", "Rethrow:");
5325 throw;
5326 }
5327 catch( const uno::Exception& )
5328 {
5329 uno::Any aCaught( ::cppu::getCaughtException() );
5330 SAL_INFO("package.xstor", "Rethrow: " << exceptionToString(aCaught));
5331
5332 throw embed::StorageWrappedTargetException( THROW_WHERE "Can't copy stream data!",
5333 uno::Reference< io::XInputStream >(),
5334 aCaught );
5335 }
5336
5337}
5338
5339// XHierarchicalStorageAccess
5340uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openStreamElementByHierarchicalName( const OUString& aStreamPath, ::sal_Int32 nOpenMode )
5341{
5342 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
5343
5344 if ( !m_pImpl )
5345 {
5346 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5347 throw lang::DisposedException( THROW_WHERE );
5348 }
5349
5350 if ( aStreamPath.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, true ) )
5351 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
5352
5353 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
5354 && ( nOpenMode & embed::ElementModes::WRITE ) )
5355 throw io::IOException( THROW_WHERE ); // Access denied
5356
5357 std::vector<OUString> aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
5358 OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
5359
5360 uno::Reference< embed::XExtendedStorageStream > xResult;
5361 if ( aListPath.size() == 1 )
5362 {
5363 try
5364 {
5365 // that must be a direct request for a stream
5366 // the transacted version of the stream should be opened
5367
5368 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamPath, nOpenMode, false );
5369 assert(pElement && pElement->m_xStream && "In case element can not be created an exception must be thrown!");
5370
5371 xResult.set(pElement->m_xStream->GetStream(nOpenMode, true),
5372 uno::UNO_QUERY_THROW);
5373 }
5374 catch ( const container::NoSuchElementException & )
5375 {
5376 throw io::IOException( THROW_WHERE ); // file not found
5377 }
5378 }
5379 else
5380 {
5381 // there are still storages in between
5382 if ( !m_rHierarchyHolder.is() )
5384 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
5385
5386 xResult = m_rHierarchyHolder->GetStreamHierarchically(
5387 ( m_pImpl->m_nStorageMode & embed::ElementModes::READWRITE ),
5388 aListPath,
5389 nOpenMode );
5390 }
5391
5392 if ( !xResult.is() )
5393 throw uno::RuntimeException( THROW_WHERE );
5394
5395 return xResult;
5396}
5397
5398uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openEncryptedStreamElementByHierarchicalName( const OUString& aStreamPath, ::sal_Int32 nOpenMode, const OUString& sPassword )
5399{
5401}
5402
5403void SAL_CALL OStorage::removeStreamElementByHierarchicalName( const OUString& aStreamPath )
5404{
5405 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
5406
5407 if ( !m_pImpl )
5408 {
5409 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5410 throw lang::DisposedException( THROW_WHERE );
5411 }
5412
5413 if ( aStreamPath.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, true ) )
5414 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
5415
5416 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE ) )
5417 throw io::IOException( THROW_WHERE ); // Access denied
5418
5419 std::vector<OUString> aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
5420 OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
5421
5422 if ( !m_rHierarchyHolder.is() )
5424 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
5425
5426 m_rHierarchyHolder->RemoveStreamHierarchically( aListPath );
5427}
5428
5429// XHierarchicalStorageAccess2
5430uno::Reference< embed::XExtendedStorageStream > SAL_CALL OStorage::openEncryptedStreamByHierarchicalName( const OUString& aStreamPath, ::sal_Int32 nOpenMode, const uno::Sequence< beans::NamedValue >& aEncryptionData )
5431{
5432 ::osl::MutexGuard aGuard( m_xSharedMutex->GetMutex() );
5433
5434 if ( !m_pImpl )
5435 {
5436 SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
5437 throw lang::DisposedException( THROW_WHERE );
5438 }
5439
5440 if ( m_pImpl->m_nStorageType != embed::StorageFormats::PACKAGE )
5441 throw packages::NoEncryptionException( THROW_WHERE );
5442
5443 if ( aStreamPath.isEmpty() || !::comphelper::OStorageHelper::IsValidZipEntryFileName( aStreamPath, true ) )
5444 throw lang::IllegalArgumentException( THROW_WHERE "Unexpected entry name syntax.", uno::Reference< uno::XInterface >(), 1 );
5445
5446 if ( !aEncryptionData.hasElements() )
5447 throw lang::IllegalArgumentException( THROW_WHERE, uno::Reference< uno::XInterface >(), 3 );
5448
5449 if ( !( m_pImpl->m_nStorageMode & embed::ElementModes::WRITE )
5450 && ( nOpenMode & embed::ElementModes::WRITE ) )
5451 throw io::IOException( THROW_WHERE ); // Access denied
5452
5453 std::vector<OUString> aListPath = OHierarchyHolder_Impl::GetListPathFromString( aStreamPath );
5454 OSL_ENSURE( aListPath.size(), "The result list must not be empty!" );
5455
5456 uno::Reference< embed::XExtendedStorageStream > xResult;
5457 if ( aListPath.size() == 1 )
5458 {
5459 // that must be a direct request for a stream
5460 // the transacted version of the stream should be opened
5461
5462 SotElement_Impl *pElement = OpenStreamElement_Impl( aStreamPath, nOpenMode, true );
5463 OSL_ENSURE(pElement && pElement->m_xStream, "In case element can not be created an exception must be thrown!");
5464
5465 xResult.set(pElement->m_xStream->GetStream(nOpenMode, aEncryptionData, true),
5466 uno::UNO_QUERY_THROW);
5467 }
5468 else
5469 {
5470 // there are still storages in between
5471 if ( !m_rHierarchyHolder.is() )
5473 uno::Reference< embed::XStorage >( static_cast< embed::XStorage* >( this ) ) );
5474
5475 xResult = m_rHierarchyHolder->GetStreamHierarchically(
5476 ( m_pImpl->m_nStorageMode & embed::ElementModes::READWRITE ),
5477 aListPath,
5478 nOpenMode,
5479 aEncryptionData );
5480 }
5481
5482 if ( !xResult.is() )
5483 throw uno::RuntimeException( THROW_WHERE );
5484
5485 return xResult;
5486}
5487
5488/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sType
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
Reference< XComponentContext > m_xContext
constexpr OUStringLiteral ENCRYPTION_ALGORITHMS_PROPERTY
#define IS_INCONSISTENT_PROPERTY
#define HAS_NONENCRYPTED_ENTRIES_PROPERTY
constexpr OUStringLiteral MEDIATYPE_FALLBACK_USED_PROPERTY
constexpr OUStringLiteral STORAGE_ENCRYPTION_KEYS_PROPERTY
#define HAS_ENCRYPTED_ENTRIES_PROPERTY
constexpr OUStringLiteral ENCRYPTION_GPG_PROPERTIES
Reference< XInputStream > xStream
constexpr OUStringLiteral sMediaType
static std::vector< OUString > GetListPathFromString(std::u16string_view aPath)
virtual void SAL_CALL addVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: xstorage.cxx:4530
void ChildIsDisposed(const css::uno::Reference< css::uno::XInterface > &xChild)
Definition: xstorage.cxx:1863
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: xstorage.cxx:4293
OStorage_Impl * m_pImpl
Definition: xstorage.hxx:281
virtual void SAL_CALL clearRelationships() override
Definition: xstorage.cxx:4871
virtual void SAL_CALL insertRelationshipByID(const OUString &sID, const css::uno::Sequence< css::beans::StringPair > &aEntry, sal_Bool bReplace) override
Definition: xstorage.cxx:4734
virtual void SAL_CALL release() noexcept override
Definition: xstorage.cxx:2076
virtual css::uno::Type SAL_CALL getElementType() override
Definition: xstorage.cxx:3874
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: xstorage.cxx:2082
virtual void SAL_CALL removeEncryption() override
Definition: xstorage.cxx:3986
virtual void SAL_CALL removeModifyListener(const css::uno::Reference< css::util::XModifyListener > &aListener) override
Definition: xstorage.cxx:3731
virtual css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > SAL_CALL getAllRelationships() override
Definition: xstorage.cxx:4697
virtual void SAL_CALL removeElement(const OUString &aElementName) override
Definition: xstorage.cxx:2745
virtual void SAL_CALL acquire() noexcept override
Definition: xstorage.cxx:2071
virtual css::uno::Reference< css::embed::XExtendedStorageStream > SAL_CALL openEncryptedStreamElementByHierarchicalName(const OUString &sStreamName, ::sal_Int32 nOpenMode, const OUString &sPassword) override
Definition: xstorage.cxx:5398
virtual void SAL_CALL removeTransactionListener(const css::uno::Reference< css::embed::XTransactionListener > &aListener) override
Definition: xstorage.cxx:3658
SotElement_Impl * OpenStreamElement_Impl(const OUString &aStreamName, sal_Int32 nOpenMode, bool bEncr)
Definition: xstorage.cxx:1957
virtual css::uno::Reference< css::io::XStream > SAL_CALL openEncryptedStreamElement(const OUString &aStreamName, sal_Int32 nOpenMode, const OUString &aPass) override
Definition: xstorage.cxx:2289
OStorage(css::uno::Reference< css::io::XInputStream > const &xInputStream, sal_Int32 nMode, const css::uno::Sequence< css::beans::PropertyValue > &xProperties, css::uno::Reference< css::uno::XComponentContext > const &xContext, sal_Int32 nStorageType)
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
Definition: xstorage.cxx:2147
virtual css::uno::Reference< css::embed::XExtendedStorageStream > SAL_CALL openEncryptedStreamByHierarchicalName(const OUString &sStreamName, ::sal_Int32 nOpenMode, const css::uno::Sequence< css::beans::NamedValue > &aEncryptionData) override
Definition: xstorage.cxx:5430
virtual sal_Bool SAL_CALL isStreamElement(const OUString &aElementName) override
Definition: xstorage.cxx:2629
virtual ~OStorage() override
Definition: xstorage.cxx:1776
virtual void SAL_CALL copyLastCommitTo(const css::uno::Reference< css::embed::XStorage > &xTargetStorage) override
Definition: xstorage.cxx:2499
virtual css::uno::Reference< css::embed::XStorage > SAL_CALL openStorageElement(const OUString &aStorName, sal_Int32 nStorageMode) override
Definition: xstorage.cxx:2295
virtual void SAL_CALL insertStreamElementDirect(const OUString &sStreamName, const css::uno::Reference< css::io::XInputStream > &xInStream, const css::uno::Sequence< css::beans::PropertyValue > &aProps) override
Definition: xstorage.cxx:4899
virtual void SAL_CALL insertRelationships(const css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > &aEntries, sal_Bool bReplace) override
Definition: xstorage.cxx:4818
virtual css::uno::Sequence< css::beans::NamedValue > SAL_CALL getEncryptionAlgorithms() override
Definition: xstorage.cxx:4232
virtual void SAL_CALL commit() override
Definition: xstorage.cxx:3520
void MakeLinkToSubComponent_Impl(const css::uno::Reference< css::lang::XComponent > &xComponent)
Definition: xstorage.cxx:1995
virtual css::uno::Sequence< css::beans::StringPair > SAL_CALL getRelationshipByID(const OUString &sID) override
Definition: xstorage.cxx:4642
::rtl::Reference< OChildDispListener_Impl > m_pSubElDispListener
Definition: xstorage.hxx:286
virtual void SAL_CALL setModified(sal_Bool bModified) override
Definition: xstorage.cxx:3690
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: xstorage.cxx:3949
virtual void SAL_CALL renameElement(const OUString &rEleName, const OUString &rNewName) override
Definition: xstorage.cxx:2822
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: xstorage.cxx:3805
virtual sal_Bool SAL_CALL hasEncryptionData() override
Definition: xstorage.cxx:4103
virtual void SAL_CALL moveElementTo(const OUString &aElementName, const css::uno::Reference< css::embed::XStorage > &xDest, const OUString &rNewName) override
Definition: xstorage.cxx:3001
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: xstorage.cxx:3749
virtual void SAL_CALL copyStorageElementLastCommitTo(const OUString &aStorName, const css::uno::Reference< css::embed::XStorage > &xTargetStorage) override
Definition: xstorage.cxx:2551
virtual void SAL_CALL removePropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &aListener) override
Definition: xstorage.cxx:4515
virtual css::uno::Reference< css::io::XStream > SAL_CALL cloneStreamElement(const OUString &aStreamName) override
Definition: xstorage.cxx:2427
virtual sal_Bool SAL_CALL hasElements() override
Definition: xstorage.cxx:3888
virtual css::uno::Reference< css::io::XStream > SAL_CALL openEncryptedStream(const OUString &sStreamName, ::sal_Int32 nOpenMode, const css::uno::Sequence< css::beans::NamedValue > &aEncryptionData) override
Definition: xstorage.cxx:3098
comphelper::OMultiTypeInterfaceContainerHelper2 m_aListenersContainer
Definition: xstorage.hxx:283
void BroadcastTransaction(sal_Int8 nMessage)
Definition: xstorage.cxx:1909
virtual void SAL_CALL attachToURL(const OUString &sURL, sal_Bool bReadOnly) override
Definition: xstorage.cxx:5114
virtual void SAL_CALL addTransactionListener(const css::uno::Reference< css::embed::XTransactionListener > &aListener) override
Definition: xstorage.cxx:3644
::std::optional< ::cppu::OTypeCollection > m_oTypeCollection
Definition: xstorage.hxx:284
void BroadcastModifiedIfNecessary()
Definition: xstorage.cxx:1878
virtual void SAL_CALL insertRawEncrStreamElement(const OUString &aStreamName, const css::uno::Reference< css::io::XInputStream > &xInStream) override
Definition: xstorage.cxx:3442
virtual void SAL_CALL addModifyListener(const css::uno::Reference< css::util::XModifyListener > &aListener) override
Definition: xstorage.cxx:3715
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
Definition: xstorage.cxx:4307
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: xstorage.cxx:4406
virtual css::uno::Reference< css::io::XStream > SAL_CALL cloneEncryptedStreamElement(const OUString &aStreamName, const OUString &aPass) override
Definition: xstorage.cxx:2492
virtual css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > SAL_CALL getRelationshipsByType(const OUString &sType) override
Definition: xstorage.cxx:4668
virtual void SAL_CALL setEncryptionData(const css::uno::Sequence< css::beans::NamedValue > &aEncryptionData) override
Definition: xstorage.cxx:4047
virtual void SAL_CALL removeVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: xstorage.cxx:4545
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getRawEncrStreamElement(const OUString &sStreamName) override
Definition: xstorage.cxx:3343
virtual void SAL_CALL dispose() override
Definition: xstorage.cxx:3919
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getPlainRawStreamElement(const OUString &sStreamName) override
Definition: xstorage.cxx:3253
virtual void SAL_CALL setGpgProperties(const css::uno::Sequence< css::uno::Sequence< css::beans::NamedValue > > &aCryptProps) override
Definition: xstorage.cxx:4172
virtual css::uno::Any SAL_CALL getElementPropertyValue(const OUString &sElementName, const OUString &sPropertyName) override
Definition: xstorage.cxx:5183
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: xstorage.cxx:3964
virtual sal_Bool SAL_CALL hasByID(const OUString &sID) override
Definition: xstorage.cxx:4564
::std::vector< css::uno::WeakReference< css::lang::XComponent > > m_aOpenSubComponentsVector
Definition: xstorage.hxx:287
bool m_bReadOnlyWrap
Definition: xstorage.hxx:285
virtual css::uno::Reference< css::embed::XExtendedStorageStream > SAL_CALL openStreamElementByHierarchicalName(const OUString &sStreamPath, ::sal_Int32 nOpenMode) override
Definition: xstorage.cxx:5340
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
Definition: xstorage.cxx:2012
virtual css::uno::Reference< css::io::XStream > SAL_CALL openStreamElement(const OUString &aStreamName, sal_Int32 nOpenMode) override
Definition: xstorage.cxx:2206
virtual void SAL_CALL copyElementTo(const OUString &aElementName, const css::uno::Reference< css::embed::XStorage > &xDest, const OUString &aNewName) override
Definition: xstorage.cxx:2920
virtual OUString SAL_CALL getTypeByID(const OUString &sID) override
Definition: xstorage.cxx:4621
virtual void SAL_CALL revert() override
Definition: xstorage.cxx:3576
virtual css::uno::Reference< css::io::XStream > SAL_CALL cloneEncryptedStream(const OUString &sStreamName, const css::uno::Sequence< css::beans::NamedValue > &aEncryptionData) override
Definition: xstorage.cxx:3183
virtual void SAL_CALL insertRawNonEncrStreamElementDirect(const OUString &sStreamName, const css::uno::Reference< css::io::XInputStream > &xInStream) override
Definition: xstorage.cxx:4890
virtual void SAL_CALL writeAndAttachToStream(const css::uno::Reference< css::io::XStream > &xStream) override
Definition: xstorage.cxx:5057
virtual OUString SAL_CALL getTargetByID(const OUString &sID) override
Definition: xstorage.cxx:4600
virtual void SAL_CALL addPropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: xstorage.cxx:4500
virtual sal_Bool SAL_CALL isStorageElement(const OUString &aElementName) override
Definition: xstorage.cxx:2687
rtl::Reference< comphelper::RefCountedMutex > m_xSharedMutex
Definition: xstorage.hxx:282
::rtl::Reference< OHierarchyHolder_Impl > m_rHierarchyHolder
Definition: xstorage.hxx:288
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: xstorage.cxx:3835
void InternalDispose(bool bNotifyImpl)
Definition: xstorage.cxx:1792
virtual sal_Bool SAL_CALL isModified() override
Definition: xstorage.cxx:3677
virtual void SAL_CALL setEncryptionAlgorithms(const css::uno::Sequence< css::beans::NamedValue > &aAlgorithms) override
Definition: xstorage.cxx:4112
virtual void SAL_CALL copyElementDirectlyTo(const OUString &sSourceName, const css::uno::Reference< css::embed::XOptimizedStorage > &xTargetStorage, const OUString &sTargetName) override
Definition: xstorage.cxx:4974
virtual void SAL_CALL setEncryptionPassword(const OUString &aPass) override
Definition: xstorage.cxx:3981
virtual void SAL_CALL copyToStorage(const css::uno::Reference< css::embed::XStorage > &xDest) override
Definition: xstorage.cxx:2154
virtual void SAL_CALL removeStreamElementByHierarchicalName(const OUString &sElementPath) override
Definition: xstorage.cxx:5403
virtual void SAL_CALL copyStreamElementData(const OUString &sStreamName, const css::uno::Reference< css::io::XStream > &xTargetStream) override
Definition: xstorage.cxx:5269
virtual void SAL_CALL removeRelationshipByID(const OUString &sID) override
Definition: xstorage.cxx:4784
sal_Int32 GetRefCount_Impl() const
Definition: xstorage.hxx:321
css::uno::XInterface * next()
OInterfaceContainerHelper2 * getContainer(const css::uno::Type &rKey) const
sal_Int32 removeInterface(const css::uno::Type &rKey, const css::uno::Reference< css::uno::XInterface > &rxIFace)
sal_Int32 addInterface(const css::uno::Type &rKey, const css::uno::Reference< css::uno::XInterface > &r)
void disposeAndClear(const css::lang::EventObject &rEvt)
static css::uno::Sequence< css::beans::NamedValue > CreatePackageEncryptionData(std::u16string_view aPassword)
static bool IsValidZipEntryFileName(std::u16string_view aName, bool bSlashAllowed)
static void CopyInputToOutput(const css::uno::Reference< css::io::XInputStream > &xInput, const css::uno::Reference< css::io::XOutputStream > &xOutput)
css::uno::Sequence< css::beans::NamedValue > getAsConstNamedValueList() const
const css::uno::Sequence< sal_Int8 > & getSeq() const
oslInterlockedCount m_refCount
OString exceptionToString(const css::uno::Any &caught)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define TOOLS_INFO_EXCEPTION(area, stream)
uno::Reference< deployment::XPackage > m_xPackage
float u
ScXMLEditAttributeMap::Entry const aEntries[]
bool bReadOnly
Sequence< PropertyValue > aArguments
OUString aName
Sequence< sal_Int8 > aSeq
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
void removeElementAt(css::uno::Sequence< T > &_rSeq, sal_Int32 _nPos)
Any SAL_CALL getCaughtException()
bool PackageEncryptionDataLessOrEqual(const ::comphelper::SequenceAsHashMap &aHash1, const ::comphelper::SequenceAsHashMap &aHash2)
const PropertyStruct aPropNames[]
bool m_bCommited
Definition: xstorage.hxx:121
css::uno::Reference< css::container::XNameContainer > m_xPackageFolder
Definition: xstorage.hxx:136
OStorage_Impl(css::uno::Reference< css::io::XInputStream > const &xInputStream, sal_Int32 nMode, const css::uno::Sequence< css::beans::PropertyValue > &xProperties, css::uno::Reference< css::uno::XComponentContext > const &xContext, sal_Int32 nStorageType)
void Commit()
Definition: xstorage.cxx:940
SotElement_Impl * InsertStorage(const OUString &aName, sal_Int32 nStorageMode)
Definition: xstorage.cxx:1362
bool m_bBroadcastModified
Definition: xstorage.hxx:119
sal_Int16 m_nRelInfoStatus
Definition: xstorage.hxx:167
void OpenSubStream(SotElement_Impl *pElement)
Definition: xstorage.cxx:1432
SotElement_Impl * InsertStream(const OUString &aName, bool bEncr)
Definition: xstorage.cxx:1276
css::uno::Reference< css::io::XInputStream > GetRelInfoStreamForName(std::u16string_view aName)
Definition: xstorage.cxx:1614
void CopyToStorage(const css::uno::Reference< css::embed::XStorage > &xDest, bool bDirect)
Definition: xstorage.cxx:605
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: xstorage.hxx:139
void CopyLastCommitTo(const css::uno::Reference< css::embed::XStorage > &xNewStor)
Definition: xstorage.cxx:909
std::unordered_map< OUString, std::vector< SotElement_Impl * > > m_aChildrenMap
Definition: xstorage.hxx:133
bool m_bMTFallbackUsed
Definition: xstorage.hxx:153
bool HasChildren()
Definition: xstorage.cxx:455
sal_Int32 m_nStorageMode
Definition: xstorage.hxx:117
void GetStorageProperties()
Definition: xstorage.cxx:463
SotElement_Impl * FindElement(const OUString &rName)
Definition: xstorage.cxx:1258
OUString m_aVersion
Definition: xstorage.hxx:156
OStorage_Impl * m_pParent
Definition: xstorage.hxx:149
std::vector< SotElement_Impl * > m_aDeletedVector
Definition: xstorage.hxx:134
SotElement_Impl * m_pRelStorElement
Definition: xstorage.hxx:163
bool m_bControlMediaType
Definition: xstorage.hxx:151
css::uno::Sequence< css::beans::PropertyValue > m_xProperties
Definition: xstorage.hxx:144
SotElement_Impl * InsertElement(const OUString &aName, bool bIsStorage)
Definition: xstorage.cxx:1373
bool m_bListCreated
Definition: xstorage.hxx:124
css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > GetAllRelationshipsIfAny()
Definition: xstorage.cxx:894
bool m_bIsModified
Definition: xstorage.hxx:118
void InsertIntoPackageFolder(const OUString &aName, const css::uno::Reference< css::container::XNameContainer > &xParentPackageFolder)
Definition: xstorage.cxx:928
rtl::Reference< comphelper::RefCountedMutex > m_xMutex
Definition: xstorage.hxx:112
std::unique_ptr< OStorage_Impl > CreateNewStorageImpl(sal_Int32 nStorageMode)
Definition: xstorage.cxx:1341
bool m_bControlVersion
Definition: xstorage.hxx:155
void OpenOwnPackage()
Definition: xstorage.cxx:368
void ReadContents()
Definition: xstorage.cxx:533
rtl::Reference< SwitchablePersistenceStream > m_pSwitchStream
Definition: xstorage.hxx:158
css::uno::Reference< css::embed::XStorage > m_xRelStorage
Definition: xstorage.hxx:164
void RemoveStreamRelInfo(std::u16string_view aOriginalName)
Definition: xstorage.cxx:1553
void CommitStreamRelInfo(std::u16string_view rName, SotElement_Impl const *pStreamElement)
Definition: xstorage.cxx:1592
static void completeStorageStreamCopy_Impl(const css::uno::Reference< css::io::XStream > &xSource, const css::uno::Reference< css::io::XStream > &xDest, sal_Int32 nStorageType, const css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > &aRelInfo)
Definition: xstorage.cxx:73
void ReadRelInfoIfNecessary()
Definition: xstorage.cxx:489
void OpenSubStorage(SotElement_Impl *pElement, sal_Int32 nStorageMode)
Definition: xstorage.cxx:1411
css::uno::Reference< css::lang::XSingleServiceFactory > m_xPackage
Definition: xstorage.hxx:138
css::uno::Sequence< css::uno::Sequence< css::beans::StringPair > > m_aRelInfo
Definition: xstorage.hxx:165
css::uno::Reference< css::io::XStream > m_xStream
Definition: xstorage.hxx:143
void CloneStreamElement(const OUString &aStreamName, bool bPassProvided, const ::comphelper::SequenceAsHashMap &aEncryptionData, css::uno::Reference< css::io::XStream > &xTargetStream)
Definition: xstorage.cxx:1518
::comphelper::SequenceAsHashMap m_aCommonEncryptionData
Definition: xstorage.hxx:146
StorageHoldersType m_aReadOnlyWrapVector
Definition: xstorage.hxx:115
static void ClearElement(SotElement_Impl *pElement)
Definition: xstorage.cxx:1512
OUString m_aMediaType
Definition: xstorage.hxx:152
void RemoveElement(OUString const &rName, SotElement_Impl *pElement)
Definition: xstorage.cxx:1481
sal_Int32 m_nStorageType
Definition: xstorage.hxx:160
::comphelper::SequenceAsHashMap GetCommonRootEncryptionData()
Definition: xstorage.cxx:1235
void SetReadOnlyWrap(OStorage &aStorage)
Definition: xstorage.cxx:339
bool m_bHasCommonEncryptionData
Definition: xstorage.hxx:145
oslInterlockedCount m_nModifiedListenerCount
Count of registered modification listeners.
Definition: xstorage.hxx:127
css::uno::Sequence< OUString > GetElementNames()
Definition: xstorage.cxx:1455
void CopyStorageElement(SotElement_Impl *pElement, const css::uno::Reference< css::embed::XStorage > &xDest, const OUString &aName, bool bDirect)
Definition: xstorage.cxx:691
css::uno::Reference< css::io::XInputStream > m_xInputStream
Definition: xstorage.hxx:142
void CommitRelInfo(const css::uno::Reference< css::container::XNameContainer > &xNewPackageFolder)
Definition: xstorage.cxx:1635
OStorage * m_pAntiImpl
Definition: xstorage.hxx:114
void CreateRelStorage()
Definition: xstorage.cxx:1567
css::uno::Reference< css::io::XInputStream > m_xNewRelInfoStream
Definition: xstorage.hxx:166
void RemoveReadOnlyWrap(const OStorage &aStorage)
Definition: xstorage.cxx:346
void InsertRawStream(const OUString &aName, const css::uno::Reference< css::io::XInputStream > &xInStream)
Definition: xstorage.cxx:1306
SotElement_Impl(OUString aName, bool bStor, bool bNew)
Definition: xstorage.cxx:129
bool m_bIsInserted
Definition: xstorage.hxx:85
std::unique_ptr< OWriteStream_Impl, o3tl::default_delete< OWriteStream_Impl > > m_xStream
Definition: xstorage.hxx:89
std::unique_ptr< OStorage_Impl > m_xStorage
Definition: xstorage.hxx:88
OUString m_aOriginalName
Definition: xstorage.hxx:83
bool hasValue()
WRITE
unsigned char sal_Bool
signed char sal_Int8
static uno::Reference< io::XInputStream > GetSeekableTempCopy(const uno::Reference< io::XInputStream > &xInStream)
Definition: xstorage.cxx:114
#define THROW_WHERE
Definition: xstorage.cxx:67
#define RELINFO_CHANGED
Definition: xstorage.hxx:65
#define STOR_MESS_PREREVERT
Definition: xstorage.hxx:73
#define RELINFO_NO_INIT
Definition: xstorage.hxx:63
#define STOR_MESS_COMMITTED
Definition: xstorage.hxx:72
#define STOR_MESS_REVERTED
Definition: xstorage.hxx:74
#define RELINFO_CHANGED_STREAM_READ
Definition: xstorage.hxx:67
#define RELINFO_BROKEN
Definition: xstorage.hxx:68
#define RELINFO_CHANGED_BROKEN
Definition: xstorage.hxx:69
#define STOR_MESS_PRECOMMIT
Definition: xstorage.hxx:71
#define RELINFO_READ
Definition: xstorage.hxx:64
#define RELINFO_CHANGED_STREAM
Definition: xstorage.hxx:66