Tag: cws_src680_dba201b User: oj Date: 05/07/11 00:18:23 Modified: /dba/dbaccess/source/core/dataaccess/ databasedocument.cxx
Log: RESYNC: (1.19-1.20); FILE MERGED File Changes: Directory: /dba/dbaccess/source/core/dataaccess/ ================================================ File [changed]: databasedocument.cxx Url: http://dba.openoffice.org/source/browse/dba/dbaccess/source/core/dataaccess/databasedocument.cxx?r1=1.19.10.1&r2=1.19.10.2 Delta lines: +44 -89 --------------------- --- databasedocument.cxx 27 May 2005 10:32:23 -0000 1.19.10.1 +++ databasedocument.cxx 11 Jul 2005 07:18:20 -0000 1.19.10.2 @@ -116,9 +116,6 @@ #ifndef _COM_SUN_STAR_UI_XUICONFIGURATIONSTORAGE_HPP_ #include <com/sun/star/ui/XUIConfigurationStorage.hpp> #endif -#ifndef DBA_COREDATAACCESS_COMMITLISTENER_HXX -#include "commitlistener.hxx" -#endif #ifndef _COM_SUN_STAR_EMBED_XTRANSACTIONBROADCASTER_HPP_ #include <com/sun/star/embed/XTransactionBroadcaster.hpp> #endif @@ -187,7 +184,8 @@ ::rtl::Reference<ODatabaseModelImpl> pImpl(new ODatabaseModelImpl(_rxFactory)); pImpl->m_pDBContext = pContext; - return *(new ODatabaseDocument(pImpl)); + Reference< XModel > xModel( pImpl->createNewModel_deliverOwnership() ); + return xModel.get(); } //-------------------------------------------------------------------------- ODatabaseDocument::ODatabaseDocument(const ::rtl::Reference<ODatabaseModelImpl>& _pImpl ) @@ -196,20 +194,10 @@ ,m_aModifyListeners(m_aMutex) ,m_aCloseListener(m_aMutex) ,m_aDocEventListeners(m_aMutex) - ,m_bCommitMasterStorage(sal_True) { DBG_CTOR(ODatabaseDocument,NULL); + // adjust our readonly flag - m_pChildCommitListen = NULL; - m_pImpl->m_xModel = this; - TStorages::iterator aIter = m_pImpl->m_aStorages.begin(); - TStorages::iterator aEnd = m_pImpl->m_aStorages.end(); - for (; aIter != aEnd ; ++aIter) - { - Reference<XComponent> xComp(aIter->second,UNO_QUERY); - if ( xComp.is() ) - xComp->addEventListener( static_cast< XTransactionListener* >( this ) ); - } try { m_xDocEventBroadcaster.set(m_pImpl->m_xServiceFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.GlobalEventBroadcaster"))), @@ -302,12 +290,6 @@ xContainer = m_pImpl->m_xCommandDefinitions; ::comphelper::disposeComponent(xContainer); - if ( m_pChildCommitListen ) - { - m_pChildCommitListen->dispose(); - m_pChildCommitListen->release(); - m_pChildCommitListen = NULL; - } m_pImpl->m_aContainer.clear(); m_pImpl->lateInit(); } @@ -412,6 +394,35 @@ if ( m_pImpl->m_xCurrentController == _xController ) m_pImpl->m_xCurrentController = NULL; + // TODO: The below fragment is conceptually wrong. + // + // There are more clients of a database document (aka XModel) than its controllers. + // In particular, people might programmatically obtain a DataSource from the + // DatabaseContext, script it, and at some point obtain the document from + // the data source (XDocumentDataSource::getDatabaseDocument). All this might happen + // without any controller being involved, which means the document gets never disposed, + // which imlpies a resource leak. + // + // You might argue that the scripter who obtained the model is responsible for disposing + // it. However, she cannot know whether the model she just got from getDatabaseDocument + // is really hers (since it was newly created), or already owned by somebody else. So, + // she cannot know whether she is really allowed to dispose it. + // + // There is a pattern which could prevent this dilemma: closing with ownership delivery + // (XCloseable::close). With this pattern, every client of a component (here: the model) + // adds itself as XCloseListener to the component. When the client dies, it tries to + // close the component, with the DeliverOwnership parameter set to <TRUE/>. If there is + // another client of the component, it will veto the closing, and take the ownership + // (and in turn do an own close attempt later on). If there is no other client, closing + // will succeed. + // + // We should implement this for models, too. Then, controllers would be clients of the + // model, and do a close attempt when they disconnect. The model would never dispose + // itself (as it does now), but it would automatically be closed when the last client + // dies (provided that all clients respect this pattern). It turn, it would not be + // allowed to dispose a model directly. + // + // #i50905# / 2005-06-21 / [EMAIL PROTECTED] if ( m_pImpl.is() && m_pImpl->m_aControllers.empty() ) { aGuard.clear(); @@ -645,9 +656,7 @@ throw IOException( aError ); } - m_bCommitMasterStorage = sal_False; m_pImpl->commitEmbeddedStorage(); - m_bCommitMasterStorage = sal_True; xMyStorage->copyToStorage( xStorage ); writeStorage(_rURL,_rArguments,xStorage); try @@ -1047,32 +1056,15 @@ { MutexGuard aGuard(m_aMutex); ::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed); - OSL_ENSURE(m_pImpl.is(),"Impl is NULL"); - Reference< XStorage > xResult = m_pImpl->getStorage(aStorageName,this,nMode); - if ( xResult.is() ) - { - Reference< XTransactionBroadcaster > xBroadcaster( xResult, UNO_QUERY ); - if ( xBroadcaster.is() ) - { - if ( m_pChildCommitListen == NULL ) - { - m_pChildCommitListen = new OChildCommitListen_Impl( static_cast<XModifiable*>(this) ); - m_pChildCommitListen->acquire(); - } - xBroadcaster->addTransactionListener( static_cast< XTransactionListener* >( m_pChildCommitListen ) ); - } - } - return xResult; + Reference< XDocumentSubStorageSupplier > xStorageAccess( m_pImpl->getDocumentSubStorageSupplier() ); + return xStorageAccess->getDocumentSubStorage( aStorageName, nMode ); } // ----------------------------------------------------------------------------- Sequence< ::rtl::OUString > SAL_CALL ODatabaseDocument::getDocumentSubStoragesNames( ) throw (::com::sun::star::io::IOException, RuntimeException) { - Sequence< ::rtl::OUString > aRet(2); - sal_Int32 nPos = 0; - aRet[nPos++] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("forms")); - aRet[nPos++] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("reports")); - return aRet; + Reference< XDocumentSubStorageSupplier > xStorageAccess( m_pImpl->getDocumentSubStorageSupplier() ); + return xStorageAccess->getDocumentSubStoragesNames(); } // ----------------------------------------------------------------------------- void ODatabaseDocument::notifyEvent(const ::rtl::OUString& _sEventName) @@ -1107,28 +1099,17 @@ //------------------------------------------------------------------------------ void ODatabaseDocument::disposing() { - Reference<XInterface> xHold = m_pImpl->m_xModel; + Reference< XModel > xHoldAlive( this ); { notifyEvent(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnUnload"))); - if ( m_pChildCommitListen ) - { - m_pChildCommitListen->dispose(); - m_pChildCommitListen->release(); - m_pChildCommitListen = NULL; - } + css::lang::EventObject aDisposeEvent(static_cast<XWeak*>(this)); m_aModifyListeners.disposeAndClear( aDisposeEvent ); m_aCloseListener.disposeAndClear( aDisposeEvent ); m_aDocEventListeners.disposeAndClear( aDisposeEvent ); - TStorages::iterator aIter = m_pImpl->m_aStorages.begin(); - TStorages::iterator aEnd = m_pImpl->m_aStorages.end(); - for (; aIter != aEnd ; ++aIter) - { - Reference<XComponent> xComp(aIter->second,UNO_QUERY); - if ( xComp.is() ) - xComp->removeEventListener( static_cast< XTransactionListener* >( this ) ); - } + m_xDocEventBroadcaster = NULL; + m_xUIConfigurationManager = NULL; Reference<XChild> xChild(m_pImpl->m_xForms.get(),UNO_QUERY); if ( xChild.is() ) @@ -1144,7 +1125,7 @@ if ( xChild.is() ) xChild->setParent(NULL); - m_pImpl->m_xModel.clear(); + m_pImpl->modelIsDisposing( ODatabaseModelImpl::ResetModelAccess() ); } m_pImpl.clear(); } @@ -1214,32 +1195,6 @@ { if ( m_pImpl.is() ) m_pImpl->disposing(Source); -} -//------------------------------------------------------------------ -void SAL_CALL ODatabaseDocument::preCommit( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) -{ -} -//------------------------------------------------------------------ -void SAL_CALL ODatabaseDocument::commited( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException) -{ - if ( m_pImpl.is() && m_bCommitMasterStorage ) - { - ::osl::MutexGuard aGuard(m_aMutex); - TStorages::iterator aFind = m_pImpl->m_aStorages.find(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("database"))); - Reference<XStorage> xStorage(aEvent.Source,UNO_QUERY); - if ( aFind != m_pImpl->m_aStorages.end() && aFind->second == xStorage ) - { - m_pImpl->commitRootStorage(); - } - } -} -//------------------------------------------------------------------ -void SAL_CALL ODatabaseDocument::preRevert( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) -{ -} -//------------------------------------------------------------------ -void SAL_CALL ODatabaseDocument::reverted( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException) -{ } //------------------------------------------------------------------ //........................................................................ --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
