xref: /trunk/main/svx/source/xml/xmleohlp.cxx (revision 86e1cf34)
1f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5f6e50924SAndrew Rist  * distributed with this work for additional information
6f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10f6e50924SAndrew Rist  *
11f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12f6e50924SAndrew Rist  *
13f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17f6e50924SAndrew Rist  * specific language governing permissions and limitations
18f6e50924SAndrew Rist  * under the License.
19f6e50924SAndrew Rist  *
20f6e50924SAndrew Rist  *************************************************************/
21f6e50924SAndrew Rist 
22f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <stdio.h>
28cdf0e10cSrcweir #include <com/sun/star/io/XStream.hpp>
29cdf0e10cSrcweir #include <com/sun/star/embed/XTransactedObject.hpp>
30cdf0e10cSrcweir #include <com/sun/star/embed/XEmbedObjectCreator.hpp>
31cdf0e10cSrcweir #include <com/sun/star/embed/XEmbedObjectFactory.hpp>
32cdf0e10cSrcweir #include <com/sun/star/embed/ElementModes.hpp>
33cdf0e10cSrcweir #include <com/sun/star/embed/XEmbeddedObject.hpp>
34cdf0e10cSrcweir #ifndef _COM_SUN_STAR_EMBED_XEMBED_PERSIST_HPP_
35cdf0e10cSrcweir #include <com/sun/star/embed/XEmbedPersist.hpp>
36cdf0e10cSrcweir #endif
37cdf0e10cSrcweir #include <com/sun/star/embed/EntryInitModes.hpp>
38cdf0e10cSrcweir #include <com/sun/star/embed/EmbedStates.hpp>
39cdf0e10cSrcweir #include <com/sun/star/embed/Aspects.hpp>
40cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
41cdf0e10cSrcweir #include <tools/debug.hxx>
42cdf0e10cSrcweir #include <unotools/streamwrap.hxx>
43cdf0e10cSrcweir #include <unotools/tempfile.hxx>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #include <svtools/embedhlp.hxx>
46cdf0e10cSrcweir #include <unotools/ucbstreamhelper.hxx>
47cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
48cdf0e10cSrcweir #include <comphelper/storagehelper.hxx>
49cdf0e10cSrcweir #include <comphelper/embeddedobjectcontainer.hxx>
50cdf0e10cSrcweir 
51cdf0e10cSrcweir #ifndef _SO_CLSIDS_HXX
52cdf0e10cSrcweir #include <sot/clsids.hxx>
53cdf0e10cSrcweir #endif
54cdf0e10cSrcweir #include <map>
55cdf0e10cSrcweir #include "svx/xmleohlp.hxx"
56cdf0e10cSrcweir 
57cdf0e10cSrcweir // -----------
58cdf0e10cSrcweir // - Defines -
59cdf0e10cSrcweir // -----------
60cdf0e10cSrcweir 
61cdf0e10cSrcweir using namespace ::osl;
62cdf0e10cSrcweir using namespace ::cppu;
63cdf0e10cSrcweir using namespace ::utl;
64cdf0e10cSrcweir using namespace ::com::sun::star;
65cdf0e10cSrcweir using namespace ::com::sun::star::document;
66cdf0e10cSrcweir using namespace ::com::sun::star::uno;
67cdf0e10cSrcweir using namespace ::com::sun::star::container;
68cdf0e10cSrcweir using namespace ::com::sun::star::io;
69cdf0e10cSrcweir using namespace ::com::sun::star::lang;
70cdf0e10cSrcweir 
71cdf0e10cSrcweir #define XML_CONTAINERSTORAGE_NAME_60		"Pictures"
72cdf0e10cSrcweir #define XML_CONTAINERSTORAGE_NAME		"ObjectReplacements"
73cdf0e10cSrcweir #define XML_EMBEDDEDOBJECT_URL_BASE		"vnd.sun.star.EmbeddedObject:"
74cdf0e10cSrcweir #define XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE		"vnd.sun.star.GraphicObject:"
75cdf0e10cSrcweir 
76cdf0e10cSrcweir // -----------------------------------------------------------------------------
77cdf0e10cSrcweir 
78cdf0e10cSrcweir // -----------------------------------------------------------------------------
79cdf0e10cSrcweir 
80cdf0e10cSrcweir class OutputStorageWrapper_Impl : public ::cppu::WeakImplHelper1<XOutputStream>
81cdf0e10cSrcweir {
82cdf0e10cSrcweir 	::osl::Mutex	maMutex;
83cdf0e10cSrcweir 	Reference < XOutputStream > xOut;
84cdf0e10cSrcweir 	TempFile aTempFile;
85cdf0e10cSrcweir 	sal_Bool bStreamClosed : 1;
86cdf0e10cSrcweir     SvStream* pStream;
87cdf0e10cSrcweir 
88cdf0e10cSrcweir public:
89cdf0e10cSrcweir 	OutputStorageWrapper_Impl();
90cdf0e10cSrcweir 	virtual ~OutputStorageWrapper_Impl();
91cdf0e10cSrcweir 
92cdf0e10cSrcweir // stario::XOutputStream
93cdf0e10cSrcweir 	virtual void SAL_CALL writeBytes(const Sequence< sal_Int8 >& aData) throw(NotConnectedException, BufferSizeExceededException, RuntimeException);
94cdf0e10cSrcweir 	virtual void SAL_CALL flush() throw(NotConnectedException, BufferSizeExceededException, RuntimeException);
95cdf0e10cSrcweir 	virtual void SAL_CALL closeOutput() throw(NotConnectedException, BufferSizeExceededException, RuntimeException);
96cdf0e10cSrcweir 
97cdf0e10cSrcweir     SvStream*   GetStream();
98cdf0e10cSrcweir };
99cdf0e10cSrcweir 
OutputStorageWrapper_Impl()100cdf0e10cSrcweir OutputStorageWrapper_Impl::OutputStorageWrapper_Impl()
101cdf0e10cSrcweir     : bStreamClosed( sal_False )
102cdf0e10cSrcweir     , pStream(0)
103cdf0e10cSrcweir {
104cdf0e10cSrcweir 	aTempFile.EnableKillingFile();
105cdf0e10cSrcweir     pStream = aTempFile.GetStream( STREAM_READWRITE );
106cdf0e10cSrcweir 	xOut = new OOutputStreamWrapper( *pStream );
107cdf0e10cSrcweir }
108cdf0e10cSrcweir 
~OutputStorageWrapper_Impl()109cdf0e10cSrcweir OutputStorageWrapper_Impl::~OutputStorageWrapper_Impl()
110cdf0e10cSrcweir {
111cdf0e10cSrcweir }
112cdf0e10cSrcweir 
GetStream()113cdf0e10cSrcweir SvStream *OutputStorageWrapper_Impl::GetStream()
114cdf0e10cSrcweir {
115cdf0e10cSrcweir     if( bStreamClosed )
116cdf0e10cSrcweir         return pStream;
117cdf0e10cSrcweir     return NULL;
118cdf0e10cSrcweir }
119cdf0e10cSrcweir 
writeBytes(const Sequence<sal_Int8> & aData)120cdf0e10cSrcweir void SAL_CALL OutputStorageWrapper_Impl::writeBytes(
121cdf0e10cSrcweir 		const Sequence< sal_Int8 >& aData)
122cdf0e10cSrcweir 	throw(NotConnectedException, BufferSizeExceededException, RuntimeException)
123cdf0e10cSrcweir {
124cdf0e10cSrcweir 	MutexGuard			aGuard( maMutex );
125cdf0e10cSrcweir 	xOut->writeBytes( aData );
126cdf0e10cSrcweir }
127cdf0e10cSrcweir 
flush()128cdf0e10cSrcweir void SAL_CALL OutputStorageWrapper_Impl::flush()
129cdf0e10cSrcweir 	throw(NotConnectedException, BufferSizeExceededException, RuntimeException)
130cdf0e10cSrcweir {
131cdf0e10cSrcweir 	MutexGuard			aGuard( maMutex );
132cdf0e10cSrcweir 	xOut->flush();
133cdf0e10cSrcweir }
134cdf0e10cSrcweir 
closeOutput()135cdf0e10cSrcweir void SAL_CALL OutputStorageWrapper_Impl::closeOutput()
136cdf0e10cSrcweir 	throw(NotConnectedException, BufferSizeExceededException, RuntimeException)
137cdf0e10cSrcweir {
138cdf0e10cSrcweir 	MutexGuard			aGuard( maMutex );
139cdf0e10cSrcweir 	xOut->closeOutput();
140cdf0e10cSrcweir 	bStreamClosed = sal_True;
141cdf0e10cSrcweir }
142cdf0e10cSrcweir 
143cdf0e10cSrcweir // -----------------------------------------------------------------------------
144cdf0e10cSrcweir 
145cdf0e10cSrcweir struct OUStringLess
146cdf0e10cSrcweir {
operator ()OUStringLess147cdf0e10cSrcweir 	bool operator() ( const ::rtl::OUString& r1, const ::rtl::OUString& r2 ) const
148cdf0e10cSrcweir 	{
149cdf0e10cSrcweir 		return (r1 < r2) != sal_False;
150cdf0e10cSrcweir 	}
151cdf0e10cSrcweir };
152cdf0e10cSrcweir 
153cdf0e10cSrcweir // -----------------------------------------------------------------------------
154cdf0e10cSrcweir 
155cdf0e10cSrcweir // -----------------------------
156cdf0e10cSrcweir // - SvXMLEmbeddedObjectHelper -
157cdf0e10cSrcweir // -----------------------------
DBG_NAME(SvXMLEmbeddedObjectHelper)158cdf0e10cSrcweir DBG_NAME(SvXMLEmbeddedObjectHelper)
159cdf0e10cSrcweir SvXMLEmbeddedObjectHelper::SvXMLEmbeddedObjectHelper() :
160cdf0e10cSrcweir 	WeakComponentImplHelper2< XEmbeddedObjectResolver, XNameAccess >( maMutex ),
161cdf0e10cSrcweir 	maReplacementGraphicsContainerStorageName( RTL_CONSTASCII_USTRINGPARAM(XML_CONTAINERSTORAGE_NAME) ),
162cdf0e10cSrcweir 	maReplacementGraphicsContainerStorageName60( RTL_CONSTASCII_USTRINGPARAM(XML_CONTAINERSTORAGE_NAME_60) ),
163cdf0e10cSrcweir 	mpDocPersist( 0 ),
164cdf0e10cSrcweir 	meCreateMode( EMBEDDEDOBJECTHELPER_MODE_READ ),
165cdf0e10cSrcweir 	mpStreamMap( 0 )
166cdf0e10cSrcweir {
167cdf0e10cSrcweir     DBG_CTOR(SvXMLEmbeddedObjectHelper,NULL);
168cdf0e10cSrcweir }
169cdf0e10cSrcweir 
SvXMLEmbeddedObjectHelper(::comphelper::IEmbeddedHelper & rDocPersist,SvXMLEmbeddedObjectHelperMode eCreateMode)170cdf0e10cSrcweir SvXMLEmbeddedObjectHelper::SvXMLEmbeddedObjectHelper( ::comphelper::IEmbeddedHelper& rDocPersist, SvXMLEmbeddedObjectHelperMode eCreateMode ) :
171cdf0e10cSrcweir 	WeakComponentImplHelper2< XEmbeddedObjectResolver, XNameAccess >( maMutex ),
172cdf0e10cSrcweir 	maReplacementGraphicsContainerStorageName( RTL_CONSTASCII_USTRINGPARAM(XML_CONTAINERSTORAGE_NAME) ),
173cdf0e10cSrcweir 	maReplacementGraphicsContainerStorageName60( RTL_CONSTASCII_USTRINGPARAM(XML_CONTAINERSTORAGE_NAME_60) ),
174cdf0e10cSrcweir 	mpDocPersist( 0 ),
175cdf0e10cSrcweir 	meCreateMode( EMBEDDEDOBJECTHELPER_MODE_READ ),
176cdf0e10cSrcweir 	mpStreamMap( 0 )
177cdf0e10cSrcweir {
178cdf0e10cSrcweir     DBG_CTOR(SvXMLEmbeddedObjectHelper,NULL);
179cdf0e10cSrcweir 	Init( 0, rDocPersist, eCreateMode );
180cdf0e10cSrcweir }
181cdf0e10cSrcweir 
182cdf0e10cSrcweir 
183cdf0e10cSrcweir // -----------------------------------------------------------------------------
184cdf0e10cSrcweir 
~SvXMLEmbeddedObjectHelper()185cdf0e10cSrcweir SvXMLEmbeddedObjectHelper::~SvXMLEmbeddedObjectHelper()
186cdf0e10cSrcweir {
187cdf0e10cSrcweir     DBG_DTOR(SvXMLEmbeddedObjectHelper,NULL);
188cdf0e10cSrcweir 	if( mpStreamMap )
189cdf0e10cSrcweir 	{
190cdf0e10cSrcweir 		SvXMLEmbeddedObjectHelper_Impl::iterator aIter = mpStreamMap->begin();
191cdf0e10cSrcweir 		SvXMLEmbeddedObjectHelper_Impl::iterator aEnd = mpStreamMap->end();
192cdf0e10cSrcweir 		for( ; aIter != aEnd; aIter++ )
193cdf0e10cSrcweir 		{
194cdf0e10cSrcweir 			if( aIter->second )
195cdf0e10cSrcweir 			{
196cdf0e10cSrcweir 				aIter->second->release();
197cdf0e10cSrcweir 				aIter->second = 0;
198cdf0e10cSrcweir 			}
199cdf0e10cSrcweir 		}
200cdf0e10cSrcweir 	}
201cdf0e10cSrcweir }
202cdf0e10cSrcweir 
203cdf0e10cSrcweir // -----------------------------------------------------------------------------
204cdf0e10cSrcweir 
disposing()205cdf0e10cSrcweir void SAL_CALL SvXMLEmbeddedObjectHelper::disposing()
206cdf0e10cSrcweir {
207cdf0e10cSrcweir 	Flush();
208cdf0e10cSrcweir }
209cdf0e10cSrcweir 
210cdf0e10cSrcweir // -----------------------------------------------------------------------------
211cdf0e10cSrcweir 
ImplGetStorageNames(const::rtl::OUString & rURLStr,::rtl::OUString & rContainerStorageName,::rtl::OUString & rObjectStorageName,sal_Bool bInternalToExternal,sal_Bool * pGraphicRepl,sal_Bool * pOasisFormat) const212cdf0e10cSrcweir sal_Bool SvXMLEmbeddedObjectHelper::ImplGetStorageNames(
213cdf0e10cSrcweir 		const ::rtl::OUString& rURLStr,
214cdf0e10cSrcweir 		::rtl::OUString& rContainerStorageName,
215cdf0e10cSrcweir 		::rtl::OUString& rObjectStorageName,
216cdf0e10cSrcweir 		sal_Bool bInternalToExternal,
217cdf0e10cSrcweir 	    sal_Bool *pGraphicRepl,
218cdf0e10cSrcweir 		sal_Bool *pOasisFormat ) const
219cdf0e10cSrcweir {
220cdf0e10cSrcweir 	// internal URL: vnd.sun.star.EmbeddedObject:<object-name>
221cdf0e10cSrcweir 	// 			 or: vnd.sun.star.EmbeddedObject:<path>/<object-name>
222cdf0e10cSrcweir 	// internal replacement images:
223cdf0e10cSrcweir 	//				 vnd.sun.star.EmbeddedObjectGraphic:<object-name>
224cdf0e10cSrcweir 	// 			 or: vnd.sun.star.EmbeddedObjectGraphic:<path>/<object-name>
225cdf0e10cSrcweir 	// external URL: ./<path>/<object-name>
226cdf0e10cSrcweir 	// 			 or: <path>/<object-name>
227cdf0e10cSrcweir 	// 			 or: <object-name>
228cdf0e10cSrcweir 	// currently, path may only consist of a single directory name
229cdf0e10cSrcweir 	// it is also possible to have additional arguments at the end of URL: <main URL>[?<name>=<value>[,<name>=<value>]*]
230cdf0e10cSrcweir 
231cdf0e10cSrcweir 	if( pGraphicRepl )
232cdf0e10cSrcweir 		*pGraphicRepl = sal_False;
233cdf0e10cSrcweir 
234cdf0e10cSrcweir 	if( pOasisFormat )
235cdf0e10cSrcweir 		*pOasisFormat = sal_True; // the default value
236cdf0e10cSrcweir 
237cdf0e10cSrcweir 	if( !rURLStr.getLength() )
238cdf0e10cSrcweir 		return sal_False;
239cdf0e10cSrcweir 
240cdf0e10cSrcweir 	// get rid of arguments
241cdf0e10cSrcweir 	sal_Int32 nPos = rURLStr.indexOf( '?' );
242cdf0e10cSrcweir 	::rtl::OUString aURLNoPar;
243cdf0e10cSrcweir 	if ( nPos == -1 )
244cdf0e10cSrcweir 		aURLNoPar = rURLStr;
245cdf0e10cSrcweir 	else
246cdf0e10cSrcweir 	{
247cdf0e10cSrcweir 		aURLNoPar = rURLStr.copy( 0, nPos );
248cdf0e10cSrcweir 
249cdf0e10cSrcweir 		// check the arguments
250cdf0e10cSrcweir 		nPos++;
251cdf0e10cSrcweir 		while( nPos >= 0 && nPos < rURLStr.getLength() )
252cdf0e10cSrcweir 		{
253cdf0e10cSrcweir 			::rtl::OUString aToken = rURLStr.getToken( 0, ',', nPos );
254cdf0e10cSrcweir 			if ( aToken.equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "oasis=false" ) ) ) )
255cdf0e10cSrcweir 			{
256cdf0e10cSrcweir 				if ( pOasisFormat )
257cdf0e10cSrcweir 					*pOasisFormat = sal_False;
258cdf0e10cSrcweir 				break;
259cdf0e10cSrcweir 			}
260cdf0e10cSrcweir 			else
261cdf0e10cSrcweir 			{
262cdf0e10cSrcweir 				DBG_ASSERT( sal_False, "invalid arguments was found in URL!" );
263cdf0e10cSrcweir 			}
264cdf0e10cSrcweir 		}
265cdf0e10cSrcweir 	}
266cdf0e10cSrcweir 
267cdf0e10cSrcweir 	if( bInternalToExternal )
268cdf0e10cSrcweir 	{
269cdf0e10cSrcweir 		nPos = aURLNoPar.indexOf( ':' );
270cdf0e10cSrcweir 		if( -1 == nPos )
271cdf0e10cSrcweir 			return sal_False;
272cdf0e10cSrcweir 		sal_Bool bObjUrl =
273cdf0e10cSrcweir 			0 == aURLNoPar.compareToAscii( XML_EMBEDDEDOBJECT_URL_BASE,
274cdf0e10cSrcweir 								 sizeof( XML_EMBEDDEDOBJECT_URL_BASE ) -1 );
275cdf0e10cSrcweir 		sal_Bool bGrUrl = !bObjUrl &&
276cdf0e10cSrcweir 		  	0 == aURLNoPar.compareToAscii( XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE,
277cdf0e10cSrcweir 						 sizeof( XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE ) -1 );
278cdf0e10cSrcweir 		if( !(bObjUrl || bGrUrl) )
279cdf0e10cSrcweir 			return sal_False;
280cdf0e10cSrcweir 
281cdf0e10cSrcweir 		sal_Int32 nPathStart = nPos + 1;
282cdf0e10cSrcweir 		nPos = aURLNoPar.lastIndexOf( '/' );
283cdf0e10cSrcweir 		if( -1 == nPos )
284cdf0e10cSrcweir 		{
285cdf0e10cSrcweir 			rContainerStorageName = ::rtl::OUString();
286cdf0e10cSrcweir 			rObjectStorageName = aURLNoPar.copy( nPathStart );
287cdf0e10cSrcweir 		}
288cdf0e10cSrcweir 		else if( nPos > nPathStart )
289cdf0e10cSrcweir 		{
290cdf0e10cSrcweir 			rContainerStorageName = aURLNoPar.copy( nPathStart, nPos-nPathStart);
291cdf0e10cSrcweir 			rObjectStorageName = aURLNoPar.copy( nPos+1 );
292cdf0e10cSrcweir 		}
293cdf0e10cSrcweir 		else
294cdf0e10cSrcweir 			return sal_False;
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 		if( bGrUrl )
297cdf0e10cSrcweir 		{
298cdf0e10cSrcweir 			sal_Bool bOASIS = mxRootStorage.is() &&
299cdf0e10cSrcweir 				( SotStorage::GetVersion( mxRootStorage ) > SOFFICE_FILEFORMAT_60 );
300cdf0e10cSrcweir 			rContainerStorageName = bOASIS
301cdf0e10cSrcweir 					? maReplacementGraphicsContainerStorageName
302cdf0e10cSrcweir 					: maReplacementGraphicsContainerStorageName60;
303cdf0e10cSrcweir 
304cdf0e10cSrcweir 			if( pGraphicRepl )
305cdf0e10cSrcweir 				*pGraphicRepl = sal_True;
306cdf0e10cSrcweir 		}
307cdf0e10cSrcweir 
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 	}
310cdf0e10cSrcweir 	else
311cdf0e10cSrcweir 	{
312cdf0e10cSrcweir 		DBG_ASSERT( '#' != aURLNoPar[0], "invalid object URL" );
313cdf0e10cSrcweir 
314cdf0e10cSrcweir 		sal_Int32 _nPos = aURLNoPar.lastIndexOf( '/' );
315cdf0e10cSrcweir 		if( -1 == _nPos )
316cdf0e10cSrcweir 		{
317cdf0e10cSrcweir 			rContainerStorageName = ::rtl::OUString();
318cdf0e10cSrcweir 			rObjectStorageName = aURLNoPar;
319cdf0e10cSrcweir 		}
320cdf0e10cSrcweir 		else
321cdf0e10cSrcweir 		{
322cdf0e10cSrcweir             //eliminate 'superfluous' slashes at start and end
323cdf0e10cSrcweir             //#i103076# load objects with all allowed xlink:href syntaxes
324cdf0e10cSrcweir             {
325cdf0e10cSrcweir                 //eliminate './' at start
326cdf0e10cSrcweir 			    sal_Int32 nStart = 0;
327cdf0e10cSrcweir                 sal_Int32 nCount = aURLNoPar.getLength();
328cdf0e10cSrcweir 			    if( 0 == aURLNoPar.compareToAscii( "./", 2 ) )
329cdf0e10cSrcweir                 {
330cdf0e10cSrcweir 				    nStart = 2;
331cdf0e10cSrcweir                     nCount -= 2;
332cdf0e10cSrcweir                 }
333cdf0e10cSrcweir 
334cdf0e10cSrcweir                 //eliminate '/' at end
335cdf0e10cSrcweir                 sal_Int32 nEnd = aURLNoPar.lastIndexOf( '/' );
336cdf0e10cSrcweir                 if( nEnd == aURLNoPar.getLength()-1 && nEnd != (nStart-1) )
337cdf0e10cSrcweir                     nCount--;
338cdf0e10cSrcweir 
339cdf0e10cSrcweir                 aURLNoPar = aURLNoPar.copy( nStart, nCount );
340cdf0e10cSrcweir             }
341cdf0e10cSrcweir 
342cdf0e10cSrcweir             _nPos = aURLNoPar.lastIndexOf( '/' );
343cdf0e10cSrcweir             if( _nPos >= 0 )
344cdf0e10cSrcweir 				rContainerStorageName = aURLNoPar.copy( 0, _nPos );
345cdf0e10cSrcweir 			rObjectStorageName = aURLNoPar.copy( _nPos+1 );
346cdf0e10cSrcweir 		}
347cdf0e10cSrcweir 	}
348cdf0e10cSrcweir 
349cdf0e10cSrcweir 	if( -1 != rContainerStorageName.indexOf( '/' ) )
350cdf0e10cSrcweir 	{
351cdf0e10cSrcweir 		DBG_ERROR( "SvXMLEmbeddedObjectHelper: invalid path name" );
352cdf0e10cSrcweir 		return sal_False;
353cdf0e10cSrcweir 	}
354cdf0e10cSrcweir 
355cdf0e10cSrcweir 	return sal_True;
356cdf0e10cSrcweir }
357cdf0e10cSrcweir 
358cdf0e10cSrcweir 
359cdf0e10cSrcweir // -----------------------------------------------------------------------------
360cdf0e10cSrcweir 
ImplGetContainerStorage(const::rtl::OUString & rStorageName)361cdf0e10cSrcweir uno::Reference < embed::XStorage > SvXMLEmbeddedObjectHelper::ImplGetContainerStorage(
362cdf0e10cSrcweir 		const ::rtl::OUString& rStorageName )
363cdf0e10cSrcweir {
364cdf0e10cSrcweir 	DBG_ASSERT( -1 == rStorageName.indexOf( '/' ) &&
365cdf0e10cSrcweir 				-1 == rStorageName.indexOf( '\\' ),
366cdf0e10cSrcweir 				"nested embedded storages aren't supported" );
367cdf0e10cSrcweir     if( !mxContainerStorage.is() ||
368cdf0e10cSrcweir 		( rStorageName != maCurContainerStorageName ) )
369cdf0e10cSrcweir 	{
370cdf0e10cSrcweir         if( mxContainerStorage.is() &&
371cdf0e10cSrcweir 			maCurContainerStorageName.getLength() > 0 &&
372cdf0e10cSrcweir 			EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode )
373cdf0e10cSrcweir         {
374cdf0e10cSrcweir             uno::Reference < embed::XTransactedObject > xTrans( mxContainerStorage, uno::UNO_QUERY );
375cdf0e10cSrcweir             if ( xTrans.is() )
376cdf0e10cSrcweir                 xTrans->commit();
377cdf0e10cSrcweir         }
378cdf0e10cSrcweir 
379cdf0e10cSrcweir         if( rStorageName.getLength() > 0 && mxRootStorage.is() )
380cdf0e10cSrcweir 		{
381cdf0e10cSrcweir             sal_Int32 nMode = EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode
382cdf0e10cSrcweir                                     ? ::embed::ElementModes::READWRITE
383cdf0e10cSrcweir                                     : ::embed::ElementModes::READ;
384cdf0e10cSrcweir             mxContainerStorage = mxRootStorage->openStorageElement( rStorageName,
385cdf0e10cSrcweir                                                              nMode );
386cdf0e10cSrcweir 		}
387cdf0e10cSrcweir 		else
388cdf0e10cSrcweir 		{
389cdf0e10cSrcweir             mxContainerStorage = mxRootStorage;
390cdf0e10cSrcweir 		}
391cdf0e10cSrcweir 		maCurContainerStorageName = rStorageName;
392cdf0e10cSrcweir 	}
393cdf0e10cSrcweir 
394cdf0e10cSrcweir 	return mxContainerStorage;
395cdf0e10cSrcweir }
396cdf0e10cSrcweir 
397cdf0e10cSrcweir // -----------------------------------------------------------------------------
398cdf0e10cSrcweir 
ImplReadObject(const::rtl::OUString & rContainerStorageName,::rtl::OUString & rObjName,const SvGlobalName * pClassId,SvStream * pTemp)399cdf0e10cSrcweir sal_Bool SvXMLEmbeddedObjectHelper::ImplReadObject(
400cdf0e10cSrcweir 		const ::rtl::OUString& rContainerStorageName,
401cdf0e10cSrcweir 		::rtl::OUString& rObjName,
402cdf0e10cSrcweir 	    const SvGlobalName *pClassId,
403cdf0e10cSrcweir         SvStream* pTemp )
404cdf0e10cSrcweir {
405cdf0e10cSrcweir 	(void)pClassId;
406cdf0e10cSrcweir 
407cdf0e10cSrcweir     uno::Reference < embed::XStorage > xDocStor( mpDocPersist->getStorage() );
408cdf0e10cSrcweir     uno::Reference < embed::XStorage > xCntnrStor( ImplGetContainerStorage( rContainerStorageName ) );
409cdf0e10cSrcweir 
410cdf0e10cSrcweir     if( !xCntnrStor.is() && !pTemp )
411cdf0e10cSrcweir 		return sal_False;
412cdf0e10cSrcweir 
413cdf0e10cSrcweir 	String aSrcObjName( rObjName );
414cdf0e10cSrcweir     comphelper::EmbeddedObjectContainer& rContainer = mpDocPersist->getEmbeddedObjectContainer();
415cdf0e10cSrcweir 
416cdf0e10cSrcweir 	// Is the object name unique?
417cdf0e10cSrcweir 	// if the object is already instantiated by GetEmbeddedObject
418cdf0e10cSrcweir     // that means that the duplication is being loaded
419cdf0e10cSrcweir     sal_Bool bDuplicate = rContainer.HasInstantiatedEmbeddedObject( rObjName );
420cdf0e10cSrcweir 	DBG_ASSERT( !bDuplicate, "An object in the document is referenced twice!" );
421cdf0e10cSrcweir 
422cdf0e10cSrcweir     if( xDocStor != xCntnrStor || pTemp || bDuplicate )
423cdf0e10cSrcweir 	{
424*86e1cf34SPedro Giffuni         // TODO/LATER: make this altogether a method in the EmbeddedObjectContainer
425cdf0e10cSrcweir 
426cdf0e10cSrcweir 		// create a unique name for the duplicate object
427cdf0e10cSrcweir         if( bDuplicate )
428cdf0e10cSrcweir             rObjName = rContainer.CreateUniqueObjectName();
429cdf0e10cSrcweir 
430cdf0e10cSrcweir 		if( pTemp )
431cdf0e10cSrcweir 		{
432cdf0e10cSrcweir             try
433cdf0e10cSrcweir             {
434cdf0e10cSrcweir 				pTemp->Seek( 0 );
435cdf0e10cSrcweir                 uno::Reference < io::XStream > xStm = xDocStor->openStreamElement( rObjName,
436cdf0e10cSrcweir                         embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
437cdf0e10cSrcweir                 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xStm );
438cdf0e10cSrcweir                 *pTemp >> *pStream;
439cdf0e10cSrcweir                 delete pStream;
440cdf0e10cSrcweir 
441cdf0e10cSrcweir 				// TODO/LATER: what to do when other types of objects are based on substream persistence?
442cdf0e10cSrcweir 				// This is an ole object
443cdf0e10cSrcweir 				uno::Reference< beans::XPropertySet > xProps( xStm, uno::UNO_QUERY_THROW );
444cdf0e10cSrcweir 				xProps->setPropertyValue(
445cdf0e10cSrcweir 					::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
446cdf0e10cSrcweir 					uno::makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ) ) );
447cdf0e10cSrcweir 
448cdf0e10cSrcweir                 xStm->getOutputStream()->closeOutput();
449cdf0e10cSrcweir             }
450cdf0e10cSrcweir             catch ( uno::Exception& )
451cdf0e10cSrcweir             {
452cdf0e10cSrcweir                 return sal_False;
453cdf0e10cSrcweir             }
454cdf0e10cSrcweir 		}
455cdf0e10cSrcweir 		else
456cdf0e10cSrcweir 		{
457cdf0e10cSrcweir             try
458cdf0e10cSrcweir             {
459cdf0e10cSrcweir                 xCntnrStor->copyElementTo( aSrcObjName, xDocStor, rObjName );
460cdf0e10cSrcweir             }
461cdf0e10cSrcweir             catch ( uno::Exception& )
462cdf0e10cSrcweir             {
463cdf0e10cSrcweir                 return sal_False;
464cdf0e10cSrcweir             }
465cdf0e10cSrcweir 		}
466cdf0e10cSrcweir 	}
467cdf0e10cSrcweir 
468cdf0e10cSrcweir     // make object known to the container
469cdf0e10cSrcweir     // TODO/LATER: could be done a little bit more efficient!
470cdf0e10cSrcweir     ::rtl::OUString aName( rObjName );
471cdf0e10cSrcweir 
472cdf0e10cSrcweir 	// TODO/LATER: The provided pClassId is ignored for now.
473cdf0e10cSrcweir 	//             The stream contains OLE storage internally and this storage already has a class id specifying the
474cdf0e10cSrcweir 	//             server that was used to create the object. pClassId could be used to specify the server that should
475cdf0e10cSrcweir 	//             be used for the next opening, but this information seems to be out of the file format responsibility
476cdf0e10cSrcweir 	//             area.
477cdf0e10cSrcweir 	rContainer.GetEmbeddedObject( aName );
478cdf0e10cSrcweir 
479cdf0e10cSrcweir 	return sal_True;
480cdf0e10cSrcweir }
481cdf0e10cSrcweir 
482cdf0e10cSrcweir // -----------------------------------------------------------------------------
483cdf0e10cSrcweir 
ImplInsertEmbeddedObjectURL(const::rtl::OUString & rURLStr)484cdf0e10cSrcweir ::rtl::OUString SvXMLEmbeddedObjectHelper::ImplInsertEmbeddedObjectURL(
485cdf0e10cSrcweir 		const ::rtl::OUString& rURLStr )
486cdf0e10cSrcweir {
487cdf0e10cSrcweir 	::rtl::OUString sRetURL;
488cdf0e10cSrcweir 
489cdf0e10cSrcweir 	::rtl::OUString	aContainerStorageName, aObjectStorageName;
490cdf0e10cSrcweir 	if( !ImplGetStorageNames( rURLStr, aContainerStorageName,
491cdf0e10cSrcweir 							  aObjectStorageName,
492cdf0e10cSrcweir 							  EMBEDDEDOBJECTHELPER_MODE_WRITE == meCreateMode ) )
493cdf0e10cSrcweir 		return sRetURL;
494cdf0e10cSrcweir 
495cdf0e10cSrcweir 	if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
496cdf0e10cSrcweir 	{
497cdf0e10cSrcweir 		OutputStorageWrapper_Impl *pOut = 0;
498cdf0e10cSrcweir 		SvXMLEmbeddedObjectHelper_Impl::iterator aIter;
499cdf0e10cSrcweir 
500cdf0e10cSrcweir 		if( mpStreamMap )
501cdf0e10cSrcweir 		{
502cdf0e10cSrcweir 			aIter = mpStreamMap->find( rURLStr );
503cdf0e10cSrcweir 			if( aIter != mpStreamMap->end() && aIter->second )
504cdf0e10cSrcweir 				pOut = aIter->second;
505cdf0e10cSrcweir 		}
506cdf0e10cSrcweir 
507cdf0e10cSrcweir 		SvGlobalName aClassId, *pClassId = 0;
508cdf0e10cSrcweir 		sal_Int32 nPos = aObjectStorageName.lastIndexOf( '!' );
509cdf0e10cSrcweir 		if( -1 != nPos && aClassId.MakeId( aObjectStorageName.copy( nPos+1 ) ) )
510cdf0e10cSrcweir 		{
511cdf0e10cSrcweir 			aObjectStorageName = aObjectStorageName.copy( 0, nPos );
512cdf0e10cSrcweir 			pClassId = &aClassId;
513cdf0e10cSrcweir 		}
514cdf0e10cSrcweir 
515cdf0e10cSrcweir         ImplReadObject( aContainerStorageName, aObjectStorageName, pClassId, pOut ? pOut->GetStream() : 0 );
516cdf0e10cSrcweir         sRetURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(XML_EMBEDDEDOBJECT_URL_BASE) );
517cdf0e10cSrcweir 		sRetURL += aObjectStorageName;
518cdf0e10cSrcweir 
519cdf0e10cSrcweir 		if( pOut )
520cdf0e10cSrcweir 		{
521cdf0e10cSrcweir 			mpStreamMap->erase( aIter );
522cdf0e10cSrcweir 			pOut->release();
523cdf0e10cSrcweir 		}
524cdf0e10cSrcweir 	}
525cdf0e10cSrcweir 	else
526cdf0e10cSrcweir 	{
527cdf0e10cSrcweir 		// Objects are written using ::comphelper::IEmbeddedHelper::SaveAs
528cdf0e10cSrcweir 		sRetURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("./") );
529cdf0e10cSrcweir 		if( aContainerStorageName.getLength() )
530cdf0e10cSrcweir 		{
531cdf0e10cSrcweir 			sRetURL += aContainerStorageName;
532cdf0e10cSrcweir 			sRetURL += ::rtl::OUString( '/' );
533cdf0e10cSrcweir 		}
534cdf0e10cSrcweir 		sRetURL += aObjectStorageName;
535cdf0e10cSrcweir 	}
536cdf0e10cSrcweir 
537cdf0e10cSrcweir 	return sRetURL;
538cdf0e10cSrcweir }
539cdf0e10cSrcweir 
540cdf0e10cSrcweir // -----------------------------------------------------------------------------
541cdf0e10cSrcweir 
ImplGetReplacementImage(const uno::Reference<embed::XEmbeddedObject> & xObj)542cdf0e10cSrcweir uno::Reference< io::XInputStream > SvXMLEmbeddedObjectHelper::ImplGetReplacementImage(
543cdf0e10cSrcweir 											const uno::Reference< embed::XEmbeddedObject >& xObj )
544cdf0e10cSrcweir {
545cdf0e10cSrcweir 	uno::Reference< io::XInputStream > xStream;
546cdf0e10cSrcweir 
547cdf0e10cSrcweir 	if( xObj.is() )
548cdf0e10cSrcweir 	{
549cdf0e10cSrcweir 		try
550cdf0e10cSrcweir 		{
551cdf0e10cSrcweir 			sal_Bool bSwitchBackToLoaded = sal_False;
552cdf0e10cSrcweir 			sal_Int32 nCurState = xObj->getCurrentState();
553cdf0e10cSrcweir 			if ( nCurState == embed::EmbedStates::LOADED || nCurState == embed::EmbedStates::RUNNING )
554cdf0e10cSrcweir 			{
555cdf0e10cSrcweir 				// means that the object is not active
556cdf0e10cSrcweir 				// copy replacement image from old to new container
557cdf0e10cSrcweir 				::rtl::OUString aMediaType;
558cdf0e10cSrcweir 				xStream = mpDocPersist->getEmbeddedObjectContainer().GetGraphicStream( xObj, &aMediaType );
559cdf0e10cSrcweir 			}
560cdf0e10cSrcweir 
561cdf0e10cSrcweir 			if ( !xStream.is() )
562cdf0e10cSrcweir 			{
563cdf0e10cSrcweir 				// the image must be regenerated
564cdf0e10cSrcweir 				// TODO/LATER: another aspect could be used
565cdf0e10cSrcweir 				if ( nCurState == embed::EmbedStates::LOADED )
566cdf0e10cSrcweir 					bSwitchBackToLoaded = sal_True;
567cdf0e10cSrcweir 
568cdf0e10cSrcweir 				::rtl::OUString aMediaType;
569cdf0e10cSrcweir 				xStream = svt::EmbeddedObjectRef::GetGraphicReplacementStream(
570cdf0e10cSrcweir 													embed::Aspects::MSOLE_CONTENT,
571cdf0e10cSrcweir 													xObj,
572cdf0e10cSrcweir 													&aMediaType );
573cdf0e10cSrcweir 			}
574cdf0e10cSrcweir 
575cdf0e10cSrcweir 			if ( bSwitchBackToLoaded )
576cdf0e10cSrcweir 				// switch back to loaded state; that way we have a minimum cache confusion
577cdf0e10cSrcweir 				xObj->changeState( embed::EmbedStates::LOADED );
578cdf0e10cSrcweir 		}
579cdf0e10cSrcweir 		catch( uno::Exception& )
580cdf0e10cSrcweir 		{}
581cdf0e10cSrcweir 	}
582cdf0e10cSrcweir 
583cdf0e10cSrcweir 	return xStream;
584cdf0e10cSrcweir }
585cdf0e10cSrcweir 
586cdf0e10cSrcweir // -----------------------------------------------------------------------------
587cdf0e10cSrcweir 
Init(const uno::Reference<embed::XStorage> & rRootStorage,::comphelper::IEmbeddedHelper & rPersist,SvXMLEmbeddedObjectHelperMode eCreateMode)588cdf0e10cSrcweir void SvXMLEmbeddedObjectHelper::Init(
589cdf0e10cSrcweir         const uno::Reference < embed::XStorage >& rRootStorage,
590cdf0e10cSrcweir         ::comphelper::IEmbeddedHelper& rPersist,
591cdf0e10cSrcweir 		SvXMLEmbeddedObjectHelperMode eCreateMode )
592cdf0e10cSrcweir {
593cdf0e10cSrcweir     mxRootStorage = rRootStorage;
594cdf0e10cSrcweir 	mpDocPersist = &rPersist;
595cdf0e10cSrcweir 	meCreateMode = eCreateMode;
596cdf0e10cSrcweir }
597cdf0e10cSrcweir 
598cdf0e10cSrcweir // -----------------------------------------------------------------------------
599cdf0e10cSrcweir 
Create(const uno::Reference<embed::XStorage> & rRootStorage,::comphelper::IEmbeddedHelper & rDocPersist,SvXMLEmbeddedObjectHelperMode eCreateMode,sal_Bool bDirect)600cdf0e10cSrcweir SvXMLEmbeddedObjectHelper* SvXMLEmbeddedObjectHelper::Create(
601cdf0e10cSrcweir         const uno::Reference < embed::XStorage >& rRootStorage,
602cdf0e10cSrcweir         ::comphelper::IEmbeddedHelper& rDocPersist,
603cdf0e10cSrcweir 		SvXMLEmbeddedObjectHelperMode eCreateMode,
604cdf0e10cSrcweir 		sal_Bool bDirect )
605cdf0e10cSrcweir {
606cdf0e10cSrcweir 	(void)bDirect;
607cdf0e10cSrcweir 
608cdf0e10cSrcweir 	SvXMLEmbeddedObjectHelper* pThis = new SvXMLEmbeddedObjectHelper;
609cdf0e10cSrcweir 
610cdf0e10cSrcweir 	pThis->acquire();
611cdf0e10cSrcweir     pThis->Init( rRootStorage, rDocPersist, eCreateMode );
612cdf0e10cSrcweir 
613cdf0e10cSrcweir 	return pThis;
614cdf0e10cSrcweir }
615cdf0e10cSrcweir 
Create(::comphelper::IEmbeddedHelper & rDocPersist,SvXMLEmbeddedObjectHelperMode eCreateMode)616cdf0e10cSrcweir SvXMLEmbeddedObjectHelper* SvXMLEmbeddedObjectHelper::Create(
617cdf0e10cSrcweir         ::comphelper::IEmbeddedHelper& rDocPersist,
618cdf0e10cSrcweir 		SvXMLEmbeddedObjectHelperMode eCreateMode )
619cdf0e10cSrcweir {
620cdf0e10cSrcweir 	SvXMLEmbeddedObjectHelper* pThis = new SvXMLEmbeddedObjectHelper;
621cdf0e10cSrcweir 
622cdf0e10cSrcweir 	pThis->acquire();
623cdf0e10cSrcweir 	pThis->Init( 0, rDocPersist, eCreateMode );
624cdf0e10cSrcweir 
625cdf0e10cSrcweir 	return pThis;
626cdf0e10cSrcweir }
627cdf0e10cSrcweir 
628cdf0e10cSrcweir // -----------------------------------------------------------------------------
629cdf0e10cSrcweir 
Destroy(SvXMLEmbeddedObjectHelper * pSvXMLEmbeddedObjectHelper)630cdf0e10cSrcweir void SvXMLEmbeddedObjectHelper::Destroy(
631cdf0e10cSrcweir 		SvXMLEmbeddedObjectHelper* pSvXMLEmbeddedObjectHelper )
632cdf0e10cSrcweir {
633cdf0e10cSrcweir 	if( pSvXMLEmbeddedObjectHelper )
634cdf0e10cSrcweir 	{
635cdf0e10cSrcweir 		pSvXMLEmbeddedObjectHelper->dispose();
636cdf0e10cSrcweir 		pSvXMLEmbeddedObjectHelper->release();
637cdf0e10cSrcweir 	}
638cdf0e10cSrcweir }
639cdf0e10cSrcweir 
640cdf0e10cSrcweir // -----------------------------------------------------------------------------
641cdf0e10cSrcweir 
Flush()642cdf0e10cSrcweir void SvXMLEmbeddedObjectHelper::Flush()
643cdf0e10cSrcweir {
644cdf0e10cSrcweir 	if( mxTempStorage.is() )
645cdf0e10cSrcweir 	{
646cdf0e10cSrcweir 		Reference < XComponent > xComp( mxTempStorage, UNO_QUERY );
647cdf0e10cSrcweir 		xComp->dispose();
648cdf0e10cSrcweir 	}
649cdf0e10cSrcweir }
650cdf0e10cSrcweir 
651cdf0e10cSrcweir // XGraphicObjectResolver: alien objects!
resolveEmbeddedObjectURL(const::rtl::OUString & aURL)652cdf0e10cSrcweir ::rtl::OUString SAL_CALL SvXMLEmbeddedObjectHelper::resolveEmbeddedObjectURL( const ::rtl::OUString& aURL )
653cdf0e10cSrcweir 	throw(RuntimeException)
654cdf0e10cSrcweir {
655cdf0e10cSrcweir 	MutexGuard			aGuard( maMutex );
656cdf0e10cSrcweir 
657cdf0e10cSrcweir 	return ImplInsertEmbeddedObjectURL( aURL );
658cdf0e10cSrcweir }
659cdf0e10cSrcweir 
660cdf0e10cSrcweir // XNameAccess: alien objects!
getByName(const::rtl::OUString & rURLStr)661cdf0e10cSrcweir Any SAL_CALL SvXMLEmbeddedObjectHelper::getByName(
662cdf0e10cSrcweir 		const ::rtl::OUString& rURLStr )
663cdf0e10cSrcweir 	throw (NoSuchElementException, WrappedTargetException, RuntimeException)
664cdf0e10cSrcweir {
665cdf0e10cSrcweir 	MutexGuard			aGuard( maMutex );
666cdf0e10cSrcweir 	Any aRet;
667cdf0e10cSrcweir 	if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
668cdf0e10cSrcweir 	{
669cdf0e10cSrcweir 		Reference < XOutputStream > xStrm;
670cdf0e10cSrcweir 		if( mpStreamMap )
671cdf0e10cSrcweir 		{
672cdf0e10cSrcweir 			SvXMLEmbeddedObjectHelper_Impl::iterator aIter =
673cdf0e10cSrcweir 				mpStreamMap->find( rURLStr );
674cdf0e10cSrcweir 			if( aIter != mpStreamMap->end() && aIter->second )
675cdf0e10cSrcweir 				xStrm = aIter->second;
676cdf0e10cSrcweir 		}
677cdf0e10cSrcweir 		if( !xStrm.is() )
678cdf0e10cSrcweir 		{
679cdf0e10cSrcweir 			OutputStorageWrapper_Impl *pOut = new OutputStorageWrapper_Impl;
680cdf0e10cSrcweir 			pOut->acquire();
681cdf0e10cSrcweir 			if( !mpStreamMap )
682cdf0e10cSrcweir 				mpStreamMap = new SvXMLEmbeddedObjectHelper_Impl;
683cdf0e10cSrcweir 			(*mpStreamMap)[rURLStr] = pOut;
684cdf0e10cSrcweir 			xStrm = pOut;
685cdf0e10cSrcweir 		}
686cdf0e10cSrcweir 
687cdf0e10cSrcweir 		aRet <<= xStrm;
688cdf0e10cSrcweir 	}
689cdf0e10cSrcweir 	else
690cdf0e10cSrcweir 	{
691cdf0e10cSrcweir 		sal_Bool bGraphicRepl = sal_False;
692cdf0e10cSrcweir 		sal_Bool bOasisFormat = sal_True;
693cdf0e10cSrcweir 		Reference < XInputStream > xStrm;
694cdf0e10cSrcweir 		::rtl::OUString aContainerStorageName, aObjectStorageName;
695cdf0e10cSrcweir 		if( ImplGetStorageNames( rURLStr, aContainerStorageName,
696cdf0e10cSrcweir 								 aObjectStorageName,
697cdf0e10cSrcweir 								 sal_True,
698cdf0e10cSrcweir 				   				 &bGraphicRepl,
699cdf0e10cSrcweir 								 &bOasisFormat ) )
700cdf0e10cSrcweir 		{
701cdf0e10cSrcweir             try
702cdf0e10cSrcweir             {
703cdf0e10cSrcweir 				comphelper::EmbeddedObjectContainer& rContainer =
704cdf0e10cSrcweir 						mpDocPersist->getEmbeddedObjectContainer();
705cdf0e10cSrcweir 
706cdf0e10cSrcweir     			Reference < embed::XEmbeddedObject > xObj = rContainer.GetEmbeddedObject( aObjectStorageName );
707cdf0e10cSrcweir 				DBG_ASSERT( xObj.is(), "Didn't get object" );
708cdf0e10cSrcweir 
709cdf0e10cSrcweir 				if( xObj.is() )
710cdf0e10cSrcweir 				{
711cdf0e10cSrcweir 					if( bGraphicRepl )
712cdf0e10cSrcweir 					{
713cdf0e10cSrcweir 						xStrm = ImplGetReplacementImage( xObj );
714cdf0e10cSrcweir 					}
715cdf0e10cSrcweir 					else
716cdf0e10cSrcweir 					{
717cdf0e10cSrcweir 						Reference < embed::XEmbedPersist > xPersist( xObj, UNO_QUERY );
718cdf0e10cSrcweir 						if( xPersist.is() )
719cdf0e10cSrcweir 						{
720cdf0e10cSrcweir 							if( !mxTempStorage.is() )
721cdf0e10cSrcweir 								mxTempStorage =
722cdf0e10cSrcweir 									comphelper::OStorageHelper::GetTemporaryStorage();
723cdf0e10cSrcweir 							Sequence < beans::PropertyValue > aDummy( 0 ), aEmbDescr( 1 );
724cdf0e10cSrcweir 							aEmbDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StoreVisualReplacement" ) );
725cdf0e10cSrcweir 					   		aEmbDescr[0].Value <<= (sal_Bool)(!bOasisFormat);
726cdf0e10cSrcweir 							if ( !bOasisFormat )
727cdf0e10cSrcweir 							{
728cdf0e10cSrcweir 								::rtl::OUString aMimeType;
729cdf0e10cSrcweir 								uno::Reference< io::XInputStream > xGrInStream = ImplGetReplacementImage( xObj );
730cdf0e10cSrcweir 								if ( xGrInStream.is() )
731cdf0e10cSrcweir 								{
732cdf0e10cSrcweir 									aEmbDescr.realloc( 2 );
733cdf0e10cSrcweir 									aEmbDescr[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VisualReplacement" ) );
734cdf0e10cSrcweir 									aEmbDescr[1].Value <<= xGrInStream;
735cdf0e10cSrcweir 								}
736cdf0e10cSrcweir 							}
737cdf0e10cSrcweir 
738cdf0e10cSrcweir 							xPersist->storeToEntry( mxTempStorage, aObjectStorageName,
739cdf0e10cSrcweir 													aDummy, aEmbDescr );
740cdf0e10cSrcweir 							Reference < io::XStream > xStream =
741cdf0e10cSrcweir 								mxTempStorage->openStreamElement(
742cdf0e10cSrcweir 														aObjectStorageName,
743cdf0e10cSrcweir 														embed::ElementModes::READ);
744cdf0e10cSrcweir 							if( xStream.is() )
745cdf0e10cSrcweir 								xStrm = xStream->getInputStream();
746cdf0e10cSrcweir 						}
747cdf0e10cSrcweir 					}
748cdf0e10cSrcweir 				}
749cdf0e10cSrcweir             }
750cdf0e10cSrcweir             catch ( uno::Exception& )
751cdf0e10cSrcweir             {
752cdf0e10cSrcweir             }
753cdf0e10cSrcweir 		}
754cdf0e10cSrcweir 
755cdf0e10cSrcweir 		aRet <<= xStrm;
756cdf0e10cSrcweir 	}
757cdf0e10cSrcweir 
758cdf0e10cSrcweir 	return aRet;
759cdf0e10cSrcweir }
760cdf0e10cSrcweir 
getElementNames()761cdf0e10cSrcweir Sequence< ::rtl::OUString > SAL_CALL SvXMLEmbeddedObjectHelper::getElementNames()
762cdf0e10cSrcweir 	throw (RuntimeException)
763cdf0e10cSrcweir {
764cdf0e10cSrcweir 	MutexGuard			aGuard( maMutex );
765cdf0e10cSrcweir 	return Sequence< ::rtl::OUString >(0);
766cdf0e10cSrcweir }
767cdf0e10cSrcweir 
hasByName(const::rtl::OUString & rURLStr)768cdf0e10cSrcweir sal_Bool SAL_CALL SvXMLEmbeddedObjectHelper::hasByName( const ::rtl::OUString& rURLStr )
769cdf0e10cSrcweir 	throw (RuntimeException)
770cdf0e10cSrcweir {
771cdf0e10cSrcweir 	MutexGuard			aGuard( maMutex );
772cdf0e10cSrcweir 	if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
773cdf0e10cSrcweir 	{
774cdf0e10cSrcweir 		return sal_True;
775cdf0e10cSrcweir 	}
776cdf0e10cSrcweir 	else
777cdf0e10cSrcweir 	{
778cdf0e10cSrcweir 		::rtl::OUString	aContainerStorageName, aObjectStorageName;
779cdf0e10cSrcweir 		if( !ImplGetStorageNames( rURLStr, aContainerStorageName,
780cdf0e10cSrcweir 								  aObjectStorageName,
781cdf0e10cSrcweir 								  sal_True ) )
782cdf0e10cSrcweir 			return sal_False;
783cdf0e10cSrcweir 
784cdf0e10cSrcweir         comphelper::EmbeddedObjectContainer& rContainer = mpDocPersist->getEmbeddedObjectContainer();
785cdf0e10cSrcweir         return aObjectStorageName.getLength() > 0 &&
786cdf0e10cSrcweir                rContainer.HasEmbeddedObject( aObjectStorageName );
787cdf0e10cSrcweir 	}
788cdf0e10cSrcweir }
789cdf0e10cSrcweir 
790cdf0e10cSrcweir // XNameAccess
getElementType()791cdf0e10cSrcweir Type SAL_CALL SvXMLEmbeddedObjectHelper::getElementType()
792cdf0e10cSrcweir 	throw (RuntimeException)
793cdf0e10cSrcweir {
794cdf0e10cSrcweir 	MutexGuard			aGuard( maMutex );
795cdf0e10cSrcweir 	if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
796cdf0e10cSrcweir 		return ::getCppuType((const Reference<XOutputStream>*)0);
797cdf0e10cSrcweir 	else
798cdf0e10cSrcweir 		return ::getCppuType((const Reference<XInputStream>*)0);
799cdf0e10cSrcweir }
800cdf0e10cSrcweir 
hasElements()801cdf0e10cSrcweir sal_Bool SAL_CALL SvXMLEmbeddedObjectHelper::hasElements()
802cdf0e10cSrcweir 	throw (RuntimeException)
803cdf0e10cSrcweir {
804cdf0e10cSrcweir 	MutexGuard			aGuard( maMutex );
805cdf0e10cSrcweir 	if( EMBEDDEDOBJECTHELPER_MODE_READ == meCreateMode )
806cdf0e10cSrcweir 	{
807cdf0e10cSrcweir 		return sal_True;
808cdf0e10cSrcweir 	}
809cdf0e10cSrcweir 	else
810cdf0e10cSrcweir 	{
811cdf0e10cSrcweir         comphelper::EmbeddedObjectContainer& rContainer = mpDocPersist->getEmbeddedObjectContainer();
812cdf0e10cSrcweir         return rContainer.HasEmbeddedObjects();
813cdf0e10cSrcweir     }
814cdf0e10cSrcweir }
815cdf0e10cSrcweir 
816