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