summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Schoenheit [fs] <frank.schoenheit@sun.com>2010-02-16 09:43:10 +0100
committerFrank Schoenheit [fs] <frank.schoenheit@sun.com>2010-02-16 09:43:10 +0100
commiteb79829c17871ccbad0daf469dfd7bd9c85eb8cc (patch)
tree69f733c72888afbf99170eb617707d75e8b05686
parenta1c40ed088aeabc90c260d9b8bc7e0db24d1b146 (diff)
autorecovery: outsourced the SubComponentRecovery class into a dedicated file, in preparation of recovering query designs
-rw-r--r--dbaccess/source/core/recovery/dbdocrecovery.cxx515
-rw-r--r--dbaccess/source/core/recovery/makefile.mk3
-rw-r--r--dbaccess/source/core/recovery/subcomponentrecovery.cxx523
-rw-r--r--dbaccess/source/core/recovery/subcomponentrecovery.hxx119
-rw-r--r--dbaccess/source/core/recovery/subcomponents.hxx88
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