1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_embeddedobj.hxx"
30 
31 #include <commonembobj.hxx>
32 #include <com/sun/star/embed/Aspects.hpp>
33 #include <com/sun/star/document/XStorageBasedDocument.hpp>
34 #include <com/sun/star/embed/EmbedStates.hpp>
35 #include <com/sun/star/embed/EmbedVerbs.hpp>
36 #include <com/sun/star/embed/EntryInitModes.hpp>
37 #include <com/sun/star/embed/XStorage.hpp>
38 #include <com/sun/star/embed/XOptimizedStorage.hpp>
39 #include <com/sun/star/embed/ElementModes.hpp>
40 #include <com/sun/star/embed/EmbedUpdateModes.hpp>
41 #include <com/sun/star/frame/XModel.hpp>
42 #include <com/sun/star/frame/XStorable.hpp>
43 #include <com/sun/star/frame/XLoadable.hpp>
44 #include <com/sun/star/frame/XComponentLoader.hpp>
45 #include <com/sun/star/frame/XModule.hpp>
46 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
48 #include <com/sun/star/lang/DisposedException.hpp>
49 #include <com/sun/star/util/XModifiable.hpp>
50 
51 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCEESS_HPP_
52 #include <com/sun/star/container/XNameAccess.hpp>
53 #endif
54 #include <com/sun/star/container/XChild.hpp>
55 #include <com/sun/star/util/XCloseable.hpp>
56 #include <com/sun/star/beans/XPropertySet.hpp>
57 #include <com/sun/star/beans/IllegalTypeException.hpp>
58 #include <com/sun/star/chart2/XChartDocument.hpp>
59 
60 #include <comphelper/fileformat.h>
61 #include <comphelper/storagehelper.hxx>
62 #include <comphelper/mimeconfighelper.hxx>
63 #include <comphelper/namedvaluecollection.hxx>
64 
65 #include <rtl/logfile.hxx>
66 
67 #include <tools/diagnose_ex.h>
68 
69 #define USE_STORAGEBASED_DOCUMENT
70 
71 using namespace ::com::sun::star;
72 
73 
74 //------------------------------------------------------
75 uno::Sequence< beans::PropertyValue > GetValuableArgs_Impl( const uno::Sequence< beans::PropertyValue >& aMedDescr,
76 															sal_Bool bCanUseDocumentBaseURL )
77 {
78 	uno::Sequence< beans::PropertyValue > aResult;
79 	sal_Int32 nResLen = 0;
80 
81 	for ( sal_Int32 nInd = 0; nInd < aMedDescr.getLength(); nInd++ )
82 	{
83 		if ( aMedDescr[nInd].Name.equalsAscii( "ComponentData" )
84 		  || aMedDescr[nInd].Name.equalsAscii( "DocumentTitle" )
85 		  || aMedDescr[nInd].Name.equalsAscii( "InteractionHandler" )
86 		  || aMedDescr[nInd].Name.equalsAscii( "JumpMark" )
87 		  // || aMedDescr[nInd].Name.equalsAscii( "Password" ) makes no sence for embedded objects
88 		  || aMedDescr[nInd].Name.equalsAscii( "Preview" )
89 		  || aMedDescr[nInd].Name.equalsAscii( "ReadOnly" )
90 		  || aMedDescr[nInd].Name.equalsAscii( "StartPresentation" )
91 		  || aMedDescr[nInd].Name.equalsAscii( "RepairPackage" )
92 		  || aMedDescr[nInd].Name.equalsAscii( "StatusIndicator" )
93 		  || aMedDescr[nInd].Name.equalsAscii( "ViewData" )
94 		  || aMedDescr[nInd].Name.equalsAscii( "ViewId" )
95 		  || aMedDescr[nInd].Name.equalsAscii( "MacroExecutionMode" )
96 		  || aMedDescr[nInd].Name.equalsAscii( "UpdateDocMode" )
97 		  || (aMedDescr[nInd].Name.equalsAscii( "DocumentBaseURL" ) && bCanUseDocumentBaseURL) )
98 		{
99 			aResult.realloc( ++nResLen );
100 			aResult[nResLen-1] = aMedDescr[nInd];
101 		}
102 	}
103 
104 	return aResult;
105 }
106 
107 //------------------------------------------------------
108 uno::Sequence< beans::PropertyValue > addAsTemplate( const uno::Sequence< beans::PropertyValue >& aOrig )
109 {
110 	sal_Bool bAsTemplateSet = sal_False;
111 	sal_Int32 nLength = aOrig.getLength();
112 	uno::Sequence< beans::PropertyValue > aResult( nLength );
113 
114 	for ( sal_Int32 nInd = 0; nInd < nLength; nInd++ )
115 	{
116 		aResult[nInd].Name = aOrig[nInd].Name;
117 		if ( aResult[nInd].Name.equalsAscii( "AsTemplate" ) )
118 		{
119 			aResult[nInd].Value <<= sal_True;
120 			bAsTemplateSet = sal_True;
121 		}
122 		else
123 			aResult[nInd].Value = aOrig[nInd].Value;
124 	}
125 
126 	if ( !bAsTemplateSet )
127 	{
128 		aResult.realloc( nLength + 1 );
129 		aResult[nLength].Name = ::rtl::OUString::createFromAscii( "AsTemplate" );
130 		aResult[nLength].Value <<= sal_True;
131 	}
132 
133 	return aResult;
134 }
135 
136 //------------------------------------------------------
137 uno::Reference< io::XInputStream > createTempInpStreamFromStor(
138 															const uno::Reference< embed::XStorage >& xStorage,
139 															const uno::Reference< lang::XMultiServiceFactory >& xFactory )
140 {
141 	OSL_ENSURE( xStorage.is(), "The storage can not be empty!" );
142 
143 	uno::Reference< io::XInputStream > xResult;
144 
145 	const ::rtl::OUString aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) );
146 	uno::Reference < io::XStream > xTempStream = uno::Reference < io::XStream > (
147 															xFactory->createInstance ( aServiceName ),
148 															uno::UNO_QUERY );
149 	if ( xTempStream.is() )
150 	{
151 		uno::Reference < lang::XSingleServiceFactory > xStorageFactory(
152 					xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
153 					uno::UNO_QUERY );
154 
155 		uno::Sequence< uno::Any > aArgs( 2 );
156 		aArgs[0] <<= xTempStream;
157 		aArgs[1] <<= embed::ElementModes::READWRITE;
158 		uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArgs ),
159 														uno::UNO_QUERY );
160 		if ( !xTempStorage.is() )
161 			throw uno::RuntimeException(); // TODO:
162 
163 		try
164 		{
165 			xStorage->copyToStorage( xTempStorage );
166 		} catch( uno::Exception& e )
167 		{
168 			throw embed::StorageWrappedTargetException(
169 						::rtl::OUString::createFromAscii( "Can't copy storage!" ),
170 						uno::Reference< uno::XInterface >(),
171 						uno::makeAny( e ) );
172 		}
173 
174 		try {
175 			uno::Reference< lang::XComponent > xComponent( xTempStorage, uno::UNO_QUERY );
176 			OSL_ENSURE( xComponent.is(), "Wrong storage implementation!" );
177 			if ( xComponent.is() )
178 				xComponent->dispose();
179 		}
180 		catch ( uno::Exception& )
181 		{
182 		}
183 
184 		try {
185 			uno::Reference< io::XOutputStream > xTempOut = xTempStream->getOutputStream();
186 			if ( xTempOut.is() )
187 				xTempOut->closeOutput();
188 		}
189 		catch ( uno::Exception& )
190 		{
191 		}
192 
193 		xResult = xTempStream->getInputStream();
194 	}
195 
196 	return xResult;
197 
198 }
199 
200 //------------------------------------------------------
201 static void TransferMediaType( const uno::Reference< embed::XStorage >& i_rSource, const uno::Reference< embed::XStorage >& i_rTarget )
202 {
203     try
204     {
205         const uno::Reference< beans::XPropertySet > xSourceProps( i_rSource, uno::UNO_QUERY_THROW );
206         const uno::Reference< beans::XPropertySet > xTargetProps( i_rTarget, uno::UNO_QUERY_THROW );
207         const ::rtl::OUString sMediaTypePropName( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
208         xTargetProps->setPropertyValue( sMediaTypePropName, xSourceProps->getPropertyValue( sMediaTypePropName ) );
209     }
210     catch( const uno::Exception& )
211     {
212     	DBG_UNHANDLED_EXCEPTION();
213     }
214 }
215 
216 //------------------------------------------------------
217 static uno::Reference< util::XCloseable > CreateDocument( const uno::Reference< lang::XMultiServiceFactory >& _rxFactory,
218     const ::rtl::OUString& _rDocumentServiceName, bool _bEmbeddedScriptSupport, const bool i_bDocumentRecoverySupport )
219 {
220     ::comphelper::NamedValueCollection aArguments;
221     aArguments.put( "EmbeddedObject", (sal_Bool)sal_True );
222     aArguments.put( "EmbeddedScriptSupport", (sal_Bool)_bEmbeddedScriptSupport );
223     aArguments.put( "DocumentRecoverySupport", (sal_Bool)i_bDocumentRecoverySupport );
224 
225     uno::Reference< uno::XInterface > xDocument;
226     try
227     {
228         xDocument = _rxFactory->createInstanceWithArguments( _rDocumentServiceName, aArguments.getWrappedPropertyValues() );
229     }
230     catch( const uno::Exception& )
231     {
232         // if an embedded object implementation does not support XInitialization,
233         // the default factory from cppuhelper will throw an
234         // IllegalArgumentException when we try to create the instance with arguments.
235         // Okay, so we fall back to creating the instance without any arguments.
236         OSL_ASSERT("Consider implementing interface XInitialization to avoid duplicate construction");
237         xDocument = _rxFactory->createInstance( _rDocumentServiceName );
238     }
239 
240     return uno::Reference< util::XCloseable >( xDocument, uno::UNO_QUERY );
241 }
242 
243 //------------------------------------------------------
244 static void SetDocToEmbedded( const uno::Reference< frame::XModel > xDocument, const ::rtl::OUString& aModuleName )
245 {
246 	if ( xDocument.is() )
247 	{
248 		uno::Sequence< beans::PropertyValue > aSeq( 1 );
249 		aSeq[0].Name = ::rtl::OUString::createFromAscii( "SetEmbedded" );
250 		aSeq[0].Value <<= sal_True;
251 		xDocument->attachResource( ::rtl::OUString(), aSeq );
252 
253 		if ( aModuleName.getLength() )
254 		{
255 			try
256 			{
257 				uno::Reference< frame::XModule > xModule( xDocument, uno::UNO_QUERY_THROW );
258 				xModule->setIdentifier( aModuleName );
259 			}
260 			catch( uno::Exception& )
261 			{}
262 		}
263 	}
264 }
265 
266 //------------------------------------------------------
267 void OCommonEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
268 												  const uno::Reference< embed::XStorage >& xNewObjectStorage,
269 												  const ::rtl::OUString& aNewName )
270 {
271 	if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) )
272 	{
273 		OSL_ENSURE( xNewObjectStorage == m_xObjectStorage, "The storage must be the same!\n" );
274 		return;
275 	}
276 
277     uno::Reference< lang::XComponent > xComponent( m_xObjectStorage, uno::UNO_QUERY );
278     OSL_ENSURE( !m_xObjectStorage.is() || xComponent.is(), "Wrong storage implementation!" );
279 
280     m_xObjectStorage = xNewObjectStorage;
281     m_xParentStorage = xNewParentStorage;
282     m_aEntryName = aNewName;
283 
284 #ifdef USE_STORAGEBASED_DOCUMENT
285 	// the linked document should not be switched
286 	if ( !m_bIsLink )
287 	{
288 		uno::Reference< document::XStorageBasedDocument > xDoc( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
289 		if ( xDoc.is() )
290             SwitchDocToStorage_Impl( xDoc, m_xObjectStorage );
291 	}
292 #endif
293 
294     try {
295         if ( xComponent.is() )
296             xComponent->dispose();
297     }
298     catch ( uno::Exception& )
299     {
300     }
301 }
302 
303 //------------------------------------------------------
304 void OCommonEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
305 												  const ::rtl::OUString& aNewName )
306 {
307 	if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) )
308 		return;
309 
310 	sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
311 
312 	uno::Reference< embed::XStorage > xNewOwnStorage = xNewParentStorage->openStorageElement( aNewName, nStorageMode );
313 	OSL_ENSURE( xNewOwnStorage.is(), "The method can not return empty reference!" );
314 
315 	SwitchOwnPersistence( xNewParentStorage, xNewOwnStorage, aNewName );
316 }
317 
318 //------------------------------------------------------
319 void OCommonEmbeddedObject::EmbedAndReparentDoc_Impl( const uno::Reference< util::XCloseable >& i_rxDocument ) const
320 {
321     SetDocToEmbedded( uno::Reference< frame::XModel >( i_rxDocument, uno::UNO_QUERY ), m_aModuleName );
322 
323     try
324     {
325         uno::Reference < container::XChild > xChild( i_rxDocument, uno::UNO_QUERY );
326         if ( xChild.is() )
327             xChild->setParent( m_xParent );
328     }
329     catch( const lang::NoSupportException & )
330     {
331         OSL_ENSURE( false, "OCommonEmbeddedObject::EmbedAndReparentDoc: cannot set parent at document!" );
332     }
333 }
334 
335 //------------------------------------------------------
336 uno::Reference< util::XCloseable > OCommonEmbeddedObject::InitNewDocument_Impl()
337 {
338     uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(),
339                                                 m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );
340 
341 	uno::Reference< frame::XModel > xModel( xDocument, uno::UNO_QUERY );
342 	uno::Reference< frame::XLoadable > xLoadable( xModel, uno::UNO_QUERY );
343 	if ( !xLoadable.is() )
344 		throw uno::RuntimeException();
345 
346 	try
347 	{
348 		// set the document mode to embedded as the first action on document!!!
349         EmbedAndReparentDoc_Impl( xDocument );
350 
351         // if we have a storage to recover the document from, do not use initNew, but instead load from that storage
352         bool bInitNew = true;
353         if ( m_xRecoveryStorage.is() )
354         {
355             uno::Reference< document::XStorageBasedDocument > xDoc( xLoadable, uno::UNO_QUERY );
356             OSL_ENSURE( xDoc.is(), "OCommonEmbeddedObject::InitNewDocument_Impl: cannot recover from a storage when the document is not storage based!" );
357             if ( xDoc.is() )
358             {
359                 ::comphelper::NamedValueCollection aLoadArgs;
360                 FillDefaultLoadArgs_Impl( m_xRecoveryStorage, aLoadArgs );
361 
362                 xDoc->loadFromStorage( m_xRecoveryStorage, aLoadArgs.getPropertyValues() );
363                 SwitchDocToStorage_Impl( xDoc, m_xObjectStorage );
364                 bInitNew = false;
365             }
366         }
367 
368         if ( bInitNew )
369         {
370 		    // init document as a new
371 		    xLoadable->initNew();
372         }
373 	    xModel->attachResource( xModel->getURL(), m_aDocMediaDescriptor );
374 	}
375 	catch( uno::Exception& )
376 	{
377 		uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
378 		if ( xCloseable.is() )
379 		{
380 			try
381 			{
382 				xCloseable->close( sal_True );
383 			}
384 			catch( uno::Exception& )
385 			{
386 			}
387 		}
388 
389 		throw; // TODO
390 	}
391 
392 	return xDocument;
393 }
394 
395 //------------------------------------------------------
396 uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadLink_Impl()
397 {
398     uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(),
399                                                 m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );
400 
401 	uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY );
402 	if ( !xLoadable.is() )
403 		throw uno::RuntimeException();
404 
405 	sal_Int32 nLen = 2;
406 	uno::Sequence< beans::PropertyValue > aArgs( nLen );
407 	aArgs[0].Name = ::rtl::OUString::createFromAscii( "URL" );
408 	aArgs[0].Value <<= m_aLinkURL;
409 	aArgs[1].Name = ::rtl::OUString::createFromAscii( "FilterName" );
410 	aArgs[1].Value <<= m_aLinkFilterName;
411 	if ( m_bLinkHasPassword )
412 	{
413 		aArgs.realloc( ++nLen );
414 		aArgs[nLen-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) );
415 		aArgs[nLen-1].Value <<= m_aLinkPassword;
416 	}
417 
418 	aArgs.realloc( m_aDocMediaDescriptor.getLength() + nLen );
419 	for ( sal_Int32 nInd = 0; nInd < m_aDocMediaDescriptor.getLength(); nInd++ )
420 	{
421 		aArgs[nInd+nLen].Name = m_aDocMediaDescriptor[nInd].Name;
422 		aArgs[nInd+nLen].Value = m_aDocMediaDescriptor[nInd].Value;
423 	}
424 
425 	try
426 	{
427 		// the document is not really an embedded one, it is a link
428         EmbedAndReparentDoc_Impl( xDocument );
429 
430 		// load the document
431 		xLoadable->load( aArgs );
432 
433 		if ( !m_bLinkHasPassword )
434 		{
435 			// check if there is a password to cache
436 			uno::Reference< frame::XModel > xModel( xLoadable, uno::UNO_QUERY_THROW );
437 			uno::Sequence< beans::PropertyValue > aProps = xModel->getArgs();
438 			for ( sal_Int32 nInd = 0; nInd < aProps.getLength(); nInd++ )
439 				if ( aProps[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) ) )
440 				  && ( aProps[nInd].Value >>= m_aLinkPassword ) )
441 				{
442 					m_bLinkHasPassword = sal_True;
443 					break;
444 				}
445 		}
446 	}
447 	catch( uno::Exception& )
448 	{
449 		uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
450 		if ( xCloseable.is() )
451 		{
452 			try
453 			{
454 				xCloseable->close( sal_True );
455 			}
456 			catch( uno::Exception& )
457 			{
458 			}
459 		}
460 
461 		throw; // TODO
462 	}
463 
464 	return xDocument;
465 
466 }
467 
468 //------------------------------------------------------
469 ::rtl::OUString OCommonEmbeddedObject::GetFilterName( sal_Int32 nVersion ) const
470 {
471     ::rtl::OUString aFilterName = GetPresetFilterName();
472     if ( !aFilterName.getLength() )
473     {
474         try {
475 	        ::comphelper::MimeConfigurationHelper aHelper( m_xFactory );
476             aFilterName = aHelper.GetDefaultFilterFromServiceName( GetDocumentServiceName(), nVersion );
477         } catch( uno::Exception& )
478         {}
479     }
480 
481     return aFilterName;
482 }
483 
484 //------------------------------------------------------
485 void OCommonEmbeddedObject::FillDefaultLoadArgs_Impl( const uno::Reference< embed::XStorage >& i_rxStorage,
486         ::comphelper::NamedValueCollection& o_rLoadArgs ) const
487 {
488     o_rLoadArgs.put( "DocumentBaseURL", GetBaseURL_Impl() );
489     o_rLoadArgs.put( "HierarchicalDocumentName", m_aEntryName );
490     o_rLoadArgs.put( "ReadOnly", m_bReadOnly );
491 
492     ::rtl::OUString aFilterName = GetFilterName( ::comphelper::OStorageHelper::GetXStorageFormat( i_rxStorage ) );
493     OSL_ENSURE( aFilterName.getLength(), "OCommonEmbeddedObject::FillDefaultLoadArgs_Impl: Wrong document service name!" );
494 	if ( !aFilterName.getLength() )
495 		throw io::IOException();    // TODO: error message/code
496 
497     o_rLoadArgs.put( "FilterName", aFilterName );
498 }
499 
500 //------------------------------------------------------
501 uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadDocumentFromStorage_Impl()
502 {
503     ENSURE_OR_THROW( m_xObjectStorage.is(), "no object storage" );
504 
505     const uno::Reference< embed::XStorage > xSourceStorage( m_xRecoveryStorage.is() ? m_xRecoveryStorage : m_xObjectStorage );
506 
507     uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(),
508                                                 m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );
509 
510     //#i103460# ODF: take the size given from the parent frame as default
511     uno::Reference< chart2::XChartDocument > xChart( xDocument, uno::UNO_QUERY );
512     if( xChart.is() )
513     {
514         uno::Reference< embed::XVisualObject > xChartVisualObject( xChart, uno::UNO_QUERY );
515         if( xChartVisualObject.is() )
516             xChartVisualObject->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, m_aDefaultSizeForChart_In_100TH_MM );
517     }
518 
519     uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY );
520     uno::Reference< document::XStorageBasedDocument > xDoc
521 #ifdef USE_STORAGEBASED_DOCUMENT
522             ( xDocument, uno::UNO_QUERY )
523 #endif
524             ;
525     if ( !xDoc.is() && !xLoadable.is() ) ///BUG: This should be || instead of && ?
526 		throw uno::RuntimeException();
527 
528     ::comphelper::NamedValueCollection aLoadArgs;
529     FillDefaultLoadArgs_Impl( xSourceStorage, aLoadArgs );
530 
531 	uno::Reference< io::XInputStream > xTempInpStream;
532     if ( !xDoc.is() )
533     {
534         xTempInpStream = createTempInpStreamFromStor( xSourceStorage, m_xFactory );
535         if ( !xTempInpStream.is() )
536             throw uno::RuntimeException();
537 
538 		::rtl::OUString aTempFileURL;
539 		try
540 		{
541 			// no need to let the file stay after the stream is removed since the embedded document
542 			// can not be stored directly
543 			uno::Reference< beans::XPropertySet > xTempStreamProps( xTempInpStream, uno::UNO_QUERY_THROW );
544 			xTempStreamProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) ) >>= aTempFileURL;
545 		}
546 		catch( uno::Exception& )
547 		{
548 		}
549 
550 		OSL_ENSURE( aTempFileURL.getLength(), "Coudn't retrieve temporary file URL!\n" );
551 
552         aLoadArgs.put( "URL", aTempFileURL );
553         aLoadArgs.put( "InputStream", xTempInpStream );
554     }
555 
556 	// aLoadArgs.put( "AsTemplate", sal_True );
557 
558     aLoadArgs.merge( m_aDocMediaDescriptor, true );
559 
560 	try
561 	{
562 		// set the document mode to embedded as the first step!!!
563         EmbedAndReparentDoc_Impl( xDocument );
564 
565         if ( xDoc.is() )
566         {
567             xDoc->loadFromStorage( xSourceStorage, aLoadArgs.getPropertyValues() );
568             if ( xSourceStorage != m_xObjectStorage )
569                 SwitchDocToStorage_Impl( xDoc, m_xObjectStorage );
570         }
571         else
572             xLoadable->load( aLoadArgs.getPropertyValues() );
573 	}
574 	catch( uno::Exception& )
575 	{
576 		uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
577 		if ( xCloseable.is() )
578 		{
579 			try
580 			{
581 				xCloseable->close( sal_True );
582 			}
583 			catch( uno::Exception& )
584 			{
585                 DBG_UNHANDLED_EXCEPTION();
586 			}
587 		}
588 
589 		throw; // TODO
590 	}
591 
592 	return xDocument;
593 }
594 
595 //------------------------------------------------------
596 uno::Reference< io::XInputStream > OCommonEmbeddedObject::StoreDocumentToTempStream_Impl(
597 																			sal_Int32 nStorageFormat,
598 																			const ::rtl::OUString& aBaseURL,
599 																			const ::rtl::OUString& aHierarchName )
600 {
601 	uno::Reference < io::XOutputStream > xTempOut(
602 				m_xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
603 				uno::UNO_QUERY );
604 	uno::Reference< io::XInputStream > aResult( xTempOut, uno::UNO_QUERY );
605 
606 	if ( !xTempOut.is() || !aResult.is() )
607 		throw uno::RuntimeException(); // TODO:
608 
609     uno::Reference< frame::XStorable > xStorable;
610 	{
611 		osl::MutexGuard aGuard( m_aMutex );
612 		if ( m_pDocHolder )
613 			xStorable = uno::Reference< frame::XStorable > ( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
614 	}
615 
616 	if( !xStorable.is() )
617 		throw uno::RuntimeException(); // TODO:
618 
619 	::rtl::OUString aFilterName = GetFilterName( nStorageFormat );
620 
621 	OSL_ENSURE( aFilterName.getLength(), "Wrong document service name!" );
622 	if ( !aFilterName.getLength() )
623 		throw io::IOException(); // TODO:
624 
625 	uno::Sequence< beans::PropertyValue > aArgs( 4 );
626 	aArgs[0].Name = ::rtl::OUString::createFromAscii( "FilterName" );
627 	aArgs[0].Value <<= aFilterName;
628 	aArgs[1].Name = ::rtl::OUString::createFromAscii( "OutputStream" );
629 	aArgs[1].Value <<= xTempOut;
630 	aArgs[2].Name = ::rtl::OUString::createFromAscii( "DocumentBaseURL" );
631 	aArgs[2].Value <<= aBaseURL;
632 	aArgs[3].Name = ::rtl::OUString::createFromAscii( "HierarchicalDocumentName" );
633 	aArgs[3].Value <<= aHierarchName;
634 
635 	xStorable->storeToURL( ::rtl::OUString::createFromAscii( "private:stream" ), aArgs );
636 	try
637 	{
638 		xTempOut->closeOutput();
639 	}
640 	catch( uno::Exception& )
641 	{
642 		OSL_ENSURE( sal_False, "Looks like stream was closed already" );
643 	}
644 
645 	return aResult;
646 }
647 
648 //------------------------------------------------------
649 void OCommonEmbeddedObject::SaveObject_Impl()
650 {
651 	if ( m_xClientSite.is() )
652 	{
653 		try
654 		{
655 			// check whether the component is modified,
656 			// if not there is no need for storing
657     		uno::Reference< util::XModifiable > xModifiable( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
658 			if ( xModifiable.is() && !xModifiable->isModified() )
659 				return;
660 		}
661 		catch( uno::Exception& )
662 		{}
663 
664 		try {
665 			m_xClientSite->saveObject();
666 		}
667 		catch( uno::Exception& )
668 		{
669 			OSL_ENSURE( sal_False, "The object was not stored!\n" );
670 		}
671 	}
672 }
673 
674 //------------------------------------------------------
675 ::rtl::OUString OCommonEmbeddedObject::GetBaseURL_Impl() const
676 {
677 	::rtl::OUString aBaseURL;
678 	sal_Int32 nInd = 0;
679 
680 	if ( m_xClientSite.is() )
681 	{
682 		try
683 		{
684 			uno::Reference< frame::XModel > xParentModel( m_xClientSite->getComponent(), uno::UNO_QUERY_THROW );
685 			uno::Sequence< beans::PropertyValue > aModelProps = xParentModel->getArgs();
686 			for ( nInd = 0; nInd < aModelProps.getLength(); nInd++ )
687 				if ( aModelProps[nInd].Name.equals(
688 												::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentBaseURL" ) ) ) )
689 				{
690 					aModelProps[nInd].Value >>= aBaseURL;
691 					break;
692 				}
693 
694 
695 		}
696 		catch( uno::Exception& )
697 		{}
698 	}
699 
700 	if ( !aBaseURL.getLength() )
701 	{
702 		for ( nInd = 0; nInd < m_aDocMediaDescriptor.getLength(); nInd++ )
703 			if ( m_aDocMediaDescriptor[nInd].Name.equals(
704 												::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentBaseURL" ) ) ) )
705 			{
706 				m_aDocMediaDescriptor[nInd].Value >>= aBaseURL;
707 				break;
708 			}
709 	}
710 
711 	if ( !aBaseURL.getLength() )
712 		aBaseURL = m_aDefaultParentBaseURL;
713 
714 	return aBaseURL;
715 }
716 
717 //------------------------------------------------------
718 ::rtl::OUString OCommonEmbeddedObject::GetBaseURLFrom_Impl(
719 					const uno::Sequence< beans::PropertyValue >& lArguments,
720 					const uno::Sequence< beans::PropertyValue >& lObjArgs )
721 {
722 	::rtl::OUString aBaseURL;
723 	sal_Int32 nInd = 0;
724 
725 	for ( nInd = 0; nInd < lArguments.getLength(); nInd++ )
726 		if ( lArguments[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentBaseURL" ) ) ) )
727 		{
728 			lArguments[nInd].Value >>= aBaseURL;
729 			break;
730 		}
731 
732 	if ( !aBaseURL.getLength() )
733 	{
734 		for ( nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
735 			if ( lObjArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultParentBaseURL" ) ) ) )
736 			{
737 				lObjArgs[nInd].Value >>= aBaseURL;
738 				break;
739 			}
740 	}
741 
742 	return aBaseURL;
743 }
744 
745 
746 //------------------------------------------------------
747 void OCommonEmbeddedObject::SwitchDocToStorage_Impl( const uno::Reference< document::XStorageBasedDocument >& xDoc, const uno::Reference< embed::XStorage >& xStorage )
748 {
749 	xDoc->switchToStorage( xStorage );
750 
751     uno::Reference< util::XModifiable > xModif( xDoc, uno::UNO_QUERY );
752 	if ( xModif.is() )
753 		xModif->setModified( sal_False );
754 
755     if ( m_xRecoveryStorage.is() )
756         m_xRecoveryStorage.clear();
757 }
758 
759 //------------------------------------------------------
760 void OCommonEmbeddedObject::StoreDocToStorage_Impl( const uno::Reference< embed::XStorage >& xStorage,
761 													sal_Int32 nStorageFormat,
762 													const ::rtl::OUString& aBaseURL,
763 													const ::rtl::OUString& aHierarchName,
764 													sal_Bool bAttachToTheStorage )
765 {
766 	OSL_ENSURE( xStorage.is(), "No storage is provided for storing!" );
767 
768 	if ( !xStorage.is() )
769 		throw uno::RuntimeException(); // TODO:
770 
771 #ifdef USE_STORAGEBASED_DOCUMENT
772     uno::Reference< document::XStorageBasedDocument > xDoc;
773 	{
774 		osl::MutexGuard aGuard( m_aMutex );
775 		if ( m_pDocHolder )
776 			xDoc = uno::Reference< document::XStorageBasedDocument >( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
777 	}
778 
779     if ( xDoc.is() )
780     {
781 	    ::rtl::OUString aFilterName = GetFilterName( nStorageFormat );
782 
783         OSL_ENSURE( aFilterName.getLength(), "Wrong document service name!" );
784         if ( !aFilterName.getLength() )
785             throw io::IOException(); // TODO:
786 
787         uno::Sequence< beans::PropertyValue > aArgs( 3 );
788         aArgs[0].Name = ::rtl::OUString::createFromAscii( "FilterName" );
789         aArgs[0].Value <<= aFilterName;
790         aArgs[2].Name = ::rtl::OUString::createFromAscii( "DocumentBaseURL" );
791         aArgs[2].Value <<= aBaseURL;
792         aArgs[1].Name = ::rtl::OUString::createFromAscii( "HierarchicalDocumentName" );
793         aArgs[1].Value <<= aHierarchName;
794 
795         xDoc->storeToStorage( xStorage, aArgs );
796 		if ( bAttachToTheStorage )
797             SwitchDocToStorage_Impl( xDoc, xStorage );
798     }
799     else
800 #endif
801     {
802         // store document to temporary stream based on temporary file
803         uno::Reference < io::XInputStream > xTempIn = StoreDocumentToTempStream_Impl( nStorageFormat, aBaseURL, aHierarchName );
804 
805         OSL_ENSURE( xTempIn.is(), "The stream reference can not be empty!\n" );
806 
807         // open storage based on document temporary file for reading
808         uno::Reference < lang::XSingleServiceFactory > xStorageFactory(
809                     m_xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
810                     uno::UNO_QUERY );
811 
812         uno::Sequence< uno::Any > aArgs(1);
813         aArgs[0] <<= xTempIn;
814         uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArgs ),
815                                                             uno::UNO_QUERY );
816         if ( !xTempStorage.is() )
817             throw uno::RuntimeException(); // TODO:
818 
819         // object storage must be commited automatically
820         xTempStorage->copyToStorage( xStorage );
821     }
822 }
823 
824 //------------------------------------------------------
825 uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateDocFromMediaDescr_Impl(
826 										const uno::Sequence< beans::PropertyValue >& aMedDescr )
827 {
828     uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(),
829                                                 m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );
830 
831 	uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY );
832 	if ( !xLoadable.is() )
833 		throw uno::RuntimeException();
834 
835 	try
836 	{
837 		// set the document mode to embedded as the first action on the document!!!
838         EmbedAndReparentDoc_Impl( xDocument );
839 
840 		xLoadable->load( addAsTemplate( aMedDescr ) );
841 	}
842 	catch( uno::Exception& )
843 	{
844 		uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
845 		if ( xCloseable.is() )
846 		{
847 			try
848 			{
849 				xCloseable->close( sal_True );
850 			}
851 			catch( uno::Exception& )
852 			{
853 			}
854 		}
855 
856 		throw; // TODO
857 	}
858 
859 	return xDocument;
860 }
861 
862 //------------------------------------------------------
863 uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateTempDocFromLink_Impl()
864 {
865     uno::Reference< util::XCloseable > xResult;
866 
867 	OSL_ENSURE( m_bIsLink, "The object is not a linked one!\n" );
868 
869 	uno::Sequence< beans::PropertyValue > aTempMediaDescr;
870 
871 	sal_Int32 nStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
872 	try {
873 		nStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
874 	}
875 	catch ( beans::IllegalTypeException& )
876 	{
877 		// the container just has an unknown type, use current file format
878 	}
879 	catch ( uno::Exception& )
880 	{
881 		OSL_ENSURE( sal_False, "Can not retrieve storage media type!\n" );
882 	}
883 
884     if ( m_pDocHolder->GetComponent().is() )
885 	{
886 		aTempMediaDescr.realloc( 4 );
887 
888 		// TODO/LATER: may be private:stream should be used as target URL
889 		::rtl::OUString aTempFileURL;
890 		uno::Reference< io::XInputStream > xTempStream = StoreDocumentToTempStream_Impl( SOFFICE_FILEFORMAT_CURRENT,
891 																						 ::rtl::OUString(),
892 																						 ::rtl::OUString() );
893 		try
894 		{
895 			// no need to let the file stay after the stream is removed since the embedded document
896 			// can not be stored directly
897 			uno::Reference< beans::XPropertySet > xTempStreamProps( xTempStream, uno::UNO_QUERY_THROW );
898 			xTempStreamProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) ) >>= aTempFileURL;
899 		}
900 		catch( uno::Exception& )
901 		{
902 		}
903 
904 		OSL_ENSURE( aTempFileURL.getLength(), "Coudn't retrieve temporary file URL!\n" );
905 
906 		aTempMediaDescr[0].Name = ::rtl::OUString::createFromAscii( "URL" );
907 		aTempMediaDescr[0].Value <<= aTempFileURL;
908 		aTempMediaDescr[1].Name = ::rtl::OUString::createFromAscii( "InputStream" );
909 		aTempMediaDescr[1].Value <<= xTempStream;
910 		aTempMediaDescr[2].Name = ::rtl::OUString::createFromAscii( "FilterName" );
911 		aTempMediaDescr[2].Value <<= GetFilterName( nStorageFormat );
912 		aTempMediaDescr[3].Name = ::rtl::OUString::createFromAscii( "AsTemplate" );
913 		aTempMediaDescr[3].Value <<= sal_True;
914 	}
915 	else
916 	{
917 		aTempMediaDescr.realloc( 2 );
918 		aTempMediaDescr[0].Name = ::rtl::OUString::createFromAscii( "URL" );
919 		aTempMediaDescr[0].Value <<= m_aLinkURL;
920 		aTempMediaDescr[1].Name = ::rtl::OUString::createFromAscii( "FilterName" );
921 		aTempMediaDescr[1].Value <<= m_aLinkFilterName;
922 		// aTempMediaDescr[2].Name = ::rtl::OUString::createFromAscii( "AsTemplate" );
923 		// aTempMediaDescr[2].Value <<= sal_True;
924 	}
925 
926 	xResult = CreateDocFromMediaDescr_Impl( aTempMediaDescr );
927 
928 	return xResult;
929 }
930 
931 //------------------------------------------------------
932 void SAL_CALL OCommonEmbeddedObject::setPersistentEntry(
933 					const uno::Reference< embed::XStorage >& xStorage,
934 					const ::rtl::OUString& sEntName,
935 					sal_Int32 nEntryConnectionMode,
936 					const uno::Sequence< beans::PropertyValue >& lArguments,
937 					const uno::Sequence< beans::PropertyValue >& lObjArgs )
938 		throw ( lang::IllegalArgumentException,
939 				embed::WrongStateException,
940 				io::IOException,
941 				uno::Exception,
942 				uno::RuntimeException )
943 {
944 	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::setPersistentEntry" );
945 
946 	// the type of the object must be already set
947 	// a kind of typedetection should be done in the factory
948 
949 	::osl::MutexGuard aGuard( m_aMutex );
950 	if ( m_bDisposed )
951 		throw lang::DisposedException(); // TODO
952 
953 	if ( !xStorage.is() )
954 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
955 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
956 											1 );
957 
958 	if ( !sEntName.getLength() )
959 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
960 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
961 											2 );
962 
963 	// May be LOADED should be forbidden here ???
964 	if ( ( m_nObjectState != -1 || nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
965 	  && ( m_nObjectState == -1 || nEntryConnectionMode != embed::EntryInitModes::NO_INIT ) )
966 	{
967 		// if the object is not loaded
968 		// it can not get persistant representation without initialization
969 
970 		// if the object is loaded
971 		// it can switch persistant representation only without initialization
972 
973 		throw embed::WrongStateException(
974 					::rtl::OUString::createFromAscii( "Can't change persistant representation of activated object!\n" ),
975 					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
976 	}
977 
978     if ( m_bWaitSaveCompleted )
979 	{
980 		if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
981         {
982             // saveCompleted is expected, handle it accordingly
983             if ( m_xNewParentStorage == xStorage && m_aNewEntryName.equals( sEntName ) )
984             {
985                 saveCompleted( sal_True );
986                 return;
987             }
988 
989             // if a completely different entry is provided, switch first back to the old persistence in saveCompleted
990             // and then switch to the target persistence
991             sal_Bool bSwitchFurther = ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) );
992 			saveCompleted( sal_False );
993             if ( !bSwitchFurther )
994                 return;
995         }
996 		else
997 			throw embed::WrongStateException(
998 						::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
999 						uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1000 	}
1001 
1002 	// for now support of this interface is required to allow breaking of links and converting them to normal embedded
1003 	// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
1004 	// OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
1005 	if ( m_bIsLink )
1006 	{
1007 		m_aEntryName = sEntName;
1008 		return;
1009 	}
1010 
1011 	uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
1012 	if ( !xNameAccess.is() )
1013 		throw uno::RuntimeException(); //TODO
1014 
1015 	// detect entry existence
1016 	sal_Bool bElExists = xNameAccess->hasByName( sEntName );
1017 
1018 	m_aDocMediaDescriptor = GetValuableArgs_Impl( lArguments,
1019 												  nEntryConnectionMode != embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT );
1020 
1021 	m_bReadOnly = sal_False;
1022 	for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
1023 		if ( lArguments[nInd].Name.equalsAscii( "ReadOnly" ) )
1024 			lArguments[nInd].Value >>= m_bReadOnly;
1025 
1026 	// TODO: use lObjArgs for StoreVisualReplacement
1027 	for ( sal_Int32 nObjInd = 0; nObjInd < lObjArgs.getLength(); nObjInd++ )
1028 		if ( lObjArgs[nObjInd].Name.equalsAscii( "OutplaceDispatchInterceptor" ) )
1029 		{
1030 			uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor;
1031 			if ( lObjArgs[nObjInd].Value >>= xDispatchInterceptor )
1032 				m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor );
1033 		}
1034 		else if ( lObjArgs[nObjInd].Name.equalsAscii( "DefaultParentBaseURL" ) )
1035 		{
1036 			lObjArgs[nObjInd].Value >>= m_aDefaultParentBaseURL;
1037 		}
1038         else if ( lObjArgs[nObjInd].Name.equalsAscii( "Parent" ) )
1039 		{
1040             lObjArgs[nObjInd].Value >>= m_xParent;
1041 		}
1042         else if ( lObjArgs[nObjInd].Name.equalsAscii( "IndividualMiscStatus" ) )
1043 		{
1044             sal_Int64 nMiscStatus=0;
1045             lObjArgs[nObjInd].Value >>= nMiscStatus;
1046             m_nMiscStatus |= nMiscStatus;
1047 		}
1048         else if ( lObjArgs[nObjInd].Name.equalsAscii( "CloneFrom" ) )
1049         {
1050             uno::Reference < embed::XEmbeddedObject > xObj;
1051             lObjArgs[nObjInd].Value >>= xObj;
1052             if ( xObj.is() )
1053             {
1054                 m_bHasClonedSize = sal_True;
1055                 m_aClonedSize = xObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
1056                 m_nClonedMapUnit = xObj->getMapUnit( embed::Aspects::MSOLE_CONTENT );
1057             }
1058         }
1059         else if ( lObjArgs[nObjInd].Name.equalsAscii( "OutplaceFrameProperties" ) )
1060 		{
1061 			uno::Sequence< uno::Any > aOutFrameProps;
1062             uno::Sequence< beans::NamedValue > aOutFramePropsTyped;
1063 			if ( lObjArgs[nObjInd].Value >>= aOutFrameProps )
1064             {
1065 				m_pDocHolder->SetOutplaceFrameProperties( aOutFrameProps );
1066             }
1067             else if ( lObjArgs[nObjInd].Value >>= aOutFramePropsTyped )
1068             {
1069                 aOutFrameProps.realloc( aOutFramePropsTyped.getLength() );
1070                 uno::Any* pProp = aOutFrameProps.getArray();
1071                 for (   const beans::NamedValue* pTypedProp = aOutFramePropsTyped.getConstArray();
1072                         pTypedProp != aOutFramePropsTyped.getConstArray() + aOutFramePropsTyped.getLength();
1073                         ++pTypedProp, ++pProp
1074                     )
1075                 {
1076                     *pProp <<= *pTypedProp;
1077                 }
1078 				m_pDocHolder->SetOutplaceFrameProperties( aOutFrameProps );
1079             }
1080             else
1081                 OSL_ENSURE( false, "OCommonEmbeddedObject::setPersistentEntry: illegal type for argument 'OutplaceFrameProperties'!" );
1082 		}
1083 		else if ( lObjArgs[nObjInd].Name.equalsAscii( "ModuleName" ) )
1084 		{
1085 			lObjArgs[nObjInd].Value >>= m_aModuleName;
1086 		}
1087 		else if ( lObjArgs[nObjInd].Name.equalsAscii( "EmbeddedScriptSupport" ) )
1088         {
1089 			OSL_VERIFY( lObjArgs[nObjInd].Value >>= m_bEmbeddedScriptSupport );
1090         }
1091 		else if ( lObjArgs[nObjInd].Name.equalsAscii( "DocumentRecoverySupport" ) )
1092         {
1093 			OSL_VERIFY( lObjArgs[nObjInd].Value >>= m_bDocumentRecoverySupport );
1094         }
1095         else if ( lObjArgs[nObjInd].Name.equalsAscii( "RecoveryStorage" ) )
1096         {
1097 			OSL_VERIFY( lObjArgs[nObjInd].Value >>= m_xRecoveryStorage );
1098         }
1099 
1100 
1101 	sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
1102 
1103 	SwitchOwnPersistence( xStorage, sEntName );
1104 
1105 	if ( nEntryConnectionMode == embed::EntryInitModes::DEFAULT_INIT )
1106 	{
1107 		if ( bElExists )
1108 		{
1109 			// the initialization from existing storage allows to leave object in loaded state
1110 			m_nObjectState = embed::EmbedStates::LOADED;
1111 		}
1112 		else
1113 		{
1114             m_pDocHolder->SetComponent( InitNewDocument_Impl(), m_bReadOnly );
1115             if ( !m_pDocHolder->GetComponent().is() )
1116 				throw io::IOException(); // TODO: can not create document
1117 
1118 			m_nObjectState = embed::EmbedStates::RUNNING;
1119 		}
1120 	}
1121 	else
1122 	{
1123 		if ( ( nStorageMode & embed::ElementModes::READWRITE ) != embed::ElementModes::READWRITE )
1124 			throw io::IOException();
1125 
1126 		if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
1127 		{
1128 			// the document just already changed its storage to store to
1129 			// the links to OOo documents for now ignore this call
1130 			// TODO: OOo links will have persistence so it will be switched here
1131 		}
1132 		else if ( nEntryConnectionMode == embed::EntryInitModes::TRUNCATE_INIT )
1133 		{
1134             if ( m_xRecoveryStorage.is() )
1135                 TransferMediaType( m_xRecoveryStorage, m_xObjectStorage );
1136 
1137 			// TODO:
1138             m_pDocHolder->SetComponent( InitNewDocument_Impl(), m_bReadOnly );
1139 
1140             if ( !m_pDocHolder->GetComponent().is() )
1141 				throw io::IOException(); // TODO: can not create document
1142 
1143 			m_nObjectState = embed::EmbedStates::RUNNING;
1144 		}
1145 		else if ( nEntryConnectionMode == embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT )
1146 		{
1147             m_pDocHolder->SetComponent( CreateDocFromMediaDescr_Impl( lArguments ), m_bReadOnly );
1148 			m_nObjectState = embed::EmbedStates::RUNNING;
1149 		}
1150 		//else if ( nEntryConnectionMode == embed::EntryInitModes::TRANSFERABLE_INIT )
1151 		//{
1152 			//TODO:
1153 		//}
1154 		else
1155 			throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Wrong connection mode is provided!\n" ),
1156 										uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1157 										3 );
1158 	}
1159 }
1160 
1161 //------------------------------------------------------
1162 void SAL_CALL OCommonEmbeddedObject::storeToEntry( const uno::Reference< embed::XStorage >& xStorage,
1163 							const ::rtl::OUString& sEntName,
1164 							const uno::Sequence< beans::PropertyValue >& lArguments,
1165 							const uno::Sequence< beans::PropertyValue >& lObjArgs )
1166 		throw ( lang::IllegalArgumentException,
1167 				embed::WrongStateException,
1168 				io::IOException,
1169 				uno::Exception,
1170 				uno::RuntimeException )
1171 {
1172 	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::storeToEntry" );
1173 
1174 	::osl::ResettableMutexGuard aGuard( m_aMutex );
1175 	if ( m_bDisposed )
1176 		throw lang::DisposedException(); // TODO
1177 
1178 	if ( m_nObjectState == -1 )
1179 	{
1180 		// the object is still not loaded
1181 		throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ),
1182 										uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1183 	}
1184 
1185 	if ( m_bWaitSaveCompleted )
1186 		throw embed::WrongStateException(
1187 					::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1188 					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1189 
1190 	// for now support of this interface is required to allow breaking of links and converting them to normal embedded
1191 	// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
1192 	// OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
1193 	if ( m_bIsLink )
1194 		return;
1195 
1196 	OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" );
1197 
1198 	sal_Int32 nTargetStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1199 	sal_Int32 nOriginalStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1200 	try {
1201 		nTargetStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( xStorage );
1202 	}
1203 	catch ( beans::IllegalTypeException& )
1204 	{
1205 		// the container just has an unknown type, use current file format
1206 	}
1207 	catch ( uno::Exception& )
1208 	{
1209 		OSL_ENSURE( sal_False, "Can not retrieve target storage media type!\n" );
1210 	}
1211 
1212 	try
1213 	{
1214 		nOriginalStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
1215 	}
1216 	catch ( beans::IllegalTypeException& )
1217 	{
1218 		// the container just has an unknown type, use current file format
1219 	}
1220 	catch ( uno::Exception& )
1221 	{
1222 		OSL_ENSURE( sal_False, "Can not retrieve own storage media type!\n" );
1223 	}
1224 
1225 	sal_Bool bTryOptimization = sal_False;
1226 	for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
1227 	{
1228 		// StoreVisualReplacement and VisualReplacement args have no sence here
1229 		if ( lObjArgs[nInd].Name.equalsAscii( "CanTryOptimization" ) )
1230 			lObjArgs[nInd].Value >>= bTryOptimization;
1231 	}
1232 
1233 	sal_Bool bSwitchBackToLoaded = sal_False;
1234 
1235 	// Storing to different format can be done only in running state.
1236 	if ( m_nObjectState == embed::EmbedStates::LOADED )
1237 	{
1238 		// TODO/LATER: copying is not legal for documents with relative links.
1239 		if ( nTargetStorageFormat == nOriginalStorageFormat )
1240 		{
1241 			sal_Bool bOptimizationWorks = sal_False;
1242 			if ( bTryOptimization )
1243 			{
1244 				try
1245 				{
1246 					// try to use optimized copying
1247 					uno::Reference< embed::XOptimizedStorage > xSource( m_xParentStorage, uno::UNO_QUERY_THROW );
1248 					uno::Reference< embed::XOptimizedStorage > xTarget( xStorage, uno::UNO_QUERY_THROW );
1249 					xSource->copyElementDirectlyTo( m_aEntryName, xTarget, sEntName );
1250 					bOptimizationWorks = sal_True;
1251 				}
1252 				catch( uno::Exception& )
1253 				{
1254 				}
1255 			}
1256 
1257 			if ( !bOptimizationWorks )
1258 				m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName );
1259 		}
1260 		else
1261 		{
1262 			changeState( embed::EmbedStates::RUNNING );
1263 			bSwitchBackToLoaded = sal_True;
1264 		}
1265 	}
1266 
1267 	if ( m_nObjectState != embed::EmbedStates::LOADED )
1268 	{
1269 		uno::Reference< embed::XStorage > xSubStorage =
1270 					xStorage->openStorageElement( sEntName, embed::ElementModes::READWRITE );
1271 
1272 		if ( !xSubStorage.is() )
1273 			throw uno::RuntimeException(); //TODO
1274 
1275 		aGuard.clear();
1276 		// TODO/LATER: support hierarchical name for embedded objects in embedded objects
1277 		StoreDocToStorage_Impl( xSubStorage, nTargetStorageFormat, GetBaseURLFrom_Impl( lArguments, lObjArgs ), sEntName, sal_False );
1278 		aGuard.reset();
1279 
1280 		if ( bSwitchBackToLoaded )
1281 			changeState( embed::EmbedStates::LOADED );
1282 	}
1283 
1284 	// TODO: should the listener notification be done?
1285 }
1286 
1287 //------------------------------------------------------
1288 void SAL_CALL OCommonEmbeddedObject::storeAsEntry( const uno::Reference< embed::XStorage >& xStorage,
1289 							const ::rtl::OUString& sEntName,
1290 							const uno::Sequence< beans::PropertyValue >& lArguments,
1291 							const uno::Sequence< beans::PropertyValue >& lObjArgs )
1292 		throw ( lang::IllegalArgumentException,
1293 				embed::WrongStateException,
1294 				io::IOException,
1295 				uno::Exception,
1296 				uno::RuntimeException )
1297 {
1298 	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::storeAsEntry" );
1299 
1300 	// TODO: use lObjArgs
1301 
1302 	::osl::ResettableMutexGuard aGuard( m_aMutex );
1303 	if ( m_bDisposed )
1304 		throw lang::DisposedException(); // TODO
1305 
1306 	if ( m_nObjectState == -1 )
1307 	{
1308 		// the object is still not loaded
1309 		throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ),
1310 										uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1311 	}
1312 
1313 	if ( m_bWaitSaveCompleted )
1314 		throw embed::WrongStateException(
1315 					::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1316 					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1317 
1318 	// for now support of this interface is required to allow breaking of links and converting them to normal embedded
1319 	// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
1320 	// OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
1321 	if ( m_bIsLink )
1322 	{
1323     	m_aNewEntryName = sEntName;
1324 		return;
1325 	}
1326 
1327 	OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" );
1328 
1329 	sal_Int32 nTargetStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1330 	sal_Int32 nOriginalStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1331 	try {
1332 		nTargetStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( xStorage );
1333 	}
1334 	catch ( beans::IllegalTypeException& )
1335 	{
1336 		// the container just has an unknown type, use current file format
1337 	}
1338 	catch ( uno::Exception& )
1339 	{
1340 		OSL_ENSURE( sal_False, "Can not retrieve target storage media type!\n" );
1341 	}
1342 
1343 	try
1344 	{
1345 		nOriginalStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
1346 	}
1347 	catch ( beans::IllegalTypeException& )
1348 	{
1349 		// the container just has an unknown type, use current file format
1350 	}
1351 	catch ( uno::Exception& )
1352 	{
1353 		OSL_ENSURE( sal_False, "Can not retrieve own storage media type!\n" );
1354 	}
1355 
1356 	PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSaveAs" ) );
1357 
1358 	sal_Bool bTryOptimization = sal_False;
1359 	for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
1360 	{
1361 		// StoreVisualReplacement and VisualReplacement args have no sence here
1362 		if ( lObjArgs[nInd].Name.equalsAscii( "CanTryOptimization" ) )
1363 			lObjArgs[nInd].Value >>= bTryOptimization;
1364 	}
1365 
1366 	sal_Bool bSwitchBackToLoaded = sal_False;
1367 
1368 	// Storing to different format can be done only in running state.
1369 	if ( m_nObjectState == embed::EmbedStates::LOADED )
1370 	{
1371 		// TODO/LATER: copying is not legal for documents with relative links.
1372 		if ( nTargetStorageFormat == nOriginalStorageFormat )
1373 		{
1374 			sal_Bool bOptimizationWorks = sal_False;
1375 			if ( bTryOptimization )
1376 			{
1377 				try
1378 				{
1379 					// try to use optimized copying
1380 					uno::Reference< embed::XOptimizedStorage > xSource( m_xParentStorage, uno::UNO_QUERY_THROW );
1381 					uno::Reference< embed::XOptimizedStorage > xTarget( xStorage, uno::UNO_QUERY_THROW );
1382 					xSource->copyElementDirectlyTo( m_aEntryName, xTarget, sEntName );
1383 					bOptimizationWorks = sal_True;
1384 				}
1385 				catch( uno::Exception& )
1386 				{
1387 				}
1388 			}
1389 
1390 			if ( !bOptimizationWorks )
1391 				m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName );
1392 		}
1393 		else
1394 		{
1395 			changeState( embed::EmbedStates::RUNNING );
1396 			bSwitchBackToLoaded = sal_True;
1397 		}
1398 	}
1399 
1400 	uno::Reference< embed::XStorage > xSubStorage =
1401 				xStorage->openStorageElement( sEntName, embed::ElementModes::READWRITE );
1402 
1403 	if ( !xSubStorage.is() )
1404 		throw uno::RuntimeException(); //TODO
1405 
1406 	if ( m_nObjectState != embed::EmbedStates::LOADED )
1407 	{
1408 		aGuard.clear();
1409 		// TODO/LATER: support hierarchical name for embedded objects in embedded objects
1410 		StoreDocToStorage_Impl( xSubStorage, nTargetStorageFormat, GetBaseURLFrom_Impl( lArguments, lObjArgs ), sEntName, sal_False );
1411 		aGuard.reset();
1412 
1413 		if ( bSwitchBackToLoaded )
1414 			changeState( embed::EmbedStates::LOADED );
1415 	}
1416 
1417 	m_bWaitSaveCompleted = sal_True;
1418 	m_xNewObjectStorage = xSubStorage;
1419 	m_xNewParentStorage = xStorage;
1420     m_aNewEntryName = sEntName;
1421 	m_aNewDocMediaDescriptor = GetValuableArgs_Impl( lArguments, sal_True );
1422 
1423 	// TODO: register listeners for storages above, in case thay are disposed
1424 	// 		 an exception will be thrown on saveCompleted( true )
1425 
1426 	// TODO: should the listener notification be done here or in saveCompleted?
1427 }
1428 
1429 //------------------------------------------------------
1430 void SAL_CALL OCommonEmbeddedObject::saveCompleted( sal_Bool bUseNew )
1431 		throw ( embed::WrongStateException,
1432 				uno::Exception,
1433 				uno::RuntimeException )
1434 {
1435 	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::saveCompleted" );
1436 
1437 	::osl::MutexGuard aGuard( m_aMutex );
1438 	if ( m_bDisposed )
1439 		throw lang::DisposedException(); // TODO
1440 
1441 	if ( m_nObjectState == -1 )
1442 	{
1443 		// the object is still not loaded
1444 		throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ),
1445 										uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1446 	}
1447 
1448 	// for now support of this interface is required to allow breaking of links and converting them to normal embedded
1449 	// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
1450 	// OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
1451 	if ( m_bIsLink )
1452 	{
1453 		if ( bUseNew )
1454 			m_aEntryName = m_aNewEntryName;
1455 		m_aNewEntryName = ::rtl::OUString();
1456 		return;
1457 	}
1458 
1459 	// it is allowed to call saveCompleted( false ) for nonstored objects
1460 	if ( !m_bWaitSaveCompleted && !bUseNew )
1461 		return;
1462 
1463 	OSL_ENSURE( m_bWaitSaveCompleted, "Unexpected saveCompleted() call!\n" );
1464 	if ( !m_bWaitSaveCompleted )
1465 		throw io::IOException(); // TODO: illegal call
1466 
1467 	OSL_ENSURE( m_xNewObjectStorage.is() && m_xNewParentStorage.is() , "Internal object information is broken!\n" );
1468 	if ( !m_xNewObjectStorage.is() || !m_xNewParentStorage.is() )
1469 		throw uno::RuntimeException(); // TODO: broken internal information
1470 
1471 	if ( bUseNew )
1472 	{
1473 		SwitchOwnPersistence( m_xNewParentStorage, m_xNewObjectStorage, m_aNewEntryName );
1474 		m_aDocMediaDescriptor = m_aNewDocMediaDescriptor;
1475 
1476 		uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
1477 		if ( xModif.is() )
1478 			xModif->setModified( sal_False );
1479 
1480 		PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSaveAsDone" ) );
1481 	}
1482 	else
1483 	{
1484 		try {
1485 			uno::Reference< lang::XComponent > xComponent( m_xNewObjectStorage, uno::UNO_QUERY );
1486 			OSL_ENSURE( xComponent.is(), "Wrong storage implementation!" );
1487 			if ( xComponent.is() )
1488 				xComponent->dispose();
1489 		}
1490 		catch ( uno::Exception& )
1491 		{
1492 		}
1493 	}
1494 
1495 	m_xNewObjectStorage = uno::Reference< embed::XStorage >();
1496 	m_xNewParentStorage = uno::Reference< embed::XStorage >();
1497 	m_aNewEntryName = ::rtl::OUString();
1498 	m_aNewDocMediaDescriptor.realloc( 0 );
1499 	m_bWaitSaveCompleted = sal_False;
1500 
1501 	if ( bUseNew )
1502 	{
1503 		// TODO: notify listeners
1504 
1505 		if ( m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE )
1506 		{
1507 			// TODO: update visual representation
1508 		}
1509 	}
1510 }
1511 
1512 //------------------------------------------------------
1513 sal_Bool SAL_CALL OCommonEmbeddedObject::hasEntry()
1514 		throw ( embed::WrongStateException,
1515 				uno::RuntimeException )
1516 {
1517 	::osl::MutexGuard aGuard( m_aMutex );
1518 	if ( m_bDisposed )
1519 		throw lang::DisposedException(); // TODO
1520 
1521 	if ( m_bWaitSaveCompleted )
1522 		throw embed::WrongStateException(
1523 					::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1524 					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1525 
1526 	if ( m_xObjectStorage.is() )
1527 		return sal_True;
1528 
1529 	return sal_False;
1530 }
1531 
1532 //------------------------------------------------------
1533 ::rtl::OUString SAL_CALL OCommonEmbeddedObject::getEntryName()
1534 		throw ( embed::WrongStateException,
1535 				uno::RuntimeException )
1536 {
1537 	::osl::MutexGuard aGuard( m_aMutex );
1538 	if ( m_bDisposed )
1539 		throw lang::DisposedException(); // TODO
1540 
1541 	if ( m_nObjectState == -1 )
1542 	{
1543 		// the object is still not loaded
1544 		throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\n" ),
1545 										uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1546 	}
1547 
1548 	if ( m_bWaitSaveCompleted )
1549 		throw embed::WrongStateException(
1550 					::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1551 					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1552 
1553 	return m_aEntryName;
1554 }
1555 
1556 //------------------------------------------------------
1557 void SAL_CALL OCommonEmbeddedObject::storeOwn()
1558 		throw ( embed::WrongStateException,
1559 				io::IOException,
1560 				uno::Exception,
1561 				uno::RuntimeException )
1562 {
1563 	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::storeOwn" );
1564 
1565 	// during switching from Activated to Running and from Running to Loaded states the object will
1566 	// ask container to store the object, the container has to make decision
1567 	// to do so or not
1568 
1569 	::osl::ResettableMutexGuard aGuard( m_aMutex );
1570 	if ( m_bDisposed )
1571 		throw lang::DisposedException(); // TODO
1572 
1573 	if ( m_nObjectState == -1 )
1574 	{
1575 		// the object is still not loaded
1576 		throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ),
1577 									uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1578 	}
1579 
1580 	if ( m_bWaitSaveCompleted )
1581 		throw embed::WrongStateException(
1582 					::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1583 					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1584 
1585 	if ( m_bReadOnly )
1586 		throw io::IOException(); // TODO: access denied
1587 
1588 	// nothing to do, if the object is in loaded state
1589 	if ( m_nObjectState == embed::EmbedStates::LOADED )
1590 		return;
1591 
1592 	PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSave" ) );
1593 
1594     OSL_ENSURE( m_pDocHolder->GetComponent().is(), "If an object is activated or in running state it must have a document!\n" );
1595     if ( !m_pDocHolder->GetComponent().is() )
1596 		throw uno::RuntimeException();
1597 
1598 	if ( m_bIsLink )
1599 	{
1600 		// TODO: just store the document to it's location
1601 		uno::Reference< frame::XStorable > xStorable( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
1602 		if ( !xStorable.is() )
1603 			throw uno::RuntimeException(); // TODO
1604 
1605         // free the main mutex for the storing time
1606         aGuard.clear();
1607 
1608         xStorable->store();
1609 
1610         aGuard.reset();
1611 	}
1612 	else
1613 	{
1614 		OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" );
1615 
1616 		if ( !m_xObjectStorage.is() )
1617 			throw io::IOException(); //TODO: access denied
1618 
1619 		sal_Int32 nStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
1620 		try {
1621 			nStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
1622 		}
1623 		catch ( beans::IllegalTypeException& )
1624 		{
1625 			// the container just has an unknown type, use current file format
1626 		}
1627 		catch ( uno::Exception& )
1628 		{
1629 			OSL_ENSURE( sal_False, "Can not retrieve storage media type!\n" );
1630 		}
1631 
1632 		aGuard.clear();
1633 		StoreDocToStorage_Impl( m_xObjectStorage, nStorageFormat, GetBaseURL_Impl(), m_aEntryName, sal_True );
1634 		aGuard.reset();
1635 	}
1636 
1637 	uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
1638 	if ( xModif.is() )
1639 		xModif->setModified( sal_False );
1640 
1641 	PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSaveDone" ) );
1642 }
1643 
1644 //------------------------------------------------------
1645 sal_Bool SAL_CALL OCommonEmbeddedObject::isReadonly()
1646 		throw ( embed::WrongStateException,
1647 				uno::RuntimeException )
1648 {
1649 	::osl::MutexGuard aGuard( m_aMutex );
1650 	if ( m_bDisposed )
1651 		throw lang::DisposedException(); // TODO
1652 
1653 	if ( m_nObjectState == -1 )
1654 	{
1655 		// the object is still not loaded
1656 		throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\n" ),
1657 										uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1658 	}
1659 
1660 	if ( m_bWaitSaveCompleted )
1661 		throw embed::WrongStateException(
1662 					::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1663 					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1664 
1665 	return m_bReadOnly;
1666 }
1667 
1668 //------------------------------------------------------
1669 void SAL_CALL OCommonEmbeddedObject::reload(
1670 				const uno::Sequence< beans::PropertyValue >& lArguments,
1671 				const uno::Sequence< beans::PropertyValue >& lObjArgs )
1672 		throw ( lang::IllegalArgumentException,
1673 				embed::WrongStateException,
1674 				io::IOException,
1675 				uno::Exception,
1676 				uno::RuntimeException )
1677 {
1678 	// TODO: use lObjArgs
1679 	// for now this method is used only to switch readonly state
1680 
1681 	::osl::MutexGuard aGuard( m_aMutex );
1682 	if ( m_bDisposed )
1683 		throw lang::DisposedException(); // TODO
1684 
1685 	if ( m_nObjectState == -1 )
1686 	{
1687 		// the object is still not loaded
1688 		throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\n" ),
1689 										uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1690 	}
1691 
1692 	if ( m_nObjectState != embed::EmbedStates::LOADED )
1693 	{
1694 		// the object is still not loaded
1695 		throw embed::WrongStateException(
1696 								::rtl::OUString::createFromAscii( "The object must be in loaded state to be reloaded!\n" ),
1697 								uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1698 	}
1699 
1700 	if ( m_bWaitSaveCompleted )
1701 		throw embed::WrongStateException(
1702 					::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1703 					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1704 
1705 	if ( m_bIsLink )
1706 	{
1707 		// reload of the link
1708 		::rtl::OUString aOldLinkFilter = m_aLinkFilterName;
1709 
1710 		::rtl::OUString aNewLinkFilter;
1711 		for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
1712 		{
1713 			if ( lArguments[nInd].Name.equalsAscii( "URL" ) )
1714 			{
1715 				// the new URL
1716 				lArguments[nInd].Value >>= m_aLinkURL;
1717 				m_aLinkFilterName = ::rtl::OUString();
1718 			}
1719 			else if ( lArguments[nInd].Name.equalsAscii( "FilterName" ) )
1720 			{
1721 				lArguments[nInd].Value >>= aNewLinkFilter;
1722 				m_aLinkFilterName = ::rtl::OUString();
1723 			}
1724 		}
1725 
1726 		::comphelper::MimeConfigurationHelper aHelper( m_xFactory );
1727 		if ( !m_aLinkFilterName.getLength() )
1728 		{
1729 			if ( aNewLinkFilter.getLength() )
1730 				m_aLinkFilterName = aNewLinkFilter;
1731 			else
1732 			{
1733 				uno::Sequence< beans::PropertyValue > aArgs( 1 );
1734 				aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
1735 				aArgs[0].Value <<= m_aLinkURL;
1736 				m_aLinkFilterName = aHelper.UpdateMediaDescriptorWithFilterName( aArgs, sal_False );
1737 			}
1738 		}
1739 
1740 		if ( !aOldLinkFilter.equals( m_aLinkFilterName ) )
1741 		{
1742 			uno::Sequence< beans::NamedValue > aObject = aHelper.GetObjectPropsByFilter( m_aLinkFilterName );
1743 
1744 			// TODO/LATER: probably the document holder could be cleaned explicitly as in the destructor
1745 			m_pDocHolder->release();
1746 			m_pDocHolder = NULL;
1747 
1748 			LinkInit_Impl( aObject, lArguments, lObjArgs );
1749 		}
1750 	}
1751 
1752 	m_aDocMediaDescriptor = GetValuableArgs_Impl( lArguments, sal_True );
1753 
1754 	// TODO: use lObjArgs for StoreVisualReplacement
1755 	for ( sal_Int32 nObjInd = 0; nObjInd < lObjArgs.getLength(); nObjInd++ )
1756 		if ( lObjArgs[nObjInd].Name.equalsAscii( "OutplaceDispatchInterceptor" ) )
1757 		{
1758 			uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor;
1759 			if ( lObjArgs[nObjInd].Value >>= xDispatchInterceptor )
1760 				m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor );
1761 
1762 			break;
1763 		}
1764 
1765 	// TODO:
1766 	// when document allows reloading through API the object can be reloaded not only in loaded state
1767 
1768 	sal_Bool bOldReadOnlyValue = m_bReadOnly;
1769 
1770 	m_bReadOnly = sal_False;
1771 	for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
1772 		if ( lArguments[nInd].Name.equalsAscii( "ReadOnly" ) )
1773 			lArguments[nInd].Value >>= m_bReadOnly;
1774 
1775 	if ( bOldReadOnlyValue != m_bReadOnly && !m_bIsLink )
1776 	{
1777 		// close own storage
1778 		try {
1779 			uno::Reference< lang::XComponent > xComponent( m_xObjectStorage, uno::UNO_QUERY );
1780 			OSL_ENSURE( !m_xObjectStorage.is() || xComponent.is(), "Wrong storage implementation!" );
1781 			if ( xComponent.is() )
1782 				xComponent->dispose();
1783 		}
1784 		catch ( uno::Exception& )
1785 		{
1786 		}
1787 
1788 		sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
1789 		m_xObjectStorage = m_xParentStorage->openStorageElement( m_aEntryName, nStorageMode );
1790 	}
1791 }
1792 
1793 //------------------------------------------------------
1794 void SAL_CALL OCommonEmbeddedObject::breakLink( const uno::Reference< embed::XStorage >& xStorage,
1795 												const ::rtl::OUString& sEntName )
1796 		throw ( lang::IllegalArgumentException,
1797 				embed::WrongStateException,
1798 				io::IOException,
1799 				uno::Exception,
1800 				uno::RuntimeException )
1801 {
1802 	::osl::ResettableMutexGuard aGuard( m_aMutex );
1803 	if ( m_bDisposed )
1804 		throw lang::DisposedException(); // TODO
1805 
1806 	if ( !m_bIsLink )
1807 	{
1808 		// it must be a linked initialized object
1809 		throw embed::WrongStateException(
1810 					::rtl::OUString::createFromAscii( "The object is not a valid linked object!\n" ),
1811 					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1812 	}
1813 #if 0
1814 	else
1815 	{
1816 		// the current implementation of OOo links does not implement this method since it does not implement
1817 		// all the set of interfaces required for OOo embedded object ( XEmbedPersist is not supported ).
1818 		throw io::IOException(); // TODO:
1819 	}
1820 #endif
1821 
1822 	if ( !xStorage.is() )
1823 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
1824 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1825 											1 );
1826 
1827 	if ( !sEntName.getLength() )
1828 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
1829 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
1830 											2 );
1831 
1832 	if ( !m_bIsLink || m_nObjectState == -1 )
1833 	{
1834 		// it must be a linked initialized object
1835 		throw embed::WrongStateException(
1836 					::rtl::OUString::createFromAscii( "The object is not a valid linked object!\n" ),
1837 					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1838 	}
1839 
1840 	if ( m_bWaitSaveCompleted )
1841 		throw embed::WrongStateException(
1842 					::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1843 					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1844 
1845 	uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
1846 	if ( !xNameAccess.is() )
1847 		throw uno::RuntimeException(); //TODO
1848 
1849 	// detect entry existence
1850 	/*sal_Bool bElExists =*/ xNameAccess->hasByName( sEntName );
1851 
1852 	m_bReadOnly = sal_False;
1853 //	sal_Int32 nStorageMode = embed::ElementModes::READWRITE;
1854 
1855 	if ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) )
1856 		SwitchOwnPersistence( xStorage, sEntName );
1857 
1858 	// for linked object it means that it becomes embedded object
1859 	// the document must switch it's persistence also
1860 
1861 	// TODO/LATER: handle the case when temp doc can not be created
1862 	// the document is a new embedded object so it must be marked as modified
1863     uno::Reference< util::XCloseable > xDocument = CreateTempDocFromLink_Impl();
1864     uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
1865 	if ( !xModif.is() )
1866 		throw uno::RuntimeException();
1867 	try
1868 	{
1869 		xModif->setModified( sal_True );
1870 	}
1871 	catch( uno::Exception& )
1872 	{}
1873 
1874     m_pDocHolder->SetComponent( xDocument, m_bReadOnly );
1875     OSL_ENSURE( m_pDocHolder->GetComponent().is(), "If document cant be created, an exception must be thrown!\n" );
1876 
1877 	if ( m_nObjectState == embed::EmbedStates::LOADED )
1878 	{
1879 		// the state is changed and can not be switched to loaded state back without saving
1880 		m_nObjectState = embed::EmbedStates::RUNNING;
1881 		StateChangeNotification_Impl( sal_False, embed::EmbedStates::LOADED, m_nObjectState, aGuard );
1882 	}
1883 	else if ( m_nObjectState == embed::EmbedStates::ACTIVE )
1884 		m_pDocHolder->Show();
1885 
1886 	m_bIsLink = sal_False;
1887 	m_aLinkFilterName = ::rtl::OUString();
1888 	m_aLinkURL = ::rtl::OUString();
1889 }
1890 
1891 //------------------------------------------------------
1892 sal_Bool SAL_CALL  OCommonEmbeddedObject::isLink()
1893 		throw ( embed::WrongStateException,
1894 				uno::RuntimeException )
1895 {
1896 	::osl::MutexGuard aGuard( m_aMutex );
1897 	if ( m_bDisposed )
1898 		throw lang::DisposedException(); // TODO
1899 
1900 	// Actually this information is clear even in case object is wayting for saveCompleted
1901 	// if ( m_bWaitSaveCompleted )
1902 	//	throw embed::WrongStateException(
1903 	//				::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1904 	//				uno::Reference< uno::XInterface >( reinterpret_cast< ::cppu::OWeakObject* >(this) ) );
1905 
1906 	return m_bIsLink;
1907 }
1908 
1909 //------------------------------------------------------
1910 ::rtl::OUString SAL_CALL OCommonEmbeddedObject::getLinkURL()
1911 		throw ( embed::WrongStateException,
1912 				uno::Exception,
1913 				uno::RuntimeException )
1914 {
1915 	::osl::MutexGuard aGuard( m_aMutex );
1916 	if ( m_bDisposed )
1917 		throw lang::DisposedException(); // TODO
1918 
1919 	// Actually this information is clear even in case object is wayting for saveCompleted
1920 	// if ( m_bWaitSaveCompleted )
1921 	// 	throw embed::WrongStateException(
1922 	// 				::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
1923 	// 				uno::Reference< uno::XInterface >( reinterpret_cast< ::cppu::OWeakObject* >(this) ) );
1924 
1925 	if ( !m_bIsLink )
1926 		throw embed::WrongStateException(
1927 					::rtl::OUString::createFromAscii( "The object is not a link object!\n" ),
1928 					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
1929 
1930 	return m_aLinkURL;
1931 }
1932 
1933