1 /************************************************************************* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * Copyright 2009 by Sun Microsystems, Inc. 5 * 6 * OpenOffice.org - a multi-platform office productivity suite 7 * 8 * This file is part of OpenOffice.org. 9 * 10 * OpenOffice.org is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License version 3 12 * only, as published by the Free Software Foundation. 13 * 14 * OpenOffice.org is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License version 3 for more details 18 * (a copy is included in the LICENSE file that accompanied this code). 19 * 20 * You should have received a copy of the GNU Lesser General Public License 21 * version 3 along with OpenOffice.org. If not, see 22 * <http://www.openoffice.org/license.html> 23 * for a copy of the LGPLv3 License. 24 ************************************************************************/ 25 26 #include "precompiled_dbaccess.hxx" 27 28 #include "subcomponentrecovery.hxx" 29 30 #include "sdbcoretools.hxx" 31 #include "storagexmlstream.hxx" 32 #include "subcomponentloader.hxx" 33 #include "settingsimport.hxx" 34 35 /** === begin UNO includes === **/ 36 #include <com/sun/star/embed/ElementModes.hpp> 37 #include <com/sun/star/frame/XModuleManager.hpp> 38 #include <com/sun/star/document/XStorageBasedDocument.hpp> 39 #include <com/sun/star/ucb/XCommandProcessor.hpp> 40 #include <com/sun/star/container/XHierarchicalNameAccess.hpp> 41 #include <com/sun/star/sdb/XFormDocumentsSupplier.hpp> 42 #include <com/sun/star/sdb/XReportDocumentsSupplier.hpp> 43 #include <com/sun/star/xml/sax/XDocumentHandler.hpp> 44 /** === end UNO includes === **/ 45 46 #include <comphelper/namedvaluecollection.hxx> 47 #include <connectivity/dbtools.hxx> 48 #include <tools/diagnose_ex.h> 49 #include <xmloff/XMLSettingsExportContext.hxx> 50 #include <xmloff/SettingsExportHelper.hxx> 51 52 //........................................................................ 53 namespace dbaccess 54 { 55 //........................................................................ 56 57 /** === begin UNO using === **/ 58 using ::com::sun::star::uno::Reference; 59 using ::com::sun::star::uno::XInterface; 60 using ::com::sun::star::uno::UNO_QUERY; 61 using ::com::sun::star::uno::UNO_QUERY_THROW; 62 using ::com::sun::star::uno::UNO_SET_THROW; 63 using ::com::sun::star::uno::Exception; 64 using ::com::sun::star::uno::RuntimeException; 65 using ::com::sun::star::uno::Any; 66 using ::com::sun::star::uno::makeAny; 67 using ::com::sun::star::uno::Sequence; 68 using ::com::sun::star::uno::Type; 69 using ::com::sun::star::lang::XMultiServiceFactory; 70 using ::com::sun::star::embed::XStorage; 71 using ::com::sun::star::sdb::application::XDatabaseDocumentUI; 72 using ::com::sun::star::beans::Pair; 73 using ::com::sun::star::frame::XModuleManager; 74 using ::com::sun::star::lang::XComponent; 75 using ::com::sun::star::frame::XModel; 76 using ::com::sun::star::frame::XController; 77 using ::com::sun::star::beans::XPropertySet; 78 using ::com::sun::star::beans::PropertyValue; 79 using ::com::sun::star::document::XStorageBasedDocument; 80 using ::com::sun::star::ucb::XCommandProcessor; 81 using ::com::sun::star::container::XHierarchicalNameAccess; 82 using ::com::sun::star::sdb::XFormDocumentsSupplier; 83 using ::com::sun::star::sdb::XReportDocumentsSupplier; 84 using ::com::sun::star::xml::sax::SAXException; 85 using ::com::sun::star::xml::sax::XLocator; 86 using ::com::sun::star::xml::sax::XDocumentHandler; 87 using ::com::sun::star::xml::sax::XAttributeList; 88 /** === end UNO using === **/ 89 90 namespace ElementModes = ::com::sun::star::embed::ElementModes; 91 92 93 //==================================================================== 94 //= helper 95 //==================================================================== 96 namespace 97 { 98 // ......................................................................... 99 static const ::rtl::OUString& lcl_getComponentStorageBaseName( const SubComponentType i_eType ) 100 { 101 static const ::rtl::OUString s_sFormBaseName( RTL_CONSTASCII_USTRINGPARAM( "form" ) ); 102 static const ::rtl::OUString s_sReportBaseName( RTL_CONSTASCII_USTRINGPARAM( "report" ) ); 103 static const ::rtl::OUString s_sTableBaseName( RTL_CONSTASCII_USTRINGPARAM( "table" ) ); 104 static const ::rtl::OUString s_sQueryBaseName( RTL_CONSTASCII_USTRINGPARAM( "query" ) ); 105 106 switch ( i_eType ) 107 { 108 case FORM: 109 return s_sFormBaseName; 110 case REPORT: 111 return s_sReportBaseName; 112 case TABLE: 113 return s_sTableBaseName; 114 case QUERY: 115 return s_sQueryBaseName; 116 default: 117 break; 118 } 119 120 OSL_ENSURE( false, "lcl_getComponentStorageBaseName: unimplemented case!" ); 121 static const ::rtl::OUString s_sFallback; 122 return s_sFallback; 123 } 124 125 // ......................................................................... 126 static SubComponentType lcl_databaseObjectToSubComponentType( const sal_Int32 i_nObjectType ) 127 { 128 switch ( i_nObjectType ) 129 { 130 case DatabaseObject::TABLE: return TABLE; 131 case DatabaseObject::QUERY: return QUERY; 132 case DatabaseObject::FORM: return FORM; 133 case DatabaseObject::REPORT:return REPORT; 134 default: 135 break; 136 } 137 return UNKNOWN; 138 } 139 140 // ......................................................................... 141 static bool lcl_determineReadOnly( const Reference< XComponent >& i_rComponent ) 142 { 143 Reference< XModel > xDocument( i_rComponent, UNO_QUERY ); 144 if ( !xDocument.is() ) 145 { 146 Reference< XController > xController( i_rComponent, UNO_QUERY_THROW ); 147 xDocument = xController->getModel(); 148 } 149 150 if ( !xDocument.is() ) 151 return false; 152 153 ::comphelper::NamedValueCollection aDocArgs( xDocument->getArgs() ); 154 return aDocArgs.getOrDefault( "ReadOnly", false ); 155 } 156 157 // ......................................................................... 158 static Reference< XCommandProcessor > lcl_getSubComponentDef_nothrow( const Reference< XDatabaseDocumentUI >& i_rAppUI, 159 const SubComponentType i_eType, const ::rtl::OUString& i_rName ) 160 { 161 Reference< XController > xController( i_rAppUI, UNO_QUERY_THROW ); 162 ENSURE_OR_RETURN( ( i_eType == FORM ) || ( i_eType == REPORT ), "lcl_getSubComponentDef_nothrow: illegal controller", NULL ); 163 164 Reference< XCommandProcessor > xCommandProcessor; 165 try 166 { 167 Reference< XHierarchicalNameAccess > xDefinitionContainer; 168 if ( i_eType == FORM ) 169 { 170 Reference< XFormDocumentsSupplier > xSuppForms( xController->getModel(), UNO_QUERY_THROW ); 171 xDefinitionContainer.set( xSuppForms->getFormDocuments(), UNO_QUERY_THROW ); 172 } 173 else 174 { 175 Reference< XReportDocumentsSupplier > xSuppReports( xController->getModel(), UNO_QUERY_THROW ); 176 xDefinitionContainer.set( xSuppReports->getReportDocuments(), UNO_QUERY_THROW ); 177 } 178 xCommandProcessor.set( xDefinitionContainer->getByHierarchicalName( i_rName ), UNO_QUERY_THROW ); 179 } 180 catch( const Exception& ) 181 { 182 DBG_UNHANDLED_EXCEPTION(); 183 } 184 return xCommandProcessor; 185 } 186 187 // ......................................................................... 188 static const ::rtl::OUString& lcl_getSettingsStreamName() 189 { 190 static const ::rtl::OUString s_sStatementStreamName( RTL_CONSTASCII_USTRINGPARAM( "settings.xml" ) ); 191 return s_sStatementStreamName; 192 } 193 194 // ......................................................................... 195 static const ::rtl::OUString& lcl_getCurrentQueryDesignName() 196 { 197 static const ::rtl::OUString s_sQuerySettingsName( RTL_CONSTASCII_USTRINGPARAM( "ooo:current-query-design" ) ); 198 return s_sQuerySettingsName; 199 } 200 } 201 202 //==================================================================== 203 //= SettingsExportContext 204 //==================================================================== 205 class DBACCESS_DLLPRIVATE SettingsExportContext : public ::xmloff::XMLSettingsExportContext 206 { 207 public: 208 SettingsExportContext( const ::comphelper::ComponentContext& i_rContext, const StorageXMLOutputStream& i_rDelegator ) 209 :m_rContext( i_rContext ) 210 ,m_rDelegator( i_rDelegator ) 211 ,m_aNamespace( ::xmloff::token::GetXMLToken( ::xmloff::token::XML_NP_CONFIG ) ) 212 { 213 } 214 215 virtual ~SettingsExportContext() 216 { 217 } 218 219 public: 220 virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, const ::rtl::OUString& i_rValue ); 221 virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue ); 222 virtual void StartElement( enum ::xmloff::token::XMLTokenEnum i_eName, const sal_Bool i_bIgnoreWhitespace ); 223 virtual void EndElement ( const sal_Bool i_bIgnoreWhitespace ); 224 virtual void Characters( const ::rtl::OUString& i_rCharacters ); 225 226 virtual ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > 227 GetServiceFactory() const; 228 229 private: 230 ::rtl::OUString impl_prefix( const ::xmloff::token::XMLTokenEnum i_eToken ) 231 { 232 ::rtl::OUStringBuffer aQualifiedName( m_aNamespace ); 233 aQualifiedName.append( sal_Unicode( ':' ) ); 234 aQualifiedName.append( ::xmloff::token::GetXMLToken( i_eToken ) ); 235 return aQualifiedName.makeStringAndClear(); 236 } 237 238 private: 239 const ::comphelper::ComponentContext& m_rContext; 240 const StorageXMLOutputStream& m_rDelegator; 241 const ::rtl::OUStringBuffer m_aNamespace; 242 }; 243 244 //-------------------------------------------------------------------- 245 void SettingsExportContext::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, const ::rtl::OUString& i_rValue ) 246 { 247 m_rDelegator.addAttribute( impl_prefix( i_eName ), i_rValue ); 248 } 249 250 //-------------------------------------------------------------------- 251 void SettingsExportContext::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue ) 252 { 253 m_rDelegator.addAttribute( impl_prefix( i_eName ), ::xmloff::token::GetXMLToken( i_eValue ) ); 254 } 255 256 //-------------------------------------------------------------------- 257 void SettingsExportContext::StartElement( enum ::xmloff::token::XMLTokenEnum i_eName, const sal_Bool i_bIgnoreWhitespace ) 258 { 259 if ( i_bIgnoreWhitespace ) 260 m_rDelegator.ignorableWhitespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) ) ); 261 262 m_rDelegator.startElement( impl_prefix( i_eName ) ); 263 } 264 265 //-------------------------------------------------------------------- 266 void SettingsExportContext::EndElement( const sal_Bool i_bIgnoreWhitespace ) 267 { 268 if ( i_bIgnoreWhitespace ) 269 m_rDelegator.ignorableWhitespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) ) ); 270 m_rDelegator.endElement(); 271 } 272 273 //-------------------------------------------------------------------- 274 void SettingsExportContext::Characters( const ::rtl::OUString& i_rCharacters ) 275 { 276 m_rDelegator.characters( i_rCharacters ); 277 } 278 279 //-------------------------------------------------------------------- 280 Reference< XMultiServiceFactory > SettingsExportContext::GetServiceFactory() const 281 { 282 return m_rContext.getLegacyServiceFactory(); 283 } 284 285 //================================================================================================================== 286 //= SettingsDocumentHandler 287 //================================================================================================================== 288 typedef ::cppu::WeakImplHelper1 < XDocumentHandler 289 > SettingsDocumentHandler_Base; 290 class DBACCESS_DLLPRIVATE SettingsDocumentHandler : public SettingsDocumentHandler_Base 291 { 292 public: 293 SettingsDocumentHandler() 294 { 295 } 296 297 protected: 298 virtual ~SettingsDocumentHandler() 299 { 300 } 301 302 public: 303 // XDocumentHandler 304 virtual void SAL_CALL startDocument( ) throw (SAXException, RuntimeException); 305 virtual void SAL_CALL endDocument( ) throw (SAXException, RuntimeException); 306 virtual void SAL_CALL startElement( const ::rtl::OUString& aName, const Reference< XAttributeList >& xAttribs ) throw (SAXException, RuntimeException); 307 virtual void SAL_CALL endElement( const ::rtl::OUString& aName ) throw (SAXException, RuntimeException); 308 virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (SAXException, RuntimeException); 309 virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (SAXException, RuntimeException); 310 virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (SAXException, RuntimeException); 311 virtual void SAL_CALL setDocumentLocator( const Reference< XLocator >& xLocator ) throw (SAXException, RuntimeException); 312 313 const ::comphelper::NamedValueCollection& getSettings() const { return m_aSettings; } 314 315 private: 316 ::std::stack< ::rtl::Reference< SettingsImport > > m_aStates; 317 ::comphelper::NamedValueCollection m_aSettings; 318 }; 319 320 //-------------------------------------------------------------------- 321 void SAL_CALL SettingsDocumentHandler::startDocument( ) throw (SAXException, RuntimeException) 322 { 323 } 324 325 //-------------------------------------------------------------------- 326 void SAL_CALL SettingsDocumentHandler::endDocument( ) throw (SAXException, RuntimeException) 327 { 328 } 329 330 //-------------------------------------------------------------------- 331 void SAL_CALL SettingsDocumentHandler::startElement( const ::rtl::OUString& i_Name, const Reference< XAttributeList >& i_Attribs ) throw (SAXException, RuntimeException) 332 { 333 ::rtl::Reference< SettingsImport > pNewState; 334 335 if ( m_aStates.empty() ) 336 { 337 if ( i_Name.equalsAscii( "office:settings" ) ) 338 { 339 pNewState = new OfficeSettingsImport( m_aSettings ); 340 } 341 else 342 { 343 OSL_ENSURE( false, "SettingsDocumentHandler::startElement: invalid settings file!" ); 344 // Yes, that's not correct. Somebody could, in theory, give us a document which starts with "foo:settings", 345 // where "foo" is mapped to the proper namespace URL. 346 // However, there's no need to bother with this. The "recovery" sub storage we're recovering from is 347 // not part of ODF, so we can impose any format restrictions on it ... 348 } 349 } 350 else 351 { 352 ::rtl::Reference< SettingsImport > pCurrentState( m_aStates.top() ); 353 pNewState = pCurrentState->nextState( i_Name ); 354 } 355 356 ENSURE_OR_THROW( pNewState.is(), "no new state - aborting import" ); 357 pNewState->startElement( i_Attribs ); 358 359 m_aStates.push( pNewState ); 360 } 361 362 //-------------------------------------------------------------------- 363 void SAL_CALL SettingsDocumentHandler::endElement( const ::rtl::OUString& i_Name ) throw (SAXException, RuntimeException) 364 { 365 ENSURE_OR_THROW( !m_aStates.empty(), "no active element" ); 366 (void)i_Name; 367 368 ::rtl::Reference< SettingsImport > pCurrentState( m_aStates.top() ); 369 pCurrentState->endElement(); 370 m_aStates.pop(); 371 } 372 373 //-------------------------------------------------------------------- 374 void SAL_CALL SettingsDocumentHandler::characters( const ::rtl::OUString& i_Chars ) throw (SAXException, RuntimeException) 375 { 376 ENSURE_OR_THROW( !m_aStates.empty(), "no active element" ); 377 378 ::rtl::Reference< SettingsImport > pCurrentState( m_aStates.top() ); 379 pCurrentState->characters( i_Chars ); 380 } 381 382 //-------------------------------------------------------------------- 383 void SAL_CALL SettingsDocumentHandler::ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (SAXException, RuntimeException) 384 { 385 // ignore them - that's why they're called "ignorable" 386 (void)aWhitespaces; 387 } 388 389 //-------------------------------------------------------------------- 390 void SAL_CALL SettingsDocumentHandler::processingInstruction( const ::rtl::OUString& i_Target, const ::rtl::OUString& i_Data ) throw (SAXException, RuntimeException) 391 { 392 OSL_ENSURE( false, "SettingsDocumentHandler::processingInstruction: unexpected ..." ); 393 (void)i_Target; 394 (void)i_Data; 395 } 396 397 //-------------------------------------------------------------------- 398 void SAL_CALL SettingsDocumentHandler::setDocumentLocator( const Reference< XLocator >& i_Locator ) throw (SAXException, RuntimeException) 399 { 400 (void)i_Locator; 401 } 402 403 //==================================================================== 404 //= SubComponentRecovery 405 //==================================================================== 406 //-------------------------------------------------------------------- 407 const ::rtl::OUString SubComponentRecovery::getComponentsStorageName( const SubComponentType i_eType ) 408 { 409 static const ::rtl::OUString s_sFormsStorageName( RTL_CONSTASCII_USTRINGPARAM( "forms" ) ); 410 static const ::rtl::OUString s_sReportsStorageName( RTL_CONSTASCII_USTRINGPARAM( "reports" ) ); 411 static const ::rtl::OUString s_sTablesStorageName( RTL_CONSTASCII_USTRINGPARAM( "tables" ) ); 412 static const ::rtl::OUString s_sQueriesStorageName( RTL_CONSTASCII_USTRINGPARAM( "queries" ) ); 413 static const ::rtl::OUString s_sRelationsStorageName( RTL_CONSTASCII_USTRINGPARAM( "relations" ) ); 414 415 switch ( i_eType ) 416 { 417 case FORM: 418 return s_sFormsStorageName; 419 case REPORT: 420 return s_sReportsStorageName; 421 case TABLE: 422 return s_sTablesStorageName; 423 case QUERY: 424 return s_sQueriesStorageName; 425 case RELATION_DESIGN: 426 return s_sRelationsStorageName; 427 default: 428 break; 429 } 430 431 OSL_ENSURE( false, "SubComponentRecovery::getComponentsStorageName: unimplemented case!" ); 432 static const ::rtl::OUString s_sFallback; 433 return s_sFallback; 434 } 435 436 //-------------------------------------------------------------------- 437 void SubComponentRecovery::saveToRecoveryStorage( const Reference< XStorage >& i_rRecoveryStorage, 438 MapCompTypeToCompDescs& io_mapCompDescs ) 439 { 440 if ( m_eType == UNKNOWN ) 441 // quite fatal, but has already been reported (as assertion) before 442 return; 443 444 // open the sub storage for the given kind of components 445 const ::rtl::OUString& rStorageName( getComponentsStorageName( m_eType ) ); 446 const Reference< XStorage > xComponentsStorage( i_rRecoveryStorage->openStorageElement( 447 rStorageName, ElementModes::READWRITE ), UNO_QUERY_THROW ); 448 449 // find a free sub storage name, and create Yet Another Sub Storage 450 const ::rtl::OUString& rBaseName( lcl_getComponentStorageBaseName( m_eType ) ); 451 const ::rtl::OUString sStorName = ::dbtools::createUniqueName( xComponentsStorage.get(), rBaseName, true ); 452 const Reference< XStorage > xObjectStor( xComponentsStorage->openStorageElement( 453 sStorName, ElementModes::READWRITE ), UNO_QUERY_THROW ); 454 455 switch ( m_eType ) 456 { 457 case FORM: 458 case REPORT: 459 impl_saveSubDocument_throw( xObjectStor ); 460 break; 461 462 case QUERY: 463 impl_saveQueryDesign_throw( xObjectStor ); 464 break; 465 466 default: 467 // TODO 468 OSL_ENSURE( false, "SubComponentRecoverys::saveToRecoveryStorage: unimplemented case!" ); 469 break; 470 } 471 472 // commit the storage(s) 473 tools::stor::commitStorageIfWriteable( xObjectStor ); 474 tools::stor::commitStorageIfWriteable( xComponentsStorage ); 475 476 // remember the relationship from the component name to the storage name 477 MapStringToCompDesc& rMapCompDescs = io_mapCompDescs[ m_eType ]; 478 OSL_ENSURE( rMapCompDescs.find( sStorName ) == rMapCompDescs.end(), 479 "SubComponentRecoverys::saveToRecoveryStorage: object name already used!" ); 480 rMapCompDescs[ sStorName ] = m_aCompDesc; 481 } 482 483 //-------------------------------------------------------------------- 484 void SubComponentRecovery::impl_identifyComponent_throw() 485 { 486 // ask the controller 487 Pair< sal_Int32, ::rtl::OUString > aComponentIdentity = m_xDocumentUI->identifySubComponent( m_xComponent ); 488 m_eType = lcl_databaseObjectToSubComponentType( aComponentIdentity.First ); 489 m_aCompDesc.sName = aComponentIdentity.Second; 490 491 // what the controller didn't give us is the information whether this is in edit mode or not ... 492 Reference< XModuleManager > xModuleManager( m_rContext.createComponent( "com.sun.star.frame.ModuleManager" ), UNO_QUERY_THROW ); 493 const ::rtl::OUString sModuleIdentifier = xModuleManager->identify( m_xComponent ); 494 495 switch ( m_eType ) 496 { 497 case TABLE: 498 m_aCompDesc.bForEditing = sModuleIdentifier.equalsAscii( "com.sun.star.sdb.TableDesign" ); 499 break; 500 501 case QUERY: 502 m_aCompDesc.bForEditing = sModuleIdentifier.equalsAscii( "com.sun.star.sdb.QueryDesign" ); 503 break; 504 505 case REPORT: 506 if ( sModuleIdentifier.equalsAscii( "com.sun.star.report.ReportDefinition" ) ) 507 { 508 // it's an SRB report desginer 509 m_aCompDesc.bForEditing = true; 510 break; 511 } 512 // fall through 513 514 case FORM: 515 m_aCompDesc.bForEditing = !lcl_determineReadOnly( m_xComponent ); 516 break; 517 518 default: 519 if ( sModuleIdentifier.equalsAscii( "com.sun.star.sdb.RelationDesign" ) ) 520 { 521 m_eType = RELATION_DESIGN; 522 m_aCompDesc.bForEditing = true; 523 } 524 else 525 { 526 OSL_ENSURE( false, "SubComponentRecovery::impl_identifyComponent_throw: couldn't classify the given sub component!" ); 527 } 528 break; 529 } 530 531 OSL_POSTCOND( m_eType != UNKNOWN, 532 "SubComponentRecovery::impl_identifyComponent_throw: couldn't classify the component!" ); 533 } 534 535 //-------------------------------------------------------------------- 536 void SubComponentRecovery::impl_saveQueryDesign_throw( const Reference< XStorage >& i_rObjectStorage ) 537 { 538 ENSURE_OR_THROW( m_eType == QUERY, "illegal sub component type" ); 539 ENSURE_OR_THROW( i_rObjectStorage.is(), "illegal storage" ); 540 541 // retrieve the current query design (which might differ from what we can retrieve as ActiveCommand property, since 542 // the latter is updated only upon successful save of the design) 543 Reference< XPropertySet > xDesignerProps( m_xComponent, UNO_QUERY_THROW ); 544 Sequence< PropertyValue > aCurrentQueryDesign; 545 OSL_VERIFY( xDesignerProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CurrentQueryDesign" ) ) ) >>= aCurrentQueryDesign ); 546 547 // write the query design 548 StorageXMLOutputStream aDesignOutput( m_rContext, i_rObjectStorage, lcl_getSettingsStreamName() ); 549 SettingsExportContext aSettingsExportContext( m_rContext, aDesignOutput ); 550 551 const ::rtl::OUString sWhitespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) ) ); 552 553 aDesignOutput.startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "office:settings" ) ) ); 554 aDesignOutput.ignorableWhitespace( sWhitespace ); 555 556 XMLSettingsExportHelper aSettingsExporter( aSettingsExportContext ); 557 aSettingsExporter.exportAllSettings( aCurrentQueryDesign, lcl_getCurrentQueryDesignName() ); 558 559 aDesignOutput.ignorableWhitespace( sWhitespace ); 560 aDesignOutput.endElement(); 561 aDesignOutput.close(); 562 } 563 564 //-------------------------------------------------------------------- 565 void SubComponentRecovery::impl_saveSubDocument_throw( const Reference< XStorage >& i_rObjectStorage ) 566 { 567 ENSURE_OR_THROW( ( m_eType == FORM ) || ( m_eType == REPORT ), "illegal sub component type" ); 568 ENSURE_OR_THROW( i_rObjectStorage.is(), "illegal storage" ); 569 570 // store the document into the storage 571 Reference< XStorageBasedDocument > xStorageDocument( m_xComponent, UNO_QUERY_THROW ); 572 xStorageDocument->storeToStorage( i_rObjectStorage, Sequence< PropertyValue >() ); 573 } 574 575 //-------------------------------------------------------------------- 576 Reference< XComponent > SubComponentRecovery::impl_recoverSubDocument_throw( const Reference< XStorage >& i_rRecoveryStorage, 577 const ::rtl::OUString& i_rComponentName, const bool i_bForEditing ) 578 { 579 Reference< XComponent > xSubComponent; 580 Reference< XCommandProcessor > xDocDefinition; 581 582 ::comphelper::NamedValueCollection aLoadArgs; 583 aLoadArgs.put( "RecoveryStorage", i_rRecoveryStorage ); 584 585 // load/create the sub component hidden. We'll show it when the main app window is shown. 586 aLoadArgs.put( "Hidden", true ); 587 588 if ( i_rComponentName.getLength() ) 589 { 590 xDocDefinition = lcl_getSubComponentDef_nothrow( m_xDocumentUI, m_eType, i_rComponentName ); 591 xSubComponent.set( m_xDocumentUI->loadComponentWithArguments( 592 m_eType, 593 i_rComponentName, 594 i_bForEditing, 595 aLoadArgs.getPropertyValues() 596 ), 597 UNO_SET_THROW 598 ); 599 } 600 else 601 { 602 Reference< XComponent > xDocDefComponent; 603 xSubComponent.set( m_xDocumentUI->createComponentWithArguments( 604 m_eType, 605 aLoadArgs.getPropertyValues(), 606 xDocDefComponent 607 ), 608 UNO_SET_THROW 609 ); 610 611 xDocDefinition.set( xDocDefComponent, UNO_QUERY ); 612 OSL_ENSURE( xDocDefinition.is(), "DatabaseDocumentRecovery::recoverSubDocuments: loaded a form/report, but don't have a document definition?!" ); 613 } 614 615 if ( xDocDefinition.is() ) 616 { 617 Reference< XController > xController( m_xDocumentUI, UNO_QUERY_THROW ); 618 Reference< XInterface > xLoader( *new SubComponentLoader( xController, xDocDefinition ) ); 619 (void)xLoader; 620 } 621 622 return xSubComponent; 623 } 624 625 //-------------------------------------------------------------------- 626 Reference< XComponent > SubComponentRecovery::impl_recoverQueryDesign_throw( const Reference< XStorage >& i_rRecoveryStorage, 627 const ::rtl::OUString& i_rComponentName, const bool i_bForEditing ) 628 { 629 Reference< XComponent > xSubComponent; 630 631 // first read the settings query design settings from the storage 632 StorageXMLInputStream aDesignInput( m_rContext, i_rRecoveryStorage, lcl_getSettingsStreamName() ); 633 634 ::rtl::Reference< SettingsDocumentHandler > pDocHandler( new SettingsDocumentHandler ); 635 aDesignInput.import( pDocHandler.get() ); 636 637 const ::comphelper::NamedValueCollection& rSettings( pDocHandler->getSettings() ); 638 const Any aCurrentQueryDesign = rSettings.get( lcl_getCurrentQueryDesignName() ); 639 #if OSL_DEBUG_LEVEL > 0 640 Sequence< PropertyValue > aQueryDesignLayout; 641 OSL_VERIFY( aCurrentQueryDesign >>= aQueryDesignLayout ); 642 #endif 643 644 // then load the query designer 645 ::comphelper::NamedValueCollection aLoadArgs; 646 aLoadArgs.put( "CurrentQueryDesign", aCurrentQueryDesign ); 647 aLoadArgs.put( "Hidden", true ); 648 649 if ( i_rComponentName.getLength() ) 650 { 651 xSubComponent.set( m_xDocumentUI->loadComponentWithArguments( 652 m_eType, 653 i_rComponentName, 654 i_bForEditing, 655 aLoadArgs.getPropertyValues() 656 ), 657 UNO_SET_THROW 658 ); 659 } 660 else 661 { 662 Reference< XComponent > xDummy; 663 xSubComponent.set( m_xDocumentUI->createComponentWithArguments( 664 m_eType, 665 aLoadArgs.getPropertyValues(), 666 xDummy 667 ), 668 UNO_SET_THROW 669 ); 670 } 671 672 Reference< XController > xController( m_xDocumentUI, UNO_QUERY_THROW ); 673 Reference< XInterface > xLoader( *new SubComponentLoader( xController, xSubComponent ) ); 674 (void)xLoader; 675 676 return xSubComponent; 677 } 678 679 //-------------------------------------------------------------------- 680 Reference< XComponent > SubComponentRecovery::recoverFromStorage( const Reference< XStorage >& i_rRecoveryStorage, 681 const ::rtl::OUString& i_rComponentName, const bool i_bForEditing ) 682 { 683 Reference< XComponent > xSubComponent; 684 switch ( m_eType ) 685 { 686 case FORM: 687 case REPORT: 688 xSubComponent = impl_recoverSubDocument_throw( i_rRecoveryStorage, i_rComponentName, i_bForEditing ); 689 break; 690 case QUERY: 691 xSubComponent = impl_recoverQueryDesign_throw( i_rRecoveryStorage, i_rComponentName, i_bForEditing ); 692 break; 693 default: 694 OSL_ENSURE( false, "SubComponentRecovery::recoverFromStorage: unimplemented case!" ); 695 break; 696 } 697 return xSubComponent; 698 } 699 700 //........................................................................ 701 } // namespace dbaccess 702 //........................................................................ 703