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