Tag: cws_dev300_odbmacros3
User: fs      
Date: 2008-04-21 10:29:09+0000
Modified:
   dba/dbaccess/source/ext/macromigration/migrationengine.cxx

Log:
 #i49133# support for migrating the script (not Macro/Dialog) libraries, by 
simply moving the respective storages

File Changes:

Directory: /dba/dbaccess/source/ext/macromigration/
===================================================

File [changed]: migrationengine.cxx
Url: 
http://dba.openoffice.org/source/browse/dba/dbaccess/source/ext/macromigration/migrationengine.cxx?r1=1.4&r2=1.4.2.1
Delta lines:  +607 -85
----------------------
--- migrationengine.cxx 2008-04-10 13:15:44+0000        1.4
+++ migrationengine.cxx 2008-04-21 10:29:06+0000        1.4.2.1
@@ -7,7 +7,7 @@
  * OpenOffice.org - a multi-platform office productivity suite
  *
  * $RCSfile: migrationengine.cxx,v $
- * $Revision: 1.4 $
+ * $Revision: 1.4.2.1 $
  *
  * This file is part of OpenOffice.org.
  *
@@ -39,6 +39,7 @@
 #include "migrationprogress.hxx"
 #include "migrationlog.hxx"
 #include "progresscapture.hxx"
+#include "progressmixer.hxx"
 
 /** === begin UNO includes === **/
 #include <com/sun/star/sdb/XFormDocumentsSupplier.hpp>
@@ -48,6 +49,11 @@
 #include <com/sun/star/frame/XComponentLoader.hpp>
 #include <com/sun/star/ucb/XCommandProcessor.hpp>
 #include <com/sun/star/embed/XComponentSupplier.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/embed/XEmbedPersist.hpp>
 /** === end UNO includes === **/
 
 #include <comphelper/string.hxx>
@@ -56,8 +62,10 @@
 #include <tools/diagnose_ex.h>
 #include <rtl/ustrbuf.hxx>
 #include <rtl/ref.hxx>
+#include <unotools/sharedunocomponent.hxx>
 
 #include <vector>
+#include <set>
 
 #define DEFAULT_DOC_PROGRESS_RANGE  100000
 
@@ -90,7 +98,19 @@
     using ::com::sun::star::ucb::Command;
     using ::com::sun::star::embed::XComponentSupplier;
     using ::com::sun::star::task::XStatusIndicator;
+    using ::com::sun::star::embed::XStorage;
+    using ::com::sun::star::document::XStorageBasedDocument;
+    using ::com::sun::star::embed::XTransactedObject;
+    using ::com::sun::star::frame::XStorable;
+    using ::com::sun::star::embed::XEmbedPersist;
        /** === end UNO using === **/
+    namespace ElementModes = ::com::sun::star::embed::ElementModes;
+
+// migration phases whose progresses are to be mixed into one progress
+#define PHASE_JAVASCRIPT    1
+#define PHASE_BEANSHELL     2
+#define PHASE_PYTHON        3
+#define PHASE_JAVA          4
 
     //====================================================================
        //= SubDocument
@@ -112,6 +132,393 @@
     typedef ::std::vector< SubDocument >    SubDocuments;
 
        //====================================================================
+       //= helper
+       //====================================================================
+    //--------------------------------------------------------------------
+    typedef ::utl::SharedUNOComponent< XStorage >   SharedStorage;
+
+    namespace
+    {
+           //----------------------------------------------------------------
+        static const ::rtl::OUString& lcl_getScriptsStorageName()
+        {
+            static const ::rtl::OUString s_sScriptsStorageName( 
RTL_CONSTASCII_USTRINGPARAM( "Scripts" ) );
+            return s_sScriptsStorageName;
+        }
+
+           //----------------------------------------------------------------
+        static const ::rtl::OUString& lcl_getScriptsSubStorageName( const 
ScriptType _eType )
+        {
+            static const ::rtl::OUString s_sBeanShell ( 
RTL_CONSTASCII_USTRINGPARAM( "beanshell" ) );   // TODO: is this correct?
+            static const ::rtl::OUString s_sJavaScript( 
RTL_CONSTASCII_USTRINGPARAM( "javascript" ) );
+            static const ::rtl::OUString s_sPython    ( 
RTL_CONSTASCII_USTRINGPARAM( "python" ) );      // TODO: is this correct?
+            static const ::rtl::OUString s_sJava      ( 
RTL_CONSTASCII_USTRINGPARAM( "java" ) );        // TODO: is this correct?
+
+            switch ( _eType )
+            {
+            case eBeanShell:    return s_sBeanShell;
+            case eJavaScript:   return s_sJavaScript;
+            case ePython:       return s_sPython;
+            case eJava:         return s_sJava;
+            default:
+                break;
+            }
+
+            OSL_ENSURE( false, "lcl_getScriptsSubStorageName: illegal type!" );
+            static ::rtl::OUString s_sEmpty;
+            return s_sEmpty;
+        }
+
+           //----------------------------------------------------------------
+        static Any lcl_executeCommand_throw( const Reference< 
XCommandProcessor >& _rxCommandProc,
+            const sal_Char* _pAsciiCommand )
+        {
+            OSL_PRECOND( _rxCommandProc.is(), "lcl_executeCommand_throw: 
illegal object!" );
+            if ( !_rxCommandProc.is() )
+                return Any();
+
+            Command aCommand;
+            aCommand.Name = ::rtl::OUString::createFromAscii( _pAsciiCommand );
+            return _rxCommandProc->execute(
+                aCommand, _rxCommandProc->createCommandIdentifier(), NULL );
+        }
+
+           //----------------------------------------------------------------
+        static void lcl_disposeComponent_nothrow( const Reference< 
XCommandProcessor >& _rxCommandProc )
+        {
+            bool bCouldClose = false;
+            try
+            {
+                OSL_VERIFY( lcl_executeCommand_throw( _rxCommandProc, 
"shutdown" ) >>= bCouldClose );
+            }
+            catch( const Exception& )
+            {
+               DBG_UNHANDLED_EXCEPTION();
+            }
+            if ( !bCouldClose )
+            {
+                ;
+                // TODO: can we handle this somehow?
+            }
+        }
+
+           //----------------------------------------------------------------
+        static Reference< XModel > lcl_loadSubDocument_nothrow( const 
SubDocument& _rDocument,
+            const Reference< XStatusIndicator >& _rxProgress )
+        {
+            Reference< XModel > xDocument;
+
+            try
+            {
+                ::comphelper::NamedValueCollection aLoadArgs;
+                aLoadArgs.put( "Hidden", (sal_Bool)sal_True );
+                aLoadArgs.put( "StatusIndicator", _rxProgress );
+
+                Reference< XCommandProcessor > xCommandProcessor( 
_rDocument.xCommandProcessor, UNO_SET_THROW );
+                Command aCommand;
+                aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 
"openDesign" ) );
+                aCommand.Argument <<= aLoadArgs.getPropertyValues();
+                Reference< XComponent > xDocComponent(
+                    xCommandProcessor->execute(
+                        aCommand, 
xCommandProcessor->createCommandIdentifier(), NULL
+                    ),
+                    UNO_QUERY
+                );
+                OSL_ENSURE( xDocComponent.is(), "lcl_loadSubDocument_nothrow: 
no component loaded!" );
+
+                xDocument.set( xDocComponent, UNO_QUERY_THROW );
+            }
+            catch( const Exception& )
+            {
+                // TODO: how to proceed?
+                   DBG_UNHANDLED_EXCEPTION();
+            }
+
+            return xDocument;
+        }
+
+        //----------------------------------------------------------------
+        bool lcl_commitStorage_nothrow( const Reference< XStorage >& 
_rxStorage )
+        {
+            try
+            {
+                Reference< XTransactedObject > xTrans( _rxStorage, 
UNO_QUERY_THROW );
+                xTrans->commit();
+            }
+            catch( const Exception& )
+            {
+               return false;
+            }
+            return true;
+        }
+
+        //----------------------------------------------------------------
+        bool lcl_commitDocumentStorage_nothrow( const Reference< XModel >& 
_rxDocument )
+        {
+            bool bSuccess = false;
+            try
+            {
+                Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, 
UNO_QUERY_THROW );
+                Reference< XStorage > xDocStorage( 
xStorageDoc->getDocumentStorage(), UNO_QUERY_THROW );
+                bSuccess = lcl_commitStorage_nothrow( xDocStorage );
+            }
+            catch( const Exception& )
+            {
+                DBG_UNHANDLED_EXCEPTION();
+            }
+               return bSuccess;
+        }
+
+        //----------------------------------------------------------------
+        bool lcl_storeDocument_nothrow( const Reference< XModel >& _rxDocument 
)
+        {
+            try
+            {
+                Reference< XStorable > xStorable( _rxDocument, UNO_QUERY_THROW 
);
+                xStorable->store();
+            }
+            catch( const Exception& )
+            {
+                DBG_UNHANDLED_EXCEPTION();
+                return false;
+            }
+            return true;
+        }
+
+        //----------------------------------------------------------------
+        bool lcl_storeEmbeddedDocument_nothrow( const SubDocument& _rDocument )
+        {
+            try
+            {
+                lcl_executeCommand_throw( _rDocument.xCommandProcessor, 
"store" );
+            }
+            catch( const Exception& )
+            {
+               DBG_UNHANDLED_EXCEPTION();
+                return false;
+            }
+            return true;
+        }
+    }
+
+    //====================================================================
+       //= ScriptsStorage - declaration
+       //====================================================================
+    /** a helper class which encapsulates access to the storages for 
Java/Script, BeanShell, and Python scripts,
+        i.e. all script types which can be manipulated on storage level.
+    */
+    class ScriptsStorage
+    {
+    public:
+        enum AccessMode
+        {
+            READ,
+            WRITE
+        };
+
+    public:
+        ScriptsStorage();
+        ScriptsStorage( const Reference< XModel >& _rxDocument, const 
AccessMode _eMode );
+        ~ScriptsStorage();
+
+        /** determines whether the instance is valid, i.e. refers to a valid 
root storage
+            for reading/storing scripts
+        */
+        inline bool isValid() const { return m_xScriptsStorage.is(); }
+
+        /** determines whether the storage is writeable
+        */
+        inline bool isWriteable() const { return isValid() && ( 
m_nStorageOpenMode != ElementModes::READ ); }
+
+        /** binds the instance to a new document. Only to be called when the 
instance is not yet
+            bound (i.e. isValid returns <FALSE/>).
+        */
+        void    bind( const Reference< XModel >& _rxDocument, const AccessMode 
_eMode );
+
+        /// determines whether scripts of the given type are present
+        bool    hasScripts( const ScriptType _eType ) const;
+
+        /// returns the root storage for the scripts of the given type
+        SharedStorage
+                getScriptsRoot( const ScriptType _eType ) const;
+
+        /** removes the sub storage for a given script type
+            @precond
+                the respective storage is empty
+            @precond
+                the ScriptsStorage instance was opened for writing
+        */
+        void    removeScriptTypeStorage( const ScriptType _eType ) const;
+
+        /** removes the "Scripts" sub storage from the given document's root 
storage
+            @precond
+                the "Scripts" storage is empty
+        */
+        static bool
+                removeFromDocument( const Reference< XModel >& _rxDocument );
+
+    private:
+        SharedStorage   m_xScriptsStorage;
+        sal_Int32       m_nStorageOpenMode;
+    };
+
+    //====================================================================
+       //= ScriptsStorage - implementation
+       //====================================================================
+       //--------------------------------------------------------------------
+    ScriptsStorage::ScriptsStorage()
+        :m_xScriptsStorage()
+        ,m_nStorageOpenMode( ElementModes::READ )
+    {
+    }
+
+       //--------------------------------------------------------------------
+    ScriptsStorage::ScriptsStorage( const Reference< XModel >& _rxDocument, 
const AccessMode _eMode )
+        :m_xScriptsStorage()
+        ,m_nStorageOpenMode( ElementModes::READ )
+    {
+        bind( _rxDocument, _eMode );
+    }
+
+       //--------------------------------------------------------------------
+    ScriptsStorage::~ScriptsStorage()
+    {
+        if ( isWriteable() )
+        {
+            OSL_VERIFY( lcl_commitStorage_nothrow( m_xScriptsStorage ) );
+        }
+    }
+
+       //--------------------------------------------------------------------
+    void ScriptsStorage::bind( const Reference< XModel >& _rxDocument, const 
AccessMode _eMode )
+    {
+        OSL_PRECOND( !isValid(), "ScriptsStorage:bind: did not bother, yet, to 
check whether this is allowed!" );
+        try
+        {
+            Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, 
UNO_QUERY_THROW );
+            Reference< XStorage > xDocStorage( 
xStorageDoc->getDocumentStorage(), UNO_QUERY_THROW );
+
+            const bool bForWrite = ( _eMode == WRITE );
+            m_nStorageOpenMode = bForWrite ? ElementModes::READWRITE : 
ElementModes::READ;
+
+            // the the "Scripts" storage exist, or if it does not (yet) exist 
and we are in write mode
+            // => open the storage
+            if  (   (   xDocStorage->hasByName( lcl_getScriptsStorageName() )
+                    &&  xDocStorage->isStorageElement( 
lcl_getScriptsStorageName() )
+                    )
+                ||  (   !xDocStorage->hasByName( lcl_getScriptsStorageName() )
+                    &&  bForWrite
+                    )
+                )
+            {
+                m_xScriptsStorage.set(
+                    xDocStorage->openStorageElement(
+                        lcl_getScriptsStorageName(), m_nStorageOpenMode
+                    ),
+                    UNO_QUERY_THROW
+                );
+            }
+        }
+        catch( const Exception& )
+        {
+               DBG_UNHANDLED_EXCEPTION();
+        }
+    }
+
+    //--------------------------------------------------------------------
+    bool ScriptsStorage::hasScripts( const ScriptType _eType ) const
+    {
+        OSL_PRECOND( isValid(), "ScriptsStorage::hasScripts: illegal call!" );
+        if ( !isValid() )
+            return false;
+
+        const ::rtl::OUString& rSubStorageName( lcl_getScriptsSubStorageName( 
_eType ) );
+        return  m_xScriptsStorage->hasByName( rSubStorageName )
+            &&  m_xScriptsStorage->isStorageElement( rSubStorageName );
+    }
+
+    //--------------------------------------------------------------------
+    SharedStorage ScriptsStorage::getScriptsRoot( const ScriptType _eType ) 
const
+    {
+        SharedStorage xStorage;
+        if ( isValid() )
+        {
+            xStorage.reset( m_xScriptsStorage->openStorageElement(
+                lcl_getScriptsSubStorageName( _eType ), m_nStorageOpenMode
+            ) );
+        }
+        return xStorage;
+    }
+
+    //--------------------------------------------------------------------
+    void ScriptsStorage::removeScriptTypeStorage( const ScriptType _eType ) 
const
+    {
+        OSL_PRECOND( isWriteable(), "ScriptsStorage::removeScriptTypeStorage: 
not writeable!" );
+        if ( isWriteable() )
+        {
+            ::rtl::OUString sSubStorageName( lcl_getScriptsSubStorageName( 
_eType ) );
+            if ( m_xScriptsStorage->hasByName( sSubStorageName ) )
+                m_xScriptsStorage->removeElement( sSubStorageName );
+        }
+    }
+
+    //--------------------------------------------------------------------
+    bool ScriptsStorage::removeFromDocument( const Reference< XModel >& 
_rxDocument )
+    {
+        try
+        {
+            Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, 
UNO_QUERY_THROW );
+            Reference< XStorage > xDocStorage( 
xStorageDoc->getDocumentStorage(), UNO_QUERY_THROW );
+            xDocStorage->removeElement( lcl_getScriptsStorageName() );
+        }
+        catch( const Exception& )
+        {
+            DBG_UNHANDLED_EXCEPTION();
+            return false;
+        }
+        return true;
+    }
+
+    //====================================================================
+    //= ProgressDelegator
+    //====================================================================
+    class ProgressDelegator : public IProgressConsumer
+    {
+    public:
+        ProgressDelegator(  IMigrationProgress& _rDelegator,
+                            const ::rtl::OUString& _rObjectName,
+                            const ::rtl::OUString& _rAction
+                          )
+            :m_rDelegator( _rDelegator )
+            ,m_sObjectName( _rObjectName )
+            ,m_sAction( _rAction )
+        {
+        }
+        virtual ~ProgressDelegator()
+        {
+        }
+
+        // IProgressConsumer
+        virtual void    start( sal_uInt32 _nRange )
+        {
+            m_rDelegator.startObject( m_sObjectName, m_sAction, _nRange );
+        }
+        virtual void    advance( sal_uInt32 _nValue )
+        {
+            m_rDelegator.setObjectProgressValue( _nValue );
+        }
+        virtual void    end()
+        {
+            m_rDelegator.endObject();
+        }
+
+    private:
+        IMigrationProgress& m_rDelegator;
+        ::rtl::OUString     m_sObjectName;
+        ::rtl::OUString     m_sAction;
+    };
+
+       //====================================================================
        //= MigrationEngine_Impl - declaration
        //====================================================================
     class MigrationEngine_Impl
@@ -132,6 +539,7 @@
     private:
         ::comphelper::ComponentContext              m_aContext;
         const Reference< XOfficeDatabaseDocument >  m_xDocument;
+        const Reference< XModel >                   m_xDocumentModel;
         IMigrationProgress&                         m_rProgress;
         MigrationLog&                               m_rLogger;
         SubDocuments                                m_aSubDocs;
@@ -154,6 +562,17 @@
         /** migrates the macros/scripts of the given sub document
         */
         bool    impl_handleDocument_nothrow( const SubDocument& _rDocument ) 
const;
+
+        /** migrates the storage-based
+        */
+        bool    impl_migrateScriptStorage_nothrow(
+                    const SubDocument& _rDocument,
+                    const Reference< XModel >& _rxDocument,
+                    const DocumentID _nDocID,
+                    const ScriptType _eType,
+                    ProgressMixer& _rProgress,
+                    const PhaseID _nPhaseID
+                ) const;
     };
 
        //====================================================================
@@ -164,6 +583,7 @@
             const Reference< XOfficeDatabaseDocument >& _rxDocument, 
IMigrationProgress& _rProgress, MigrationLog& _rLogger )
         :m_aContext( _rContext )
         ,m_xDocument( _rxDocument )
+        ,m_xDocumentModel( _rxDocument, UNO_QUERY_THROW )
         ,m_rProgress( _rProgress )
         ,m_rLogger( _rLogger )
         ,m_aSubDocs()
@@ -215,6 +635,16 @@
             m_rProgress.setOverallProgressValue( nOverallProgressValue );
         }
 
+        // commit the root storage of the database document, for all changes 
made so far to take effect
+        if ( !lcl_commitDocumentStorage_nothrow( m_xDocumentModel ) )
+            // TODO: can we propagate the error?
+            return false;
+
+        // save the document
+        if ( !lcl_storeDocument_nothrow( m_xDocumentModel ) )
+            // TODO: is this a critical error? Do we need to report it?
+            return false;
+
         return true;
     }
 
@@ -263,16 +693,18 @@
     //--------------------------------------------------------------------
     bool MigrationEngine_Impl::impl_collectSubDocuments_nothrow()
     {
+        OSL_PRECOND( m_xDocument.is(), 
"MigrationEngine_Impl::impl_collectSubDocuments_nothrow: invalid document!" );
+        if ( !m_xDocument.is() )
+            return false;
+
         try
         {
             ::rtl::OUString sRootLocation;
 
-            Reference< XFormDocumentsSupplier > xSuppForms( m_xDocument, 
UNO_QUERY_THROW );
-            Reference< XNameAccess > xDocContainer( 
xSuppForms->getFormDocuments(), UNO_SET_THROW );
+            Reference< XNameAccess > xDocContainer( 
m_xDocument->getFormDocuments(), UNO_SET_THROW );
             m_nFormCount = lcl_collectHierarchicalElementNames_throw( 
xDocContainer, sRootLocation, m_aSubDocs, eForm );
 
-            Reference< XReportDocumentsSupplier > xSuppReports( m_xDocument, 
UNO_QUERY_THROW );
-            xDocContainer.set( xSuppReports->getReportDocuments(), 
UNO_SET_THROW );
+            xDocContainer.set( m_xDocument->getReportDocuments(), 
UNO_SET_THROW );
             m_nReportCount = lcl_collectHierarchicalElementNames_throw( 
xDocContainer, sRootLocation, m_aSubDocs, eReport );
         }
         catch( const Exception& )
@@ -286,103 +718,192 @@
     }
 
        //--------------------------------------------------------------------
-    namespace
-    {
-           //................................................................
-        static void lcl_disposeComponent_nothrow( const Reference< 
XCommandProcessor >& _rxCommandProc )
+    bool MigrationEngine_Impl::impl_handleDocument_nothrow( const SubDocument& 
_rDocument ) const
         {
-            OSL_PRECOND( _rxCommandProc.is(), "lcl_disposeComponent_nothrow: 
illegal object!" );
-            if ( !_rxCommandProc.is() )
-                return;
+        DocumentID nDocID = m_rLogger.startedDocument( _rDocument.eType, 
_rDocument.sHierarchicalName );
 
-            bool bCouldClose = false;
-            try
-            {
-                Command aCommand;
-                aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 
"shutdown" ) );
-                OSL_VERIFY( _rxCommandProc->execute(
-                    aCommand, _rxCommandProc->createCommandIdentifier(), NULL 
) >>= bCouldClose );
-            }
-            catch( const Exception& )
-            {
-               DBG_UNHANDLED_EXCEPTION();
-            }
-            if ( !bCouldClose )
+        // start the progress
+        ::rtl::OUString sObjectName;
+        sObjectName = String( MacroMigrationResId( _rDocument.eType == eForm ? 
STR_FORM : STR_REPORT ) );
+        ::comphelper::string::searchAndReplaceAsciiI( sObjectName, "$name$", 
_rDocument.sHierarchicalName );
+        m_rProgress.startObject( sObjectName, ::rtl::OUString(), 
DEFAULT_DOC_PROGRESS_RANGE );
+
+        // -----------------
+        // load the document
+        ::rtl::Reference< ProgressCapture > pStatusIndicator( new 
ProgressCapture( sObjectName, m_rProgress ) );
+        Reference< XModel > xSubDocument( lcl_loadSubDocument_nothrow( 
_rDocument, pStatusIndicator.get() ) );
+        if ( !xSubDocument.is() )
             {
-                ;
-                // TODO: can we handle this somehow?
-            }
+            pStatusIndicator->dispose();
+            m_rProgress.endObject();
+            m_rLogger.finishedDocument( nDocID, false );
+                // TODO: log the *reason* for the failure
+            return false;
         }
 
-           //................................................................
-        static Reference< XModel > lcl_loadSubDocument_nothrow( const 
SubDocument& _rDocument,
-            const Reference< XStatusIndicator >& _rxProgress )
-        {
-            Reference< XModel > xDocument;
+        // -----------------
+        // migrate the libraries
+        ProgressDelegator aDelegator( m_rProgress, sObjectName, String( 
MacroMigrationResId( STR_MIGRATING_LIBS ) ) );
+        ProgressMixer aProgressMixer( aDelegator );
+        aProgressMixer.registerPhase( PHASE_JAVASCRIPT, 1 );
+        aProgressMixer.registerPhase( PHASE_BEANSHELL, 1 );
+        aProgressMixer.registerPhase( PHASE_PYTHON, 1 );
+        aProgressMixer.registerPhase( PHASE_JAVA, 1 );
+
+        // migrate storage-based script libraries (which can be handled by 
mere storage operations)
+        bool bSuccess =
+                impl_migrateScriptStorage_nothrow( _rDocument, xSubDocument, 
nDocID, eJavaScript, aProgressMixer, PHASE_JAVASCRIPT )
+            &&  impl_migrateScriptStorage_nothrow( _rDocument, xSubDocument, 
nDocID, eBeanShell, aProgressMixer, PHASE_BEANSHELL )
+            &&  impl_migrateScriptStorage_nothrow( _rDocument, xSubDocument, 
nDocID, ePython, aProgressMixer, PHASE_PYTHON )
+            &&  impl_migrateScriptStorage_nothrow( _rDocument, xSubDocument, 
nDocID, eJava, aProgressMixer, PHASE_JAVA );
 
-            try
-            {
-                ::comphelper::NamedValueCollection aLoadArgs;
-                aLoadArgs.put( "Hidden", (sal_Bool)sal_True );
-                aLoadArgs.put( "StatusIndicator", _rxProgress );
+        // TODO: more to come
 
-                Reference< XCommandProcessor > xCommandProcessor( 
_rDocument.xCommandProcessor, UNO_SET_THROW );
-                Command aCommand;
-                aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 
"openDesign" ) );
-                aCommand.Argument <<= aLoadArgs.getPropertyValues();
-                Reference< XComponent > xDocComponent(
-                    xCommandProcessor->execute(
-                        aCommand, 
xCommandProcessor->createCommandIdentifier(), NULL
-                    ),
-                    UNO_QUERY
-                );
-                OSL_ENSURE( xDocComponent.is(), "lcl_loadSubDocument_nothrow: 
no component loaded!" );
+        // -----------------
+        // clean up
+        if ( bSuccess )
+            bSuccess =  /*lcl_commitDocumentStorage_nothrow( xSubDocument )
+                    &&  */lcl_storeEmbeddedDocument_nothrow( _rDocument )
+                    &&  ScriptsStorage::removeFromDocument( xSubDocument )
+                    &&  lcl_commitDocumentStorage_nothrow( xSubDocument );
+        lcl_disposeComponent_nothrow( _rDocument.xCommandProcessor );
+        pStatusIndicator->dispose();
 
-                xDocument.set( xDocComponent, UNO_QUERY_THROW );
+        // end the progress, just in case the ProgressCapture didn't receive 
the XStatusIndicator::end event
+        m_rProgress.endObject();
+
+        m_rLogger.finishedDocument( nDocID, bSuccess );
+        return bSuccess;
             }
-            catch( const Exception& )
+
+       //--------------------------------------------------------------------
+    namespace
             {
-                // TODO: how to proceed?
-                   DBG_UNHANDLED_EXCEPTION();
-            }
+        static ::rtl::OUString lcl_createTargetLibName( const SubDocument& 
_rDocument,
+            const ::rtl::OUString& _rSourceLibName, const Reference< XStorage 
>& _rxTargetStorage )
+        {
+            // a prefix denoting the type
+            const ::rtl::OUString sPrefix( ::rtl::OUString::createFromAscii( 
_rDocument.eType == eForm ? "Form_" : "Report_" ) );
+
+            ::rtl::OUStringBuffer aBuffer;
+            aBuffer.append( sPrefix );
+
+            // first try with the base name of the sub document
+            aBuffer.append( _rDocument.sHierarchicalName.copy(
+                _rDocument.sHierarchicalName.lastIndexOf( '/' ) + 1 ) );
+            ::rtl::OUString sTargetName( aBuffer.makeStringAndClear() );
+            if ( !_rxTargetStorage->hasByName( sTargetName ) )
+                return sTargetName;
+
+            // if this name is already used (which is valid, since documents 
with the same base
+            // name can exist in different logical folders), then use the 
complete name
+            aBuffer.append( sPrefix );
+            aBuffer.append( 
::comphelper::string::searchAndReplaceAllAsciiWithAscii(
+                _rDocument.sHierarchicalName, "/", "_" ) );
+            aBuffer.appendAscii( "_" );
+            aBuffer.append( _rSourceLibName );
+            return aBuffer.makeStringAndClear();
 
-            return xDocument;
         }
     }
 
        //--------------------------------------------------------------------
-    bool MigrationEngine_Impl::impl_handleDocument_nothrow( const SubDocument& 
_rDocument ) const
+    bool MigrationEngine_Impl::impl_migrateScriptStorage_nothrow( const 
SubDocument& _rDocument, const Reference< XModel >& _rxDocument,
+        const DocumentID _nDocID, const ScriptType _eScriptType, 
ProgressMixer& _rProgress, const PhaseID _nPhaseID ) const
     {
-        DocumentID nDocID = m_rLogger.startedDocument( _rDocument.eType, 
_rDocument.sHierarchicalName );
+        OSL_PRECOND( _rxDocument.is(), 
"MigrationEngine_Impl::impl_migrateScriptStorage_nothrow: invalid document!" );
+        if ( !_rxDocument.is() )
+            return false;
 
-        // start the progress
-        ::rtl::OUString aProgress;
-        aProgress = String( MacroMigrationResId( _rDocument.eType == eForm ? 
STR_FORM : STR_REPORT ) );
-        ::comphelper::string::searchAndReplaceAsciiI( aProgress, "$name$", 
_rDocument.sHierarchicalName );
-        m_rProgress.startObject( aProgress, ::rtl::OUString(), 
DEFAULT_DOC_PROGRESS_RANGE );
+        ScriptsStorage aDatabaseScripts;
+            // the scripts of our complete database document - created on 
demand only
+        SharedStorage xTargetStorage;
+            // the target for moving the scripts storages - created on demand 
only
 
-        // load the document
-        ::rtl::Reference< ProgressCapture > pStatusIndicator( new 
ProgressCapture( aProgress, m_rProgress ) );
-        Reference< XModel > xDocument( lcl_loadSubDocument_nothrow( 
_rDocument, pStatusIndicator.get() ) );
-        if ( !xDocument.is() )
+        try
         {
-            pStatusIndicator->dispose();
-            m_rProgress.endObject();
-            m_rLogger.finishedDocument( nDocID, false );
-                // TODO: log the *reason* for the failure
+            // the root storage of the document whose scripts are to be 
migrated
+            ScriptsStorage aDocStorage( _rxDocument, ScriptsStorage::WRITE );
+            if  (   !aDocStorage.isValid()
+                ||  !aDocStorage.hasScripts( _eScriptType )
+                )
+            {
+                // no scripts at all, or no scripts of the given type
+                _rProgress.startPhase( _nPhaseID, 1 );
+                _rProgress.endPhase();
+                return true;
+            }
+
+            SharedStorage xScriptsRoot( aDocStorage.getScriptsRoot( 
_eScriptType ) );
+            if ( !xScriptsRoot.is() )
+                throw RuntimeException( ::rtl::OUString( 
RTL_CONSTASCII_USTRINGPARAM( "internal error" ) ), NULL );
+
+            // loop through the script libraries
+            Sequence< ::rtl::OUString > aStorageElements( 
xScriptsRoot->getElementNames() );
+            _rProgress.startPhase( _nPhaseID, aStorageElements.getLength() );
+
+            for (   const ::rtl::OUString* element = 
aStorageElements.getConstArray();
+                    element != aStorageElements.getConstArray() + 
aStorageElements.getLength();
+                    ++element
+                )
+            {
+                bool bIsScriptLibrary = xScriptsRoot->isStorageElement( 
*element );
+                OSL_ENSURE( bIsScriptLibrary,
+                    "MigrationEngine_Impl::impl_migrateScriptStorage_nothrow: 
warning: unknown scripts storage structure!" );
+                    // we cannot handle this. We would need to copy this 
stream to the respective scripts storage
+                    // of the database document, but we cannot guarantee that 
the name is not used, yet, and we cannot
+                    // simply rename the thing.
+                if ( !bIsScriptLibrary )
+                    // TODO: propagate the type of the error
+                    return false;
+
+                // ensure we have access to the DBDoc's scripts storage
+                if ( !aDatabaseScripts.isValid() )
+                {   // not needed 'til now
+                    aDatabaseScripts.bind( m_xDocumentModel, 
ScriptsStorage::WRITE );
+                    if ( !aDatabaseScripts.isValid() )
+                        // TODO: propagate the type of the error
+                        return false;
+                    xTargetStorage = aDatabaseScripts.getScriptsRoot( 
_eScriptType );
+                    if ( !xTargetStorage.is() )
+                        // TODO: propagate the type of the error
             return false;
         }
 
-        // TODO
+                // move the library to the DBDoc's scripts library, under the 
new name
+                ::rtl::OUString sNewLibName( lcl_createTargetLibName( 
_rDocument, *element, xTargetStorage ) );
+                xScriptsRoot->moveElementTo( *element, xTargetStorage, 
sNewLibName );
 
-        // clean up
-        lcl_disposeComponent_nothrow( _rDocument.xCommandProcessor );
-        pStatusIndicator->dispose();
+                // log the fact that we moved the library
+                m_rLogger.movedLibrary( _nDocID, _eScriptType, *element, 
sNewLibName );
 
-        // end the progress, just in case the ProgressCapture didn't receive 
the XStatusIndicator::end event
-        m_rProgress.endObject();
+                // progress
+                _rProgress.advancePhase( element - 
aStorageElements.getConstArray() );
+            }
+
+            // commit the storages, so the changes we made persist
+            if ( !lcl_commitStorage_nothrow( xScriptsRoot ) )
+                // TODO: propagate the type of the error
+                return false;
+            if ( xTargetStorage.is() && !lcl_commitStorage_nothrow( 
xTargetStorage ) )
+                // TODO: propagate the type of the error
+                return false;
+
+            // now that the concrete scripts storage does not have any 
elements anymore,
+            // remove it
+            xScriptsRoot.reset( NULL ); // need to reset the storage to be 
allowed to remove it
+            aDocStorage.removeScriptTypeStorage( _eScriptType );
+
+            // progress - we're done with this phase
+            _rProgress.endPhase();
+        }
+        catch( const Exception& )
+        {
+               DBG_UNHANDLED_EXCEPTION();
+            // TODO: propagate the error to the user.
+            return false;
+        }
 
-        m_rLogger.finishedDocument( nDocID, true );
         return true;
     }
 
@@ -396,8 +917,9 @@
        //= MigrationEngine
        //====================================================================
        //--------------------------------------------------------------------
-    MigrationEngine::MigrationEngine( const ::comphelper::ComponentContext& 
_rContext, const Reference< XOfficeDatabaseDocument >& _rxDocument,
-            IMigrationProgress& _rProgress, MigrationLog& _rLogger )
+    MigrationEngine::MigrationEngine( const ::comphelper::ComponentContext& 
_rContext,
+            const Reference< XOfficeDatabaseDocument >& _rxDocument, 
IMigrationProgress& _rProgress,
+            MigrationLog& _rLogger )
         :m_pImpl( new MigrationEngine_Impl( _rContext, _rxDocument, 
_rProgress, _rLogger ) )
     {
     }




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

Reply via email to