196de5490SAndrew Rist /************************************************************** 296de5490SAndrew Rist * 396de5490SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 496de5490SAndrew Rist * or more contributor license agreements. See the NOTICE file 596de5490SAndrew Rist * distributed with this work for additional information 696de5490SAndrew Rist * regarding copyright ownership. The ASF licenses this file 796de5490SAndrew Rist * to you under the Apache License, Version 2.0 (the 896de5490SAndrew Rist * "License"); you may not use this file except in compliance 996de5490SAndrew Rist * with the License. You may obtain a copy of the License at 1096de5490SAndrew Rist * 1196de5490SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 1296de5490SAndrew Rist * 1396de5490SAndrew Rist * Unless required by applicable law or agreed to in writing, 1496de5490SAndrew Rist * software distributed under the License is distributed on an 1596de5490SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1696de5490SAndrew Rist * KIND, either express or implied. See the License for the 1796de5490SAndrew Rist * specific language governing permissions and limitations 1896de5490SAndrew Rist * under the License. 1996de5490SAndrew Rist * 2096de5490SAndrew Rist *************************************************************/ 2196de5490SAndrew Rist 2296de5490SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include "precompiled_dbaccess.hxx" 25cdf0e10cSrcweir 26cdf0e10cSrcweir #include "recovery/dbdocrecovery.hxx" 27cdf0e10cSrcweir #include "sdbcoretools.hxx" 28cdf0e10cSrcweir #include "storagetextstream.hxx" 29cdf0e10cSrcweir #include "subcomponentrecovery.hxx" 30cdf0e10cSrcweir #include "subcomponents.hxx" 31cdf0e10cSrcweir #include "dbastrings.hrc" 32cdf0e10cSrcweir 33cdf0e10cSrcweir /** === begin UNO includes === **/ 34cdf0e10cSrcweir #include <com/sun/star/sdb/application/XDatabaseDocumentUI.hpp> 35cdf0e10cSrcweir #include <com/sun/star/embed/ElementModes.hpp> 36cdf0e10cSrcweir #include <com/sun/star/document/XStorageBasedDocument.hpp> 37cdf0e10cSrcweir #include <com/sun/star/io/XTextOutputStream.hpp> 38cdf0e10cSrcweir #include <com/sun/star/io/XTextInputStream.hpp> 39cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataSource.hpp> 40cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataSink.hpp> 41cdf0e10cSrcweir #include <com/sun/star/util/XModifiable.hpp> 42cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp> 43cdf0e10cSrcweir /** === end UNO includes === **/ 44cdf0e10cSrcweir 45cdf0e10cSrcweir #include <comphelper/componentcontext.hxx> 46cdf0e10cSrcweir #include <comphelper/namedvaluecollection.hxx> 47cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 48cdf0e10cSrcweir #include <tools/diagnose_ex.h> 49cdf0e10cSrcweir 50cdf0e10cSrcweir #include <algorithm> 51cdf0e10cSrcweir 52cdf0e10cSrcweir //........................................................................ 53cdf0e10cSrcweir namespace dbaccess 54cdf0e10cSrcweir { 55cdf0e10cSrcweir //........................................................................ 56cdf0e10cSrcweir 57cdf0e10cSrcweir /** === begin UNO using === **/ 58cdf0e10cSrcweir using ::com::sun::star::uno::Reference; 59cdf0e10cSrcweir using ::com::sun::star::uno::XInterface; 60cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY; 61cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY_THROW; 62cdf0e10cSrcweir using ::com::sun::star::uno::UNO_SET_THROW; 63cdf0e10cSrcweir using ::com::sun::star::uno::Exception; 64cdf0e10cSrcweir using ::com::sun::star::uno::RuntimeException; 65cdf0e10cSrcweir using ::com::sun::star::uno::Any; 66cdf0e10cSrcweir using ::com::sun::star::uno::makeAny; 67cdf0e10cSrcweir using ::com::sun::star::uno::Sequence; 68cdf0e10cSrcweir using ::com::sun::star::uno::Type; 69cdf0e10cSrcweir using ::com::sun::star::embed::XStorage; 70cdf0e10cSrcweir using ::com::sun::star::frame::XController; 71cdf0e10cSrcweir using ::com::sun::star::sdb::application::XDatabaseDocumentUI; 72cdf0e10cSrcweir using ::com::sun::star::lang::XComponent; 73cdf0e10cSrcweir using ::com::sun::star::document::XStorageBasedDocument; 74cdf0e10cSrcweir using ::com::sun::star::beans::PropertyValue; 75cdf0e10cSrcweir using ::com::sun::star::io::XStream; 76cdf0e10cSrcweir using ::com::sun::star::io::XTextOutputStream; 77cdf0e10cSrcweir using ::com::sun::star::io::XActiveDataSource; 78cdf0e10cSrcweir using ::com::sun::star::io::XTextInputStream; 79cdf0e10cSrcweir using ::com::sun::star::io::XActiveDataSink; 80cdf0e10cSrcweir using ::com::sun::star::frame::XModel; 81cdf0e10cSrcweir using ::com::sun::star::util::XModifiable; 82cdf0e10cSrcweir using ::com::sun::star::beans::XPropertySet; 83cdf0e10cSrcweir using ::com::sun::star::lang::XMultiServiceFactory; 84cdf0e10cSrcweir /** === end UNO using === **/ 85cdf0e10cSrcweir 86cdf0e10cSrcweir namespace ElementModes = ::com::sun::star::embed::ElementModes; 87cdf0e10cSrcweir 88cdf0e10cSrcweir //==================================================================== 89cdf0e10cSrcweir //= helpers 90cdf0e10cSrcweir //==================================================================== 91cdf0e10cSrcweir namespace 92cdf0e10cSrcweir { 93cdf0e10cSrcweir // ......................................................................... lcl_getPersistentRepresentation(const MapStringToCompDesc::value_type & i_rComponentDesc,::rtl::OUStringBuffer & o_rBuffer)94cdf0e10cSrcweir static void lcl_getPersistentRepresentation( const MapStringToCompDesc::value_type& i_rComponentDesc, ::rtl::OUStringBuffer& o_rBuffer ) 95cdf0e10cSrcweir { 96cdf0e10cSrcweir o_rBuffer.append( i_rComponentDesc.first ); 97cdf0e10cSrcweir o_rBuffer.append( sal_Unicode( '=' ) ); 98cdf0e10cSrcweir o_rBuffer.append( i_rComponentDesc.second.sName ); 99cdf0e10cSrcweir o_rBuffer.append( sal_Unicode( ',' ) ); 100cdf0e10cSrcweir o_rBuffer.append( sal_Unicode( i_rComponentDesc.second.bForEditing ? '1' : '0' ) ); 101cdf0e10cSrcweir } 102cdf0e10cSrcweir 103cdf0e10cSrcweir // ......................................................................... lcl_extractCompDesc(const::rtl::OUString & i_rIniLine,::rtl::OUString & o_rStorName,SubComponentDescriptor & o_rCompDesc)104cdf0e10cSrcweir static bool lcl_extractCompDesc( const ::rtl::OUString& i_rIniLine, ::rtl::OUString& o_rStorName, SubComponentDescriptor& o_rCompDesc ) 105cdf0e10cSrcweir { 106cdf0e10cSrcweir const sal_Int32 nEqualSignPos = i_rIniLine.indexOf( sal_Unicode( '=' ) ); 107cdf0e10cSrcweir if ( nEqualSignPos < 1 ) 108cdf0e10cSrcweir { 109cdf0e10cSrcweir OSL_ENSURE( false, "lcl_extractCompDesc: invalid map file entry - unexpected pos of '='" ); 110cdf0e10cSrcweir return false; 111cdf0e10cSrcweir } 112cdf0e10cSrcweir o_rStorName = i_rIniLine.copy( 0, nEqualSignPos ); 113cdf0e10cSrcweir 114cdf0e10cSrcweir const sal_Int32 nCommaPos = i_rIniLine.lastIndexOf( sal_Unicode( ',' ) ); 115cdf0e10cSrcweir if ( nCommaPos != i_rIniLine.getLength() - 2 ) 116cdf0e10cSrcweir { 117cdf0e10cSrcweir OSL_ENSURE( false, "lcl_extractCompDesc: invalid map file entry - unexpected pos of ','" ); 118cdf0e10cSrcweir return false; 119cdf0e10cSrcweir } 120cdf0e10cSrcweir o_rCompDesc.sName = i_rIniLine.copy( nEqualSignPos + 1, nCommaPos - nEqualSignPos - 1 ); 121cdf0e10cSrcweir o_rCompDesc.bForEditing = ( i_rIniLine.getStr()[ nCommaPos + 1 ] == '1' ); 122cdf0e10cSrcweir return true; 123cdf0e10cSrcweir } 124cdf0e10cSrcweir 125cdf0e10cSrcweir // ......................................................................... lcl_getRecoveryDataSubStorageName()126cdf0e10cSrcweir static const ::rtl::OUString& lcl_getRecoveryDataSubStorageName() 127cdf0e10cSrcweir { 128cdf0e10cSrcweir static const ::rtl::OUString s_sRecDataStorName( RTL_CONSTASCII_USTRINGPARAM( "recovery" ) ); 129cdf0e10cSrcweir return s_sRecDataStorName; 130cdf0e10cSrcweir } 131cdf0e10cSrcweir // ......................................................................... lcl_getObjectMapStreamName()132cdf0e10cSrcweir static const ::rtl::OUString& lcl_getObjectMapStreamName() 133cdf0e10cSrcweir { 134cdf0e10cSrcweir static const ::rtl::OUString s_sObjectMapStreamName( RTL_CONSTASCII_USTRINGPARAM( "storage-component-map.ini" ) ); 135cdf0e10cSrcweir return s_sObjectMapStreamName; 136cdf0e10cSrcweir } 137cdf0e10cSrcweir 138cdf0e10cSrcweir // ......................................................................... lcl_getMapStreamEncodingName()139cdf0e10cSrcweir static const ::rtl::OUString& lcl_getMapStreamEncodingName() 140cdf0e10cSrcweir { 141cdf0e10cSrcweir static const ::rtl::OUString s_sMapStreamEncodingName( RTL_CONSTASCII_USTRINGPARAM( "UTF-8" ) ); 142cdf0e10cSrcweir return s_sMapStreamEncodingName; 143cdf0e10cSrcweir } 144cdf0e10cSrcweir 145cdf0e10cSrcweir // ......................................................................... lcl_writeObjectMap_throw(const::comphelper::ComponentContext & i_rContext,const Reference<XStorage> & i_rStorage,const MapStringToCompDesc & i_mapStorageToCompDesc)146cdf0e10cSrcweir static void lcl_writeObjectMap_throw( const ::comphelper::ComponentContext& i_rContext, const Reference< XStorage >& i_rStorage, 147cdf0e10cSrcweir const MapStringToCompDesc& i_mapStorageToCompDesc ) 148cdf0e10cSrcweir { 149cdf0e10cSrcweir if ( i_mapStorageToCompDesc.empty() ) 150cdf0e10cSrcweir // nothing to do 151cdf0e10cSrcweir return; 152cdf0e10cSrcweir 153cdf0e10cSrcweir StorageTextOutputStream aTextOutput( i_rContext, i_rStorage, lcl_getObjectMapStreamName() ); 154cdf0e10cSrcweir 155cdf0e10cSrcweir aTextOutput.writeLine( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[storages]" ) ) ); 156cdf0e10cSrcweir 157cdf0e10cSrcweir for ( MapStringToCompDesc::const_iterator stor = i_mapStorageToCompDesc.begin(); 158cdf0e10cSrcweir stor != i_mapStorageToCompDesc.end(); 159cdf0e10cSrcweir ++stor 160cdf0e10cSrcweir ) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir ::rtl::OUStringBuffer aLine; 163cdf0e10cSrcweir lcl_getPersistentRepresentation( *stor, aLine ); 164cdf0e10cSrcweir 165cdf0e10cSrcweir aTextOutput.writeLine( aLine.makeStringAndClear() ); 166cdf0e10cSrcweir } 167cdf0e10cSrcweir 168cdf0e10cSrcweir aTextOutput.writeLine(); 169cdf0e10cSrcweir } 170cdf0e10cSrcweir 171cdf0e10cSrcweir // ......................................................................... lcl_isSectionStart(const::rtl::OUString & i_rIniLine,::rtl::OUString & o_rSectionName)172cdf0e10cSrcweir static bool lcl_isSectionStart( const ::rtl::OUString& i_rIniLine, ::rtl::OUString& o_rSectionName ) 173cdf0e10cSrcweir { 174cdf0e10cSrcweir const sal_Int32 nLen = i_rIniLine.getLength(); 175cdf0e10cSrcweir if ( ( nLen > 0 ) && ( i_rIniLine.getStr()[0] == '[' ) && ( i_rIniLine.getStr()[ nLen - 1 ] == ']' ) ) 176cdf0e10cSrcweir { 177cdf0e10cSrcweir o_rSectionName = i_rIniLine.copy( 1, nLen -2 ); 178cdf0e10cSrcweir return true; 179cdf0e10cSrcweir } 180cdf0e10cSrcweir return false; 181cdf0e10cSrcweir } 182cdf0e10cSrcweir 183cdf0e10cSrcweir // ......................................................................... lcl_stripTrailingLineFeed(::rtl::OUString & io_rLine)184cdf0e10cSrcweir static void lcl_stripTrailingLineFeed( ::rtl::OUString& io_rLine ) 185cdf0e10cSrcweir { 186cdf0e10cSrcweir const sal_Int32 nLen = io_rLine.getLength(); 187cdf0e10cSrcweir if ( ( nLen > 0 ) && ( io_rLine.getStr()[ nLen - 1 ] == '\n' ) ) 188cdf0e10cSrcweir io_rLine = io_rLine.copy( 0, nLen - 1 ); 189cdf0e10cSrcweir } 190cdf0e10cSrcweir 191cdf0e10cSrcweir // ......................................................................... lcl_readObjectMap_throw(const::comphelper::ComponentContext & i_rContext,const Reference<XStorage> & i_rStorage,MapStringToCompDesc & o_mapStorageToObjectName)192cdf0e10cSrcweir static void lcl_readObjectMap_throw( const ::comphelper::ComponentContext& i_rContext, const Reference< XStorage >& i_rStorage, 193cdf0e10cSrcweir MapStringToCompDesc& o_mapStorageToObjectName ) 194cdf0e10cSrcweir { 195cdf0e10cSrcweir ENSURE_OR_THROW( i_rStorage.is(), "invalid storage" ); 196cdf0e10cSrcweir if ( !i_rStorage->hasByName( lcl_getObjectMapStreamName() ) ) 197cdf0e10cSrcweir { // nothing to do, though suspicious 198cdf0e10cSrcweir OSL_ENSURE( false, "lcl_readObjectMap_throw: if there's no map file, then there's expected to be no storage, too!" ); 199cdf0e10cSrcweir return; 200cdf0e10cSrcweir } 201cdf0e10cSrcweir 202cdf0e10cSrcweir Reference< XStream > xIniStream( i_rStorage->openStreamElement( 203cdf0e10cSrcweir lcl_getObjectMapStreamName(), ElementModes::READ ), UNO_SET_THROW ); 204cdf0e10cSrcweir 205cdf0e10cSrcweir Reference< XTextInputStream > xTextInput( i_rContext.createComponent( "com.sun.star.io.TextInputStream" ), UNO_QUERY_THROW ); 206cdf0e10cSrcweir xTextInput->setEncoding( lcl_getMapStreamEncodingName() ); 207cdf0e10cSrcweir 208cdf0e10cSrcweir Reference< XActiveDataSink > xDataSink( xTextInput, UNO_QUERY_THROW ); 209cdf0e10cSrcweir xDataSink->setInputStream( xIniStream->getInputStream() ); 210cdf0e10cSrcweir 211cdf0e10cSrcweir ::rtl::OUString sCurrentSection; 212cdf0e10cSrcweir bool bCurrentSectionIsKnownToBeUnsupported = true; 213cdf0e10cSrcweir while ( !xTextInput->isEOF() ) 214cdf0e10cSrcweir { 215cdf0e10cSrcweir ::rtl::OUString sLine = xTextInput->readLine(); 216cdf0e10cSrcweir lcl_stripTrailingLineFeed( sLine ); 217cdf0e10cSrcweir 218cdf0e10cSrcweir if ( sLine.getLength() == 0 ) 219cdf0e10cSrcweir continue; 220cdf0e10cSrcweir 221cdf0e10cSrcweir if ( lcl_isSectionStart( sLine, sCurrentSection ) ) 222cdf0e10cSrcweir { 223cdf0e10cSrcweir bCurrentSectionIsKnownToBeUnsupported = false; 224cdf0e10cSrcweir continue; 225cdf0e10cSrcweir } 226cdf0e10cSrcweir 227cdf0e10cSrcweir if ( bCurrentSectionIsKnownToBeUnsupported ) 228cdf0e10cSrcweir continue; 229cdf0e10cSrcweir 230cdf0e10cSrcweir // the only section we support so far is "storages" 231cdf0e10cSrcweir if ( !sCurrentSection.equalsAscii( "storages" ) ) 232cdf0e10cSrcweir { 233cdf0e10cSrcweir bCurrentSectionIsKnownToBeUnsupported = true; 234cdf0e10cSrcweir continue; 235cdf0e10cSrcweir } 236cdf0e10cSrcweir 237cdf0e10cSrcweir ::rtl::OUString sStorageName; 238cdf0e10cSrcweir SubComponentDescriptor aCompDesc; 239cdf0e10cSrcweir if ( !lcl_extractCompDesc( sLine, sStorageName, aCompDesc ) ) 240cdf0e10cSrcweir continue; 241cdf0e10cSrcweir o_mapStorageToObjectName[ sStorageName ] = aCompDesc; 242cdf0e10cSrcweir } 243cdf0e10cSrcweir } 244cdf0e10cSrcweir 245cdf0e10cSrcweir // ......................................................................... lcl_markModified(const Reference<XComponent> & i_rSubComponent)246cdf0e10cSrcweir static void lcl_markModified( const Reference< XComponent >& i_rSubComponent ) 247cdf0e10cSrcweir { 248cdf0e10cSrcweir const Reference< XModifiable > xModify( i_rSubComponent, UNO_QUERY ); 249cdf0e10cSrcweir if ( !xModify.is() ) 250cdf0e10cSrcweir { 251cdf0e10cSrcweir OSL_ENSURE( false, "lcl_markModified: unhandled case!" ); 252cdf0e10cSrcweir return; 253cdf0e10cSrcweir } 254cdf0e10cSrcweir 255cdf0e10cSrcweir xModify->setModified( sal_True ); 256cdf0e10cSrcweir } 257cdf0e10cSrcweir } 258cdf0e10cSrcweir 259cdf0e10cSrcweir //==================================================================== 260cdf0e10cSrcweir //= DatabaseDocumentRecovery_Data 261cdf0e10cSrcweir //==================================================================== 262cdf0e10cSrcweir struct DBACCESS_DLLPRIVATE DatabaseDocumentRecovery_Data 263cdf0e10cSrcweir { 264cdf0e10cSrcweir const ::comphelper::ComponentContext aContext; 265cdf0e10cSrcweir DatabaseDocumentRecovery_Datadbaccess::DatabaseDocumentRecovery_Data266cdf0e10cSrcweir DatabaseDocumentRecovery_Data( const ::comphelper::ComponentContext& i_rContext ) 267cdf0e10cSrcweir :aContext( i_rContext ) 268cdf0e10cSrcweir { 269cdf0e10cSrcweir } 270cdf0e10cSrcweir }; 271cdf0e10cSrcweir 272cdf0e10cSrcweir //==================================================================== 273cdf0e10cSrcweir //= DatabaseDocumentRecovery 274cdf0e10cSrcweir //==================================================================== 275cdf0e10cSrcweir //-------------------------------------------------------------------- DatabaseDocumentRecovery(const::comphelper::ComponentContext & i_rContext)276cdf0e10cSrcweir DatabaseDocumentRecovery::DatabaseDocumentRecovery( const ::comphelper::ComponentContext& i_rContext ) 277cdf0e10cSrcweir :m_pData( new DatabaseDocumentRecovery_Data( i_rContext ) ) 278cdf0e10cSrcweir { 279cdf0e10cSrcweir } 280cdf0e10cSrcweir 281cdf0e10cSrcweir //-------------------------------------------------------------------- ~DatabaseDocumentRecovery()282cdf0e10cSrcweir DatabaseDocumentRecovery::~DatabaseDocumentRecovery() 283cdf0e10cSrcweir { 284cdf0e10cSrcweir } 285cdf0e10cSrcweir 286cdf0e10cSrcweir //-------------------------------------------------------------------- saveModifiedSubComponents(const Reference<XStorage> & i_rTargetStorage,const::std::vector<Reference<XController>> & i_rControllers)287cdf0e10cSrcweir void DatabaseDocumentRecovery::saveModifiedSubComponents( const Reference< XStorage >& i_rTargetStorage, 288cdf0e10cSrcweir const ::std::vector< Reference< XController > >& i_rControllers ) 289cdf0e10cSrcweir { 290cdf0e10cSrcweir ENSURE_OR_THROW( i_rTargetStorage.is(), "invalid document storage" ); 291cdf0e10cSrcweir 292cdf0e10cSrcweir // create a sub storage for recovery data 293cdf0e10cSrcweir if ( i_rTargetStorage->hasByName( lcl_getRecoveryDataSubStorageName() ) ) 294cdf0e10cSrcweir i_rTargetStorage->removeElement( lcl_getRecoveryDataSubStorageName() ); 295cdf0e10cSrcweir Reference< XStorage > xRecoveryStorage = i_rTargetStorage->openStorageElement( lcl_getRecoveryDataSubStorageName(), ElementModes::READWRITE ); 296cdf0e10cSrcweir 297cdf0e10cSrcweir // store recovery data for open sub components of the given controller(s) 298cdf0e10cSrcweir if ( !i_rControllers.empty() ) 299cdf0e10cSrcweir { 300cdf0e10cSrcweir ENSURE_OR_THROW( i_rControllers.size() == 1, "can't handle more than one controller" ); 301cdf0e10cSrcweir // At the moment, there can be only one view to a database document. If we ever allow for more than this, 302cdf0e10cSrcweir // then we need a concept for sub documents opened from different controllers (i.e. two document views, 303cdf0e10cSrcweir // and the user opens the very same form in both views). And depending on this, we need a concept for 304cdf0e10cSrcweir // how those are saved to the recovery file. 305cdf0e10cSrcweir 306cdf0e10cSrcweir MapCompTypeToCompDescs aMapCompDescs; 307cdf0e10cSrcweir 308cdf0e10cSrcweir for ( ::std::vector< Reference< XController > >::const_iterator ctrl = i_rControllers.begin(); 309cdf0e10cSrcweir ctrl != i_rControllers.end(); 310cdf0e10cSrcweir ++ctrl 311cdf0e10cSrcweir ) 312cdf0e10cSrcweir { 313cdf0e10cSrcweir Reference< XDatabaseDocumentUI > xDatabaseUI( *ctrl, UNO_QUERY_THROW ); 314cdf0e10cSrcweir Sequence< Reference< XComponent > > aComponents( xDatabaseUI->getSubComponents() ); 315cdf0e10cSrcweir 316cdf0e10cSrcweir const Reference< XComponent >* component = aComponents.getConstArray(); 317cdf0e10cSrcweir const Reference< XComponent >* componentEnd = aComponents.getConstArray() + aComponents.getLength(); 318cdf0e10cSrcweir for ( ; component != componentEnd; ++component ) 319cdf0e10cSrcweir { 320cdf0e10cSrcweir SubComponentRecovery aComponentRecovery( m_pData->aContext, xDatabaseUI, *component ); 321cdf0e10cSrcweir aComponentRecovery.saveToRecoveryStorage( xRecoveryStorage, aMapCompDescs ); 322cdf0e10cSrcweir } 323cdf0e10cSrcweir } 324cdf0e10cSrcweir 325cdf0e10cSrcweir for ( MapCompTypeToCompDescs::const_iterator map = aMapCompDescs.begin(); 326cdf0e10cSrcweir map != aMapCompDescs.end(); 327cdf0e10cSrcweir ++map 328cdf0e10cSrcweir ) 329cdf0e10cSrcweir { 330cdf0e10cSrcweir Reference< XStorage > xComponentsStor( xRecoveryStorage->openStorageElement( 331cdf0e10cSrcweir SubComponentRecovery::getComponentsStorageName( map->first ), ElementModes::WRITE | ElementModes::NOCREATE ) ); 332cdf0e10cSrcweir lcl_writeObjectMap_throw( m_pData->aContext, xComponentsStor, map->second ); 333cdf0e10cSrcweir tools::stor::commitStorageIfWriteable( xComponentsStor ); 334cdf0e10cSrcweir } 335cdf0e10cSrcweir } 336cdf0e10cSrcweir 337cdf0e10cSrcweir // commit the recovery storage 338cdf0e10cSrcweir tools::stor::commitStorageIfWriteable( xRecoveryStorage ); 339cdf0e10cSrcweir } 340cdf0e10cSrcweir 341cdf0e10cSrcweir //-------------------------------------------------------------------- recoverSubDocuments(const Reference<XStorage> & i_rDocumentStorage,const Reference<XController> & i_rTargetController)342cdf0e10cSrcweir void DatabaseDocumentRecovery::recoverSubDocuments( const Reference< XStorage >& i_rDocumentStorage, 343cdf0e10cSrcweir const Reference< XController >& i_rTargetController ) 344cdf0e10cSrcweir { 345cdf0e10cSrcweir ENSURE_OR_THROW( i_rDocumentStorage.is(), "illegal document storage" ); 346cdf0e10cSrcweir Reference< XDatabaseDocumentUI > xDocumentUI( i_rTargetController, UNO_QUERY_THROW ); 347cdf0e10cSrcweir 348cdf0e10cSrcweir if ( !i_rDocumentStorage->hasByName( lcl_getRecoveryDataSubStorageName() ) ) 349cdf0e10cSrcweir // that's allowed 350cdf0e10cSrcweir return; 351cdf0e10cSrcweir 352cdf0e10cSrcweir // the "recovery" sub storage 353cdf0e10cSrcweir Reference< XStorage > xRecoveryStorage = i_rDocumentStorage->openStorageElement( lcl_getRecoveryDataSubStorageName(), ElementModes::READ ); 354cdf0e10cSrcweir 355cdf0e10cSrcweir // read the map from sub storages to object names 356cdf0e10cSrcweir MapCompTypeToCompDescs aMapCompDescs; 357cdf0e10cSrcweir SubComponentType aKnownTypes[] = { TABLE, QUERY, FORM, REPORT, RELATION_DESIGN }; 358cdf0e10cSrcweir for ( size_t i = 0; i < sizeof( aKnownTypes ) / sizeof( aKnownTypes[0] ); ++i ) 359cdf0e10cSrcweir { 360cdf0e10cSrcweir if ( !xRecoveryStorage->hasByName( SubComponentRecovery::getComponentsStorageName( aKnownTypes[i] ) ) ) 361cdf0e10cSrcweir continue; 362cdf0e10cSrcweir 363cdf0e10cSrcweir Reference< XStorage > xComponentsStor( xRecoveryStorage->openStorageElement( 364cdf0e10cSrcweir SubComponentRecovery::getComponentsStorageName( aKnownTypes[i] ), ElementModes::READ ) ); 365cdf0e10cSrcweir lcl_readObjectMap_throw( m_pData->aContext, xComponentsStor, aMapCompDescs[ aKnownTypes[i] ] ); 366cdf0e10cSrcweir xComponentsStor->dispose(); 367cdf0e10cSrcweir } 368cdf0e10cSrcweir 369cdf0e10cSrcweir // recover all sub components as indicated by the map 370cdf0e10cSrcweir for ( MapCompTypeToCompDescs::const_iterator map = aMapCompDescs.begin(); 371cdf0e10cSrcweir map != aMapCompDescs.end(); 372cdf0e10cSrcweir ++map 373cdf0e10cSrcweir ) 374cdf0e10cSrcweir { 375cdf0e10cSrcweir const SubComponentType eComponentType = map->first; 376cdf0e10cSrcweir 377cdf0e10cSrcweir // the storage for all components of the current type 378cdf0e10cSrcweir Reference< XStorage > xComponentsStor( xRecoveryStorage->openStorageElement( 379cdf0e10cSrcweir SubComponentRecovery::getComponentsStorageName( eComponentType ), ElementModes::READ ), UNO_QUERY_THROW ); 380cdf0e10cSrcweir 381cdf0e10cSrcweir // loop thru all components of this type 382cdf0e10cSrcweir for ( MapStringToCompDesc::const_iterator stor = map->second.begin(); 383cdf0e10cSrcweir stor != map->second.end(); 384cdf0e10cSrcweir ++stor 385cdf0e10cSrcweir ) 386cdf0e10cSrcweir { 387cdf0e10cSrcweir const ::rtl::OUString sComponentName( stor->second.sName ); 388cdf0e10cSrcweir if ( !xComponentsStor->hasByName( stor->first ) ) 389cdf0e10cSrcweir { 390cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 391cdf0e10cSrcweir ::rtl::OStringBuffer message; 392cdf0e10cSrcweir message.append( "DatabaseDocumentRecovery::recoverSubDocuments: inconsistent recovery storage: storage '" ); 393cdf0e10cSrcweir message.append( ::rtl::OUStringToOString( stor->first, RTL_TEXTENCODING_ASCII_US ) ); 394cdf0e10cSrcweir message.append( "' not found in '" ); 395cdf0e10cSrcweir message.append( ::rtl::OUStringToOString( SubComponentRecovery::getComponentsStorageName( eComponentType ), RTL_TEXTENCODING_ASCII_US ) ); 396cdf0e10cSrcweir message.append( "', but required per map file!" ); 397*24c56ab9SHerbert Dürr OSL_ENSURE( false, message.getStr() ); 398cdf0e10cSrcweir #endif 399cdf0e10cSrcweir continue; 400cdf0e10cSrcweir } 401cdf0e10cSrcweir 402cdf0e10cSrcweir // the controller needs to have a connection to be able to open sub components 403cdf0e10cSrcweir if ( !xDocumentUI->isConnected() ) 404cdf0e10cSrcweir xDocumentUI->connect(); 405cdf0e10cSrcweir 406cdf0e10cSrcweir // recover the single component 407cdf0e10cSrcweir Reference< XStorage > xCompStor( xComponentsStor->openStorageElement( stor->first, ElementModes::READ ) ); 408cdf0e10cSrcweir SubComponentRecovery aComponentRecovery( m_pData->aContext, xDocumentUI, eComponentType ); 409cdf0e10cSrcweir Reference< XComponent > xSubComponent( aComponentRecovery.recoverFromStorage( xCompStor, sComponentName, stor->second.bForEditing ) ); 410cdf0e10cSrcweir 411cdf0e10cSrcweir // at the moment, we only store, during session save, sub components which are modified. So, set this 412cdf0e10cSrcweir // recovered sub component to "modified", too. 413cdf0e10cSrcweir lcl_markModified( xSubComponent ); 414cdf0e10cSrcweir } 415cdf0e10cSrcweir 416cdf0e10cSrcweir xComponentsStor->dispose(); 417cdf0e10cSrcweir } 418cdf0e10cSrcweir 419cdf0e10cSrcweir xRecoveryStorage->dispose(); 420cdf0e10cSrcweir 421cdf0e10cSrcweir // now that we successfully recovered, removed the "recovery" sub storage 422cdf0e10cSrcweir try 423cdf0e10cSrcweir { 424cdf0e10cSrcweir i_rDocumentStorage->removeElement( lcl_getRecoveryDataSubStorageName() ); 425cdf0e10cSrcweir } 426cdf0e10cSrcweir catch( const Exception& ) 427cdf0e10cSrcweir { 428cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 429cdf0e10cSrcweir } 430cdf0e10cSrcweir } 431cdf0e10cSrcweir 432cdf0e10cSrcweir //........................................................................ 433cdf0e10cSrcweir } // namespace dbaccess 434cdf0e10cSrcweir //........................................................................ 435