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