diff options
author | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2010-02-16 09:43:10 +0100 |
---|---|---|
committer | Frank Schoenheit [fs] <frank.schoenheit@sun.com> | 2010-02-16 09:43:10 +0100 |
commit | eb79829c17871ccbad0daf469dfd7bd9c85eb8cc (patch) | |
tree | 69f733c72888afbf99170eb617707d75e8b05686 | |
parent | a1c40ed088aeabc90c260d9b8bc7e0db24d1b146 (diff) |
autorecovery: outsourced the SubComponentRecovery class into a dedicated file, in preparation of recovering query designs
-rw-r--r-- | dbaccess/source/core/recovery/dbdocrecovery.cxx | 515 | ||||
-rw-r--r-- | dbaccess/source/core/recovery/makefile.mk | 3 | ||||
-rw-r--r-- | dbaccess/source/core/recovery/subcomponentrecovery.cxx | 523 | ||||
-rw-r--r-- | dbaccess/source/core/recovery/subcomponentrecovery.hxx | 119 | ||||
-rw-r--r-- | dbaccess/source/core/recovery/subcomponents.hxx | 88 |
5 files changed, 754 insertions, 494 deletions
diff --git a/dbaccess/source/core/recovery/dbdocrecovery.cxx b/dbaccess/source/core/recovery/dbdocrecovery.cxx index 296f3ba901d5..76a67794ee53 100644 --- a/dbaccess/source/core/recovery/dbdocrecovery.cxx +++ b/dbaccess/source/core/recovery/dbdocrecovery.cxx @@ -27,38 +27,28 @@ #include "recovery/dbdocrecovery.hxx" #include "sdbcoretools.hxx" -#include "storagexmlstream.hxx" #include "storagetextstream.hxx" -#include "subcomponentloader.hxx" +#include "subcomponentrecovery.hxx" +#include "subcomponents.hxx" #include "dbastrings.hrc" /** === begin UNO includes === **/ #include <com/sun/star/sdb/application/XDatabaseDocumentUI.hpp> -#include <com/sun/star/frame/XModuleManager.hpp> #include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/document/XStorageBasedDocument.hpp> #include <com/sun/star/io/XTextOutputStream.hpp> #include <com/sun/star/io/XTextInputStream.hpp> #include <com/sun/star/io/XActiveDataSource.hpp> #include <com/sun/star/io/XActiveDataSink.hpp> -#include <com/sun/star/sdb/application/DatabaseObject.hpp> #include <com/sun/star/util/XModifiable.hpp> -#include <com/sun/star/sdb/XFormDocumentsSupplier.hpp> -#include <com/sun/star/sdb/XReportDocumentsSupplier.hpp> -#include <com/sun/star/ucb/XCommandProcessor.hpp> -#include <com/sun/star/container/XHierarchicalNameAccess.hpp> #include <com/sun/star/beans/XPropertySet.hpp> /** === end UNO includes === **/ #include <comphelper/componentcontext.hxx> #include <comphelper/namedvaluecollection.hxx> -#include <connectivity/dbtools.hxx> -#include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> #include <tools/diagnose_ex.h> -#include <xmloff/XMLSettingsExportContext.hxx> -#include <xmloff/SettingsExportHelper.hxx> -#include <hash_map> #include <algorithm> //........................................................................ @@ -81,11 +71,9 @@ namespace dbaccess using ::com::sun::star::embed::XStorage; using ::com::sun::star::frame::XController; using ::com::sun::star::sdb::application::XDatabaseDocumentUI; - using ::com::sun::star::frame::XModuleManager; using ::com::sun::star::lang::XComponent; using ::com::sun::star::document::XStorageBasedDocument; using ::com::sun::star::beans::PropertyValue; - using ::com::sun::star::beans::Pair; using ::com::sun::star::io::XStream; using ::com::sun::star::io::XTextOutputStream; using ::com::sun::star::io::XActiveDataSource; @@ -93,16 +81,11 @@ namespace dbaccess using ::com::sun::star::io::XActiveDataSink; using ::com::sun::star::frame::XModel; using ::com::sun::star::util::XModifiable; - using ::com::sun::star::sdb::XFormDocumentsSupplier; - using ::com::sun::star::sdb::XReportDocumentsSupplier; - using ::com::sun::star::ucb::XCommandProcessor; - using ::com::sun::star::container::XHierarchicalNameAccess; using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::lang::XMultiServiceFactory; /** === end UNO using === **/ namespace ElementModes = ::com::sun::star::embed::ElementModes; - namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject; //==================================================================== //= helpers @@ -110,41 +93,6 @@ namespace dbaccess namespace { // ......................................................................... - enum SubComponentType - { - TABLE = DatabaseObject::TABLE, - QUERY = DatabaseObject::QUERY, - FORM = DatabaseObject::FORM, - REPORT = DatabaseObject::REPORT, - - RELATION_DESIGN = 1000, - - UNKNOWN = 10001 - }; - - struct DBACCESS_DLLPRIVATE SubComponentDescriptor - { - ::rtl::OUString sName; - bool bForEditing; - - SubComponentDescriptor() - :sName() - ,bForEditing( false ) - { - } - - SubComponentDescriptor( const ::rtl::OUString& i_rName, const bool i_bForEditing ) - :sName( i_rName ) - ,bForEditing( i_bForEditing ) - { - } - }; - - // ......................................................................... - typedef ::std::hash_map< ::rtl::OUString, SubComponentDescriptor, ::rtl::OUStringHash > MapStringToCompDesc; - typedef ::std::map< SubComponentType, MapStringToCompDesc > MapCompTypeToCompDescs; - - // ......................................................................... static void lcl_getPersistentRepresentation( const MapStringToCompDesc::value_type& i_rComponentDesc, ::rtl::OUStringBuffer& o_rBuffer ) { o_rBuffer.append( i_rComponentDesc.first ); @@ -177,84 +125,12 @@ namespace dbaccess } // ......................................................................... - static SubComponentType lcl_databaseObjectToSubComponentType( const sal_Int32 i_nObjectType ) - { - switch ( i_nObjectType ) - { - case DatabaseObject::TABLE: return TABLE; - case DatabaseObject::QUERY: return QUERY; - case DatabaseObject::FORM: return FORM; - case DatabaseObject::REPORT:return REPORT; - default: - break; - } - return UNKNOWN; - } - - // ......................................................................... static const ::rtl::OUString& lcl_getRecoveryDataSubStorageName() { static const ::rtl::OUString s_sRecDataStorName( RTL_CONSTASCII_USTRINGPARAM( "recovery" ) ); return s_sRecDataStorName; } // ......................................................................... - static const ::rtl::OUString& lcl_getComponentStorageBaseName( const SubComponentType i_eType ) - { - static const ::rtl::OUString s_sFormBaseName( RTL_CONSTASCII_USTRINGPARAM( "form" ) ); - static const ::rtl::OUString s_sReportBaseName( RTL_CONSTASCII_USTRINGPARAM( "report" ) ); - static const ::rtl::OUString s_sTableBaseName( RTL_CONSTASCII_USTRINGPARAM( "table" ) ); - static const ::rtl::OUString s_sQueryBaseName( RTL_CONSTASCII_USTRINGPARAM( "query" ) ); - - switch ( i_eType ) - { - case FORM: - return s_sFormBaseName; - case REPORT: - return s_sReportBaseName; - case TABLE: - return s_sTableBaseName; - case QUERY: - return s_sQueryBaseName; - default: - break; - } - - OSL_ENSURE( false, "lcl_getComponentStorageBaseName: unimplemented case!" ); - static const ::rtl::OUString s_sFallback; - return s_sFallback; - } - - // ......................................................................... - static const ::rtl::OUString& lcl_getComponentsStorageName( const SubComponentType i_eType ) - { - static const ::rtl::OUString s_sFormsStorageName( RTL_CONSTASCII_USTRINGPARAM( "forms" ) ); - static const ::rtl::OUString s_sReportsStorageName( RTL_CONSTASCII_USTRINGPARAM( "reports" ) ); - static const ::rtl::OUString s_sTablesStorageName( RTL_CONSTASCII_USTRINGPARAM( "tables" ) ); - static const ::rtl::OUString s_sQueriesStorageName( RTL_CONSTASCII_USTRINGPARAM( "queries" ) ); - static const ::rtl::OUString s_sRelationsStorageName( RTL_CONSTASCII_USTRINGPARAM( "relations" ) ); - - switch ( i_eType ) - { - case FORM: - return s_sFormsStorageName; - case REPORT: - return s_sReportsStorageName; - case TABLE: - return s_sTablesStorageName; - case QUERY: - return s_sQueriesStorageName; - case RELATION_DESIGN: - return s_sRelationsStorageName; - default: - break; - } - - OSL_ENSURE( false, "lcl_getComponentsStorageName: unimplemented case!" ); - static const ::rtl::OUString s_sFallback; - return s_sFallback; - } - - // ......................................................................... static const ::rtl::OUString& lcl_getObjectMapStreamName() { static const ::rtl::OUString s_sObjectMapStreamName( RTL_CONSTASCII_USTRINGPARAM( "storage-component-map.ini" ) ); @@ -269,20 +145,6 @@ namespace dbaccess } // ......................................................................... - static const ::rtl::OUString& lcl_getSettingsStreamName() - { - static const ::rtl::OUString s_sStatementStreamName( RTL_CONSTASCII_USTRINGPARAM( "settings.xml" ) ); - return s_sStatementStreamName; - } - - // ......................................................................... - static const ::rtl::OUString& lcl_getCurrentQueryDesignName() - { - static const ::rtl::OUString s_sQuerySettingsName( RTL_CONSTASCII_USTRINGPARAM( "ooo:current-query-design" ) ); - return s_sQuerySettingsName; - } - - // ......................................................................... static const ::rtl::OUString& lcl_getMapStreamEncodingName() { static const ::rtl::OUString s_sMapStreamEncodingName( RTL_CONSTASCII_USTRINGPARAM( "UTF-8" ) ); @@ -390,23 +252,6 @@ namespace dbaccess } // ......................................................................... - static bool lcl_determineReadOnly( const Reference< XComponent >& i_rComponent ) - { - Reference< XModel > xDocument( i_rComponent, UNO_QUERY ); - if ( !xDocument.is() ) - { - Reference< XController > xController( i_rComponent, UNO_QUERY_THROW ); - xDocument = xController->getModel(); - } - - if ( !xDocument.is() ) - return false; - - ::comphelper::NamedValueCollection aDocArgs( xDocument->getArgs() ); - return aDocArgs.getOrDefault( "ReadOnly", false ); - } - - // ......................................................................... static void lcl_markModified( const Reference< XComponent >& i_rSubComponent ) { const Reference< XModifiable > xModify( i_rSubComponent, UNO_QUERY ); @@ -418,36 +263,6 @@ namespace dbaccess xModify->setModified( sal_True ); } - - // ......................................................................... - static Reference< XCommandProcessor > lcl_getSubComponentDef_nothrow( const Reference< XController >& i_rAppUI, - SubComponentType i_eType, const ::rtl::OUString& i_rName ) - { - ENSURE_OR_RETURN( i_rAppUI.is(), "lcl_getSubComponentDef_nothrow: illegal controller", NULL ); - ENSURE_OR_RETURN( ( i_eType == FORM ) || ( i_eType == REPORT ), "lcl_getSubComponentDef_nothrow: illegal controller", NULL ); - - Reference< XCommandProcessor > xCommandProcessor; - try - { - Reference< XHierarchicalNameAccess > xDefinitionContainer; - if ( i_eType == FORM ) - { - Reference< XFormDocumentsSupplier > xSuppForms( i_rAppUI->getModel(), UNO_QUERY_THROW ); - xDefinitionContainer.set( xSuppForms->getFormDocuments(), UNO_QUERY_THROW ); - } - else - { - Reference< XReportDocumentsSupplier > xSuppReports( i_rAppUI->getModel(), UNO_QUERY_THROW ); - xDefinitionContainer.set( xSuppReports->getReportDocuments(), UNO_QUERY_THROW ); - } - xCommandProcessor.set( xDefinitionContainer->getByHierarchicalName( i_rName ), UNO_QUERY_THROW ); - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION(); - } - return xCommandProcessor; - } } //==================================================================== @@ -464,265 +279,6 @@ namespace dbaccess }; //==================================================================== - //= SettingsExportContext - //==================================================================== - class DBACCESS_DLLPRIVATE SettingsExportContext : public ::xmloff::XMLSettingsExportContext - { - public: - SettingsExportContext( const ::comphelper::ComponentContext& i_rContext, const StorageXMLOutputStream& i_rDelegator ) - :m_rContext( i_rContext ) - ,m_rDelegator( i_rDelegator ) - ,m_aNamespace( ::xmloff::token::GetXMLToken( ::xmloff::token::XML_NP_CONFIG ) ) - { - } - - public: - virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, const ::rtl::OUString& i_rValue ); - virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue ); - virtual void StartElement( enum ::xmloff::token::XMLTokenEnum i_eName, const sal_Bool i_bIgnoreWhitespace ); - virtual void EndElement ( const sal_Bool i_bIgnoreWhitespace ); - virtual void Characters( const ::rtl::OUString& i_rCharacters ); - - virtual ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > - GetServiceFactory() const; - - private: - ::rtl::OUString impl_prefix( const ::xmloff::token::XMLTokenEnum i_eToken ) - { - ::rtl::OUStringBuffer aQualifiedName( m_aNamespace ); - aQualifiedName.append( sal_Unicode( ':' ) ); - aQualifiedName.append( ::xmloff::token::GetXMLToken( i_eToken ) ); - return aQualifiedName.makeStringAndClear(); - } - - private: - const ::comphelper::ComponentContext& m_rContext; - const StorageXMLOutputStream& m_rDelegator; - const ::rtl::OUStringBuffer m_aNamespace; - }; - - //-------------------------------------------------------------------- - void SettingsExportContext::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, const ::rtl::OUString& i_rValue ) - { - m_rDelegator.addAttribute( impl_prefix( i_eName ), i_rValue ); - } - - //-------------------------------------------------------------------- - void SettingsExportContext::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue ) - { - m_rDelegator.addAttribute( impl_prefix( i_eName ), ::xmloff::token::GetXMLToken( i_eValue ) ); - } - - //-------------------------------------------------------------------- - void SettingsExportContext::StartElement( enum ::xmloff::token::XMLTokenEnum i_eName, const sal_Bool i_bIgnoreWhitespace ) - { - if ( i_bIgnoreWhitespace ) - m_rDelegator.ignorableWhitespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) ) ); - - m_rDelegator.startElement( impl_prefix( i_eName ) ); - } - - //-------------------------------------------------------------------- - void SettingsExportContext::EndElement( const sal_Bool i_bIgnoreWhitespace ) - { - if ( i_bIgnoreWhitespace ) - m_rDelegator.ignorableWhitespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) ) ); - m_rDelegator.endElement(); - } - - //-------------------------------------------------------------------- - void SettingsExportContext::Characters( const ::rtl::OUString& i_rCharacters ) - { - m_rDelegator.characters( i_rCharacters ); - } - - //-------------------------------------------------------------------- - Reference< XMultiServiceFactory > SettingsExportContext::GetServiceFactory() const - { - return m_rContext.getLegacyServiceFactory(); - } - - //==================================================================== - //= SubComponentRecovery - //==================================================================== - class DBACCESS_DLLPRIVATE SubComponentRecovery - { - public: - SubComponentRecovery( const ::comphelper::ComponentContext& i_rContext, const Reference< XDatabaseDocumentUI >& i_rController, - const Reference< XComponent >& i_rComponent ) - :m_rContext( i_rContext ) - ,m_xComponent( i_rComponent ) - ,m_eType( UNKNOWN ) - ,m_aCompDesc() - { - impl_identifyComponent_throw( i_rController ); - } - - void saveToRecoveryStorage( const Reference< XStorage >& i_rRecoveryStorage, MapCompTypeToCompDescs& io_mapCompDescs ); - - private: - void impl_saveSubDocument_throw( - const Reference< XStorage >& i_rObjectStorage - ); - - void impl_saveQueryDesign_throw( - const Reference< XStorage >& i_rObjectStorage - ); - - void impl_identifyComponent_throw( - const Reference< XDatabaseDocumentUI >& i_rController - ); - - private: - const ::comphelper::ComponentContext& m_rContext; - const Reference< XComponent > m_xComponent; - SubComponentType m_eType; - SubComponentDescriptor m_aCompDesc; - }; - - //-------------------------------------------------------------------- - void SubComponentRecovery::saveToRecoveryStorage( const Reference< XStorage >& i_rRecoveryStorage, - MapCompTypeToCompDescs& io_mapCompDescs ) - { - - if ( m_eType == UNKNOWN ) - // quite fatal, but has already been reported (as assertion) before - return; - - // open the sub storage for the given kind of components - const ::rtl::OUString& rStorageName( lcl_getComponentsStorageName( m_eType ) ); - const Reference< XStorage > xComponentsStorage( i_rRecoveryStorage->openStorageElement( - rStorageName, ElementModes::READWRITE ), UNO_QUERY_THROW ); - - // find a free sub storage name, and create Yet Another Sub Storage - const ::rtl::OUString& rBaseName( lcl_getComponentStorageBaseName( m_eType ) ); - const ::rtl::OUString sStorName = ::dbtools::createUniqueName( xComponentsStorage.get(), rBaseName, true ); - const Reference< XStorage > xObjectStor( xComponentsStorage->openStorageElement( - sStorName, ElementModes::READWRITE ), UNO_QUERY_THROW ); - - switch ( m_eType ) - { - case FORM: - case REPORT: - impl_saveSubDocument_throw( xObjectStor ); - break; - - case QUERY: - impl_saveQueryDesign_throw( xObjectStor ); - break; - - default: - // TODO - OSL_ENSURE( false, "SubComponentRecoverys::saveToRecoveryStorage: unimplemented case!" ); - break; - } - - // commit the storage(s) - tools::stor::commitStorageIfWriteable( xObjectStor ); - tools::stor::commitStorageIfWriteable( xComponentsStorage ); - - // remember the relationship from the component name to the storage name - MapStringToCompDesc& rMapCompDescs = io_mapCompDescs[ m_eType ]; - OSL_ENSURE( rMapCompDescs.find( sStorName ) == rMapCompDescs.end(), - "SubComponentRecoverys::saveToRecoveryStorage: object name already used!" ); - rMapCompDescs[ sStorName ] = m_aCompDesc; - } - - //-------------------------------------------------------------------- - void SubComponentRecovery::impl_identifyComponent_throw( const Reference< XDatabaseDocumentUI >& i_rController ) - { - ENSURE_OR_THROW( i_rController.is(), "illegal controller" ); - - // ask the controller - Pair< sal_Int32, ::rtl::OUString > aComponentIdentity = i_rController->identifySubComponent( m_xComponent ); - m_eType = lcl_databaseObjectToSubComponentType( aComponentIdentity.First ); - m_aCompDesc.sName = aComponentIdentity.Second; - - // what the controller didn't give us is the information whether this is in edit mode or not ... - Reference< XModuleManager > xModuleManager( m_rContext.createComponent( "com.sun.star.frame.ModuleManager" ), UNO_QUERY_THROW ); - const ::rtl::OUString sModuleIdentifier = xModuleManager->identify( m_xComponent ); - - switch ( m_eType ) - { - case TABLE: - m_aCompDesc.bForEditing = sModuleIdentifier.equalsAscii( "com.sun.star.sdb.TableDesign" ); - break; - - case QUERY: - m_aCompDesc.bForEditing = sModuleIdentifier.equalsAscii( "com.sun.star.sdb.QueryDesign" ); - break; - - case REPORT: - if ( sModuleIdentifier.equalsAscii( "com.sun.star.report.ReportDefinition" ) ) - { - // it's an SRB report desginer - m_aCompDesc.bForEditing = true; - break; - } - // fall through - - case FORM: - m_aCompDesc.bForEditing = !lcl_determineReadOnly( m_xComponent ); - break; - - default: - if ( sModuleIdentifier.equalsAscii( "com.sun.star.sdb.RelationDesign" ) ) - { - m_eType = RELATION_DESIGN; - m_aCompDesc.bForEditing = true; - } - else - { - OSL_ENSURE( false, "SubComponentRecovery::impl_identifyComponent_throw: couldn't classify the given sub component!" ); - } - break; - } - - OSL_POSTCOND( m_eType != UNKNOWN, - "SubComponentRecovery::impl_identifyComponent_throw: couldn't classify the component!" ); - } - - //-------------------------------------------------------------------- - void SubComponentRecovery::impl_saveQueryDesign_throw( const Reference< XStorage >& i_rObjectStorage ) - { - ENSURE_OR_THROW( m_eType == QUERY, "illegal sub component type" ); - ENSURE_OR_THROW( i_rObjectStorage.is(), "illegal storage" ); - - // retrieve the current query design (which might differ from what we can retrieve as ActiveCommand property, since - // the latter is updated only upon successful save of the design) - Reference< XPropertySet > xDesignerProps( m_xComponent, UNO_QUERY_THROW ); - Sequence< PropertyValue > aCurrentQueryDesign; - OSL_VERIFY( xDesignerProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CurrentQueryDesign" ) ) ) >>= aCurrentQueryDesign ); - - // write the query design - StorageXMLOutputStream aDesignOutput( m_rContext, i_rObjectStorage, lcl_getSettingsStreamName() ); - SettingsExportContext aSettingsExportContext( m_rContext, aDesignOutput ); - - const ::rtl::OUString sWhitespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) ) ); - - aDesignOutput.startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "office:settings" ) ) ); - aDesignOutput.ignorableWhitespace( sWhitespace ); - - XMLSettingsExportHelper aSettingsExporter( aSettingsExportContext ); - aSettingsExporter.exportAllSettings( aCurrentQueryDesign, lcl_getCurrentQueryDesignName() ); - - aDesignOutput.ignorableWhitespace( sWhitespace ); - aDesignOutput.endElement(); - aDesignOutput.close(); - } - - //-------------------------------------------------------------------- - void SubComponentRecovery::impl_saveSubDocument_throw( const Reference< XStorage >& i_rObjectStorage ) - { - ENSURE_OR_THROW( ( m_eType == FORM ) || ( m_eType == REPORT ), "illegal sub component type" ); - ENSURE_OR_THROW( i_rObjectStorage.is(), "illegal storage" ); - - // store the document into the storage - Reference< XStorageBasedDocument > xStorageDocument( m_xComponent, UNO_QUERY_THROW ); - xStorageDocument->storeToStorage( i_rObjectStorage, Sequence< PropertyValue >() ); - } - - //==================================================================== //= DatabaseDocumentRecovery //==================================================================== //-------------------------------------------------------------------- @@ -781,7 +337,7 @@ namespace dbaccess ) { Reference< XStorage > xComponentsStor( xRecoveryStorage->openStorageElement( - lcl_getComponentsStorageName( map->first ), ElementModes::WRITE | ElementModes::NOCREATE ) ); + SubComponentRecovery::getComponentsStorageName( map->first ), ElementModes::WRITE | ElementModes::NOCREATE ) ); lcl_writeObjectMap_throw( m_pData->aContext, xComponentsStor, map->second ); tools::stor::commitStorageIfWriteable( xComponentsStor ); } @@ -810,11 +366,11 @@ namespace dbaccess SubComponentType aKnownTypes[] = { TABLE, QUERY, FORM, REPORT, RELATION_DESIGN }; for ( size_t i = 0; i < sizeof( aKnownTypes ) / sizeof( aKnownTypes[0] ); ++i ) { - if ( !xRecoveryStorage->hasByName( lcl_getComponentsStorageName( aKnownTypes[i] ) ) ) + if ( !xRecoveryStorage->hasByName( SubComponentRecovery::getComponentsStorageName( aKnownTypes[i] ) ) ) continue; Reference< XStorage > xComponentsStor( xRecoveryStorage->openStorageElement( - lcl_getComponentsStorageName( aKnownTypes[i] ), ElementModes::READ ) ); + SubComponentRecovery::getComponentsStorageName( aKnownTypes[i] ), ElementModes::READ ) ); lcl_readObjectMap_throw( m_pData->aContext, xComponentsStor, aMapCompDescs[ aKnownTypes[i] ] ); xComponentsStor->dispose(); } @@ -835,7 +391,7 @@ namespace dbaccess // the storage for all components of the current type Reference< XStorage > xComponentsStor( xRecoveryStorage->openStorageElement( - lcl_getComponentsStorageName( eComponentType ), ElementModes::READ ), UNO_QUERY_THROW ); + SubComponentRecovery::getComponentsStorageName( eComponentType ), ElementModes::READ ), UNO_QUERY_THROW ); // loop thru all components of this type for ( MapStringToCompDesc::const_iterator stor = map->second.begin(); @@ -851,7 +407,7 @@ namespace dbaccess message.append( "DatabaseDocumentRecovery::recoverSubDocuments: inconsistent recovery storage: storage '" ); message.append( ::rtl::OUStringToOString( stor->first, RTL_TEXTENCODING_ASCII_US ) ); message.append( "' not found in '" ); - message.append( ::rtl::OUStringToOString( lcl_getComponentsStorageName( eComponentType ), RTL_TEXTENCODING_ASCII_US ) ); + message.append( ::rtl::OUStringToOString( SubComponentRecovery::getComponentsStorageName( eComponentType ), RTL_TEXTENCODING_ASCII_US ) ); message.append( "', but required per map file!" ); OSL_ENSURE( false, message.makeStringAndClear() ); #endif @@ -864,47 +420,8 @@ namespace dbaccess // recover the single component Reference< XStorage > xCompStor( xComponentsStor->openStorageElement( stor->first, ElementModes::READ ) ); - ::comphelper::NamedValueCollection aLoadArgs; - aLoadArgs.put( "RecoveryStorage", xCompStor ); - - // load/create the sub component hidden. We'll show it when the main app window is shown. - aLoadArgs.put( "Hidden", true ); - - Reference< XComponent > xSubComponent; - Reference< XCommandProcessor > xDocDefinition; - - if ( sComponentName.getLength() ) - { - xDocDefinition = lcl_getSubComponentDef_nothrow( i_rTargetController, eComponentType, sComponentName ); - xSubComponent.set( xDocumentUI->loadComponentWithArguments( - eComponentType, - sComponentName, - stor->second.bForEditing, - aLoadArgs.getPropertyValues() - ), - UNO_SET_THROW - ); - } - else - { - Reference< XComponent > xDocDefComponent; - xSubComponent.set( xDocumentUI->createComponentWithArguments( - eComponentType, - aLoadArgs.getPropertyValues(), - xDocDefComponent - ), - UNO_SET_THROW - ); - - xDocDefinition.set( xDocDefComponent, UNO_QUERY ); - OSL_ENSURE( xDocDefinition.is(), "DatabaseDocumentRecovery::recoverSubDocuments: loaded a form/report, but don't have a document definition?!" ); - } - - if ( xDocDefinition.is() ) - { - Reference< XInterface > xLoader( *new SubComponentLoader( i_rTargetController, xDocDefinition ) ); - (void)xLoader; - } + SubComponentRecovery aComponentRecovery( m_pData->aContext, xDocumentUI, eComponentType ); + Reference< XComponent > xSubComponent( aComponentRecovery.recoverFromStorage( xCompStor, sComponentName, stor->second.bForEditing ) ); // at the moment, we only store, during session save, sub components which are modified. So, set this // recovered sub component to "modified", too. @@ -913,6 +430,18 @@ namespace dbaccess xComponentsStor->dispose(); } + + xRecoveryStorage->dispose(); + + // now that we successfully recovered, removed the "recovery" sub storage + try + { + i_rDocumentStorage->removeElement( lcl_getRecoveryDataSubStorageName() ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } } //........................................................................ diff --git a/dbaccess/source/core/recovery/makefile.mk b/dbaccess/source/core/recovery/makefile.mk index 04f6e44e8e34..8679a23dcfec 100644 --- a/dbaccess/source/core/recovery/makefile.mk +++ b/dbaccess/source/core/recovery/makefile.mk @@ -48,7 +48,8 @@ SLOFILES= \ $(SLO)$/subcomponentloader.obj \ $(SLO)$/storagestream.obj \ $(SLO)$/storagexmlstream.obj \ - $(SLO)$/storagetextstream.obj + $(SLO)$/storagetextstream.obj \ + $(SLO)$/subcomponentrecovery.obj # --- Targets ---------------------------------- diff --git a/dbaccess/source/core/recovery/subcomponentrecovery.cxx b/dbaccess/source/core/recovery/subcomponentrecovery.cxx new file mode 100644 index 000000000000..2331b70d42cc --- /dev/null +++ b/dbaccess/source/core/recovery/subcomponentrecovery.cxx @@ -0,0 +1,523 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +#include "precompiled_dbaccess.hxx" + +#include "subcomponentrecovery.hxx" + +#include "sdbcoretools.hxx" +#include "storagexmlstream.hxx" +#include "subcomponentloader.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/frame/XModuleManager.hpp> +#include <com/sun/star/document/XStorageBasedDocument.hpp> +#include <com/sun/star/ucb/XCommandProcessor.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/sdb/XFormDocumentsSupplier.hpp> +#include <com/sun/star/sdb/XReportDocumentsSupplier.hpp> +/** === end UNO includes === **/ + +#include <comphelper/namedvaluecollection.hxx> +#include <connectivity/dbtools.hxx> +#include <tools/diagnose_ex.h> +#include <xmloff/XMLSettingsExportContext.hxx> +#include <xmloff/SettingsExportHelper.hxx> + +//........................................................................ +namespace dbaccess +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + using ::com::sun::star::lang::XMultiServiceFactory; + using ::com::sun::star::embed::XStorage; + using ::com::sun::star::sdb::application::XDatabaseDocumentUI; + using ::com::sun::star::beans::Pair; + using ::com::sun::star::frame::XModuleManager; + using ::com::sun::star::lang::XComponent; + using ::com::sun::star::frame::XModel; + using ::com::sun::star::frame::XController; + using ::com::sun::star::beans::XPropertySet; + using ::com::sun::star::beans::PropertyValue; + using ::com::sun::star::document::XStorageBasedDocument; + using ::com::sun::star::ucb::XCommandProcessor; + using ::com::sun::star::container::XHierarchicalNameAccess; + using ::com::sun::star::sdb::XFormDocumentsSupplier; + using ::com::sun::star::sdb::XReportDocumentsSupplier; + /** === end UNO using === **/ + + namespace ElementModes = ::com::sun::star::embed::ElementModes; + + + //==================================================================== + //= helper + //==================================================================== + namespace + { + // ......................................................................... + static const ::rtl::OUString& lcl_getComponentStorageBaseName( const SubComponentType i_eType ) + { + static const ::rtl::OUString s_sFormBaseName( RTL_CONSTASCII_USTRINGPARAM( "form" ) ); + static const ::rtl::OUString s_sReportBaseName( RTL_CONSTASCII_USTRINGPARAM( "report" ) ); + static const ::rtl::OUString s_sTableBaseName( RTL_CONSTASCII_USTRINGPARAM( "table" ) ); + static const ::rtl::OUString s_sQueryBaseName( RTL_CONSTASCII_USTRINGPARAM( "query" ) ); + + switch ( i_eType ) + { + case FORM: + return s_sFormBaseName; + case REPORT: + return s_sReportBaseName; + case TABLE: + return s_sTableBaseName; + case QUERY: + return s_sQueryBaseName; + default: + break; + } + + OSL_ENSURE( false, "lcl_getComponentStorageBaseName: unimplemented case!" ); + static const ::rtl::OUString s_sFallback; + return s_sFallback; + } + + // ......................................................................... + static SubComponentType lcl_databaseObjectToSubComponentType( const sal_Int32 i_nObjectType ) + { + switch ( i_nObjectType ) + { + case DatabaseObject::TABLE: return TABLE; + case DatabaseObject::QUERY: return QUERY; + case DatabaseObject::FORM: return FORM; + case DatabaseObject::REPORT:return REPORT; + default: + break; + } + return UNKNOWN; + } + + // ......................................................................... + static bool lcl_determineReadOnly( const Reference< XComponent >& i_rComponent ) + { + Reference< XModel > xDocument( i_rComponent, UNO_QUERY ); + if ( !xDocument.is() ) + { + Reference< XController > xController( i_rComponent, UNO_QUERY_THROW ); + xDocument = xController->getModel(); + } + + if ( !xDocument.is() ) + return false; + + ::comphelper::NamedValueCollection aDocArgs( xDocument->getArgs() ); + return aDocArgs.getOrDefault( "ReadOnly", false ); + } + + // ......................................................................... + static Reference< XCommandProcessor > lcl_getSubComponentDef_nothrow( const Reference< XDatabaseDocumentUI >& i_rAppUI, + const SubComponentType i_eType, const ::rtl::OUString& i_rName ) + { + Reference< XController > xController( i_rAppUI, UNO_QUERY_THROW ); + ENSURE_OR_RETURN( ( i_eType == FORM ) || ( i_eType == REPORT ), "lcl_getSubComponentDef_nothrow: illegal controller", NULL ); + + Reference< XCommandProcessor > xCommandProcessor; + try + { + Reference< XHierarchicalNameAccess > xDefinitionContainer; + if ( i_eType == FORM ) + { + Reference< XFormDocumentsSupplier > xSuppForms( xController->getModel(), UNO_QUERY_THROW ); + xDefinitionContainer.set( xSuppForms->getFormDocuments(), UNO_QUERY_THROW ); + } + else + { + Reference< XReportDocumentsSupplier > xSuppReports( xController->getModel(), UNO_QUERY_THROW ); + xDefinitionContainer.set( xSuppReports->getReportDocuments(), UNO_QUERY_THROW ); + } + xCommandProcessor.set( xDefinitionContainer->getByHierarchicalName( i_rName ), UNO_QUERY_THROW ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return xCommandProcessor; + } + + // ......................................................................... + static const ::rtl::OUString& lcl_getSettingsStreamName() + { + static const ::rtl::OUString s_sStatementStreamName( RTL_CONSTASCII_USTRINGPARAM( "settings.xml" ) ); + return s_sStatementStreamName; + } + + // ......................................................................... + static const ::rtl::OUString& lcl_getCurrentQueryDesignName() + { + static const ::rtl::OUString s_sQuerySettingsName( RTL_CONSTASCII_USTRINGPARAM( "ooo:current-query-design" ) ); + return s_sQuerySettingsName; + } + } + + //==================================================================== + //= SettingsExportContext + //==================================================================== + class DBACCESS_DLLPRIVATE SettingsExportContext : public ::xmloff::XMLSettingsExportContext + { + public: + SettingsExportContext( const ::comphelper::ComponentContext& i_rContext, const StorageXMLOutputStream& i_rDelegator ) + :m_rContext( i_rContext ) + ,m_rDelegator( i_rDelegator ) + ,m_aNamespace( ::xmloff::token::GetXMLToken( ::xmloff::token::XML_NP_CONFIG ) ) + { + } + + virtual ~SettingsExportContext() + { + } + + public: + virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, const ::rtl::OUString& i_rValue ); + virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue ); + virtual void StartElement( enum ::xmloff::token::XMLTokenEnum i_eName, const sal_Bool i_bIgnoreWhitespace ); + virtual void EndElement ( const sal_Bool i_bIgnoreWhitespace ); + virtual void Characters( const ::rtl::OUString& i_rCharacters ); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > + GetServiceFactory() const; + + private: + ::rtl::OUString impl_prefix( const ::xmloff::token::XMLTokenEnum i_eToken ) + { + ::rtl::OUStringBuffer aQualifiedName( m_aNamespace ); + aQualifiedName.append( sal_Unicode( ':' ) ); + aQualifiedName.append( ::xmloff::token::GetXMLToken( i_eToken ) ); + return aQualifiedName.makeStringAndClear(); + } + + private: + const ::comphelper::ComponentContext& m_rContext; + const StorageXMLOutputStream& m_rDelegator; + const ::rtl::OUStringBuffer m_aNamespace; + }; + + //-------------------------------------------------------------------- + void SettingsExportContext::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, const ::rtl::OUString& i_rValue ) + { + m_rDelegator.addAttribute( impl_prefix( i_eName ), i_rValue ); + } + + //-------------------------------------------------------------------- + void SettingsExportContext::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue ) + { + m_rDelegator.addAttribute( impl_prefix( i_eName ), ::xmloff::token::GetXMLToken( i_eValue ) ); + } + + //-------------------------------------------------------------------- + void SettingsExportContext::StartElement( enum ::xmloff::token::XMLTokenEnum i_eName, const sal_Bool i_bIgnoreWhitespace ) + { + if ( i_bIgnoreWhitespace ) + m_rDelegator.ignorableWhitespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) ) ); + + m_rDelegator.startElement( impl_prefix( i_eName ) ); + } + + //-------------------------------------------------------------------- + void SettingsExportContext::EndElement( const sal_Bool i_bIgnoreWhitespace ) + { + if ( i_bIgnoreWhitespace ) + m_rDelegator.ignorableWhitespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) ) ); + m_rDelegator.endElement(); + } + + //-------------------------------------------------------------------- + void SettingsExportContext::Characters( const ::rtl::OUString& i_rCharacters ) + { + m_rDelegator.characters( i_rCharacters ); + } + + //-------------------------------------------------------------------- + Reference< XMultiServiceFactory > SettingsExportContext::GetServiceFactory() const + { + return m_rContext.getLegacyServiceFactory(); + } + + //==================================================================== + //= SubComponentRecovery + //==================================================================== + //-------------------------------------------------------------------- + const ::rtl::OUString SubComponentRecovery::getComponentsStorageName( const SubComponentType i_eType ) + { + static const ::rtl::OUString s_sFormsStorageName( RTL_CONSTASCII_USTRINGPARAM( "forms" ) ); + static const ::rtl::OUString s_sReportsStorageName( RTL_CONSTASCII_USTRINGPARAM( "reports" ) ); + static const ::rtl::OUString s_sTablesStorageName( RTL_CONSTASCII_USTRINGPARAM( "tables" ) ); + static const ::rtl::OUString s_sQueriesStorageName( RTL_CONSTASCII_USTRINGPARAM( "queries" ) ); + static const ::rtl::OUString s_sRelationsStorageName( RTL_CONSTASCII_USTRINGPARAM( "relations" ) ); + + switch ( i_eType ) + { + case FORM: + return s_sFormsStorageName; + case REPORT: + return s_sReportsStorageName; + case TABLE: + return s_sTablesStorageName; + case QUERY: + return s_sQueriesStorageName; + case RELATION_DESIGN: + return s_sRelationsStorageName; + default: + break; + } + + OSL_ENSURE( false, "SubComponentRecovery::getComponentsStorageName: unimplemented case!" ); + static const ::rtl::OUString s_sFallback; + return s_sFallback; + } + + //-------------------------------------------------------------------- + void SubComponentRecovery::saveToRecoveryStorage( const Reference< XStorage >& i_rRecoveryStorage, + MapCompTypeToCompDescs& io_mapCompDescs ) + { + if ( m_eType == UNKNOWN ) + // quite fatal, but has already been reported (as assertion) before + return; + + // open the sub storage for the given kind of components + const ::rtl::OUString& rStorageName( getComponentsStorageName( m_eType ) ); + const Reference< XStorage > xComponentsStorage( i_rRecoveryStorage->openStorageElement( + rStorageName, ElementModes::READWRITE ), UNO_QUERY_THROW ); + + // find a free sub storage name, and create Yet Another Sub Storage + const ::rtl::OUString& rBaseName( lcl_getComponentStorageBaseName( m_eType ) ); + const ::rtl::OUString sStorName = ::dbtools::createUniqueName( xComponentsStorage.get(), rBaseName, true ); + const Reference< XStorage > xObjectStor( xComponentsStorage->openStorageElement( + sStorName, ElementModes::READWRITE ), UNO_QUERY_THROW ); + + switch ( m_eType ) + { + case FORM: + case REPORT: + impl_saveSubDocument_throw( xObjectStor ); + break; + + case QUERY: + impl_saveQueryDesign_throw( xObjectStor ); + break; + + default: + // TODO + OSL_ENSURE( false, "SubComponentRecoverys::saveToRecoveryStorage: unimplemented case!" ); + break; + } + + // commit the storage(s) + tools::stor::commitStorageIfWriteable( xObjectStor ); + tools::stor::commitStorageIfWriteable( xComponentsStorage ); + + // remember the relationship from the component name to the storage name + MapStringToCompDesc& rMapCompDescs = io_mapCompDescs[ m_eType ]; + OSL_ENSURE( rMapCompDescs.find( sStorName ) == rMapCompDescs.end(), + "SubComponentRecoverys::saveToRecoveryStorage: object name already used!" ); + rMapCompDescs[ sStorName ] = m_aCompDesc; + } + + //-------------------------------------------------------------------- + void SubComponentRecovery::impl_identifyComponent_throw() + { + // ask the controller + Pair< sal_Int32, ::rtl::OUString > aComponentIdentity = m_xDocumentUI->identifySubComponent( m_xComponent ); + m_eType = lcl_databaseObjectToSubComponentType( aComponentIdentity.First ); + m_aCompDesc.sName = aComponentIdentity.Second; + + // what the controller didn't give us is the information whether this is in edit mode or not ... + Reference< XModuleManager > xModuleManager( m_rContext.createComponent( "com.sun.star.frame.ModuleManager" ), UNO_QUERY_THROW ); + const ::rtl::OUString sModuleIdentifier = xModuleManager->identify( m_xComponent ); + + switch ( m_eType ) + { + case TABLE: + m_aCompDesc.bForEditing = sModuleIdentifier.equalsAscii( "com.sun.star.sdb.TableDesign" ); + break; + + case QUERY: + m_aCompDesc.bForEditing = sModuleIdentifier.equalsAscii( "com.sun.star.sdb.QueryDesign" ); + break; + + case REPORT: + if ( sModuleIdentifier.equalsAscii( "com.sun.star.report.ReportDefinition" ) ) + { + // it's an SRB report desginer + m_aCompDesc.bForEditing = true; + break; + } + // fall through + + case FORM: + m_aCompDesc.bForEditing = !lcl_determineReadOnly( m_xComponent ); + break; + + default: + if ( sModuleIdentifier.equalsAscii( "com.sun.star.sdb.RelationDesign" ) ) + { + m_eType = RELATION_DESIGN; + m_aCompDesc.bForEditing = true; + } + else + { + OSL_ENSURE( false, "SubComponentRecovery::impl_identifyComponent_throw: couldn't classify the given sub component!" ); + } + break; + } + + OSL_POSTCOND( m_eType != UNKNOWN, + "SubComponentRecovery::impl_identifyComponent_throw: couldn't classify the component!" ); + } + + //-------------------------------------------------------------------- + void SubComponentRecovery::impl_saveQueryDesign_throw( const Reference< XStorage >& i_rObjectStorage ) + { + ENSURE_OR_THROW( m_eType == QUERY, "illegal sub component type" ); + ENSURE_OR_THROW( i_rObjectStorage.is(), "illegal storage" ); + + // retrieve the current query design (which might differ from what we can retrieve as ActiveCommand property, since + // the latter is updated only upon successful save of the design) + Reference< XPropertySet > xDesignerProps( m_xComponent, UNO_QUERY_THROW ); + Sequence< PropertyValue > aCurrentQueryDesign; + OSL_VERIFY( xDesignerProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CurrentQueryDesign" ) ) ) >>= aCurrentQueryDesign ); + + // write the query design + StorageXMLOutputStream aDesignOutput( m_rContext, i_rObjectStorage, lcl_getSettingsStreamName() ); + SettingsExportContext aSettingsExportContext( m_rContext, aDesignOutput ); + + const ::rtl::OUString sWhitespace( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) ) ); + + aDesignOutput.startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "office:settings" ) ) ); + aDesignOutput.ignorableWhitespace( sWhitespace ); + + XMLSettingsExportHelper aSettingsExporter( aSettingsExportContext ); + aSettingsExporter.exportAllSettings( aCurrentQueryDesign, lcl_getCurrentQueryDesignName() ); + + aDesignOutput.ignorableWhitespace( sWhitespace ); + aDesignOutput.endElement(); + aDesignOutput.close(); + } + + //-------------------------------------------------------------------- + void SubComponentRecovery::impl_saveSubDocument_throw( const Reference< XStorage >& i_rObjectStorage ) + { + ENSURE_OR_THROW( ( m_eType == FORM ) || ( m_eType == REPORT ), "illegal sub component type" ); + ENSURE_OR_THROW( i_rObjectStorage.is(), "illegal storage" ); + + // store the document into the storage + Reference< XStorageBasedDocument > xStorageDocument( m_xComponent, UNO_QUERY_THROW ); + xStorageDocument->storeToStorage( i_rObjectStorage, Sequence< PropertyValue >() ); + } + + //-------------------------------------------------------------------- + Reference< XComponent > SubComponentRecovery::impl_recoverSubDocument_throw( const Reference< XStorage >& i_rRecoveryStorage, + const ::rtl::OUString& i_rComponentName, const bool i_bForEditing ) + { + Reference< XComponent > xSubComponent; + Reference< XCommandProcessor > xDocDefinition; + + ::comphelper::NamedValueCollection aLoadArgs; + aLoadArgs.put( "RecoveryStorage", i_rRecoveryStorage ); + + // load/create the sub component hidden. We'll show it when the main app window is shown. + aLoadArgs.put( "Hidden", true ); + + if ( i_rComponentName.getLength() ) + { + xDocDefinition = lcl_getSubComponentDef_nothrow( m_xDocumentUI, m_eType, i_rComponentName ); + xSubComponent.set( m_xDocumentUI->loadComponentWithArguments( + m_eType, + i_rComponentName, + i_bForEditing, + aLoadArgs.getPropertyValues() + ), + UNO_SET_THROW + ); + } + else + { + Reference< XComponent > xDocDefComponent; + xSubComponent.set( m_xDocumentUI->createComponentWithArguments( + m_eType, + aLoadArgs.getPropertyValues(), + xDocDefComponent + ), + UNO_SET_THROW + ); + + xDocDefinition.set( xDocDefComponent, UNO_QUERY ); + OSL_ENSURE( xDocDefinition.is(), "DatabaseDocumentRecovery::recoverSubDocuments: loaded a form/report, but don't have a document definition?!" ); + } + + if ( xDocDefinition.is() ) + { + Reference< XController > xController( m_xDocumentUI, UNO_QUERY_THROW ); + Reference< XInterface > xLoader( *new SubComponentLoader( xController, xDocDefinition ) ); + (void)xLoader; + } + + return xSubComponent; + } + + //-------------------------------------------------------------------- + Reference< XComponent > SubComponentRecovery::recoverFromStorage( const Reference< XStorage >& i_rRecoveryStorage, + const ::rtl::OUString& i_rComponentName, const bool i_bForEditing ) + { + Reference< XComponent > xSubComponent; + switch ( m_eType ) + { + case FORM: + case REPORT: + xSubComponent = impl_recoverSubDocument_throw( i_rRecoveryStorage, i_rComponentName, i_bForEditing ); + break; + case QUERY: + // TODO + default: + OSL_ENSURE( false, "SubComponentRecovery::recoverFromStorage: unimplemented case!" ); + break; + } + return xSubComponent; + } + +//........................................................................ +} // namespace dbaccess +//........................................................................ diff --git a/dbaccess/source/core/recovery/subcomponentrecovery.hxx b/dbaccess/source/core/recovery/subcomponentrecovery.hxx new file mode 100644 index 000000000000..59a67d802faa --- /dev/null +++ b/dbaccess/source/core/recovery/subcomponentrecovery.hxx @@ -0,0 +1,119 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +#ifndef SUBCOMPONENTRECOVERY_HXX +#define SUBCOMPONENTRECOVERY_HXX + +#include "subcomponents.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/sdb/application/XDatabaseDocumentUI.hpp> +#include <com/sun/star/embed/XStorage.hpp> +/** === end UNO includes === **/ + +#include <comphelper/componentcontext.hxx> + +//........................................................................ +namespace dbaccess +{ +//........................................................................ + + //==================================================================== + //= SubComponentRecovery + //==================================================================== + class DBACCESS_DLLPRIVATE SubComponentRecovery + { + public: + SubComponentRecovery( const ::comphelper::ComponentContext& i_rContext, const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::application::XDatabaseDocumentUI >& i_rController, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& i_rComponent ) + :m_rContext( i_rContext ) + ,m_xDocumentUI( i_rController, ::com::sun::star::uno::UNO_SET_THROW ) + ,m_xComponent( i_rComponent ) + ,m_eType( UNKNOWN ) + ,m_aCompDesc() + { + impl_identifyComponent_throw(); + } + + SubComponentRecovery( const ::comphelper::ComponentContext& i_rContext, const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::application::XDatabaseDocumentUI >& i_rController, + const SubComponentType i_eType ) + :m_rContext( i_rContext ) + ,m_xDocumentUI( i_rController, ::com::sun::star::uno::UNO_SET_THROW ) + ,m_xComponent() + ,m_eType( i_eType ) + ,m_aCompDesc() + { + } + + // only to be used after being constructed with a component + void saveToRecoveryStorage( + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& i_rRecoveryStorage, + MapCompTypeToCompDescs& io_mapCompDescs + ); + + // only to be used after being constructed with a type + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > + recoverFromStorage( + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& i_rRecoveryStorage, + const ::rtl::OUString& i_rComponentName, + const bool i_bForEditing + ); + + static const ::rtl::OUString getComponentsStorageName( const SubComponentType i_eType ); + + private: + void impl_saveSubDocument_throw( + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& i_rObjectStorage + ); + + void impl_saveQueryDesign_throw( + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& i_rObjectStorage + ); + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > + impl_recoverSubDocument_throw( + const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& i_rRecoveryStorage, + const ::rtl::OUString& i_rComponentName, + const bool i_bForEditing + ); + + void impl_identifyComponent_throw(); + + private: + const ::comphelper::ComponentContext& m_rContext; + ::com::sun::star::uno::Reference< ::com::sun::star::sdb::application::XDatabaseDocumentUI > + m_xDocumentUI; + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > + m_xComponent; + SubComponentType m_eType; + SubComponentDescriptor m_aCompDesc; + }; + + +//........................................................................ +} // namespace dbaccess +//........................................................................ + +#endif // SUBCOMPONENTRECOVERY_HXX diff --git a/dbaccess/source/core/recovery/subcomponents.hxx b/dbaccess/source/core/recovery/subcomponents.hxx new file mode 100644 index 000000000000..d1ba0ccb1966 --- /dev/null +++ b/dbaccess/source/core/recovery/subcomponents.hxx @@ -0,0 +1,88 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +#ifndef SUBCOMPONENTS_HXX +#define SUBCOMPONENTS_HXX + +#include "dbaccessdllapi.h" + +/** === begin UNO includes === **/ +#include <com/sun/star/sdb/application/DatabaseObject.hpp> +/** === end UNO includes === **/ + +#include <rtl/ustring.hxx> + +#include <hash_map> +#include <map> + +//........................................................................ +namespace dbaccess +{ +//........................................................................ + + namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject; + + // ------------------------------------------------------------------- + enum SubComponentType + { + TABLE = DatabaseObject::TABLE, + QUERY = DatabaseObject::QUERY, + FORM = DatabaseObject::FORM, + REPORT = DatabaseObject::REPORT, + + RELATION_DESIGN = 1000, + + UNKNOWN = 10001 + }; + + // ------------------------------------------------------------------- + struct DBACCESS_DLLPRIVATE SubComponentDescriptor + { + ::rtl::OUString sName; + bool bForEditing; + + SubComponentDescriptor() + :sName() + ,bForEditing( false ) + { + } + + SubComponentDescriptor( const ::rtl::OUString& i_rName, const bool i_bForEditing ) + :sName( i_rName ) + ,bForEditing( i_bForEditing ) + { + } + }; + + // ------------------------------------------------------------------- + typedef ::std::hash_map< ::rtl::OUString, SubComponentDescriptor, ::rtl::OUStringHash > MapStringToCompDesc; + typedef ::std::map< SubComponentType, MapStringToCompDesc > MapCompTypeToCompDescs; + + +//........................................................................ +} // namespace dbaccess +//........................................................................ + +#endif // SUBCOMPONENTS_HXX |