User: kz      
Date: 2008-03-06 17:58:20+0000
Modified:
   dba/dbaccess/source/core/dataaccess/databasedocument.cxx

Log:
 INTEGRATION: CWS odbmacros2 (1.36.2); FILE MERGED
 2008/02/26 14:05:34 fs 1.36.2.16: additional comment
 2008/02/26 14:07:44 fs 1.36.2.15.2.2: additional comment
 2008/02/14 12:18:07 fs 1.36.2.15.2.1: #i49133# re-enable the macros in DBDocs, 
which had been temporarily disable to finalize CWS odbmacros2
 2008/02/14 08:36:45 fs 1.36.2.15: typo
 2008/02/14 08:22:19 fs 1.36.2.14: temporarily disable scripting support for 
database documents,  so we have an intermediate version of the CWS which we can 
integrate
 2008/02/06 21:43:37 fs 1.36.2.13: some less ModifyLocks
 2008/02/06 08:33:02 fs 1.36.2.12: #i49133# when we have an interaction 
handler, then use it when storing the document fails
 2008/02/04 13:07:08 fs 1.36.2.11: RESYNC: (1.36-1.37); FILE MERGED
 2008/01/26 21:18:31 fs 1.36.2.10: slight code re-arrangement
 2008/01/24 10:06:42 fs 1.36.2.9: #i49133# don't support XEmbeddedScripts and 
XScriptInvocationContext if we already have forms/reports with macros
 2008/01/02 21:29:39 fs 1.36.2.8: #i49133# let the DatabaODatabaseModelImpl be 
an XModifyListener at the document storage (via 
::sfx2::DocumentStorageModifyListener)
 2007/12/17 12:41:39 fs 1.36.2.7: #i49133# implement XScriptInvocationContext
 2007/12/10 14:16:39 fs 1.36.2.6: #i49133# cache the script provider as weak 
ref, sounds cheaper
 2007/12/10 14:03:09 fs 1.36.2.5: #i49133# implement XScriptProviderSupplier
 2007/12/10 08:04:12 fs 1.36.2.4: recognize (and properly handle) empty salvage 
URLs
 2007/12/06 20:34:30 fs 1.36.2.3: impl_storeAs_throw: don't expect an existing 
storage
 2007/12/06 20:17:16 fs 1.36.2.2: impl_storeAs_throw: don't expect an existing 
storage
 2007/12/06 13:32:54 fs 1.36.2.1: #i49133# support 
Script/DialogLibraryContainers in database documents, implement 
XEmbeddedScripts/XStorageBasedDocument

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.37&r2=1.38
Delta lines:  +583 -428
-----------------------
--- databasedocument.cxx        2008-01-30 08:33:34+0000        1.37
+++ databasedocument.cxx        2008-03-06 17:58:17+0000        1.38
@@ -42,6 +42,7 @@
 #include "module_dba.hxx"
 
 #include <comphelper/documentconstants.hxx>
+#include <comphelper/interaction.hxx>
 #include <comphelper/namedvaluecollection.hxx>
 #include <comphelper/enumhelper.hxx>
 #ifndef _COM_SUN_STAR_EMBED_XTRANSACTEDOBJECT_HPP_
@@ -107,6 +108,9 @@
 #ifndef _COM_SUN_STAR_DOCUMENT_XIMPORTER_HPP_
 #include <com/sun/star/document/XImporter.hpp>
 #endif
+#ifndef _COM_SUN_STAR_SCRIPT_PROVIDER_XSCRIPTPROVIDERFACTORY_HPP_
+#include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
+#endif
 #ifndef _TOOLS_DEBUG_HXX
 #include <tools/debug.hxx>
 #endif
@@ -118,7 +122,9 @@
 #include <boost/bind.hpp>
 #endif
 
-namespace css = ::com::sun::star;
+#include <algorithm>
+#include <functional>
+
 using namespace ::com::sun::star::uno;
 using namespace ::com::sun::star::beans;
 using namespace ::com::sun::star::frame;
@@ -133,9 +139,12 @@
 using namespace ::com::sun::star::sdbc;
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::script::provider;
+using namespace ::com::sun::star::ui;
 using namespace ::cppu;
 using namespace ::osl;
-namespace css = ::com::sun::star;
+
 //........................................................................
 namespace dbaccess
 {
@@ -158,6 +167,7 @@
             ,m_aModifyListeners( getMutex() )
                        ,m_aCloseListener( getMutex() )
             ,m_aDocEventListeners( getMutex() )
+            ,m_aStorageListeners( getMutex() )
 {
        DBG_CTOR(ODatabaseDocument,NULL);
 
@@ -170,6 +180,7 @@
     }
     osl_decrementInterlockedCount( &m_refCount );
 }
+
 //--------------------------------------------------------------------------
 ODatabaseDocument::~ODatabaseDocument()
 {
@@ -182,21 +193,90 @@
 }
 
 // 
-----------------------------------------------------------------------------
-// local functions
+bool ODatabaseDocument::impl_shouldDisallowScripting_nolck_nothrow() const
+{
+    ::osl::MutexGuard aGuard( getMutex() );
+    // TODO: revert to the disabled code. The current version is just to be 
able
+    // to integrate an intermediate version of the CWS, which should behave as
+    // if no macros in DB docs are allowed
+//    if ( m_pImpl.is() && m_pImpl->hasAnyObjectWithMacros() )
+        return true;
+//    return false;
+}
+
 // 
-----------------------------------------------------------------------------
-void lcl_stripLoadArguments( ::comphelper::MediaDescriptor& _rDescriptor, 
Sequence< PropertyValue >& _rArgs )
+Any SAL_CALL ODatabaseDocument::queryInterface( const Type& _rType ) throw 
(RuntimeException)
 {
-    _rDescriptor.erase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 
"StatusIndicator" ) ) );
-       _rDescriptor.erase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 
"Model" ) ) );
-    _rDescriptor >> _rArgs;
+    // strip XEmbeddedScripts and XScriptInvocationContext if we have any 
form/report
+    // which already contains macros. In this case, the database document 
itself is not
+    // allowed to contain macros, too.
+    if  (   impl_shouldDisallowScripting_nolck_nothrow()
+        &&  (   _rType.equals( XEmbeddedScripts::static_type() )
+            ||  _rType.equals( XScriptInvocationContext::static_type() )
+            )
+        )
+        return Any();
+
+    return ODatabaseDocument_OfficeDocument::queryInterface( _rType );
 }
+
 // 
-----------------------------------------------------------------------------
-void lcl_extractAndStartStatusIndicator( const ::comphelper::MediaDescriptor& 
_rDescriptor, Reference< XStatusIndicator >& _rxStatusIndicator,
-    Sequence< Any >& _rCallArgs )
+Sequence< Type > SAL_CALL ODatabaseDocument::getTypes(  ) throw 
(RuntimeException)
 {
+    Sequence< Type > aTypes( ODatabaseDocument_OfficeDocument::getTypes() );
+
+    // strip XEmbeddedScripts and XScriptInvocationContext if we have any 
form/report
+    // which already contains macros. In this case, the database document 
itself is not
+    // allowed to contain macros, too.
+    if ( impl_shouldDisallowScripting_nolck_nothrow() )
+    {
+        Sequence< Type > aStrippedTypes( aTypes.getLength() );
+        Type* pStripTo( aStrippedTypes.getArray() );
+
+        // strip XEmbeddedScripts, and immediately re-assign to aTypes
+        aTypes = Sequence< Type >(
+            pStripTo,
+            ::std::remove_copy_if(
+                aTypes.getConstArray(),
+                aTypes.getConstArray() + aTypes.getLength(),
+                pStripTo,
+                ::std::bind2nd( ::std::equal_to< Type >(), 
XEmbeddedScripts::static_type() )
+            ) - pStripTo
+        );
+
+        // strip XScriptInvocationContext, and immediately re-assign to aTypes
+        aTypes = Sequence< Type >(
+            pStripTo,
+            ::std::remove_copy_if(
+                aTypes.getConstArray(),
+                aTypes.getConstArray() + aTypes.getLength(),
+                pStripTo,
+                ::std::bind2nd( ::std::equal_to< Type >(), 
XScriptInvocationContext::static_type() )
+            ) - pStripTo
+        );
+    }
+
+    return aTypes;
+}
+
+// 
-----------------------------------------------------------------------------
+// local functions
+// 
-----------------------------------------------------------------------------
+namespace
+{
+    static void lcl_stripLoadArguments( ::comphelper::NamedValueCollection& 
_rArguments, Sequence< PropertyValue >& _rArgs )
+    {
+        _rArguments.remove( "Model" );
+        _rArguments >>= _rArgs;
+    }
+
+    // 
-----------------------------------------------------------------------------
+    static void lcl_extractAndStartStatusIndicator( const 
::comphelper::NamedValueCollection& _rArguments, Reference< XStatusIndicator >& 
_rxStatusIndicator,
+        Sequence< Any >& _rCallArgs )
+    {
     try
     {
-        _rxStatusIndicator = _rDescriptor.getUnpackedValueOrDefault( 
_rDescriptor.PROP_STATUSINDICATOR(), _rxStatusIndicator );
+            _rxStatusIndicator = _rArguments.getOrDefault( "StatusIndicator", 
_rxStatusIndicator );
         if ( _rxStatusIndicator.is() )
         {
                    _rxStatusIndicator->start( ::rtl::OUString(), 
(sal_Int32)1000000 );
@@ -208,111 +288,126 @@
     }
     catch( const Exception& )
     {
-       OSL_ENSURE( sal_False, "lcl_extractAndStartStatusIndicator: caught an 
exception!" );
+            DBG_UNHANDLED_EXCEPTION();
+        }
+    }
+
+    static Sequence< PropertyValue > lcl_appendFileNameToDescriptor( const 
Sequence< PropertyValue >& _rDescriptor, const ::rtl::OUString _rURL )
+    {
+        Sequence< PropertyValue > aMediaDescriptor( _rDescriptor );
+        if ( _rURL.getLength() )
+        {
+            aMediaDescriptor.realloc( _rDescriptor.getLength() + 1 );
+            aMediaDescriptor[ _rDescriptor.getLength() ].Name = 
::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ) );
+            aMediaDescriptor[ _rDescriptor.getLength() ].Value <<= _rURL;
+        }
+        return aMediaDescriptor;
     }
 }
 
 // 
-----------------------------------------------------------------------------
-// XModel
-// ATTENTION: The Application controller attaches the same resource to force a 
reload.
-sal_Bool SAL_CALL ODatabaseDocument::attachResource( const ::rtl::OUString& 
_rURL, const Sequence< PropertyValue >& _aArguments ) throw (RuntimeException)
+void ODatabaseDocument::impl_reset_nothrow()
 {
-    ModelMethodGuard aGuard( *this );
-    OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
-
     try
        {
                m_pImpl->clearConnections();
         m_pImpl->disposeStorages();
+        m_pImpl->resetRootStroage();
 
-        if ( m_pImpl->m_bOwnStorage )
-                   ::comphelper::disposeComponent(m_pImpl->m_xStorage);
-
-        clearObjectContainer( m_xForms);
-               clearObjectContainer( m_xReports);
-               clearObjectContainer( m_pImpl->m_xTableDefinitions);
-               clearObjectContainer( m_pImpl->m_xCommandDefinitions);
+        clearObjectContainer( m_xForms );
+               clearObjectContainer( m_xReports );
+               clearObjectContainer( m_pImpl->m_xTableDefinitions );
+               clearObjectContainer( m_pImpl->m_xCommandDefinitions );
 
                m_pImpl->reset();
        }
        catch(const Exception&)
        {
         DBG_UNHANDLED_EXCEPTION();
-               m_pImpl->m_xStorage = NULL;
        }
-
        m_pImpl->m_bDocumentReadOnly = sal_False;
+}
 
-       ::comphelper::MediaDescriptor aDescriptor( _aArguments );
-    lcl_stripLoadArguments( aDescriptor, m_pImpl->m_aArgs );
-
-    m_pImpl->m_sFileURL = _rURL;
-    m_pImpl->m_sRealFileURL = aDescriptor.getUnpackedValueOrDefault(
-        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SalvagedFile" ) ), 
_rURL );
-    if ( !m_pImpl->m_sRealFileURL.getLength() )
-        m_pImpl->m_sRealFileURL = m_pImpl->m_sFileURL;
-
-    if ( !m_pImpl->m_sName.getLength() )
-        m_pImpl->m_sName = m_pImpl->m_sRealFileURL;
-
-       m_pImpl->getStorage();
-
+// 
-----------------------------------------------------------------------------
+bool ODatabaseDocument::impl_import_throw( const 
::comphelper::NamedValueCollection& _rResource )
+{
        try
        {
-               Sequence<Any> aFilterArgs;
-        Reference<XStatusIndicator> xStatusIndicator;
-        lcl_extractAndStartStatusIndicator( aDescriptor, xStatusIndicator, 
aFilterArgs );
-
-               Reference<XImporter> xImporter(
-            m_pImpl->m_xServiceFactory->createInstanceWithArguments(
-                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 
"com.sun.star.comp.sdb.DBFilter" ) ),
-                aFilterArgs
-            ),
-            UNO_QUERY
-        );
+               Sequence< Any > aFilterArgs;
+        Reference< XStatusIndicator > xStatusIndicator;
+        lcl_extractAndStartStatusIndicator( _rResource, xStatusIndicator, 
aFilterArgs );
+
+               Reference< XImporter > xImporter(
+            m_pImpl->m_aContext.createComponentWithArguments( 
"com.sun.star.comp.sdb.DBFilter", aFilterArgs ),
+            UNO_QUERY_THROW );
 
-               if ( xImporter.is() )
-               {
-                       Reference<XComponent> xComponent(*this,UNO_QUERY);
-                       xImporter->setTargetDocument(xComponent);
-                       Reference<XFilter> xFilter(xImporter,UNO_QUERY);
+               Reference< XComponent > xComponent( *this, UNO_QUERY_THROW );
+               xImporter->setTargetDocument( xComponent );
+
+        Reference< XFilter > xFilter( xImporter, UNO_QUERY_THROW );
+               xFilter->filter( m_pImpl->m_aArgs );
 
-                       xFilter->filter(_aArguments);
             if ( xStatusIndicator.is() )
                 xStatusIndicator->end();
                }
-               else
-                       return sal_False;
-       }
-       catch(const RuntimeException& e)
+       catch( const RuntimeException& e )
        {
                throw e;
        }
-       catch(const Exception&)
+       catch( const Exception& )
        {
-               return sal_False;
+               return false;
        }
-    if ( m_pImpl->m_pDBContext && m_pImpl->m_sRealFileURL.getLength() )
+    return true;
+}
+
+// 
-----------------------------------------------------------------------------
+// XModel
+// ATTENTION: The Application controller attaches the same resource to force a 
reload.
+// TODO: this is a bug. By (API) definition, attachResource is only for 
notifying the document
+// of its resource, *not* for loading it. We should implement an XLoadable, 
and move all the
+// load logic therein.
+sal_Bool SAL_CALL ODatabaseDocument::attachResource( const ::rtl::OUString& 
_rURL, const Sequence< PropertyValue >& _aArguments ) throw (RuntimeException)
+{
+    ModelMethodGuard aGuard( *this );
+    OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
+
+    impl_reset_nothrow();
+
+    ::comphelper::NamedValueCollection aResource( _aArguments );
+    lcl_stripLoadArguments( aResource, m_pImpl->m_aArgs );
+
+    ::rtl::OUString sDocumentURL( aResource.getOrDefault( "SalvagedFile", 
_rURL ) );
+    if ( !sDocumentURL.getLength() )
+        // this indicates "the document is being recovered, but _rURL already 
is the real document URL,
+        // not the temporary document location"
+        sDocumentURL = _rURL;
+    m_pImpl->switchToURL( _rURL, sDocumentURL );
+
+    bool bSuccess =
+        (   m_pImpl->getOrCreateRootStorage().is()
+        &&  impl_import_throw( aResource )  // TODO: this doesn't belong here, 
but into an (externally called) XLoadable::load implementation
+        );
+
+    if ( !bSuccess )
     {
-        
m_pImpl->m_pDBContext->registerPrivate(m_pImpl->m_sRealFileURL,m_pImpl);
-        m_pImpl->setModified(sal_False);
+        m_pImpl->revokeDataSource();
+        return sal_False;
     }
+
+    impl_setModified_throw( sal_False, aGuard );
        return sal_True;
 }
 // 
-----------------------------------------------------------------------------
 ::rtl::OUString SAL_CALL ODatabaseDocument::getURL(  ) throw (RuntimeException)
 {
     ModelMethodGuard aGuard( *this );
-    OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
-
-    return m_pImpl->m_sRealFileURL;
+    return m_pImpl->getURL();
 }
 // 
-----------------------------------------------------------------------------
 Sequence< PropertyValue > SAL_CALL ODatabaseDocument::getArgs(  ) throw 
(RuntimeException)
 {
     ModelMethodGuard aGuard( *this );
-    OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
-
     return m_pImpl->m_aArgs;
 }
 // 
-----------------------------------------------------------------------------
@@ -322,11 +417,14 @@
 
     m_aControllers.push_back( _xController );
 
-    if ( m_aControllers.size() == 1 )
-    {
+    if ( m_aControllers.size() != 1 )
+        return;
+
+    // it's the first controller
+
         // check/adjust our macro mode. Note: This is only temporary. When we 
fully support the
-        // XEmbeddedScripts interface, then the controller is able to do this 
itself, since
-        // we'll then have a UNO method for this.
+    // XEmbeddedScripts interface, plus related functionality, then the 
controller is able
+    // to do this itself, since we'll then have a UNO method for this.
         //
         // Also, the same has to happen in the loader then, since the checks 
must be made
         // *before* OnLoad events are triggered - finally, the user can bind 
events to OnLoad ...
@@ -337,8 +435,8 @@
         // forms/reports, it's sufficient to do the check here.
         //
         m_pImpl->checkMacrosOnLoading();
-    }
 }
+
 // 
-----------------------------------------------------------------------------
 void SAL_CALL ODatabaseDocument::disconnectController( const Reference< 
XController >& _xController ) throw (RuntimeException)
 {
@@ -431,17 +529,13 @@
 sal_Bool SAL_CALL ODatabaseDocument::hasLocation(  ) throw (RuntimeException)
 {
     ModelMethodGuard aGuard( *this );
-    OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
-
-    return m_pImpl->m_sRealFileURL.getLength() != 0;
+    return m_pImpl->getLocation().getLength() > 0;
 }
 // 
-----------------------------------------------------------------------------
 ::rtl::OUString SAL_CALL ODatabaseDocument::getLocation(  ) throw 
(RuntimeException)
 {
     ModelMethodGuard aGuard( *this );
-    OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
-
-    return m_pImpl->m_sRealFileURL;
+    return m_pImpl->getLocation();
 }
 // 
-----------------------------------------------------------------------------
 sal_Bool SAL_CALL ODatabaseDocument::isReadonly(  ) throw (RuntimeException)
@@ -455,80 +549,127 @@
 void SAL_CALL ODatabaseDocument::store(  ) throw (IOException, 
RuntimeException)
 {
     ModelMethodGuard aGuard( *this );
-    OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
+    //ModifyLock aLock( *this );
 
-    if ( m_pImpl->m_sFileURL == m_pImpl->m_sRealFileURL )
-           store( m_pImpl->m_sFileURL, m_pImpl->m_aArgs ,aGuard);
-    else
-        storeAsURL( m_pImpl->m_sRealFileURL, m_pImpl->m_aArgs );
+    if ( m_pImpl->getLocation() == m_pImpl->getURL() )
+        if ( m_pImpl->m_bDocumentReadOnly )
+            throw IOException();
 
-    impl_notifyEvent( "OnSaveDone", aGuard );
+    impl_storeAs_throw( m_pImpl->getURL(), m_pImpl->m_aArgs, "OnSaveDone", 
aGuard );
 }
+
 // 
-----------------------------------------------------------------------------
-void ODatabaseDocument::store(const ::rtl::OUString& _rURL
-                                                        ,const Sequence< 
PropertyValue >& _rArguments
-                             ,ModelMethodGuard& _rGuard)
+void ODatabaseDocument::impl_storeAs_throw( const ::rtl::OUString& _rURL, 
const Sequence< PropertyValue>& _rArguments,
+        const sal_Char* _pAsciiDocumentEventName, ModelMethodGuard& _rGuard )
 {
-    OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
-       if ( m_pImpl->m_bDocumentReadOnly )
-               throw IOException();
+    Reference< XStorage > xNewRootStorage;
+        // will be non-NULL if our storage changed
+
+    sal_Bool bLocationChanged = ( _rURL != m_pImpl->getLocation() );
+       if ( bLocationChanged )
+       {
+        // create storage for target URL
+        Reference< XStorage > xTargetStorage;
+        if ( !impl_createStorageFor_throw( _rURL, xTargetStorage ) )
+            // failed, but handled by an interaction handler
+            return;
+
+        if ( m_pImpl->isEmbeddedDatabase() )
+            m_pImpl->clearConnections();
 
+        // commit everything
+        m_pImpl->commitEmbeddedStorage();
     m_pImpl->commitStorages();
 
-       Reference<XStorage> xMyStorage = m_pImpl->getStorage();
-    OSL_ENSURE( xMyStorage.is(), "ODatabaseDocument::storeToURL: no own 
storage?" );
-       if ( !xMyStorage.is() )
-    {
-        IOException aError;
-        aError.Message = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 
"Internal error: no source storage available." ) );
-        aError.Context = *this;
-               throw IOException( aError );
+        // copy own storage to target storage
+        Reference< XStorage > xCurrentStorage( m_pImpl->getRootStorage() );
+        if ( xCurrentStorage.is() )
+            xCurrentStorage->copyToStorage( xTargetStorage );
+
+        m_pImpl->disposeStorages();
+
+        xNewRootStorage = m_pImpl->switchToStorage( xTargetStorage );
+
+        m_pImpl->m_bDocumentReadOnly = sal_False;
     }
-       writeStorage(_rURL,_rArguments,xMyStorage);
 
-    m_pImpl->commitRootStorage();
+    // adjust arguments
+    ::comphelper::NamedValueCollection aResource( _rArguments );
+       lcl_stripLoadArguments( aResource, m_pImpl->m_aArgs );
+    Sequence< PropertyValue > aMediaDescriptor( 
lcl_appendFileNameToDescriptor( m_pImpl->m_aArgs, _rURL ) );
+
+    // store to current storage
+    Reference< XStorage > xCurrentStorage( m_pImpl->getOrCreateRootStorage(), 
UNO_QUERY_THROW );
+    impl_storeToStorage_throw( xCurrentStorage, aMediaDescriptor );
+
+    // success - tell our impl the new URL
+    m_pImpl->switchToURL( _rURL, _rURL );
+
+    // create a document event (mutex still locked)
+    document::EventObject aEvent( *this, ::rtl::OUString::createFromAscii( 
_pAsciiDocumentEventName ) );
 
-    setModified( sal_False,_rGuard );
+    // reset our "modified" flag, and clear the guard
+    impl_setModified_throw( sal_False, _rGuard );
+
+    // notify the document event
+    impl_notifyEvent_nolck_nothrow( aEvent );
+
+    // notify storage listeners
+    impl_notifyStorageChange_nolck_nothrow( xNewRootStorage );
 }
+
 // 
-----------------------------------------------------------------------------
-void SAL_CALL ODatabaseDocument::storeAsURL( const ::rtl::OUString& _rURL, 
const Sequence< PropertyValue >& _rArguments ) throw (IOException, 
RuntimeException)
+bool ODatabaseDocument::impl_createStorageFor_throw( const ::rtl::OUString& 
_rURL, Reference< XStorage >& _out_rxStorage ) const
 {
-    ModelMethodGuard aGuard( *this );
-    OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
-
-    Reference< XSingleServiceFactory > xStorageFactory( 
m_pImpl->createStorageFactory() );
-       if ( !xStorageFactory.is() )
-               throw RuntimeException();
-
-    // don't use _rURL - we might be recovering/salvaging a file currently ...
-    // #i45314# / 2005-03-21 / [EMAIL PROTECTED]
-       ::comphelper::MediaDescriptor aDescriptor( _rArguments );
+    _out_rxStorage.clear();
 
-    sal_Bool bLocationChanged = ( _rURL != m_pImpl->m_sFileURL );
-       if ( bLocationChanged )
-       {
                Sequence<Any> aParam(2);
                aParam[0] <<= _rURL;
                aParam[1] <<= ElementModes::READWRITE | ElementModes::TRUNCATE;
 
-        Reference<XStorage> xStorage;
-        ::rtl::OUString sOriginalExceptionType;
-        ::rtl::OUString sOriginalExceptionMessage;
+    Any aOriginalError;
                try
                {
-                       
xStorage.set(xStorageFactory->createInstanceWithArguments( aParam ),UNO_QUERY);
+        Reference< XSingleServiceFactory > xStorageFactory( 
m_pImpl->createStorageFactory(), UNO_SET_THROW );
+               _out_rxStorage.set( 
xStorageFactory->createInstanceWithArguments( aParam ), UNO_QUERY_THROW );
                }
-        catch ( const Exception& e )
+    catch ( const Exception& )
                {
-            Any aException( ::cppu::getCaughtException() );
-            sOriginalExceptionType = aException.getValueTypeName();
-            sOriginalExceptionMessage = e.Message;
+        aOriginalError = ::cppu::getCaughtException();
                }
 
-        if ( !xStorage.is() )
+    if ( _out_rxStorage.is() )
+        return true;
+
+    // try handling the error with the interaction handler
+    ::comphelper::NamedValueCollection aArgs( m_pImpl->m_aArgs );
+    Reference< XInteractionHandler > xHandler( aArgs.getOrDefault( 
"InteractionHandler", Reference< XInteractionHandler >() ) );
+    if ( xHandler.is() )
+    {
+        ::rtl::Reference< ::comphelper::OInteractionRequest > pRequest( new 
::comphelper::OInteractionRequest( aOriginalError ) );
+        ::rtl::Reference< ::comphelper::OInteractionApprove > pApprove( new 
::comphelper::OInteractionApprove );
+        pRequest->addContinuation( pApprove.get() );
+
+        try
+        {
+            xHandler->handle( pRequest.get() );
+        }
+        catch( const Exception& )
         {
+            DBG_UNHANDLED_EXCEPTION();
+        }
+
+        if ( pApprove->wasSelected() )
+            return false;
+    }
+
+    Exception aException;
+    OSL_VERIFY( aOriginalError >>= aException );
+    ::rtl::OUString sOriginalExceptionType = aOriginalError.getValueTypeName();
+    ::rtl::OUString sOriginalExceptionMessage = aException.Message;
+
             // TODO: resource
-            ::rtl::OUString sMessage = ::rtl::OUString::createFromAscii( 
"Could not store the database document to '" );
+    ::rtl::OUString sMessage = ::rtl::OUString::createFromAscii( "Could not 
create a storage for '" );
             sMessage += _rURL;
             sMessage += ::rtl::OUString::createFromAscii( "'." );
             if ( sOriginalExceptionMessage.getLength() )
@@ -541,98 +682,71 @@
                 sMessage += ::rtl::OUString::createFromAscii( "\noriginal 
error type: " );
                 sMessage += sOriginalExceptionType;
             }
-                       throw IOException( sMessage, *this );
-        }
+       throw IOException( sMessage, *const_cast< ODatabaseDocument* >( this ) 
);
+}
 
-        if ( m_pImpl->isEmbeddedDatabase() )
-            m_pImpl->clearConnections();
-        m_pImpl->commitEmbeddedStorage();
+// 
-----------------------------------------------------------------------------
+void SAL_CALL ODatabaseDocument::storeAsURL( const ::rtl::OUString& _rURL, 
const Sequence< PropertyValue >& _rArguments ) throw (IOException, 
RuntimeException)
+{
+    ModelMethodGuard aGuard( *this );
+    //ModifyLock aLock( *this );
 
-               Reference<XStorage> xMyStorage = m_pImpl->getStorage();
-               if ( xMyStorage.is() )
-               {
-            m_pImpl->commitStorages();
-                       xMyStorage->copyToStorage( xStorage );
-               }
+    impl_storeAs_throw( _rURL, _rArguments, "OnSaveAsDone", aGuard );
+}
 
-        m_pImpl->disposeStorages();
+// 
-----------------------------------------------------------------------------
+void ODatabaseDocument::impl_storeToStorage_throw( const Reference< XStorage 
>& _rxTargetStorage, const Sequence< PropertyValue >& _rMediaDescriptor ) const
+{
+    if ( !_rxTargetStorage.is() )
+        throw IllegalArgumentException( ::rtl::OUString(), *const_cast< 
ODatabaseDocument* >( this ), 1 );
 
-        m_pImpl->m_xStorage = xStorage;
-        if ( m_pImpl->m_bOwnStorage )
-                       ::comphelper::disposeComponent(xMyStorage);
-        else
-            m_pImpl->m_bOwnStorage = sal_True;
+    if ( !m_pImpl.is() )
+        throw DisposedException( ::rtl::OUString(), *const_cast< 
ODatabaseDocument* >( this ) );
 
-               m_pImpl->m_bDocumentReadOnly = sal_False;
-        if ( _rURL != m_pImpl->m_sRealFileURL )
-               {
-                       if ( m_pImpl->m_pDBContext )
+       try
                        {
-                if ( m_pImpl->m_sRealFileURL.getLength() )
-                    
m_pImpl->m_pDBContext->nameChangePrivate(m_pImpl->m_sRealFileURL,_rURL);
-                else
-                    m_pImpl->m_pDBContext->registerPrivate(_rURL,m_pImpl);
-            }
+        // commit everything
+           m_pImpl->commitEmbeddedStorage();
+        m_pImpl->commitStorages();
 
-                       INetURLObject aURL( _rURL );
-                       if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
-                               m_pImpl->m_sName = _rURL;
+        // copy own storage to target storage
+        Reference< XStorage > xCurrentStorage( 
m_pImpl->getOrCreateRootStorage(), UNO_QUERY_THROW );
+        if ( xCurrentStorage != _rxTargetStorage )
+               xCurrentStorage->copyToStorage( _rxTargetStorage );
+
+        // write into target storage
+        writeStorage( _rxTargetStorage, _rMediaDescriptor );
+
+        // commit target storage
+        OSL_VERIFY( m_pImpl->commitStorageIfWriteable_ignoreErrors( 
_rxTargetStorage ) );
                }
-        m_pImpl->m_sRealFileURL = m_pImpl->m_sFileURL = _rURL;
+    catch( const IOException& ) { throw; }
+    catch( const RuntimeException& ) { throw; }
+       catch ( const Exception& e )
+       {
+               throw IOException( e.Message, *const_cast< ODatabaseDocument* 
>( this ) );
        }
-       lcl_stripLoadArguments( aDescriptor, m_pImpl->m_aArgs );
-       store(m_pImpl->m_sFileURL,_rArguments,aGuard);
-
-    impl_notifyEvent( "OnSaveAsDone", aGuard );
 }
 
 // 
-----------------------------------------------------------------------------
 void SAL_CALL ODatabaseDocument::storeToURL( const ::rtl::OUString& _rURL, 
const Sequence< PropertyValue >& _rArguments ) throw (IOException, 
RuntimeException)
 {
     ModelMethodGuard aGuard( *this );
-    OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
+    ModifyLock aLock( *this );
 
-    Reference< XSingleServiceFactory > xStorageFactory( 
m_pImpl->createStorageFactory() );
-       Sequence<Any> aParam(2);
-       aParam[0] <<= _rURL;
-       aParam[1] <<= ElementModes::READWRITE  | ElementModes::TRUNCATE;
-       Reference<XStorage> xStorage;
-    if ( xStorageFactory.is() )
-        xStorage = xStorage.query( 
xStorageFactory->createInstanceWithArguments( aParam ) );
-    OSL_ENSURE( xStorage.is(), "ODatabaseDocument::storeToURL: no storage 
factory!" );
-       if ( !xStorage.is() )
-    {
-        IOException aError;
-        aError.Message = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could 
not create a target storage." ) );
-        aError.Context = *this;
-               throw IOException( aError );
-    }
-
-    Reference<XStorage> xMyStorage = m_pImpl->getStorage();
-    OSL_ENSURE( xMyStorage.is(), "ODatabaseDocument::storeToURL: no own 
storage?" );
-       if ( !xMyStorage.is() )
-    {
-        IOException aError;
-        aError.Message = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 
"Internal error: no source storage available." ) );
-        aError.Context = *this;
-               throw IOException( aError );
-    }
+    // create storage for target URL
+    Reference< XStorage > xTargetStorage;
+    if ( !impl_createStorageFor_throw( _rURL, xTargetStorage ) )
+        // failed, but handled by an interaction handler
+        return;
 
-       m_pImpl->commitEmbeddedStorage();
-       xMyStorage->copyToStorage( xStorage );
-       writeStorage(_rURL,_rArguments,xStorage);
-       try
-       {
-               Reference<XTransactedObject> xTransact(xStorage,UNO_QUERY);
-               if ( xTransact.is() )
-                       xTransact->commit();
-       }
-       catch(Exception)
-       {
-               OSL_ENSURE(0,"Exception Caught: Could not store database!");
-               throw IOException();
-       }
+    // extend media descriptor with URL
+    Sequence< PropertyValue > aMediaDescriptor( 
lcl_appendFileNameToDescriptor( _rArguments, _rURL ) );
+
+    // store to this storage
+    impl_storeToStorage_throw( xTargetStorage, aMediaDescriptor );
 }
+
 // 
-----------------------------------------------------------------------------
 // XModifyBroadcaster
 void SAL_CALL ODatabaseDocument::addModifyListener( const Reference< 
XModifyListener >& _xListener ) throw (RuntimeException)
@@ -640,12 +754,14 @@
        
::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed);
        m_aModifyListeners.addInterface(_xListener);
 }
+
 // 
-----------------------------------------------------------------------------
 void SAL_CALL ODatabaseDocument::removeModifyListener( const Reference< 
XModifyListener >& _xListener ) throw (RuntimeException)
 {
        
::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed);
        m_aModifyListeners.removeInterface(_xListener);
 }
+
 // 
-----------------------------------------------------------------------------
 // XModifiable
 sal_Bool SAL_CALL ODatabaseDocument::isModified(  ) throw (RuntimeException)
@@ -655,67 +771,76 @@
 
        return m_pImpl->m_bModified;
 }
+
 // 
-----------------------------------------------------------------------------
 void SAL_CALL ODatabaseDocument::setModified( sal_Bool _bModified ) throw 
(PropertyVetoException, RuntimeException)
 {
     ModelMethodGuard aGuard( *this );
-    setModified( _bModified,aGuard );
+    impl_setModified_throw( _bModified, aGuard );
 }
+
 // 
-----------------------------------------------------------------------------
-void ODatabaseDocument::setModified( sal_Bool _bModified,ModelMethodGuard& 
_rGuard )
+void ODatabaseDocument::impl_setModified_throw( sal_Bool _bModified, 
ModelMethodGuard& _rGuard )
 {
        if ( m_pImpl->m_bModified == _bModified )
         return;
 
+    if ( m_pImpl->isModifyLocked() )
+        return;
+
     m_pImpl->m_bModified = _bModified;
-       lang::EventObject aEvt( *this );
 
+    document::EventObject aEvent( *this, ::rtl::OUString( 
RTL_CONSTASCII_USTRINGPARAM( "OnModifyChanged" ) ) );
     _rGuard.clear();
-    m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvt );
 
-    _rGuard.reset();
-    impl_notifyEvent( "OnModifyChanged", _rGuard );
+    m_aModifyListeners.notifyEach( &XModifyListener::modified, (const 
lang::EventObject&)aEvent );
+    impl_notifyEvent_nolck_nothrow( aEvent );
 }
-// 
-----------------------------------------------------------------------------
 
-// ::com::sun::star::document::XEventBroadcaster
-void SAL_CALL ODatabaseDocument::addEventListener(const css::uno::Reference< 
css::document::XEventListener >& _xListener ) throw (css::uno::RuntimeException)
+// 
-----------------------------------------------------------------------------
+void SAL_CALL ODatabaseDocument::addEventListener(const Reference< 
XEventListener >& _xListener ) throw (RuntimeException)
 {
        
::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed);
     m_aDocEventListeners.addInterface(_xListener);
 }
+
 // 
-----------------------------------------------------------------------------
-void SAL_CALL ODatabaseDocument::removeEventListener( const 
css::uno::Reference< css::document::XEventListener >& _xListener ) throw 
(css::uno::RuntimeException)
+void SAL_CALL ODatabaseDocument::removeEventListener( const Reference< 
XEventListener >& _xListener ) throw (RuntimeException)
 {
        
::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed);
     m_aDocEventListeners.removeInterface(_xListener);
 }
+
 // 
-----------------------------------------------------------------------------
-// ::com::sun::star::document::XEventListener
-void SAL_CALL ODatabaseDocument::notifyEvent( const 
css::document::EventObject& aEvent ) throw (css::uno::RuntimeException)
+void SAL_CALL ODatabaseDocument::notifyEvent( const document::EventObject& 
_rEvent ) throw (RuntimeException)
 {
     ModelMethodGuard aGuard( *this );
     // used only to forward external events (e.g. for doc creation) from the 
frame loader
     // to the global event broadcaster and all other interested doc event 
listener.
-    impl_notifyEvent( aEvent.EventName, aGuard );
+    document::EventObject aEvent( *this, _rEvent.EventName );
+    aGuard.clear();
+    impl_notifyEvent_nolck_nothrow( aEvent );
 }
+
 // 
-----------------------------------------------------------------------------
-// ::com::sun::star::view::XPrintable
 Sequence< PropertyValue > SAL_CALL ODatabaseDocument::getPrinter(  ) throw 
(RuntimeException)
 {
     DBG_ERROR( "ODatabaseDocument::getPrinter: not supported!" );
        return Sequence< PropertyValue >();
 }
+
 // 
-----------------------------------------------------------------------------
 void SAL_CALL ODatabaseDocument::setPrinter( const Sequence< PropertyValue >& 
/*aPrinter*/ ) throw (IllegalArgumentException, RuntimeException)
 {
     DBG_ERROR( "ODatabaseDocument::setPrinter: not supported!" );
 }
+
 // 
-----------------------------------------------------------------------------
 void SAL_CALL ODatabaseDocument::print( const Sequence< PropertyValue >& 
/*xOptions*/ ) throw (IllegalArgumentException, RuntimeException)
 {
     DBG_ERROR( "ODatabaseDocument::print: not supported!" );
 }
+
 // 
-----------------------------------------------------------------------------
 void ODatabaseDocument::impl_reparent_nothrow( const WeakReference< 
XNameAccess >& _rxContainer )
 {
@@ -750,7 +875,7 @@
        if ( !xContainer.is() )
        {
         TContentPtr& rContainerData( m_pImpl->getObjectContainer( _eType ) );
-        rContainerRef = xContainer = new ODocumentContainer( 
m_pImpl->m_xServiceFactory, *this, rContainerData, bFormsContainer );
+        rContainerRef = xContainer = new ODocumentContainer( 
m_pImpl->m_aContext.getLegacyServiceFactory(), *this, rContainerData, 
bFormsContainer );
         impl_reparent_nothrow( xContainer );
        }
        return xContainer;
@@ -813,7 +938,7 @@
 {
     ModelMethodGuard aGuard( *this );
 
-    lang::EventObject aEvent( *this );
+    document::EventObject aEvent( *this, ::rtl::OUString( 
RTL_CONSTASCII_USTRINGPARAM( "OnUnload" ) ) );
 
     {
         aGuard.clear();
@@ -824,11 +949,12 @@
 
     impl_closeControllerFrames( _bDeliverOwnership );
 
-    {
         aGuard.clear();
-        m_aCloseListener.notifyEach( &XCloseListener::notifyClosing, aEvent );
-        aGuard.reset();
-    }
+
+    m_aCloseListener.notifyEach( &XCloseListener::notifyClosing, (const 
lang::EventObject&)aEvent );
+
+    // notify the OnUnload at the earliest possibility - which is here and now
+       impl_notifyEvent_nolck_nothrow( aEvent );
 
     dispose();
 }
@@ -854,196 +980,114 @@
 {
     return impl_getDocumentContainer_throw( ODatabaseModelImpl::E_REPORT );
 }
+
 // 
-----------------------------------------------------------------------------
-sal_Bool ODatabaseDocument::WriteThroughComponent(
-       const Reference<XComponent> & xComponent,
-       const sal_Char* pStreamName,
-       const sal_Char* pServiceName,
-       const Sequence<Any> & rArguments,
-       const Sequence<PropertyValue> & rMediaDesc,
-       sal_Bool bPlainStream
-       ,const Reference<XStorage>& _xStorageToSaveTo)
+void ODatabaseDocument::WriteThroughComponent( const Reference< XComponent >& 
xComponent, const sal_Char* pStreamName,
+       const sal_Char* pServiceName, const Sequence< Any >& _rArguments, const 
Sequence< PropertyValue >& rMediaDesc,
+       const Reference<XStorage>& _xStorageToSaveTo ) const
 {
-       OSL_ENSURE( NULL != pStreamName, "Need stream name!" );
-       OSL_ENSURE( NULL != pServiceName, "Need service name!" );
+       OSL_ENSURE( pStreamName, "Need stream name!" );
+       OSL_ENSURE( pServiceName, "Need service name!" );
 
-       Reference<XStorage> xMyStorage = _xStorageToSaveTo;
        // open stream
        ::rtl::OUString sStreamName = ::rtl::OUString::createFromAscii( 
pStreamName );
-       Reference<XStream> xStream = xMyStorage->openStreamElement( 
sStreamName,ElementModes::READWRITE | ElementModes::TRUNCATE );
+    Reference< XStream > xStream = _xStorageToSaveTo->openStreamElement( 
sStreamName, ElementModes::READWRITE | ElementModes::TRUNCATE );
        if ( !xStream.is() )
-               return sal_False;
-       Reference<XOutputStream> xOutputStream = xStream->getOutputStream();
-       OSL_ENSURE(xOutputStream.is(), "Can't create output stream in 
package!");
-       if ( ! xOutputStream.is() )
-               return sal_False;
+        return;
 
-       Reference<XPropertySet> xStreamProp(xOutputStream,UNO_QUERY);
-       OSL_ENSURE(xStreamProp.is(),"No valid preoperty set for the output 
stream!");
+    Reference< XOutputStream > xOutputStream( xStream->getOutputStream() );
+    OSL_ENSURE( xOutputStream.is(), "Can't create output stream in package!" );
+    if ( !xOutputStream.is() )
+        return;
 
-       Reference<XSeekable> xSeek(xStreamProp,UNO_QUERY);
+    Reference< XSeekable > xSeek( xOutputStream, UNO_QUERY );
        if ( xSeek.is() )
-       {
-        OSL_TRACE("Length of stream %i",(int)xSeek->getPosition());
                xSeek->seek(0);
-       }
-
-       ::rtl::OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
-       Any aAny;
-       aAny <<= aMime;
-       xStreamProp->setPropertyValue( INFO_MEDIATYPE, aAny );
-
-       if( bPlainStream )
-       {
-               sal_Bool bFalse = sal_False;
-               aAny.setValue( &bFalse, ::getBooleanCppuType() );
-               xStreamProp->setPropertyValue( ::rtl::OUString( 
RTL_CONSTASCII_USTRINGPARAM("Compressed") ), aAny );
-       }
-       else
-       {
-               sal_Bool bTrue = sal_True;
-               aAny.setValue( &bTrue, ::getBooleanCppuType() );
-               xStreamProp->setPropertyValue( ::rtl::OUString( 
RTL_CONSTASCII_USTRINGPARAM("Encrypted") ), aAny );
-       }
-
 
-       // set buffer and create outputstream
+    Reference< XPropertySet > xStreamProp( xOutputStream, UNO_QUERY_THROW );
+    xStreamProp->setPropertyValue( INFO_MEDIATYPE, makeAny( ::rtl::OUString( 
RTL_CONSTASCII_USTRINGPARAM( "text/xml" ) ) ) );
+    xStreamProp->setPropertyValue( ::rtl::OUString( 
RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) ), makeAny( (sal_Bool)sal_True ) );
 
        // write the stuff
-       sal_Bool bRet = WriteThroughComponent(
-               xOutputStream, xComponent,
-               pServiceName, rArguments, rMediaDesc );
-
-       // finally, commit stream.
-       return bRet;
+       WriteThroughComponent( xOutputStream, xComponent, pServiceName, 
_rArguments, rMediaDesc );
 }
 
-sal_Bool ODatabaseDocument::WriteThroughComponent(
-       const Reference<XOutputStream> & xOutputStream,
-       const Reference<XComponent> & xComponent,
-       const sal_Char* pServiceName,
-       const Sequence<Any> & rArguments,
-       const Sequence<PropertyValue> & rMediaDesc)
+void ODatabaseDocument::WriteThroughComponent( const Reference< XOutputStream 
>& xOutputStream,
+    const Reference< XComponent >& xComponent, const sal_Char* pServiceName, 
const Sequence< Any >& _rArguments,
+       const Sequence< PropertyValue >& rMediaDesc ) const
 {
        OSL_ENSURE( xOutputStream.is(), "I really need an output stream!" );
        OSL_ENSURE( xComponent.is(), "Need component!" );
        OSL_ENSURE( NULL != pServiceName, "Need component name!" );
 
        // get component
-       Reference< XActiveDataSource > xSaxWriter(
-               
m_pImpl->m_xServiceFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer"))),
-               UNO_QUERY );
-       OSL_ENSURE( xSaxWriter.is(), "can't instantiate XML 
com.sun.star.xml.sax.Writer" );
-       if(!xSaxWriter.is())
-               return sal_False;
+       Reference< XActiveDataSource > xSaxWriter;
+    OSL_VERIFY( m_pImpl->m_aContext.createComponent( 
"com.sun.star.xml.sax.Writer", xSaxWriter ) );
+       if ( !xSaxWriter.is() )
+               return;
 
        // connect XML writer to output stream
        xSaxWriter->setOutputStream( xOutputStream );
 
        // prepare arguments (prepend doc handler to given arguments)
-       Reference<XDocumentHandler> xDocHandler( xSaxWriter,UNO_QUERY);
-       Sequence<Any> aArgs( 1 + rArguments.getLength() );
+       Reference< XDocumentHandler > xDocHandler( xSaxWriter,UNO_QUERY);
+       Sequence<Any> aArgs( 1 + _rArguments.getLength() );
        aArgs[0] <<= xDocHandler;
-       for(sal_Int32 i = 0; i < rArguments.getLength(); i++)
-               aArgs[i+1] = rArguments[i];
+       for ( sal_Int32 i = 0; i < _rArguments.getLength(); ++i )
+               aArgs[ i+1 ] = _rArguments[i];
 
        // get filter component
-       Reference< XExporter > xExporter(
-               m_pImpl->m_xServiceFactory->createInstanceWithArguments(
-                       ::rtl::OUString::createFromAscii(pServiceName), aArgs), 
UNO_QUERY);
-       OSL_ENSURE( xExporter.is(),
-                       "can't instantiate export filter component" );
-       if( !xExporter.is() )
-               return sal_False;
-
+       Reference< XExporter > xExporter;
+    OSL_VERIFY( m_pImpl->m_aContext.createComponentWithArguments( 
pServiceName, aArgs, xExporter ) );
+       if ( !xExporter.is() )
+               return;
 
        // connect model and filter
        xExporter->setSourceDocument( xComponent );
 
-       // filter!
-       Reference<XFilter> xFilter( xExporter, UNO_QUERY );
-       return xFilter->filter( rMediaDesc );
+       // filter
+    Reference< XFilter > xFilter( xExporter, UNO_QUERY_THROW );
+       xFilter->filter( rMediaDesc );
 }
+
 // 
-----------------------------------------------------------------------------
-void ODatabaseDocument::writeStorage(const ::rtl::OUString& _rURL
-                                                                       ,const 
Sequence< PropertyValue >& _rArguments
-                                                                       ,const 
Reference<XStorage>& _xStorageToSaveTo)
+void ODatabaseDocument::writeStorage( const Reference< XStorage >& 
_rxTargetStorage, const ::comphelper::NamedValueCollection& _rMediaDescriptor ) 
const
 {
-       // create XStatusIndicator
-       Reference<XStatusIndicator> xStatusIndicator;
+       // extract status indicator
     Sequence< Any > aDelegatorArguments;
-       ::comphelper::MediaDescriptor aDescriptor( _rArguments );
-    lcl_extractAndStartStatusIndicator( aDescriptor, xStatusIndicator, 
aDelegatorArguments );
+    Reference< XStatusIndicator > xStatusIndicator;
+    lcl_extractAndStartStatusIndicator( _rMediaDescriptor, xStatusIndicator, 
aDelegatorArguments );
 
-       // properties
-       Sequence < PropertyValue > aProps( _rURL.getLength() ? 1 : 0 );
-       if( _rURL.getLength() )
-       {
-               PropertyValue *pProps = aProps.getArray();
-               pProps->Name = ::rtl::OUString( 
RTL_CONSTASCII_USTRINGPARAM("FileName") );
-               (pProps++)->Value <<= _rURL;
-       }
+       Reference< XPropertySet > xProp( _rxTargetStorage, UNO_QUERY_THROW );
+    xProp->setPropertyValue( INFO_MEDIATYPE, makeAny( 
(rtl::OUString)MIMETYPE_OASIS_OPENDOCUMENT_DATABASE ) );
 
-       // export sub streams for package, else full stream into a file
-       sal_Bool bWarn = sal_False, bErr = sal_False;
-       String sWarnFile, sErrFile;
+       Reference< XComponent > xComponent( *const_cast< ODatabaseDocument* >( 
this ), UNO_QUERY_THROW );
 
-       Reference<XPropertySet> xProp(_xStorageToSaveTo,UNO_QUERY);
-       if ( xProp.is() )
-       {
-               Any aAny;
-               aAny <<= MIMETYPE_OASIS_OPENDOCUMENT_DATABASE;
-               xProp->setPropertyValue( INFO_MEDIATYPE, aAny );
-       }
+    Sequence< PropertyValue > aMediaDescriptor;
+    _rMediaDescriptor >>= aMediaDescriptor;
 
-       Reference<XComponent> xCom(static_cast<OWeakObject*>(this),UNO_QUERY);
-       if( !bErr )
-       {
-               if( !WriteThroughComponent(
-                       xCom, "settings.xml",
-                       "com.sun.star.comp.sdb.XMLSettingsExporter",
-                       aDelegatorArguments, aProps, sal_True,_xStorageToSaveTo 
) )
-               {
-                       if( !bWarn )
-                       {
-                               bWarn = sal_True;
-                               sWarnFile = String( 
RTL_CONSTASCII_STRINGPARAM("settings.xml"),
-                                                                       
RTL_TEXTENCODING_ASCII_US );
-                       }
-               }
-       }
+    WriteThroughComponent( xComponent, "settings.xml", 
"com.sun.star.comp.sdb.XMLSettingsExporter",
+        aDelegatorArguments, aMediaDescriptor, _rxTargetStorage );
 
-       if ( !bErr )
-       {
-               if( !WriteThroughComponent(
-                               xCom, "content.xml",
-                               "com.sun.star.comp.sdb.DBExportFilter",
-                               aDelegatorArguments, aProps, 
sal_True,_xStorageToSaveTo ) )
-               {
-                       bErr = sal_True;
-                       sErrFile = String( 
RTL_CONSTASCII_STRINGPARAM("content.xml"),
-                                                          
RTL_TEXTENCODING_ASCII_US );
-               }
-       }
+    WriteThroughComponent( xComponent, "content.xml", 
"com.sun.star.comp.sdb.DBExportFilter",
+        aDelegatorArguments, aMediaDescriptor, _rxTargetStorage );
 
+    m_pImpl->storeLibraryContainersTo( _rxTargetStorage );
 
        if ( xStatusIndicator.is() )
                xStatusIndicator->end();
 }
+
 // 
-----------------------------------------------------------------------------
-Reference< ::com::sun::star::ui::XUIConfigurationManager > SAL_CALL 
ODatabaseDocument::getUIConfigurationManager(  ) throw (RuntimeException)
+Reference< XUIConfigurationManager > SAL_CALL 
ODatabaseDocument::getUIConfigurationManager(  ) throw (RuntimeException)
 {
     ModelMethodGuard aGuard( *this );
     OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
 
        if ( !m_xUIConfigurationManager.is() )
     {
-        m_xUIConfigurationManager = Reference< 
::com::sun::star::ui::XUIConfigurationManager >(
-            m_pImpl->m_xServiceFactory->createInstance(
-                ::rtl::OUString::createFromAscii( 
"com.sun.star.ui.UIConfigurationManager" )),
-                UNO_QUERY );
-
-        Reference< ::com::sun::star::ui::XUIConfigurationStorage > 
xUIConfigStorage( m_xUIConfigurationManager, UNO_QUERY );
+        m_pImpl->m_aContext.createComponent( 
"com.sun.star.ui.UIConfigurationManager", m_xUIConfigurationManager );
+        Reference< XUIConfigurationStorage > xUIConfigStorage( 
m_xUIConfigurationManager, UNO_QUERY );
         if ( xUIConfigStorage.is() )
         {
             rtl::OUString aUIConfigFolderName( RTL_CONSTASCII_USTRINGPARAM( 
"Configurations2" ));
@@ -1087,19 +1131,29 @@
     Reference< XDocumentSubStorageSupplier > xStorageAccess( 
m_pImpl->getDocumentSubStorageSupplier() );
     return xStorageAccess->getDocumentSubStoragesNames();
 }
+
 // 
-----------------------------------------------------------------------------
-void ODatabaseDocument::impl_notifyEvent( const ::rtl::OUString& _sEventName, 
::osl::ClearableMutexGuard& _rGuard )
+void ODatabaseDocument::impl_notifyEvent_nolck_nothrow( const 
document::EventObject& _rEvent )
 {
        try
        {
-               css::document::EventObject aEvt(*this, _sEventName);
-        _rGuard.clear();
-        m_aDocEventListeners.notifyEach( 
&css::document::XEventListener::notifyEvent, aEvt );
+        m_aDocEventListeners.notifyEach( &XEventListener::notifyEvent, _rEvent 
);
        }
-       catch(Exception&)
+       catch(const Exception&)
        {
+        DBG_UNHANDLED_EXCEPTION();
        }
 }
+
+//------------------------------------------------------------------------------
+void ODatabaseDocument::impl_notifyStorageChange_nolck_nothrow( const 
Reference< XStorage >& _rxNewRootStorage )
+{
+    Reference< XInterface > xMe( *const_cast< ODatabaseDocument* >( this ) );
+
+    m_aStorageListeners.forEach< XStorageChangeListener >(
+        boost::bind( &XStorageChangeListener::notifyStorageChange, _1, 
boost::cref( xMe ), boost::cref( _rxNewRootStorage ) ) );
+}
+
 
//------------------------------------------------------------------------------
 void ODatabaseDocument::disposing()
 {
@@ -1116,20 +1170,16 @@
 
     Reference< XModel > xHoldAlive( this );
     {
-        {
-            ::osl::ClearableMutexGuard aGuard( getMutex() );
-               impl_notifyEvent( "OnUnload", aGuard );
-        }
-
-           css::lang::EventObject aDisposeEvent(static_cast<XWeak*>(this));
+        lang::EventObject aDisposeEvent(static_cast<XWeak*>(this));
            m_aModifyListeners.disposeAndClear( aDisposeEvent );
            m_aCloseListener.disposeAndClear( aDisposeEvent );
            m_aDocEventListeners.disposeAndClear( aDisposeEvent );
+        m_aStorageListeners.disposeAndClear( aDisposeEvent );
 
         m_xUIConfigurationManager = NULL;
 
-        clearObjectContainer( m_xForms);
-               clearObjectContainer( m_xReports);
+        clearObjectContainer( m_xForms );
+               clearObjectContainer( m_xReports );
 
         m_pImpl->modelIsDisposing( ODatabaseModelImpl::ResetModelAccess() );
 
@@ -1148,14 +1198,14 @@
     ::cppu::WeakComponentImplHelperBase::dispose();
 }
 // 
-----------------------------------------------------------------------------
-void SAL_CALL ODatabaseDocument::addEventListener( const Reference< 
css::lang::XEventListener >& _xListener ) throw (RuntimeException)
+void SAL_CALL ODatabaseDocument::addEventListener( const Reference< 
lang::XEventListener >& _xListener ) throw (RuntimeException)
 {
-       ::cppu::WeakComponentImplHelperBase::addEventListener(_xListener);
+       ::cppu::WeakComponentImplHelperBase::addEventListener( _xListener );
 }
 // 
-----------------------------------------------------------------------------
-void SAL_CALL ODatabaseDocument::removeEventListener( const Reference< 
css::lang::XEventListener >& _xListener ) throw (RuntimeException)
+void SAL_CALL ODatabaseDocument::removeEventListener( const Reference< 
lang::XEventListener >& _xListener ) throw (RuntimeException)
 {
-       ::cppu::WeakComponentImplHelperBase::removeEventListener(_xListener);
+       ::cppu::WeakComponentImplHelperBase::removeEventListener( _xListener );
 }
 // XServiceInfo
 
//------------------------------------------------------------------------------
@@ -1210,6 +1260,111 @@
     OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
     return m_pImpl->getDataSource();
 }
+
+// 
-----------------------------------------------------------------------------
+void SAL_CALL ODatabaseDocument::loadFromStorage( const Reference< XStorage >& 
/*xStorage*/, const Sequence< PropertyValue >& /*aMediaDescriptor*/ ) throw 
(IllegalArgumentException, DoubleInitializationException, IOException, 
Exception, RuntimeException)
+{
+    ModelMethodGuard aGuard( *this );
+
+    throw Exception(
+        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Embedding of database 
documents is not supported." ) ),
+            // TODO: resource
+        *this
+    );
+}
+
+// 
-----------------------------------------------------------------------------
+void SAL_CALL ODatabaseDocument::storeToStorage( const Reference< XStorage >& 
_rxStorage, const Sequence< PropertyValue >& _rMediaDescriptor ) throw 
(IllegalArgumentException, IOException, Exception, RuntimeException)
+{
+    ModelMethodGuard aGuard( *this );
+    //ModifyLock aLock( *this );
+
+    impl_storeToStorage_throw( _rxStorage, _rMediaDescriptor );
+}
+
+// 
-----------------------------------------------------------------------------
+void SAL_CALL ODatabaseDocument::switchToStorage( const Reference< XStorage >& 
_rxNewRootStorage ) throw (IllegalArgumentException, IOException, Exception, 
RuntimeException)
+{
+    ModelMethodGuard aGuard( *this );
+
+    Reference< XStorage > xNewRootStorage( m_pImpl->switchToStorage( 
_rxNewRootStorage ) );
+
+    aGuard.clear();
+    impl_notifyStorageChange_nolck_nothrow( xNewRootStorage );
+}
+
+// 
-----------------------------------------------------------------------------
+Reference< XStorage > SAL_CALL ODatabaseDocument::getDocumentStorage(  ) throw 
(IOException, Exception, RuntimeException)
+{
+    ModelMethodGuard aGuard( *this );
+    return m_pImpl->getRootStorage();
+}
+
+// 
-----------------------------------------------------------------------------
+void SAL_CALL ODatabaseDocument::addStorageChangeListener( const Reference< 
XStorageChangeListener >& _Listener ) throw (RuntimeException)
+{
+    ModelMethodGuard aGuard( *this );
+    m_aStorageListeners.addInterface( _Listener );
+}
+
+// 
-----------------------------------------------------------------------------
+void SAL_CALL ODatabaseDocument::removeStorageChangeListener( const Reference< 
XStorageChangeListener >& _Listener ) throw (RuntimeException)
+{
+    ModelMethodGuard aGuard( *this );
+    m_aStorageListeners.addInterface( _Listener );
+}
+
+// 
-----------------------------------------------------------------------------
+Reference< XStorageBasedLibraryContainer > SAL_CALL 
ODatabaseDocument::getBasicLibraries() throw (RuntimeException)
+{
+    ModelMethodGuard aGuard( *this );
+    return m_pImpl->getLibraryContainer( true );
+}
+
+// 
-----------------------------------------------------------------------------
+Reference< XStorageBasedLibraryContainer > SAL_CALL 
ODatabaseDocument::getDialogLibraries() throw (RuntimeException)
+{
+    ModelMethodGuard aGuard( *this );
+    return m_pImpl->getLibraryContainer( false );
+}
+
+// 
-----------------------------------------------------------------------------
+::sal_Bool SAL_CALL ODatabaseDocument::getAllowMacroExecution() throw 
(RuntimeException)
+{
+    ModelMethodGuard aGuard( *this );
+    return m_pImpl->adjustMacroMode_AutoReject();
+}
+
+// 
-----------------------------------------------------------------------------
+Reference< XEmbeddedScripts > SAL_CALL ODatabaseDocument::getScriptContainer() 
throw (RuntimeException)
+{
+    ModelMethodGuard aGuard( *this );
+    return this;
+}
+
+// 
-----------------------------------------------------------------------------
+Reference< provider::XScriptProvider > SAL_CALL 
ODatabaseDocument::getScriptProvider(  ) throw (RuntimeException)
+{
+    ModelMethodGuard aGuard( *this );
+
+    Reference< XScriptProvider > xScriptProvider( m_xScriptProvider );
+    if ( !xScriptProvider.is() )
+    {
+        Reference < XScriptProviderFactory > xFactory(
+            m_pImpl->m_aContext.getSingleton( 
"com.sun.star.script.provider.theMasterScriptProviderFactory" ), 
UNO_QUERY_THROW );
+
+        Any aScriptProviderContext;
+        if ( !impl_shouldDisallowScripting_nolck_nothrow() )
+            aScriptProviderContext <<= Reference< XModel >( this );
+
+        xScriptProvider.set( xFactory->createScriptProvider( 
aScriptProviderContext ), UNO_SET_THROW );
+        m_xScriptProvider = xScriptProvider;
+    }
+
+    return xScriptProvider;
+}
+
+
 // 
-----------------------------------------------------------------------------
 void SAL_CALL ODatabaseDocument::disposing( const 
::com::sun::star::lang::EventObject& Source ) throw(RuntimeException)
 {
@@ -1218,9 +1373,9 @@
 }
 
 //------------------------------------------------------------------
-Reference< XInterface > ODatabaseDocument::getThis()
+Reference< XInterface > ODatabaseDocument::getThis() const
 {
-    return *this;
+    return *const_cast< ODatabaseDocument* >( this );
 }
 // 
-----------------------------------------------------------------------------
 struct CreateAny : public ::std::unary_function< Reference<XController>, Any>




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

Reply via email to