Tag: cws_src680_dba30 User: fs Date: 05/09/29 23:09:55 Modified: /dba/dbaccess/source/core/dataaccess/ ModelImpl.cxx
Log: RESYNC: (1.5-1.7); FILE MERGED File Changes: Directory: /dba/dbaccess/source/core/dataaccess/ ================================================ File [changed]: ModelImpl.cxx Url: http://dba.openoffice.org/source/browse/dba/dbaccess/source/core/dataaccess/ModelImpl.cxx?r1=1.3.2.3&r2=1.3.2.4 Delta lines: +257 -89 ---------------------- --- ModelImpl.cxx 1 Jul 2005 07:06:53 -0000 1.3.2.3 +++ ModelImpl.cxx 30 Sep 2005 06:09:52 -0000 1.3.2.4 @@ -1,22 +1,20 @@ /************************************************************************* * + * OpenOffice.org - a multi-platform office productivity suite + * * $RCSfile$ * * $Revision$ * * last change: $Author$ $Date$ * - * The Contents of this file are made available subject to the terms of - * either of the following licenses - * - * - GNU Lesser General Public License Version 2.1 - * - Sun Industry Standards Source License Version 1.1 + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. * - * Sun Microsystems Inc., October, 2000 * * GNU Lesser General Public License Version 2.1 * ============================================= - * Copyright 2000 by Sun Microsystems, Inc. + * Copyright 2005 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or @@ -33,30 +31,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * - * - * Sun Industry Standards Source License Version 1.1 - * ================================================= - * The contents of this file are subject to the Sun Industry Standards - * Source License Version 1.1 (the "License"); You may not use this file - * except in compliance with the License. You may obtain a copy of the - * License at http://www.openoffice.org/license.html. - * - * Software provided under this License is provided on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, - * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, - * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. - * See the License for the specific provisions governing your rights and - * obligations concerning the Software. - * - * The Initial Developer of the Original Code is: Sun Microsystems, Inc. - * - * Copyright: 2000 by Sun Microsystems, Inc. - * - * All Rights Reserved. - * - * Contributor(s): _______________________________________ - * - * ************************************************************************/ #ifndef _DBA_COREDATAACCESS_MODELIMPL_HXX_ @@ -140,9 +114,6 @@ #ifndef _COMPHELPER_INTERACTION_HXX_ #include <comphelper/interaction.hxx> #endif -#ifndef DBA_COREDATAACCESS_COMMITLISTENER_HXX -#include "commitlistener.hxx" -#endif #ifndef _DBA_CORE_CONNECTION_HXX_ #include "connection.hxx" #endif @@ -212,6 +183,169 @@ //........................................................................ //============================================================ +//= DocumentStorageAccess +//============================================================ +DBG_NAME( DocumentStorageAccess ) +class DocumentStorageAccess : public ::cppu::WeakImplHelper2< XDocumentSubStorageSupplier + , XTransactionListener > +{ + typedef ::std::map< ::rtl::OUString, Reference< XStorage > > NamedStorages; + + ::osl::Mutex m_aMutex; + /// all sub storages which we ever gave to the outer world + NamedStorages m_aExposedStorages; + ODatabaseModelImpl* m_pModelImplementation; + bool m_bPropagateCommitToRoot; + +public: + DocumentStorageAccess( ODatabaseModelImpl& _rModelImplementation ) + :m_pModelImplementation( &_rModelImplementation ) + ,m_bPropagateCommitToRoot( true ) + { + DBG_CTOR( DocumentStorageAccess, NULL ); + } + +protected: + ~DocumentStorageAccess() + { + DBG_DTOR( DocumentStorageAccess, NULL ); + } + +public: + void dispose(); + + void suspendCommitPropagation() + { + DBG_ASSERT( m_bPropagateCommitToRoot, "DocumentStorageAccess:: suspendCommitPropagation: already suspended" ); + m_bPropagateCommitToRoot = false; + } + void resumeCommitPropagation() + { + DBG_ASSERT( !m_bPropagateCommitToRoot, "DocumentStorageAccess:: suspendCommitPropagation: already suspended" ); + m_bPropagateCommitToRoot = true; + } + + // XDocumentSubStorageSupplier + virtual Reference< XStorage > SAL_CALL getDocumentSubStorage( const ::rtl::OUString& aStorageName, ::sal_Int32 nMode ) throw (RuntimeException); + virtual Sequence< ::rtl::OUString > SAL_CALL getDocumentSubStoragesNames( ) throw (IOException, RuntimeException); + + // XTransactionListener + virtual void SAL_CALL preCommit( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL commited( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL preRevert( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL reverted( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); +}; + +//-------------------------------------------------------------------------- +void DocumentStorageAccess::dispose() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + for ( NamedStorages::iterator loop = m_aExposedStorages.begin(); + loop != m_aExposedStorages.end(); + ++loop + ) + { + try + { + Reference< XTransactionBroadcaster > xBroadcaster( loop->second, UNO_QUERY ); + if ( xBroadcaster.is() ) + xBroadcaster->removeTransactionListener( this ); + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "DocumentStorageAccess::dispose: caught an exception!" ); + } + } + + m_aExposedStorages.clear(); + + m_pModelImplementation = NULL; +} + +//-------------------------------------------------------------------------- +Reference< XStorage > SAL_CALL DocumentStorageAccess::getDocumentSubStorage( const ::rtl::OUString& aStorageName, ::sal_Int32 nMode ) throw (RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + NamedStorages::iterator pos = m_aExposedStorages.find( aStorageName ); + if ( pos == m_aExposedStorages.end() ) + { + Reference< XStorage > xResult = m_pModelImplementation->getStorage( aStorageName, nMode ); + Reference< XTransactionBroadcaster > xBroadcaster( xResult, UNO_QUERY ); + if ( xBroadcaster.is() ) + xBroadcaster->addTransactionListener( this ); + + pos = m_aExposedStorages.insert( NamedStorages::value_type( aStorageName, xResult ) ).first; + } + + return pos->second; +} + +//-------------------------------------------------------------------------- +Sequence< ::rtl::OUString > SAL_CALL DocumentStorageAccess::getDocumentSubStoragesNames( ) throw (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; +} + +//-------------------------------------------------------------------------- +void SAL_CALL DocumentStorageAccess::preCommit( const css::lang::EventObject& aEvent ) throw (Exception, RuntimeException) +{ + // not interested in +} + +//-------------------------------------------------------------------------- +void SAL_CALL DocumentStorageAccess::commited( const css::lang::EventObject& aEvent ) throw (RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_pModelImplementation ) + { + Reference< XModifiable > xModiable( m_pModelImplementation->getModel_noCreate(), UNO_QUERY ); + if ( xModiable.is() ) + xModiable->setModified( sal_True ); + } + + if ( m_pModelImplementation && m_bPropagateCommitToRoot ) + { + TStorages::iterator aFind = m_pModelImplementation->m_aStorages.find(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("database"))); + Reference<XStorage> xStorage(aEvent.Source,UNO_QUERY); + if ( ( aFind != m_pModelImplementation->m_aStorages.end() ) + && ( aFind->second == xStorage ) + ) + { + m_pModelImplementation->commitRootStorage(); + } + } +} + +//-------------------------------------------------------------------------- +void SAL_CALL DocumentStorageAccess::preRevert( const css::lang::EventObject& aEvent ) throw (Exception, RuntimeException) +{ + // not interested in +} + +//-------------------------------------------------------------------------- +void SAL_CALL DocumentStorageAccess::reverted( const css::lang::EventObject& aEvent ) throw (RuntimeException) +{ + // not interested in +} + +//-------------------------------------------------------------------------- +void SAL_CALL DocumentStorageAccess::disposing( const css::lang::EventObject& Source ) throw ( RuntimeException ) +{ + ODatabaseModelImpl* pImpl = m_pModelImplementation; + if ( pImpl ) + pImpl->disposing( Source ); +} + +//============================================================ //= ODatabaseModelImpl //============================================================ DBG_NAME(ODatabaseModelImpl) @@ -229,9 +363,10 @@ ,m_pDBContext(NULL) ,m_nControllerLockCount(0) ,m_bOwnStorage(sal_False) - ,m_xModel(_xModel) + ,m_xTempModel(_xModel) ,m_nLoginTimeout(0) ,m_refCount(0) + ,m_pStorageAccess( NULL ) { // some kind of default DBG_CTOR(ODatabaseModelImpl,NULL); @@ -261,6 +396,7 @@ ,m_bOwnStorage(sal_False) ,m_nLoginTimeout(0) ,m_refCount(0) + ,m_pStorageAccess( NULL ) { DBG_CTOR(ODatabaseModelImpl,NULL); // adjust our readonly flag @@ -279,7 +415,7 @@ m_bReadOnly = sal_False; m_aContainer.resize(4); - // create the property bag to hold the settings (also know as "Info" property) + // create the property bag to hold the settings (also known as "Info" property) try { // the set of property value types in the bag is limited: @@ -323,6 +459,13 @@ { OSL_ENSURE( sal_False, "ODatabaseModelImpl::lateInit: could not create the PropertyBag for the Info/Settings properties!" ); } + + if ( m_pStorageAccess ) + { + m_pStorageAccess->dispose(); + m_pStorageAccess->release(); + m_pStorageAccess = NULL; + } } // ----------------------------------------------------------------------------- ::rtl::OUString ODatabaseModelImpl::getURL( ) @@ -389,6 +532,21 @@ //------------------------------------------------------------------------------ void ODatabaseModelImpl::dispose() { + // dispose the data source and the model + try + { + Reference< XDataSource > xDS( m_xDataSource ); + ::comphelper::disposeComponent( xDS ); + m_xDataSource = WeakReference<XDataSource>(); + + ::comphelper::disposeComponent(m_xTempModel); + } + catch( const Exception& ) + { + } + m_xDataSource = WeakReference<XDataSource>(); + m_xTempModel.clear(); + ::std::vector<TContentPtr>::iterator aIter = m_aContainer.begin(); ::std::vector<TContentPtr>::iterator aEnd = m_aContainer.end(); for (;aIter != aEnd ; ++aIter) @@ -545,10 +703,24 @@ return m_xStorage; } // ----------------------------------------------------------------------------- -Reference<XStorage> ODatabaseModelImpl::getStorage(const ::rtl::OUString& _sStorageName,const Reference<css::embed::XTransactionListener>& _xEventListener, sal_Int32 nMode) +DocumentStorageAccess* ODatabaseModelImpl::getDocumentStorageAccess() +{ + if ( !m_pStorageAccess ) + { + m_pStorageAccess = new DocumentStorageAccess( *this ); + m_pStorageAccess->acquire(); + } + return m_pStorageAccess; +} +// ----------------------------------------------------------------------------- +Reference< XDocumentSubStorageSupplier > ODatabaseModelImpl::getDocumentSubStorageSupplier() +{ + return getDocumentStorageAccess(); +} +// ----------------------------------------------------------------------------- +Reference<XStorage> ODatabaseModelImpl::getStorage(const ::rtl::OUString& _sStorageName,sal_Int32 nMode) { OSL_ENSURE(_sStorageName.getLength(),"ODatabaseModelImpl::getStorage: Invalid storage name!"); - OSL_ENSURE(_xEventListener.is(),"No Eventlistener set!"); Reference<XStorage> xStorage; TStorages::iterator aFind = m_aStorages.find(_sStorageName); if ( aFind == m_aStorages.end() ) @@ -562,7 +734,7 @@ xStorage = xMyStorage->openStorageElement(_sStorageName, m_bDocumentReadOnly ? ElementModes::READ : nMode); Reference<XTransactionBroadcaster> xBroad(xStorage,UNO_QUERY); if ( xBroad.is() ) - xBroad->addTransactionListener(_xEventListener); + xBroad->addTransactionListener( getDocumentStorageAccess() ); aFind = m_aStorages.insert(TStorages::value_type(_sStorageName,xStorage)).first; } catch(Exception&) @@ -577,6 +749,22 @@ return xStorage; } // ----------------------------------------------------------------------------- +sal_Bool ODatabaseModelImpl::commitEmbeddedStorage( sal_Bool _bPreventRootCommits ) +{ + if ( _bPreventRootCommits && m_pStorageAccess ) + m_pStorageAccess->suspendCommitPropagation(); + + sal_Bool bStore = sal_False; + TStorages::iterator aFind = m_aStorages.find(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("database"))); + if ( aFind != m_aStorages.end() ) + bStore = commitStorageIfWriteable_ignoreErrors( aFind->second ); + + if ( _bPreventRootCommits && m_pStorageAccess ) + m_pStorageAccess->resumeCommitPropagation(); + + return bStore; +} +// ----------------------------------------------------------------------------- bool ODatabaseModelImpl::commitStorageIfWriteable( const Reference< XStorage >& _rxStorage ) SAL_THROW(( IOException, WrappedTargetException, RuntimeException )) { bool bSuccess = false; @@ -616,26 +804,17 @@ return bSuccess; } // ----------------------------------------------------------------------------- -sal_Bool ODatabaseModelImpl::commitEmbeddedStorage() -{ - sal_Bool bStore = sal_False; - TStorages::iterator aFind = m_aStorages.find(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("database"))); - if ( aFind != m_aStorages.end() ) - bStore = commitStorageIfWriteable_ignoreErrors( aFind->second ); - return bStore; -} -// ----------------------------------------------------------------------------- void ODatabaseModelImpl::setModified( sal_Bool _bModified ) { try { - Reference<XModifiable> xModi(m_xModel.get(),UNO_QUERY); + Reference<XModifiable> xModi(m_xTempModel.get(),UNO_QUERY); if ( xModi.is() ) xModi->setModified(_bModified); } catch(Exception) { - OSL_ENSURE(0,"Exception catched!"); + OSL_ENSURE(0,"ODatabaseModelImpl::setModified: Exception caught!"); } } // ----------------------------------------------------------------------------- @@ -654,10 +833,10 @@ } } // ----------------------------------------------------------------------------- -Reference<XDataSource> ODatabaseModelImpl::getDataSource() +Reference<XDataSource> ODatabaseModelImpl::getDataSource( bool _bCreateIfNecessary ) { Reference<XDataSource> xDs = m_xDataSource; - if ( !xDs.is() ) + if ( !xDs.is() && _bCreateIfNecessary ) { // no data source, so we have to create one and register it later on xDs = new ODatabaseSource(this); m_xDataSource = xDs; @@ -665,28 +844,17 @@ return xDs; } // ----------------------------------------------------------------------------- -Reference< XModel> ODatabaseModelImpl::getModel() +Reference< XModel> ODatabaseModelImpl::getModel_noCreate() { - Reference< XModel> xModel = m_xModel; - if ( !xModel.is() ) - xModel = new ODatabaseDocument(this); - return xModel; + return m_xTempModel; } // ----------------------------------------------------------------------------- -void ODatabaseModelImpl::clear() +Reference< XModel> ODatabaseModelImpl::createNewModel_deliverOwnership() { - try - { - Reference< XComponent > xComp(m_xDataSource.get(), UNO_QUERY); - m_xDataSource = WeakReference<XDataSource>(); - if ( xComp.is() ) - xComp->dispose(); - ::comphelper::disposeComponent(m_xModel); - } - catch(Exception&) - { - m_xModel = NULL; - } + OSL_PRECOND( !m_xTempModel.is(), "ODatabaseModelImpl::getModel_noCreate: not to be called if there already is a model!" ); + if ( !m_xTempModel.is() ) + m_xTempModel = ODatabaseDocument::createDatabaseDocument( this, ODatabaseDocument::FactoryAccess() ); + return m_xTempModel; } // ----------------------------------------------------------------------------- oslInterlockedCount SAL_CALL ODatabaseModelImpl::acquire() @@ -698,7 +866,7 @@ { if ( osl_decrementInterlockedCount(&m_refCount) == 0 ) { - clear(); + acquire(); // prevent multiple releases dispose(); m_pDBContext->deregisterPrivate(m_sRealFileURL); delete this; --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
