Tag: cws_dev300_odbmacros3 User: fs Date: 2008-04-21 21:23:27+0000 Modified: dba/dbaccess/source/ext/macromigration/migrationengine.cxx
Log: migrate Basic macros and UNO dialogs 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.2.2&r2=1.4.2.3 Delta lines: +177 -22 ---------------------- --- migrationengine.cxx 2008-04-21 10:40:24+0000 1.4.2.2 +++ migrationengine.cxx 2008-04-21 21:23:24+0000 1.4.2.3 @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: migrationengine.cxx,v $ - * $Revision: 1.4.2.2 $ + * $Revision: 1.4.2.3 $ * * This file is part of OpenOffice.org. * @@ -54,9 +54,13 @@ #include <com/sun/star/embed/XTransactedObject.hpp> #include <com/sun/star/frame/XStorable.hpp> #include <com/sun/star/embed/XEmbedPersist.hpp> +#include <com/sun/star/script/DocumentScriptLibraryContainer.hpp> +#include <com/sun/star/script/DocumentDialogLibraryContainer.hpp> +#include <com/sun/star/document/XEmbeddedScripts.hpp> /** === end UNO includes === **/ #include <comphelper/string.hxx> +#include <comphelper/types.hxx> #include <comphelper/namedvaluecollection.hxx> #include <tools/string.hxx> #include <tools/diagnose_ex.h> @@ -103,6 +107,11 @@ using ::com::sun::star::embed::XTransactedObject; using ::com::sun::star::frame::XStorable; using ::com::sun::star::embed::XEmbedPersist; + using ::com::sun::star::script::DocumentDialogLibraryContainer; + using ::com::sun::star::script::DocumentScriptLibraryContainer; + using ::com::sun::star::script::XStorageBasedLibraryContainer; + using ::com::sun::star::document::XEmbeddedScripts; + using ::com::sun::star::container::XNameContainer; /** === end UNO using === **/ namespace ElementModes = ::com::sun::star::embed::ElementModes; @@ -111,6 +120,8 @@ #define PHASE_BEANSHELL 2 #define PHASE_PYTHON 3 #define PHASE_JAVA 4 +#define PHASE_BASIC 5 +#define PHASE_DIALOGS 6 //==================================================================== //= SubDocument @@ -184,12 +195,12 @@ } //---------------------------------------------------------------- - static void lcl_disposeComponent_nothrow( const Reference< XCommandProcessor >& _rxCommandProc ) + static void lcl_closeComponent_nothrow( const Reference< XCommandProcessor >& _rxCommandProc ) { bool bCouldClose = false; try { - OSL_VERIFY( lcl_executeCommand_throw( _rxCommandProc, "shutdown" ) >>= bCouldClose ); + OSL_VERIFY( lcl_executeCommand_throw( _rxCommandProc, "close" ) >>= bCouldClose ); } catch( const Exception& ) { @@ -542,6 +553,7 @@ const Reference< XModel > m_xDocumentModel; IMigrationProgress& m_rProgress; MigrationLog& m_rLogger; + mutable DocumentID m_nCurrentDocumentID; SubDocuments m_aSubDocs; size_t m_nFormCount; size_t m_nReportCount; @@ -563,13 +575,22 @@ */ bool impl_handleDocument_nothrow( const SubDocument& _rDocument ) const; - /** migrates the storage-based + /** migrates the scripts of the given "storage-based" script typ */ bool impl_migrateScriptStorage_nothrow( const SubDocument& _rDocument, const Reference< XModel >& _rxDocument, - const DocumentID _nDocID, - const ScriptType _eType, + const ScriptType _eScriptType, + ProgressMixer& _rProgress, + const PhaseID _nPhaseID + ) const; + + /** migrates the content of the given "container based" libraries (Basic/Dialogs) + */ + bool impl_migrateContainerLibraries_nothrow( + const SubDocument& _rDocument, + const Reference< XModel >& _rxDocument, + const ScriptType _eScriptType, ProgressMixer& _rProgress, const PhaseID _nPhaseID ) const; @@ -586,6 +607,7 @@ ,m_xDocumentModel( _rxDocument, UNO_QUERY_THROW ) ,m_rProgress( _rProgress ) ,m_rLogger( _rLogger ) + ,m_nCurrentDocumentID( - 1 ) ,m_aSubDocs() ,m_nFormCount( 0 ) ,m_nReportCount( 0 ) @@ -720,7 +742,9 @@ //-------------------------------------------------------------------- bool MigrationEngine_Impl::impl_handleDocument_nothrow( const SubDocument& _rDocument ) const { - DocumentID nDocID = m_rLogger.startedDocument( _rDocument.eType, _rDocument.sHierarchicalName ); + OSL_ENSURE( m_nCurrentDocumentID == -1, + "MigrationEngine_Impl::impl_handleDocument_nothrow: there already is a current document!"); + m_nCurrentDocumentID = m_rLogger.startedDocument( _rDocument.eType, _rDocument.sHierarchicalName ); // start the progress ::rtl::OUString sObjectName; @@ -736,7 +760,8 @@ { pStatusIndicator->dispose(); m_rProgress.endObject(); - m_rLogger.finishedDocument( nDocID, false ); + m_nCurrentDocumentID = -1; + m_rLogger.finishedDocument( m_nCurrentDocumentID, false ); // TODO: log the *reason* for the failure return false; } @@ -749,29 +774,40 @@ aProgressMixer.registerPhase( PHASE_BEANSHELL, 1 ); aProgressMixer.registerPhase( PHASE_PYTHON, 1 ); aProgressMixer.registerPhase( PHASE_JAVA, 1 ); + aProgressMixer.registerPhase( PHASE_BASIC, 5 ); + // more weight than then others, assuming their usually are much Basic macros than any other scripts + aProgressMixer.registerPhase( PHASE_DIALOGS, 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 ); + impl_migrateScriptStorage_nothrow( _rDocument, xSubDocument, eJavaScript, aProgressMixer, PHASE_JAVASCRIPT ) + && impl_migrateScriptStorage_nothrow( _rDocument, xSubDocument, eBeanShell, aProgressMixer, PHASE_BEANSHELL ) + && impl_migrateScriptStorage_nothrow( _rDocument, xSubDocument, ePython, aProgressMixer, PHASE_PYTHON ) + && impl_migrateScriptStorage_nothrow( _rDocument, xSubDocument, eJava, aProgressMixer, PHASE_JAVA ); + + // migrate Basic and dialog libraries + bSuccess = bSuccess + && impl_migrateContainerLibraries_nothrow( _rDocument, xSubDocument, eBasic, aProgressMixer, PHASE_BASIC ) + && impl_migrateContainerLibraries_nothrow( _rDocument, xSubDocument, eDialog, aProgressMixer, PHASE_DIALOGS ); // TODO: more to come // ----------------- // clean up - if ( bSuccess ) - bSuccess = ScriptsStorage::removeFromDocument( xSubDocument ) + // store the sub document, including removal of the (now obsolete) "Scripts" sub folder + bSuccess = bSuccess + && ScriptsStorage::removeFromDocument( xSubDocument ) && lcl_commitDocumentStorage_nothrow( xSubDocument ) && lcl_storeEmbeddedDocument_nothrow( _rDocument ); - lcl_disposeComponent_nothrow( _rDocument.xCommandProcessor ); + + lcl_closeComponent_nothrow( _rDocument.xCommandProcessor ); pStatusIndicator->dispose(); // end the progress, just in case the ProgressCapture didn't receive the XStatusIndicator::end event m_rProgress.endObject(); - m_rLogger.finishedDocument( nDocID, bSuccess ); + m_rLogger.finishedDocument( m_nCurrentDocumentID, bSuccess ); + m_nCurrentDocumentID = -1; return bSuccess; } @@ -779,7 +815,7 @@ namespace { static ::rtl::OUString lcl_createTargetLibName( const SubDocument& _rDocument, - const ::rtl::OUString& _rSourceLibName, const Reference< XStorage >& _rxTargetStorage ) + const ::rtl::OUString& _rSourceLibName, const Reference< XNameAccess >& _rxTargetStorage ) { // a prefix denoting the type const ::rtl::OUString sPrefix( ::rtl::OUString::createFromAscii( _rDocument.eType == eForm ? "Form_" : "Report_" ) ); @@ -790,6 +826,8 @@ // first try with the base name of the sub document aBuffer.append( _rDocument.sHierarchicalName.copy( _rDocument.sHierarchicalName.lastIndexOf( '/' ) + 1 ) ); + aBuffer.appendAscii( "_" ); + aBuffer.append( _rSourceLibName ); ::rtl::OUString sTargetName( aBuffer.makeStringAndClear() ); if ( !_rxTargetStorage->hasByName( sTargetName ) ) return sTargetName; @@ -808,7 +846,7 @@ //-------------------------------------------------------------------- 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 + const ScriptType _eScriptType, ProgressMixer& _rProgress, const PhaseID _nPhaseID ) const { OSL_PRECOND( _rxDocument.is(), "MigrationEngine_Impl::impl_migrateScriptStorage_nothrow: invalid document!" ); if ( !_rxDocument.is() ) @@ -870,11 +908,11 @@ } // move the library to the DBDoc's scripts library, under the new name - ::rtl::OUString sNewLibName( lcl_createTargetLibName( _rDocument, *element, xTargetStorage ) ); + ::rtl::OUString sNewLibName( lcl_createTargetLibName( _rDocument, *element, xTargetStorage.getTyped().get() ) ); xScriptsRoot->moveElementTo( *element, xTargetStorage, sNewLibName ); // log the fact that we moved the library - m_rLogger.movedLibrary( _nDocID, _eScriptType, *element, sNewLibName ); + m_rLogger.movedLibrary( m_nCurrentDocumentID, _eScriptType, *element, sNewLibName ); // progress _rProgress.advancePhase( element - aStorageElements.getConstArray() ); @@ -907,6 +945,123 @@ } //-------------------------------------------------------------------- + bool MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow( const SubDocument& _rDocument, + const Reference< XModel >& _rxDocument, const ScriptType _eScriptType, + ProgressMixer& _rProgress, const PhaseID _nPhaseID ) const + { + OSL_PRECOND( ( _eScriptType == eBasic ) || ( _eScriptType == eDialog ), + "MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow: illegal script type!" ); + + try + { + // access library container of the sub document + Reference< XEmbeddedScripts > xSubDocScripts( _rxDocument, UNO_QUERY ); + if ( !xSubDocScripts.is() ) + // no script support in the sub document -> nothing to migrate + // (though ... this is suspicious, at least ...) + return true; + Reference< XStorageBasedLibraryContainer > xSourceLibraries( + _eScriptType == eBasic ? xSubDocScripts->getBasicLibraries() : xSubDocScripts->getDialogLibraries(), + UNO_QUERY_THROW + ); + Sequence< ::rtl::OUString > aSourceLibNames( xSourceLibraries->getElementNames() ); + _rProgress.startPhase( _nPhaseID, aSourceLibNames.getLength() ); + + if ( !xSourceLibraries->hasElements() ) + { + _rProgress.endPhase(); + return true; + } + + // create library containers for the document - those will be the target for the migration + Reference< XStorageBasedDocument > xStorageDoc( m_xDocument, UNO_QUERY_THROW ); + Reference< XStorageBasedLibraryContainer > xTargetLibraries; + if ( _eScriptType == eBasic ) + { + xTargetLibraries.set( DocumentScriptLibraryContainer::create( + m_aContext.getUNOContext(), xStorageDoc ), UNO_QUERY_THROW ); + } + else + { + xTargetLibraries.set( DocumentDialogLibraryContainer::create( + m_aContext.getUNOContext(), xStorageDoc ), UNO_QUERY_THROW ); + } + + // copy all libs to the target, with potentially renaming them + const ::rtl::OUString* pSourceLibBegin = aSourceLibNames.getConstArray(); + const ::rtl::OUString* pSourceLibEnd = pSourceLibBegin + aSourceLibNames.getLength(); + for ( const ::rtl::OUString* pSourceLibName = pSourceLibBegin; + pSourceLibName != pSourceLibEnd; + ++pSourceLibName + ) + { + ::rtl::OUString sNewLibName( lcl_createTargetLibName( _rDocument, *pSourceLibName, xTargetLibraries.get() ) ); + + if ( xSourceLibraries->isLibraryLink( *pSourceLibName ) ) + { + // just re-create the link in the target library + xTargetLibraries->createLibraryLink( + sNewLibName, + xSourceLibraries->getLibraryLinkURL( *pSourceLibName ), + xSourceLibraries->isLibraryReadOnly( *pSourceLibName ) + ); + } + else + { + if ( !xSourceLibraries->isLibraryLoaded( *pSourceLibName ) ) + xSourceLibraries->loadLibrary( *pSourceLibName ); + + // copy the content of this particular libary + Reference< XNameAccess > xSourceLib( xSourceLibraries->getByName( *pSourceLibName ), UNO_QUERY_THROW ); + Reference< XNameContainer > xTargetLib( xTargetLibraries->createLibrary( sNewLibName ), UNO_QUERY_THROW ); + + Sequence< ::rtl::OUString > aLibElementNames( xSourceLib->getElementNames() ); + for ( const ::rtl::OUString* pSourceElementName = aLibElementNames.getConstArray(); + pSourceElementName != aLibElementNames.getConstArray() + aLibElementNames.getLength(); + ++pSourceElementName + ) + { + Any aElement = xSourceLib->getByName( *pSourceElementName ); + OSL_ENSURE( aElement.hasValue(), + "MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow: invalid (empty) lib element!" ); + xTargetLib->insertByName( *pSourceElementName, aElement ); + } + + // transfer the read-only flag + xTargetLibraries->setLibraryReadOnly( + sNewLibName, xSourceLibraries->isLibraryReadOnly( *pSourceLibName ) ); + } + + // remove the source lib + xSourceLibraries->removeLibrary( *pSourceLibName ); + + // tell the logger + m_rLogger.movedLibrary( m_nCurrentDocumentID, _eScriptType, *pSourceLibName, sNewLibName ); + + // tell the progress + _rProgress.advancePhase( pSourceLibName - pSourceLibBegin ); + } + + // clean up + xSourceLibraries->storeLibraries(); + + xTargetLibraries->storeLibraries(); + Reference< XStorage > xTargetRoot( xTargetLibraries->getRootLocation(), UNO_QUERY_THROW ); + lcl_commitStorage_nothrow( xTargetRoot ); + + // done with this phase + _rProgress.endPhase(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + // TODO: can we handle this? Do we need to revert the changes? + } + + return true; + } + + //-------------------------------------------------------------------- void MigrationEngine_Impl::impl_reportError_nothrow( const Any& _rError ) const { DocumentErrorHandling::reportError( m_aContext, m_xDocument, _rError ); --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
