INTEGRATION: CWS odbmacros2 (1.1.4); FILE ADDED
2008/03/05 21:03:47 fs 1.1.4.2: ongoing work - merge all the changes which so far happened on the intermediate branch 'odbmacros_2_5' 2008/02/14 12:16:19 fs 1.1.4.1: file migrationengine.cxx was added on branch cws_src680_odbmacros2 on 2008-03-05 21:03:47 +0000
This commit is contained in:
parent
a5ca6fbb5c
commit
ae56326aac
1 changed files with 435 additions and 0 deletions
435
dbaccess/source/ext/macromigration/migrationengine.cxx
Normal file
435
dbaccess/source/ext/macromigration/migrationengine.cxx
Normal file
|
@ -0,0 +1,435 @@
|
|||
/*************************************************************************
|
||||
*
|
||||
* OpenOffice.org - a multi-platform office productivity suite
|
||||
*
|
||||
* $RCSfile: migrationengine.cxx,v $
|
||||
*
|
||||
* $Revision: 1.2 $
|
||||
*
|
||||
* last change: $Author: kz $ $Date: 2008-03-06 18:04:57 $
|
||||
*
|
||||
* The Contents of this file are made available subject to
|
||||
* the terms of GNU Lesser General Public License Version 2.1.
|
||||
*
|
||||
*
|
||||
* GNU Lesser General Public License Version 2.1
|
||||
* =============================================
|
||||
* Copyright 2005 by Sun Microsystems, Inc.
|
||||
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License version 2.1, as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
// MARKER(update_precomp.py): autogen include statement, do not remove
|
||||
#include "precompiled_dbaccess.hxx"
|
||||
|
||||
#include "dbmm_global.hrc"
|
||||
#include "dbmm_module.hxx"
|
||||
#include "dbmm_types.hxx"
|
||||
#include "docerrorhandling.hxx"
|
||||
#include "migrationengine.hxx"
|
||||
#include "migrationprogress.hxx"
|
||||
#include "migrationlog.hxx"
|
||||
#include "progresscapture.hxx"
|
||||
|
||||
/** === begin UNO includes === **/
|
||||
#include <com/sun/star/sdb/XFormDocumentsSupplier.hpp>
|
||||
#include <com/sun/star/sdb/XReportDocumentsSupplier.hpp>
|
||||
#include <com/sun/star/util/XCloseable.hpp>
|
||||
#include <com/sun/star/frame/XModel.hpp>
|
||||
#include <com/sun/star/frame/XComponentLoader.hpp>
|
||||
#include <com/sun/star/ucb/XCommandProcessor.hpp>
|
||||
#include <com/sun/star/embed/XComponentSupplier.hpp>
|
||||
/** === end UNO includes === **/
|
||||
|
||||
#include <comphelper/string.hxx>
|
||||
#include <comphelper/namedvaluecollection.hxx>
|
||||
#include <tools/string.hxx>
|
||||
#include <tools/diagnose_ex.h>
|
||||
#include <rtl/ustrbuf.hxx>
|
||||
#include <rtl/ref.hxx>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define DEFAULT_DOC_PROGRESS_RANGE 100000
|
||||
|
||||
//........................................................................
|
||||
namespace dbmm
|
||||
{
|
||||
//........................................................................
|
||||
|
||||
/** === begin UNO using === **/
|
||||
using ::com::sun::star::uno::Reference;
|
||||
using ::com::sun::star::uno::XInterface;
|
||||
using ::com::sun::star::uno::UNO_QUERY;
|
||||
using ::com::sun::star::uno::UNO_QUERY_THROW;
|
||||
using ::com::sun::star::uno::UNO_SET_THROW;
|
||||
using ::com::sun::star::uno::Exception;
|
||||
using ::com::sun::star::uno::RuntimeException;
|
||||
using ::com::sun::star::uno::Any;
|
||||
using ::com::sun::star::uno::makeAny;
|
||||
using ::com::sun::star::sdb::XOfficeDatabaseDocument;
|
||||
using ::com::sun::star::sdb::XFormDocumentsSupplier;
|
||||
using ::com::sun::star::sdb::XReportDocumentsSupplier;
|
||||
using ::com::sun::star::container::XNameAccess;
|
||||
using ::com::sun::star::uno::Sequence;
|
||||
using ::com::sun::star::util::XCloseable;
|
||||
using ::com::sun::star::util::CloseVetoException;
|
||||
using ::com::sun::star::lang::XComponent;
|
||||
using ::com::sun::star::frame::XModel;
|
||||
using ::com::sun::star::frame::XComponentLoader;
|
||||
using ::com::sun::star::ucb::XCommandProcessor;
|
||||
using ::com::sun::star::ucb::Command;
|
||||
using ::com::sun::star::embed::XComponentSupplier;
|
||||
using ::com::sun::star::task::XStatusIndicator;
|
||||
/** === end UNO using === **/
|
||||
|
||||
//====================================================================
|
||||
//= SubDocument
|
||||
//====================================================================
|
||||
struct SubDocument
|
||||
{
|
||||
const Reference< XCommandProcessor > xCommandProcessor;
|
||||
const ::rtl::OUString sHierarchicalName;
|
||||
const SubDocumentType eType;
|
||||
|
||||
SubDocument( const Reference< XCommandProcessor >& _rxCommandProcessor, const ::rtl::OUString& _rName, const SubDocumentType _eType )
|
||||
:xCommandProcessor( _rxCommandProcessor )
|
||||
,sHierarchicalName( _rName )
|
||||
,eType( _eType )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef ::std::vector< SubDocument > SubDocuments;
|
||||
|
||||
//====================================================================
|
||||
//= MigrationEngine_Impl - declaration
|
||||
//====================================================================
|
||||
class MigrationEngine_Impl
|
||||
{
|
||||
public:
|
||||
MigrationEngine_Impl(
|
||||
const ::comphelper::ComponentContext& _rContext,
|
||||
const Reference< XOfficeDatabaseDocument >& _rxDocument,
|
||||
IMigrationProgress& _rProgress,
|
||||
MigrationLog& _rLogger
|
||||
);
|
||||
~MigrationEngine_Impl();
|
||||
|
||||
inline sal_Int32 getFormCount() const { return m_nFormCount; }
|
||||
inline sal_Int32 getReportCount()const { return m_nReportCount; }
|
||||
bool migrateAll();
|
||||
|
||||
private:
|
||||
::comphelper::ComponentContext m_aContext;
|
||||
const Reference< XOfficeDatabaseDocument > m_xDocument;
|
||||
IMigrationProgress& m_rProgress;
|
||||
MigrationLog& m_rLogger;
|
||||
SubDocuments m_aSubDocs;
|
||||
size_t m_nFormCount;
|
||||
size_t m_nReportCount;
|
||||
|
||||
private:
|
||||
/** collects a description of all sub documents of our database document
|
||||
|
||||
@return
|
||||
<TRUE/> if and only if collecting the documents was successful
|
||||
*/
|
||||
bool impl_collectSubDocuments_nothrow();
|
||||
|
||||
/** reports the given error (usually an exception caught on the caller's side)
|
||||
to the user, using the document's interaction handler, if any.
|
||||
*/
|
||||
void impl_reportError_nothrow( const Any& _rError ) const;
|
||||
|
||||
/** migrates the macros/scripts of the given sub document
|
||||
*/
|
||||
bool impl_handleDocument_nothrow( const SubDocument& _rDocument ) const;
|
||||
};
|
||||
|
||||
//====================================================================
|
||||
//= MigrationEngine_Impl - implementation
|
||||
//====================================================================
|
||||
//--------------------------------------------------------------------
|
||||
MigrationEngine_Impl::MigrationEngine_Impl( const ::comphelper::ComponentContext& _rContext,
|
||||
const Reference< XOfficeDatabaseDocument >& _rxDocument, IMigrationProgress& _rProgress, MigrationLog& _rLogger )
|
||||
:m_aContext( _rContext )
|
||||
,m_xDocument( _rxDocument )
|
||||
,m_rProgress( _rProgress )
|
||||
,m_rLogger( _rLogger )
|
||||
,m_aSubDocs()
|
||||
,m_nFormCount( 0 )
|
||||
,m_nReportCount( 0 )
|
||||
{
|
||||
OSL_VERIFY( impl_collectSubDocuments_nothrow() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
MigrationEngine_Impl::~MigrationEngine_Impl()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool MigrationEngine_Impl::migrateAll()
|
||||
{
|
||||
if ( m_aSubDocs.empty() )
|
||||
{
|
||||
OSL_ENSURE( false, "MigrationEngine_Impl::migrateAll: no forms/reports found!" );
|
||||
// The whole migration wizard is not expected to be called when there are no forms/reports
|
||||
// with macros, not to mention when there are no forms/reports at all.
|
||||
return false;
|
||||
}
|
||||
|
||||
// initialize global progress
|
||||
sal_Int32 nOverallRange( m_aSubDocs.size() );
|
||||
String sProgressSkeleton = String( MacroMigrationResId( STR_OVERALL_PROGRESS ) );
|
||||
sProgressSkeleton.SearchAndReplaceAscii( "$overall$", String::CreateFromInt32( nOverallRange ) );
|
||||
|
||||
m_rProgress.start( nOverallRange );
|
||||
|
||||
for ( SubDocuments::const_iterator doc = m_aSubDocs.begin();
|
||||
doc != m_aSubDocs.end();
|
||||
++doc
|
||||
)
|
||||
{
|
||||
sal_Int32 nOverallProgressValue( doc - m_aSubDocs.begin() + 1 );
|
||||
// update overall progress text
|
||||
::rtl::OUString sOverallProgress( sProgressSkeleton );
|
||||
::comphelper::string::searchAndReplaceAsciiI( sOverallProgress, "$current$", ::rtl::OUString::valueOf( nOverallProgressValue ) );
|
||||
m_rProgress.setOverallProgressText( sOverallProgress );
|
||||
|
||||
// migrate document
|
||||
if ( !impl_handleDocument_nothrow( *doc ) )
|
||||
return false;
|
||||
|
||||
// update overall progress vallue
|
||||
m_rProgress.setOverallProgressValue( nOverallProgressValue );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
namespace
|
||||
{
|
||||
size_t lcl_collectHierarchicalElementNames_throw(
|
||||
const Reference< XNameAccess >& _rxContainer, const ::rtl::OUString& _rContainerLoc,
|
||||
SubDocuments& _out_rDocs, const SubDocumentType _eType )
|
||||
{
|
||||
size_t nAddedElements = 0;
|
||||
|
||||
const ::rtl::OUString sHierarhicalBase(
|
||||
_rContainerLoc.getLength() ? ::rtl::OUStringBuffer( _rContainerLoc ).appendAscii( "/" ).makeStringAndClear()
|
||||
: ::rtl::OUString() );
|
||||
|
||||
Sequence< ::rtl::OUString > aElementNames( _rxContainer->getElementNames() );
|
||||
for ( const ::rtl::OUString* elementName = aElementNames.getConstArray();
|
||||
elementName != aElementNames.getConstArray() + aElementNames.getLength();
|
||||
++elementName
|
||||
)
|
||||
{
|
||||
Any aElement( _rxContainer->getByName( *elementName ) );
|
||||
::rtl::OUString sElementName( ::rtl::OUStringBuffer( sHierarhicalBase ).append( *elementName ) );
|
||||
|
||||
Reference< XNameAccess > xSubContainer( aElement, UNO_QUERY );
|
||||
if ( xSubContainer.is() )
|
||||
{
|
||||
nAddedElements += lcl_collectHierarchicalElementNames_throw( xSubContainer, sElementName, _out_rDocs, _eType );
|
||||
}
|
||||
else
|
||||
{
|
||||
Reference< XCommandProcessor > xCommandProcessor( aElement, UNO_QUERY );
|
||||
OSL_ENSURE( xCommandProcessor.is(), "lcl_collectHierarchicalElementNames_throw: no container, and no comand processor? What *is* it, then?!" );
|
||||
if ( xCommandProcessor.is() )
|
||||
{
|
||||
_out_rDocs.push_back( SubDocument( xCommandProcessor, sElementName, _eType ) );
|
||||
++nAddedElements;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nAddedElements;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool MigrationEngine_Impl::impl_collectSubDocuments_nothrow()
|
||||
{
|
||||
try
|
||||
{
|
||||
::rtl::OUString sRootLocation;
|
||||
|
||||
Reference< XFormDocumentsSupplier > xSuppForms( m_xDocument, UNO_QUERY_THROW );
|
||||
Reference< XNameAccess > xDocContainer( xSuppForms->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 );
|
||||
m_nReportCount = lcl_collectHierarchicalElementNames_throw( xDocContainer, sRootLocation, m_aSubDocs, eReport );
|
||||
}
|
||||
catch( const Exception& )
|
||||
{
|
||||
// TODO: check whether we can handle this error
|
||||
DBG_UNHANDLED_EXCEPTION();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
namespace
|
||||
{
|
||||
//................................................................
|
||||
static void lcl_disposeComponent_nothrow( const Reference< XCommandProcessor >& _rxCommandProc )
|
||||
{
|
||||
OSL_PRECOND( _rxCommandProc.is(), "lcl_disposeComponent_nothrow: illegal object!" );
|
||||
if ( !_rxCommandProc.is() )
|
||||
return;
|
||||
|
||||
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 )
|
||||
{
|
||||
;
|
||||
// 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 MigrationEngine_Impl::impl_handleDocument_nothrow( const SubDocument& _rDocument ) const
|
||||
{
|
||||
DocumentID nDocID = m_rLogger.startedDocument( _rDocument.eType, _rDocument.sHierarchicalName );
|
||||
|
||||
// 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 );
|
||||
|
||||
// load the document
|
||||
::rtl::Reference< ProgressCapture > pStatusIndicator( new ProgressCapture( aProgress, m_rProgress ) );
|
||||
Reference< XModel > xDocument( lcl_loadSubDocument_nothrow( _rDocument, pStatusIndicator.get() ) );
|
||||
if ( !xDocument.is() )
|
||||
{
|
||||
pStatusIndicator->dispose();
|
||||
m_rProgress.endObject();
|
||||
m_rLogger.finishedDocument( nDocID, false );
|
||||
// TODO: log the *reason* for the failure
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
// clean up
|
||||
lcl_disposeComponent_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, true );
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void MigrationEngine_Impl::impl_reportError_nothrow( const Any& _rError ) const
|
||||
{
|
||||
DocumentErrorHandling::reportError( m_aContext, m_xDocument, _rError );
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
//= MigrationEngine
|
||||
//====================================================================
|
||||
//--------------------------------------------------------------------
|
||||
MigrationEngine::MigrationEngine( const ::comphelper::ComponentContext& _rContext, const Reference< XOfficeDatabaseDocument >& _rxDocument,
|
||||
IMigrationProgress& _rProgress, MigrationLog& _rLogger )
|
||||
:m_pImpl( new MigrationEngine_Impl( _rContext, _rxDocument, _rProgress, _rLogger ) )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
MigrationEngine::~MigrationEngine()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
sal_Int32 MigrationEngine::getFormCount() const
|
||||
{
|
||||
return m_pImpl->getFormCount();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
sal_Int32 MigrationEngine::getReportCount() const
|
||||
{
|
||||
return m_pImpl->getReportCount();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool MigrationEngine::migrateAll()
|
||||
{
|
||||
return m_pImpl->migrateAll();
|
||||
}
|
||||
|
||||
//........................................................................
|
||||
} // namespace dbmm
|
||||
//........................................................................
|
Loading…
Reference in a new issue