User: hr      
Date: 05/09/23 05:04:58

Modified:
 /dba/dbaccess/source/core/dataaccess/
  databasedocument.cxx

Log:
 INTEGRATION: CWS dba201b (1.19.10); FILE MERGED
 2005/09/21 07:01:01 oj 1.19.10.5: RESYNC: (1.20-1.21); FILE MERGED
 2005/07/20 10:18:08 fs 1.19.10.4: #i52171# better control over model ownership
 2005/07/11 13:37:00 fs 1.19.10.3: merging CWS dba201 into CWS dba201b
 2005/07/11 07:18:20 oj 1.19.10.2: RESYNC: (1.19-1.20); FILE MERGED
 2005/05/27 10:32:23 oj 1.19.10.1: #i49860# don't clear connection when 
storeToUrl is called

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.21&r2=1.22
Delta lines:  +42 -53
---------------------
--- databasedocument.cxx        8 Sep 2005 12:02:43 -0000       1.21
+++ databasedocument.cxx        23 Sep 2005 12:04:55 -0000      1.22
@@ -367,41 +367,6 @@
     
m_pImpl->m_aControllers.erase(::std::find(m_pImpl->m_aControllers.begin(),m_pImpl->m_aControllers.end(),_xController));
        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();
-               dispose();
-    }
 }
 // 
-----------------------------------------------------------------------------
 void SAL_CALL ODatabaseDocument::lockControllers(  ) throw (RuntimeException)
@@ -717,32 +682,50 @@
 {
 }
 // 
-----------------------------------------------------------------------------
-void SAL_CALL ODatabaseDocument::close( sal_Bool bDeliverOwnership ) throw 
(::com::sun::star::util::CloseVetoException, RuntimeException)
+void ODatabaseDocument::impl_closeControllerFrames( sal_Bool 
_bDeliverOwnership )
 {
-       ResettableMutexGuard _rGuard(m_aMutex);
-       
::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed);
-
-    lang::EventObject aEvt( static_cast< ::cppu::OWeakObject* >( this ) );
-       
NOTIFY_LISTERNERS1(m_aCloseListener,com::sun::star::util::XCloseListener,queryClosing,bDeliverOwnership);
-
        ::std::vector< Reference< XController> > aCopy = 
m_pImpl->m_aControllers;
+
        ::std::vector< Reference< XController> >::iterator aIter = 
aCopy.begin();
        ::std::vector< Reference< XController> >::iterator aEnd = aCopy.end();
-       for (;aIter != aEnd ; ++aIter)
+       for ( ;aIter != aEnd ; ++aIter )
        {
                if ( aIter->is() )
                {
-                       Reference< XCloseable> 
xFrame((*aIter)->getFrame(),UNO_QUERY);
+            try
+            {
+                           Reference< XCloseable> xFrame( 
(*aIter)->getFrame(), UNO_QUERY );
                        if ( xFrame.is() )
-                               xFrame->close(bDeliverOwnership);
+                                   xFrame->close( _bDeliverOwnership );
                }
+            catch( const CloseVetoException& ) { throw; }
+            catch( const Exception& )
+            {
+               OSL_ENSURE( sal_False, 
"ODatabaseDocument::impl_closeControllerFrames: caught an unexpected 
exception!" );
        }
-    if ( m_pImpl.is() )
-       m_pImpl->m_aControllers.clear();
-       dispose();
+               }
+       }
+}
+
+// 
-----------------------------------------------------------------------------
+void SAL_CALL ODatabaseDocument::close( sal_Bool _bDeliverOwnership ) throw 
(::com::sun::star::util::CloseVetoException, RuntimeException)
+{
+       ResettableMutexGuard _rGuard(m_aMutex);
+       
::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed);
+
+    lang::EventObject aEvt( static_cast< ::cppu::OWeakObject* >( this ) );
+    {
+           
NOTIFY_LISTERNERS1(m_aCloseListener,com::sun::star::util::XCloseListener,queryClosing,_bDeliverOwnership);
+    }
+
+    DBG_ASSERT( m_pImpl->m_aControllers.empty(), "ODatabaseDocument::close: 
aren't controllers expected to veto the closing?" );
+    impl_closeControllerFrames( _bDeliverOwnership );
+
        {
                
NOTIFY_LISTERNERS(m_aCloseListener,com::sun::star::util::XCloseListener,notifyClosing);
        }
+
+    dispose();
 }
 // 
-----------------------------------------------------------------------------
 void SAL_CALL ODatabaseDocument::addCloseListener( const Reference< 
::com::sun::star::util::XCloseListener >& Listener ) throw (RuntimeException)
@@ -1073,6 +1056,12 @@
 
//------------------------------------------------------------------------------
 void ODatabaseDocument::disposing()
 {
+    DBG_ASSERT( m_pImpl->m_aControllers.empty(), 
"ODatabaseDocument::disposing: there still are controllers!" );
+        // normally, nobody should explicitly dispose, but only 
XCloseable::close the document. And controllers
+        // are expected to veto the closing, so when we're here, there 
shouldn't be any controllers anymore.
+    if ( m_pImpl.is() )
+       m_pImpl->m_aControllers.clear();
+
     Reference< XModel > xHoldAlive( this );
     {
            
notifyEvent(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnUnload")));




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to