Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / svx / source / xml / xmleohlp.cxx
blob6754225356140de73f6f72fa7302bb11f8fb2461
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <stdio.h>
31 #include <com/sun/star/io/XStream.hpp>
32 #include <com/sun/star/embed/XTransactedObject.hpp>
33 #include <com/sun/star/embed/XEmbedObjectCreator.hpp>
34 #include <com/sun/star/embed/XEmbedObjectFactory.hpp>
35 #include <com/sun/star/embed/ElementModes.hpp>
36 #include <com/sun/star/embed/XEmbeddedObject.hpp>
37 #include <com/sun/star/embed/XEmbedPersist.hpp>
38 #include <com/sun/star/embed/EntryInitModes.hpp>
39 #include <com/sun/star/embed/EmbedStates.hpp>
40 #include <com/sun/star/embed/Aspects.hpp>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <tools/debug.hxx>
43 #include <unotools/streamwrap.hxx>
44 #include <unotools/tempfile.hxx>
46 #include <svtools/embedhlp.hxx>
47 #include <unotools/ucbstreamhelper.hxx>
48 #include <comphelper/processfactory.hxx>
49 #include <comphelper/storagehelper.hxx>
50 #include <comphelper/embeddedobjectcontainer.hxx>
52 #include <sot/clsids.hxx>
53 #include <map>
54 #include "svx/xmleohlp.hxx"
56 // -----------
57 // - Defines -
58 // -----------
60 using namespace ::osl;
61 using namespace ::cppu;
62 using namespace ::utl;
63 using namespace ::com::sun::star;
64 using namespace ::com::sun::star::document;
65 using namespace ::com::sun::star::uno;
66 using namespace ::com::sun::star::container;
67 using namespace ::com::sun::star::io;
68 using namespace ::com::sun::star::lang;
70 #define XML_CONTAINERSTORAGE_NAME_60 "Pictures"
71 #define XML_CONTAINERSTORAGE_NAME "ObjectReplacements"
72 #define XML_EMBEDDEDOBJECT_URL_BASE "vnd.sun.star.EmbeddedObject:"
73 #define XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE "vnd.sun.star.GraphicObject:"
75 // -----------------------------------------------------------------------------
77 // -----------------------------------------------------------------------------
79 class OutputStorageWrapper_Impl : public ::cppu::WeakImplHelper1<XOutputStream>
81 ::osl::Mutex maMutex;
82 Reference < XOutputStream > xOut;
83 TempFile aTempFile;
84 sal_Bool bStreamClosed : 1;
85 SvStream* pStream;
87 public:
88 OutputStorageWrapper_Impl();
89 virtual ~OutputStorageWrapper_Impl();
91 // stario::XOutputStream
92 virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData) throw(NotConnectedException, BufferSizeExceededException, RuntimeException);
93 virtual void SAL_CALL flush() throw(NotConnectedException, BufferSizeExceededException, RuntimeException);
94 virtual void SAL_CALL closeOutput() throw(NotConnectedException, BufferSizeExceededException, RuntimeException);
96 SvStream* GetStream();
99 OutputStorageWrapper_Impl::OutputStorageWrapper_Impl()
100 : bStreamClosed( sal_False )
101 , pStream(0)
103 aTempFile.EnableKillingFile();
104 pStream = aTempFile.GetStream( STREAM_READWRITE );
105 xOut = new OOutputStreamWrapper( *pStream );
108 OutputStorageWrapper_Impl::~OutputStorageWrapper_Impl()
112 SvStream *OutputStorageWrapper_Impl::GetStream()
114 if( bStreamClosed )
115 return pStream;
116 return NULL;
119 void SAL_CALL OutputStorageWrapper_Impl::writeBytes(
120 const Sequence< sal_Int8 >& aData)
121 throw(NotConnectedException, BufferSizeExceededException, RuntimeException)
123 MutexGuard aGuard( maMutex );
124 xOut->writeBytes( aData );
127 void SAL_CALL OutputStorageWrapper_Impl::flush()
128 throw(NotConnectedException, BufferSizeExceededException, RuntimeException)
130 MutexGuard aGuard( maMutex );
131 xOut->flush();
134 void SAL_CALL OutputStorageWrapper_Impl::closeOutput()
135 throw(NotConnectedException, BufferSizeExceededException, RuntimeException)
137 MutexGuard aGuard( maMutex );
138 xOut->closeOutput();
139 bStreamClosed = sal_True;
142 // -----------------------------------------------------------------------------
144 struct OUStringLess
146 bool operator() ( const ::rtl::OUString& r1, const ::rtl::OUString& r2 ) const
148 return (r1 < r2) != sal_False;
152 // -----------------------------------------------------------------------------
154 // -----------------------------
155 // - SvXMLEmbeddedObjectHelper -
156 // -----------------------------
157 DBG_NAME(SvXMLEmbeddedObjectHelper)
158 SvXMLEmbeddedObjectHelper::SvXMLEmbeddedObjectHelper() :
159 WeakComponentImplHelper2< XEmbeddedObjectResolver, XNameAccess >( maMutex ),
160 maReplacementGraphicsContainerStorageName( RTL_CONSTASCII_USTRINGPARAM(XML_CONTAINERSTORAGE_NAME) ),
161 maReplacementGraphicsContainerStorageName60( RTL_CONSTASCII_USTRINGPARAM(XML_CONTAINERSTORAGE_NAME_60) ),
162 mpDocPersist( 0 ),
163 meCreateMode( EMBEDDEDOBJECTHELPER_MODE_READ ),
164 mpStreamMap( 0 )
166 DBG_CTOR(SvXMLEmbeddedObjectHelper,NULL);
169 SvXMLEmbeddedObjectHelper::SvXMLEmbeddedObjectHelper( ::comphelper::IEmbeddedHelper& rDocPersist, SvXMLEmbeddedObjectHelperMode eCreateMode ) :
170 WeakComponentImplHelper2< XEmbeddedObjectResolver, XNameAccess >( maMutex ),
171 maReplacementGraphicsContainerStorageName( RTL_CONSTASCII_USTRINGPARAM(XML_CONTAINERSTORAGE_NAME) ),
172 maReplacementGraphicsContainerStorageName60( RTL_CONSTASCII_USTRINGPARAM(XML_CONTAINERSTORAGE_NAME_60) ),
173 mpDocPersist( 0 ),
174 meCreateMode( EMBEDDEDOBJECTHELPER_MODE_READ ),
175 mpStreamMap( 0 )
177 DBG_CTOR(SvXMLEmbeddedObjectHelper,NULL);
178 Init( 0, rDocPersist, eCreateMode );
182 // -----------------------------------------------------------------------------
184 SvXMLEmbeddedObjectHelper::~SvXMLEmbeddedObjectHelper()
186 DBG_DTOR(SvXMLEmbeddedObjectHelper,NULL);
187 if( mpStreamMap )
189 SvXMLEmbeddedObjectHelper_Impl::iterator aIter = mpStreamMap->begin();
190 SvXMLEmbeddedObjectHelper_Impl::iterator aEnd = mpStreamMap->end();
191 for( ; aIter != aEnd; ++aIter )
193 if( aIter->second )
195 aIter->second->release();
196 aIter->second = 0;
199 delete mpStreamMap;
203 // -----------------------------------------------------------------------------
205 void SAL_CALL SvXMLEmbeddedObjectHelper::disposing()
207 Flush();
211 void SvXMLEmbeddedObjectHelper::splitObjectURL(::rtl::OUString aURLNoPar,
212 ::rtl::OUString& rContainerStorageName,
213 ::rtl::OUString& rObjectStorageName)
215 DBG_ASSERT( '#' != aURLNoPar[0], "invalid object URL" );
217 sal_Int32 _nPos = aURLNoPar.lastIndexOf( '/' );
218 if( -1 == _nPos )
220 rContainerStorageName = ::rtl::OUString();
221 rObjectStorageName = aURLNoPar;
223 else
225 //eliminate 'superfluous' slashes at start and end
226 //#i103076# load objects with all allowed xlink:href syntaxes
228 //eliminate './' at start
229 sal_Int32 nStart = 0;
230 sal_Int32 nCount = aURLNoPar.getLength();
231 if( 0 == aURLNoPar.compareToAscii( "./", 2 ) )
233 nStart = 2;
234 nCount -= 2;
237 //eliminate '/' at end
238 sal_Int32 nEnd = aURLNoPar.lastIndexOf( '/' );
239 if( nEnd == aURLNoPar.getLength()-1 && nEnd != (nStart-1) )
240 nCount--;
242 aURLNoPar = aURLNoPar.copy( nStart, nCount );
245 _nPos = aURLNoPar.lastIndexOf( '/' );
246 if( _nPos >= 0 )
247 rContainerStorageName = aURLNoPar.copy( 0, _nPos );
248 rObjectStorageName = aURLNoPar.copy( _nPos+1 );
252 // -----------------------------------------------------------------------------
254 sal_Bool SvXMLEmbeddedObjectHelper::ImplGetStorageNames(
255 const ::rtl::OUString& rURLStr,
256 ::rtl::OUString& rContainerStorageName,
257 ::rtl::OUString& rObjectStorageName,
258 sal_Bool bInternalToExternal,
259 sal_Bool *pGraphicRepl,
260 sal_Bool *pOasisFormat ) const
262 // internal URL: vnd.sun.star.EmbeddedObject:<object-name>
263 // or: vnd.sun.star.EmbeddedObject:<path>/<object-name>
264 // internal replacement images:
265 // vnd.sun.star.EmbeddedObjectGraphic:<object-name>
266 // or: vnd.sun.star.EmbeddedObjectGraphic:<path>/<object-name>
267 // external URL: ./<path>/<object-name>
268 // or: <path>/<object-name>
269 // or: <object-name>
270 // currently, path may only consist of a single directory name
271 // it is also possible to have additional arguments at the end of URL: <main URL>[?<name>=<value>[,<name>=<value>]*]
273 if( pGraphicRepl )
274 *pGraphicRepl = sal_False;
276 if( pOasisFormat )
277 *pOasisFormat = sal_True; // the default value
279 if( rURLStr.isEmpty() )
280 return sal_False;
282 // get rid of arguments
283 sal_Int32 nPos = rURLStr.indexOf( '?' );
284 ::rtl::OUString aURLNoPar;
285 if ( nPos == -1 )
286 aURLNoPar = rURLStr;
287 else
289 aURLNoPar = rURLStr.copy( 0, nPos );
291 // check the arguments
292 nPos++;
293 while( nPos >= 0 && nPos < rURLStr.getLength() )
295 ::rtl::OUString aToken = rURLStr.getToken( 0, ',', nPos );
296 if ( aToken.equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "oasis=false" ) ) ) )
298 if ( pOasisFormat )
299 *pOasisFormat = sal_False;
300 break;
302 else
304 DBG_ASSERT( sal_False, "invalid arguments was found in URL!" );
309 if( bInternalToExternal )
311 nPos = aURLNoPar.indexOf( ':' );
312 if( -1 == nPos )
313 return sal_False;
314 sal_Bool bObjUrl =
315 0 == aURLNoPar.compareToAscii( XML_EMBEDDEDOBJECT_URL_BASE,
316 sizeof( XML_EMBEDDEDOBJECT_URL_BASE ) -1 );
317 sal_Bool bGrUrl = !bObjUrl &&
318 0 == aURLNoPar.compareToAscii( XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE,
319 sizeof( XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE ) -1 );
320 if( !(bObjUrl || bGrUrl) )
321 return sal_False;
323 sal_Int32 nPathStart = nPos + 1;
324 nPos = aURLNoPar.lastIndexOf( '/' );
325 if( -1 == nPos )
327 rContainerStorageName = ::rtl::OUString();
328 rObjectStorageName = aURLNoPar.copy( nPathStart );
330 else if( nPos > nPathStart )
332 rContainerStorageName = aURLNoPar.copy( nPathStart, nPos-nPathStart);
333 rObjectStorageName = aURLNoPar.copy( nPos+1 );
335 else
336 return sal_False;
338 if( bGrUrl )
340 sal_Bool bOASIS = mxRootStorage.is() &&
341 ( SotStorage::GetVersion( mxRootStorage ) > SOFFICE_FILEFORMAT_60 );
342 rContainerStorageName = bOASIS
343 ? maReplacementGraphicsContainerStorageName
344 : maReplacementGraphicsContainerStorageName60;
346 if( pGraphicRepl )
347 *pGraphicRepl = sal_True;
352 else
354 splitObjectURL(aURLNoPar, rContainerStorageName, rObjectStorageName);
357 if( -1 != rContainerStorageName.indexOf( '/' ) )
359 OSL_FAIL( "SvXMLEmbeddedObjectHelper: invalid path name" );
360 return sal_False;
363 return sal_True;
367 // -----------------------------------------------------------------------------
369 uno::Reference < embed::XStorage > SvXMLEmbeddedObjectHelper::ImplGetContainerStorage(
370 const ::rtl::OUString& rStorageName )
372 DBG_ASSERT( -1 == rStorageName.indexOf( '/' ) &&
373 -1 == rStorageName.indexOf( '\\' ),
374 "nested embedded storages aren't supported" );
375 if( !mxContainerStorage.is() ||
376 ( rStorageName != maCurContainerStorageName ) )
378 if( mxContainerStorage.is() &&
379 !maCurContainerStorageName.isEmpty() &&
380 EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode )
382 uno::Reference < embed::XTransactedObject > xTrans( mxContainerStorage, uno::UNO_QUERY );
383 if ( xTrans.is() )
384 xTrans->commit();
387 if( !rStorageName.isEmpty() && mxRootStorage.is() )
389 sal_Int32 nMode = EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode
390 ? ::embed::ElementModes::READWRITE
391 : ::embed::ElementModes::READ;
392 mxContainerStorage = mxRootStorage->openStorageElement( rStorageName,
393 nMode );
395 else
397 mxContainerStorage = mxRootStorage;
399 maCurContainerStorageName = rStorageName;
402 return mxContainerStorage;
405 // -----------------------------------------------------------------------------
407 sal_Bool SvXMLEmbeddedObjectHelper::ImplReadObject(
408 const ::rtl::OUString& rContainerStorageName,
409 ::rtl::OUString& rObjName,
410 const SvGlobalName *pClassId,
411 SvStream* pTemp )
413 (void)pClassId;
415 uno::Reference < embed::XStorage > xDocStor( mpDocPersist->getStorage() );
416 uno::Reference < embed::XStorage > xCntnrStor( ImplGetContainerStorage( rContainerStorageName ) );
418 if( !xCntnrStor.is() && !pTemp )
419 return sal_False;
421 String aSrcObjName( rObjName );
422 comphelper::EmbeddedObjectContainer& rContainer = mpDocPersist->getEmbeddedObjectContainer();
424 // Is the object name unique?
425 // if the object is already instantiated by GetEmbeddedObject
426 // that means that the duplication is being loaded
427 sal_Bool bDuplicate = rContainer.HasInstantiatedEmbeddedObject( rObjName );
428 DBG_ASSERT( !bDuplicate, "An object in the document is referenced twice!" );
430 if( xDocStor != xCntnrStor || pTemp || bDuplicate )
432 // TODO/LATER: make this alltogether a method in the EmbeddedObjectContainer
434 // create a unique name for the duplicate object
435 if( bDuplicate )
436 rObjName = rContainer.CreateUniqueObjectName();
438 if( pTemp )
442 pTemp->Seek( 0 );
443 uno::Reference < io::XStream > xStm = xDocStor->openStreamElement( rObjName,
444 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
445 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xStm );
446 *pTemp >> *pStream;
447 delete pStream;
449 // TODO/LATER: what to do when other types of objects are based on substream persistence?
450 // This is an ole object
451 uno::Reference< beans::XPropertySet > xProps( xStm, uno::UNO_QUERY_THROW );
452 xProps->setPropertyValue(
453 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
454 uno::makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ) ) );
456 xStm->getOutputStream()->closeOutput();
458 catch ( uno::Exception& )
460 return sal_False;
463 else
467 xCntnrStor->copyElementTo( aSrcObjName, xDocStor, rObjName );
469 catch ( uno::Exception& )
471 return sal_False;
476 // make object known to the container
477 // TODO/LATER: could be done a little bit more efficient!
478 ::rtl::OUString aName( rObjName );
480 // TODO/LATER: The provided pClassId is ignored for now.
481 // The stream contains OLE storage internally and this storage already has a class id specifying the
482 // server that was used to create the object. pClassId could be used to specify the server that should
483 // be used for the next opening, but this information seems to be out of the file format responsibility
484 // area.
485 rContainer.GetEmbeddedObject( aName );
487 return sal_True;
490 // -----------------------------------------------------------------------------
492 ::rtl::OUString SvXMLEmbeddedObjectHelper::ImplInsertEmbeddedObjectURL(
493 const ::rtl::OUString& rURLStr )
495 ::rtl::OUString sRetURL;
497 ::rtl::OUString aContainerStorageName, aObjectStorageName;
498 if( !ImplGetStorageNames( rURLStr, aContainerStorageName,
499 aObjectStorageName,
500 EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode ) )
501 return sRetURL;
503 if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
505 OutputStorageWrapper_Impl *pOut = 0;
506 SvXMLEmbeddedObjectHelper_Impl::iterator aIter;
508 if( mpStreamMap )
510 aIter = mpStreamMap->find( rURLStr );
511 if( aIter != mpStreamMap->end() && aIter->second )
512 pOut = aIter->second;
515 SvGlobalName aClassId, *pClassId = 0;
516 sal_Int32 nPos = aObjectStorageName.lastIndexOf( '!' );
517 if( -1 != nPos && aClassId.MakeId( aObjectStorageName.copy( nPos+1 ) ) )
519 aObjectStorageName = aObjectStorageName.copy( 0, nPos );
520 pClassId = &aClassId;
523 ImplReadObject( aContainerStorageName, aObjectStorageName, pClassId, pOut ? pOut->GetStream() : 0 );
524 sRetURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(XML_EMBEDDEDOBJECT_URL_BASE) );
525 sRetURL += aObjectStorageName;
527 if( pOut )
529 mpStreamMap->erase( aIter );
530 pOut->release();
533 else
535 // Objects are written using ::comphelper::IEmbeddedHelper::SaveAs
536 sRetURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("./") );
537 if( !aContainerStorageName.isEmpty() )
539 sRetURL += aContainerStorageName;
540 sRetURL += ::rtl::OUString( '/' );
542 sRetURL += aObjectStorageName;
545 return sRetURL;
548 // -----------------------------------------------------------------------------
550 uno::Reference< io::XInputStream > SvXMLEmbeddedObjectHelper::ImplGetReplacementImage(
551 const uno::Reference< embed::XEmbeddedObject >& xObj )
553 uno::Reference< io::XInputStream > xStream;
555 if( xObj.is() )
559 sal_Bool bSwitchBackToLoaded = sal_False;
560 sal_Int32 nCurState = xObj->getCurrentState();
561 if ( nCurState == embed::EmbedStates::LOADED || nCurState == embed::EmbedStates::RUNNING )
563 // means that the object is not active
564 // copy replacement image from old to new container
565 ::rtl::OUString aMediaType;
566 xStream = mpDocPersist->getEmbeddedObjectContainer().GetGraphicStream( xObj, &aMediaType );
569 if ( !xStream.is() )
571 // the image must be regenerated
572 // TODO/LATER: another aspect could be used
573 if ( nCurState == embed::EmbedStates::LOADED )
574 bSwitchBackToLoaded = sal_True;
576 ::rtl::OUString aMediaType;
577 xStream = svt::EmbeddedObjectRef::GetGraphicReplacementStream(
578 embed::Aspects::MSOLE_CONTENT,
579 xObj,
580 &aMediaType );
583 if ( bSwitchBackToLoaded )
584 // switch back to loaded state; that way we have a minimum cache confusion
585 xObj->changeState( embed::EmbedStates::LOADED );
587 catch( uno::Exception& )
591 return xStream;
594 // -----------------------------------------------------------------------------
596 void SvXMLEmbeddedObjectHelper::Init(
597 const uno::Reference < embed::XStorage >& rRootStorage,
598 ::comphelper::IEmbeddedHelper& rPersist,
599 SvXMLEmbeddedObjectHelperMode eCreateMode )
601 mxRootStorage = rRootStorage;
602 mpDocPersist = &rPersist;
603 meCreateMode = eCreateMode;
606 // -----------------------------------------------------------------------------
608 SvXMLEmbeddedObjectHelper* SvXMLEmbeddedObjectHelper::Create(
609 const uno::Reference < embed::XStorage >& rRootStorage,
610 ::comphelper::IEmbeddedHelper& rDocPersist,
611 SvXMLEmbeddedObjectHelperMode eCreateMode,
612 sal_Bool bDirect )
614 (void)bDirect;
616 SvXMLEmbeddedObjectHelper* pThis = new SvXMLEmbeddedObjectHelper;
618 pThis->acquire();
619 pThis->Init( rRootStorage, rDocPersist, eCreateMode );
621 return pThis;
624 SvXMLEmbeddedObjectHelper* SvXMLEmbeddedObjectHelper::Create(
625 ::comphelper::IEmbeddedHelper& rDocPersist,
626 SvXMLEmbeddedObjectHelperMode eCreateMode )
628 SvXMLEmbeddedObjectHelper* pThis = new SvXMLEmbeddedObjectHelper;
630 pThis->acquire();
631 pThis->Init( 0, rDocPersist, eCreateMode );
633 return pThis;
636 // -----------------------------------------------------------------------------
638 void SvXMLEmbeddedObjectHelper::Destroy(
639 SvXMLEmbeddedObjectHelper* pSvXMLEmbeddedObjectHelper )
641 if( pSvXMLEmbeddedObjectHelper )
643 pSvXMLEmbeddedObjectHelper->dispose();
644 pSvXMLEmbeddedObjectHelper->release();
648 // -----------------------------------------------------------------------------
650 void SvXMLEmbeddedObjectHelper::Flush()
652 if( mxTempStorage.is() )
654 Reference < XComponent > xComp( mxTempStorage, UNO_QUERY );
655 xComp->dispose();
659 // XGraphicObjectResolver: alien objects!
660 ::rtl::OUString SAL_CALL SvXMLEmbeddedObjectHelper::resolveEmbeddedObjectURL( const ::rtl::OUString& aURL )
661 throw(RuntimeException)
663 MutexGuard aGuard( maMutex );
665 return ImplInsertEmbeddedObjectURL( aURL );
668 // XNameAccess: alien objects!
669 Any SAL_CALL SvXMLEmbeddedObjectHelper::getByName(
670 const ::rtl::OUString& rURLStr )
671 throw (NoSuchElementException, WrappedTargetException, RuntimeException)
673 MutexGuard aGuard( maMutex );
674 Any aRet;
675 if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
677 Reference < XOutputStream > xStrm;
678 if( mpStreamMap )
680 SvXMLEmbeddedObjectHelper_Impl::iterator aIter =
681 mpStreamMap->find( rURLStr );
682 if( aIter != mpStreamMap->end() && aIter->second )
683 xStrm = aIter->second;
685 if( !xStrm.is() )
687 OutputStorageWrapper_Impl *pOut = new OutputStorageWrapper_Impl;
688 pOut->acquire();
689 if( !mpStreamMap )
690 mpStreamMap = new SvXMLEmbeddedObjectHelper_Impl;
691 (*mpStreamMap)[rURLStr] = pOut;
692 xStrm = pOut;
695 aRet <<= xStrm;
697 else
699 sal_Bool bGraphicRepl = sal_False;
700 sal_Bool bOasisFormat = sal_True;
701 Reference < XInputStream > xStrm;
702 ::rtl::OUString aContainerStorageName, aObjectStorageName;
703 if( ImplGetStorageNames( rURLStr, aContainerStorageName,
704 aObjectStorageName,
705 sal_True,
706 &bGraphicRepl,
707 &bOasisFormat ) )
711 comphelper::EmbeddedObjectContainer& rContainer =
712 mpDocPersist->getEmbeddedObjectContainer();
714 Reference < embed::XEmbeddedObject > xObj = rContainer.GetEmbeddedObject( aObjectStorageName );
715 DBG_ASSERT( xObj.is(), "Didn't get object" );
717 if( xObj.is() )
719 if( bGraphicRepl )
721 xStrm = ImplGetReplacementImage( xObj );
723 else
725 Reference < embed::XEmbedPersist > xPersist( xObj, UNO_QUERY );
726 if( xPersist.is() )
728 if( !mxTempStorage.is() )
729 mxTempStorage =
730 comphelper::OStorageHelper::GetTemporaryStorage();
731 Sequence < beans::PropertyValue > aDummy( 0 ), aEmbDescr( 1 );
732 aEmbDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StoreVisualReplacement" ) );
733 aEmbDescr[0].Value <<= (sal_Bool)(!bOasisFormat);
734 if ( !bOasisFormat )
736 uno::Reference< io::XInputStream > xGrInStream = ImplGetReplacementImage( xObj );
737 if ( xGrInStream.is() )
739 aEmbDescr.realloc( 2 );
740 aEmbDescr[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VisualReplacement" ) );
741 aEmbDescr[1].Value <<= xGrInStream;
745 xPersist->storeToEntry( mxTempStorage, aObjectStorageName,
746 aDummy, aEmbDescr );
747 Reference < io::XStream > xStream =
748 mxTempStorage->openStreamElement(
749 aObjectStorageName,
750 embed::ElementModes::READ);
751 if( xStream.is() )
752 xStrm = xStream->getInputStream();
757 catch ( uno::Exception& )
762 aRet <<= xStrm;
765 return aRet;
768 Sequence< ::rtl::OUString > SAL_CALL SvXMLEmbeddedObjectHelper::getElementNames()
769 throw (RuntimeException)
771 MutexGuard aGuard( maMutex );
772 return Sequence< ::rtl::OUString >(0);
775 sal_Bool SAL_CALL SvXMLEmbeddedObjectHelper::hasByName( const ::rtl::OUString& rURLStr )
776 throw (RuntimeException)
778 MutexGuard aGuard( maMutex );
779 if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
781 return sal_True;
783 else
785 ::rtl::OUString aContainerStorageName, aObjectStorageName;
786 if( !ImplGetStorageNames( rURLStr, aContainerStorageName,
787 aObjectStorageName,
788 sal_True ) )
789 return sal_False;
791 comphelper::EmbeddedObjectContainer& rContainer = mpDocPersist->getEmbeddedObjectContainer();
792 return !aObjectStorageName.isEmpty() &&
793 rContainer.HasEmbeddedObject( aObjectStorageName );
797 // XNameAccess
798 Type SAL_CALL SvXMLEmbeddedObjectHelper::getElementType()
799 throw (RuntimeException)
801 MutexGuard aGuard( maMutex );
802 if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
803 return ::getCppuType((const Reference<XOutputStream>*)0);
804 else
805 return ::getCppuType((const Reference<XInputStream>*)0);
808 sal_Bool SAL_CALL SvXMLEmbeddedObjectHelper::hasElements()
809 throw (RuntimeException)
811 MutexGuard aGuard( maMutex );
812 if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
814 return sal_True;
816 else
818 comphelper::EmbeddedObjectContainer& rContainer = mpDocPersist->getEmbeddedObjectContainer();
819 return rContainer.HasEmbeddedObjects();
823 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */